chefspec 4.0.2 → 4.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +2 -1
- data/CHANGELOG.md +19 -0
- data/README.md +84 -87
- data/chefspec.gemspec +1 -1
- data/examples/apt_package/spec/install_spec.rb +1 -1
- data/examples/apt_package/spec/purge_spec.rb +1 -1
- data/examples/apt_package/spec/reconfig_spec.rb +1 -1
- data/examples/apt_package/spec/remove_spec.rb +1 -1
- data/examples/apt_package/spec/upgrade_spec.rb +1 -1
- data/examples/attributes/spec/default_spec.rb +1 -1
- data/examples/batch/spec/run_spec.rb +1 -1
- data/examples/cached/spec/default_spec.rb +1 -1
- data/examples/chef_gem/spec/install_spec.rb +1 -1
- data/examples/chef_gem/spec/purge_spec.rb +1 -1
- data/examples/chef_gem/spec/reconfig_spec.rb +1 -1
- data/examples/chef_gem/spec/remove_spec.rb +1 -1
- data/examples/chef_gem/spec/upgrade_spec.rb +1 -1
- data/examples/compile_time/spec/default_spec.rb +1 -1
- data/examples/cookbook_file/spec/create_if_missing_spec.rb +1 -1
- data/examples/cookbook_file/spec/create_spec.rb +1 -1
- data/examples/cookbook_file/spec/delete_spec.rb +1 -1
- data/examples/cookbook_file/spec/touch_spec.rb +1 -1
- data/examples/cron/spec/create_spec.rb +1 -1
- data/examples/cron/spec/delete_spec.rb +1 -1
- data/examples/custom_matcher/libraries/matcher.rb +1 -1
- data/examples/custom_matcher/spec/install_spec.rb +1 -1
- data/examples/custom_matcher/spec/remove_spec.rb +1 -1
- data/examples/deploy/spec/deploy_spec.rb +1 -1
- data/examples/deploy/spec/force_deploy_spec.rb +1 -1
- data/examples/deploy/spec/rollback_spec.rb +1 -1
- data/examples/directory/spec/create_spec.rb +1 -1
- data/examples/directory/spec/delete_spec.rb +1 -1
- data/examples/do_nothing/spec/default_spec.rb +1 -1
- data/examples/dpkg_package/spec/install_spec.rb +1 -1
- data/examples/dpkg_package/spec/purge_spec.rb +1 -1
- data/examples/dpkg_package/spec/remove_spec.rb +1 -1
- data/examples/easy_install_package/spec/install_spec.rb +1 -1
- data/examples/easy_install_package/spec/purge_spec.rb +1 -1
- data/examples/easy_install_package/spec/remove_spec.rb +1 -1
- data/examples/easy_install_package/spec/upgrade_spec.rb +1 -1
- data/examples/env/spec/create_spec.rb +1 -1
- data/examples/env/spec/delete_spec.rb +1 -1
- data/examples/env/spec/modify_spec.rb +1 -1
- data/examples/erl_call/spec/run_spec.rb +1 -1
- data/examples/execute/spec/run_spec.rb +1 -1
- data/examples/expect_exception/spec/compile_error_spec.rb +1 -1
- data/examples/expect_exception/spec/converge_error_spec.rb +1 -1
- data/examples/expect_exception/spec/no_error_spec.rb +1 -1
- data/examples/file/spec/create_if_missing_spec.rb +1 -1
- data/examples/file/spec/create_spec.rb +1 -1
- data/examples/file/spec/delete_spec.rb +1 -1
- data/examples/file/spec/touch_spec.rb +1 -1
- data/examples/freebsd_package/spec/install_spec.rb +1 -1
- data/examples/freebsd_package/spec/remove_spec.rb +1 -1
- data/examples/gem_package/spec/install_spec.rb +1 -1
- data/examples/gem_package/spec/purge_spec.rb +1 -1
- data/examples/gem_package/spec/reconfig_spec.rb +1 -1
- data/examples/gem_package/spec/remove_spec.rb +1 -1
- data/examples/gem_package/spec/upgrade_spec.rb +1 -1
- data/examples/git/spec/checkout_spec.rb +1 -1
- data/examples/git/spec/export_spec.rb +1 -1
- data/examples/git/spec/sync_spec.rb +1 -1
- data/examples/group/spec/create_spec.rb +1 -1
- data/examples/group/spec/manage_spec.rb +1 -1
- data/examples/group/spec/modify_spec.rb +1 -1
- data/examples/group/spec/remove_spec.rb +1 -1
- data/examples/guards/spec/default_spec.rb +1 -1
- data/examples/heavy_provider_light_resource/spec/provider_service_spec.rb +1 -1
- data/examples/http_request/spec/delete_spec.rb +1 -1
- data/examples/http_request/spec/get_spec.rb +1 -1
- data/examples/http_request/spec/head_spec.rb +1 -1
- data/examples/http_request/spec/options_spec.rb +1 -1
- data/examples/http_request/spec/post_spec.rb +1 -1
- data/examples/http_request/spec/put_spec.rb +1 -1
- data/examples/ifconfig/spec/add_spec.rb +1 -1
- data/examples/ifconfig/spec/delete_spec.rb +1 -1
- data/examples/ifconfig/spec/disable_spec.rb +1 -1
- data/examples/ifconfig/spec/enable_spec.rb +1 -1
- data/examples/include_recipe/spec/default_spec.rb +1 -1
- data/examples/inherits/spec/default_spec.rb +1 -1
- data/examples/ips_package/spec/install_spec.rb +1 -1
- data/examples/ips_package/spec/remove_spec.rb +1 -1
- data/examples/ips_package/spec/upgrade_spec.rb +1 -1
- data/examples/link/spec/create_spec.rb +1 -1
- data/examples/link/spec/delete_spec.rb +1 -1
- data/examples/link/spec/link_to_spec.rb +1 -1
- data/examples/log/spec/write_spec.rb +1 -1
- data/examples/macports_package/spec/install_spec.rb +1 -1
- data/examples/macports_package/spec/purge_spec.rb +1 -1
- data/examples/macports_package/spec/remove_spec.rb +1 -1
- data/examples/macports_package/spec/upgrade_spec.rb +1 -1
- data/examples/mdadm/spec/assemble_spec.rb +1 -1
- data/examples/mdadm/spec/create_spec.rb +1 -1
- data/examples/mdadm/spec/stop_spec.rb +1 -1
- data/examples/mount/spec/disable_spec.rb +1 -1
- data/examples/mount/spec/enable_spec.rb +1 -1
- data/examples/mount/spec/mount_spec.rb +1 -1
- data/examples/mount/spec/remount_spec.rb +1 -1
- data/examples/mount/spec/umount_spec.rb +1 -1
- data/examples/multiple_actions/spec/default_spec.rb +1 -1
- data/examples/multiple_actions/spec/sequential_spec.rb +4 -1
- data/examples/multiple_run_action/spec/default_spec.rb +1 -1
- data/examples/notifications/spec/chained_spec.rb +1 -1
- data/examples/notifications/spec/default_spec.rb +1 -1
- data/examples/notifications/spec/delayed_spec.rb +1 -1
- data/examples/notifications/spec/immediately_spec.rb +1 -1
- data/examples/ohai/spec/reload_spec.rb +1 -1
- data/examples/package/spec/install_spec.rb +1 -1
- data/examples/package/spec/purge_spec.rb +1 -1
- data/examples/package/spec/reconfig_spec.rb +1 -1
- data/examples/package/spec/remove_spec.rb +1 -1
- data/examples/package/spec/upgrade_spec.rb +1 -1
- data/examples/pacman_package/spec/install_spec.rb +1 -1
- data/examples/pacman_package/spec/purge_spec.rb +1 -1
- data/examples/pacman_package/spec/remove_spec.rb +1 -1
- data/examples/pacman_package/spec/upgrade_spec.rb +1 -1
- data/examples/portage_package/spec/install_spec.rb +1 -1
- data/examples/portage_package/spec/purge_spec.rb +1 -1
- data/examples/portage_package/spec/remove_spec.rb +1 -1
- data/examples/portage_package/spec/upgrade_spec.rb +1 -1
- data/examples/powershell_script/spec/run_spec.rb +1 -1
- data/examples/registry_key/spec/create_if_missing_spec.rb +1 -1
- data/examples/registry_key/spec/create_spec.rb +1 -1
- data/examples/registry_key/spec/delete_key_spec.rb +1 -1
- data/examples/registry_key/spec/delete_spec.rb +1 -1
- data/examples/remote_directory/spec/create_if_missing_spec.rb +1 -1
- data/examples/remote_directory/spec/create_spec.rb +1 -1
- data/examples/remote_directory/spec/delete_spec.rb +1 -1
- data/examples/remote_file/spec/create_if_missing_spec.rb +1 -1
- data/examples/remote_file/spec/create_spec.rb +1 -1
- data/examples/remote_file/spec/delete_spec.rb +1 -1
- data/examples/remote_file/spec/touch_spec.rb +1 -1
- data/examples/render_file/spec/default_spec.rb +1 -1
- data/examples/render_file/spec/template_helpers_spec.rb +1 -1
- data/examples/roles/spec/default_spec.rb +1 -1
- data/examples/route/spec/add_spec.rb +1 -1
- data/examples/route/spec/delete_spec.rb +1 -1
- data/examples/rpm_package/spec/install_spec.rb +1 -1
- data/examples/rpm_package/spec/remove_spec.rb +1 -1
- data/examples/rpm_package/spec/upgrade_spec.rb +1 -1
- data/examples/ruby_block/spec/run_spec.rb +1 -1
- data/examples/script/spec/run_bash_spec.rb +1 -1
- data/examples/script/spec/run_csh_spec.rb +1 -1
- data/examples/script/spec/run_perl_spec.rb +1 -1
- data/examples/script/spec/run_python_spec.rb +1 -1
- data/examples/script/spec/run_ruby_spec.rb +1 -1
- data/examples/script/spec/run_script_spec.rb +1 -1
- data/examples/server/spec/client_spec.rb +5 -4
- data/examples/server/spec/data_bag_spec.rb +10 -9
- data/examples/server/spec/environment_spec.rb +5 -4
- data/examples/server/spec/node_spec.rb +20 -14
- data/examples/server/spec/render_with_cached_spec.rb +1 -2
- data/examples/server/spec/role_spec.rb +5 -4
- data/examples/server/spec/search_spec.rb +7 -8
- data/examples/service/spec/disable_spec.rb +1 -1
- data/examples/service/spec/enable_spec.rb +1 -1
- data/examples/service/spec/reload_spec.rb +1 -1
- data/examples/service/spec/restart_spec.rb +1 -1
- data/examples/service/spec/start_spec.rb +1 -1
- data/examples/service/spec/stop_spec.rb +1 -1
- data/examples/smartos_package/spec/install_spec.rb +1 -1
- data/examples/smartos_package/spec/remove_spec.rb +1 -1
- data/examples/smartos_package/spec/upgrade_spec.rb +1 -1
- data/examples/solaris_package/spec/install_spec.rb +1 -1
- data/examples/solaris_package/spec/remove_spec.rb +1 -1
- data/examples/state_attrs/spec/default_spec.rb +2 -2
- data/examples/step_into/spec/default_spec.rb +5 -2
- data/examples/stub_command/spec/default_spec.rb +1 -1
- data/examples/stub_data_bag/spec/default_spec.rb +1 -1
- data/examples/stub_data_bag_item/spec/default_spec.rb +1 -1
- data/examples/stub_search/spec/default_spec.rb +1 -1
- data/examples/subscribes/spec/chained_spec.rb +1 -1
- data/examples/subscribes/spec/default_spec.rb +1 -1
- data/examples/subscribes/spec/delayed_spec.rb +1 -1
- data/examples/subscribes/spec/immediately_spec.rb +1 -1
- data/examples/subversion/spec/checkout_spec.rb +1 -1
- data/examples/subversion/spec/export_spec.rb +1 -1
- data/examples/subversion/spec/force_export_spec.rb +1 -1
- data/examples/subversion/spec/sync_spec.rb +1 -1
- data/examples/template/spec/create_if_missing_spec.rb +1 -1
- data/examples/template/spec/create_spec.rb +1 -1
- data/examples/template/spec/delete_spec.rb +1 -1
- data/examples/template/spec/touch_spec.rb +1 -1
- data/examples/use_inline_resources/spec/default_spec.rb +4 -1
- data/examples/user/spec/create_spec.rb +1 -1
- data/examples/user/spec/lock_spec.rb +1 -1
- data/examples/user/spec/manage_spec.rb +1 -1
- data/examples/user/spec/modify_spec.rb +1 -1
- data/examples/user/spec/remove_spec.rb +1 -1
- data/examples/user/spec/unlock_spec.rb +1 -1
- data/examples/yum_package/spec/install_spec.rb +1 -1
- data/examples/yum_package/spec/purge_spec.rb +1 -1
- data/examples/yum_package/spec/remove_spec.rb +1 -1
- data/examples/yum_package/spec/upgrade_spec.rb +1 -1
- data/features/batch.feature +0 -3
- data/features/powershell_script.feature +0 -3
- data/features/render_file.feature +1 -6
- data/features/server.feature +0 -3
- data/features/smartos_package.feature +0 -4
- data/features/solaris_package.feature +0 -4
- data/features/state_attrs.feature +0 -4
- data/features/support/env.rb +0 -7
- data/gemfiles/{chef-11.12.0.gemfile → chef-11.16.0.gemfile} +1 -1
- data/gemfiles/chef-12.0.0.alpha.gemfile +5 -0
- data/lib/chefspec.rb +46 -14
- data/lib/chefspec/api.rb +0 -2
- data/lib/chefspec/api/apt_package.rb +1 -1
- data/lib/chefspec/api/batch.rb +1 -1
- data/lib/chefspec/api/chef_gem.rb +1 -1
- data/lib/chefspec/api/cookbook_file.rb +1 -1
- data/lib/chefspec/api/cron.rb +1 -1
- data/lib/chefspec/api/deploy.rb +1 -1
- data/lib/chefspec/api/directory.rb +1 -1
- data/lib/chefspec/api/dpkg_package.rb +1 -1
- data/lib/chefspec/api/easy_install_package.rb +1 -1
- data/lib/chefspec/api/env.rb +1 -1
- data/lib/chefspec/api/erl_call.rb +1 -1
- data/lib/chefspec/api/execute.rb +1 -1
- data/lib/chefspec/api/file.rb +1 -1
- data/lib/chefspec/api/freebsd_package.rb +1 -1
- data/lib/chefspec/api/gem_package.rb +1 -1
- data/lib/chefspec/api/git.rb +1 -1
- data/lib/chefspec/api/group.rb +1 -1
- data/lib/chefspec/api/http_request.rb +1 -1
- data/lib/chefspec/api/ifconfig.rb +1 -1
- data/lib/chefspec/api/ips_package.rb +1 -1
- data/lib/chefspec/api/link.rb +1 -1
- data/lib/chefspec/api/log.rb +1 -1
- data/lib/chefspec/api/macports_package.rb +1 -1
- data/lib/chefspec/api/mdadm.rb +1 -1
- data/lib/chefspec/api/mount.rb +1 -1
- data/lib/chefspec/api/ohai.rb +2 -2
- data/lib/chefspec/api/package.rb +1 -1
- data/lib/chefspec/api/pacman_package.rb +1 -1
- data/lib/chefspec/api/portage_package.rb +1 -1
- data/lib/chefspec/api/powershell_script.rb +1 -1
- data/lib/chefspec/api/registry_key.rb +1 -1
- data/lib/chefspec/api/remote_directory.rb +4 -4
- data/lib/chefspec/api/remote_file.rb +1 -1
- data/lib/chefspec/api/route.rb +1 -1
- data/lib/chefspec/api/rpm_package.rb +1 -1
- data/lib/chefspec/api/ruby_block.rb +1 -1
- data/lib/chefspec/api/script.rb +6 -6
- data/lib/chefspec/api/service.rb +1 -1
- data/lib/chefspec/api/smartos_package.rb +1 -1
- data/lib/chefspec/api/solaris_package.rb +1 -1
- data/lib/chefspec/api/subversion.rb +1 -1
- data/lib/chefspec/api/template.rb +1 -1
- data/lib/chefspec/api/user.rb +1 -1
- data/lib/chefspec/api/yum_package.rb +1 -1
- data/lib/chefspec/coverage/filters.rb +3 -0
- data/lib/chefspec/deprecations.rb +19 -123
- data/lib/chefspec/macros.rb +2 -2
- data/lib/chefspec/matchers/render_file_matcher.rb +2 -2
- data/lib/chefspec/matchers/resource_matcher.rb +1 -1
- data/lib/chefspec/matchers/state_attrs_matcher.rb +1 -1
- data/lib/chefspec/server.rb +4 -361
- data/lib/chefspec/server_methods.rb +175 -0
- data/lib/chefspec/server_runner.rb +86 -0
- data/lib/chefspec/{runner.rb → solo_runner.rb} +92 -43
- data/lib/chefspec/version.rb +1 -1
- data/spec/unit/{runner_spec.rb → solo_runner_spec.rb} +31 -25
- metadata +13 -10
@@ -0,0 +1,175 @@
|
|
1
|
+
module ChefSpec
|
2
|
+
# This module contains the list of methods that are specific to creating and
|
3
|
+
# managing resources within an Chef Zero instance. It is designed to be
|
4
|
+
# included in a class which exposes a `server` instance variable or method
|
5
|
+
# that returns a {ChefZero::Server} instance.
|
6
|
+
module ServerMethods
|
7
|
+
#
|
8
|
+
# The actual Chef Zero Server object.
|
9
|
+
#
|
10
|
+
# @return [ChefZero::Server]
|
11
|
+
#
|
12
|
+
def server
|
13
|
+
@server ||= ChefZero::Server.new(
|
14
|
+
# Set the log level from RSpec, defaulting to warn
|
15
|
+
log_level: RSpec.configuration.log_level || :warn,
|
16
|
+
|
17
|
+
# Set a random port so ChefSpec may be run in multiple contexts
|
18
|
+
port: port,
|
19
|
+
)
|
20
|
+
end
|
21
|
+
|
22
|
+
#
|
23
|
+
# @macro entity
|
24
|
+
# @method create_$1(name, data = {})
|
25
|
+
# Create a new $1 on the Chef Server
|
26
|
+
#
|
27
|
+
# @param [String] name
|
28
|
+
# the name of the $1
|
29
|
+
# @param [Hash] data
|
30
|
+
# the list of data to load
|
31
|
+
#
|
32
|
+
#
|
33
|
+
# @method $1(name)
|
34
|
+
# Find a $1 at the given name
|
35
|
+
#
|
36
|
+
# @param [String] name
|
37
|
+
# the name of the $1
|
38
|
+
#
|
39
|
+
# @return [$2, nil]
|
40
|
+
#
|
41
|
+
#
|
42
|
+
# @method $3
|
43
|
+
# The list of $1 on the Chef Server
|
44
|
+
#
|
45
|
+
# @return [Array<Hash>]
|
46
|
+
# all the $1 on the Chef Server
|
47
|
+
#
|
48
|
+
#
|
49
|
+
# @method has_$1?(name)
|
50
|
+
# Determine if the Chef Server has the given $1
|
51
|
+
#
|
52
|
+
# @param [String] name
|
53
|
+
# the name of the $1 to find
|
54
|
+
#
|
55
|
+
# @return [true, false]
|
56
|
+
#
|
57
|
+
def self.entity(method, klass, key)
|
58
|
+
class_eval <<-EOH, __FILE__, __LINE__ + 1
|
59
|
+
def create_#{method}(name, data = {})
|
60
|
+
# Automatically set the "name" if no explicit one was given
|
61
|
+
data[:name] ||= name
|
62
|
+
|
63
|
+
# Convert it to JSON
|
64
|
+
data = JSON.fast_generate(data)
|
65
|
+
|
66
|
+
load_data(name, '#{key}', data)
|
67
|
+
end
|
68
|
+
|
69
|
+
def get_#{method}(name)
|
70
|
+
data = get('#{key}', name)
|
71
|
+
json = JSON.parse(data)
|
72
|
+
|
73
|
+
if #{klass}.respond_to?(:json_create)
|
74
|
+
#{klass}.json_create(json)
|
75
|
+
else
|
76
|
+
#{klass}.new(json)
|
77
|
+
end
|
78
|
+
rescue ChefZero::DataStore::DataNotFoundError
|
79
|
+
nil
|
80
|
+
end
|
81
|
+
|
82
|
+
def get_#{key}
|
83
|
+
get('#{key}')
|
84
|
+
end
|
85
|
+
|
86
|
+
def has_#{method}?(name)
|
87
|
+
!get('#{key}', name).nil?
|
88
|
+
rescue ChefZero::DataStore::DataNotFoundError
|
89
|
+
false
|
90
|
+
end
|
91
|
+
EOH
|
92
|
+
end
|
93
|
+
|
94
|
+
entity :client, Chef::Client, 'clients'
|
95
|
+
entity :data_bag, Chef::DataBag, 'data'
|
96
|
+
entity :environment, Chef::Environment, 'environments'
|
97
|
+
entity :node, Chef::Node, 'nodes'
|
98
|
+
entity :role, Chef::Role, 'roles'
|
99
|
+
|
100
|
+
#
|
101
|
+
# Create a new data_bag on the Chef Server. This overrides the method
|
102
|
+
# created by {entity}
|
103
|
+
#
|
104
|
+
# @param [String] name
|
105
|
+
# the name of the data bag
|
106
|
+
# @param [Hash] data
|
107
|
+
# the data to load into the data bag
|
108
|
+
#
|
109
|
+
def create_data_bag(name, data = {})
|
110
|
+
load_data(name, 'data', data)
|
111
|
+
end
|
112
|
+
|
113
|
+
#
|
114
|
+
# Create a new node on the Chef Server. This overrides the method created
|
115
|
+
# by {entity}, permitting users to pass a raw +Chef::Node+ object in
|
116
|
+
# addition to a hash.
|
117
|
+
#
|
118
|
+
# @example Create a node from a hash
|
119
|
+
#
|
120
|
+
# create_node('bacon', attribute: 'value')
|
121
|
+
#
|
122
|
+
# @example Create a node from a +Chef::Node+ object
|
123
|
+
#
|
124
|
+
# node = stub_node('bacon', platform: 'ubuntu', version: '12.04')
|
125
|
+
# create_node(node)
|
126
|
+
#
|
127
|
+
# @param [String, Chef::Node] object
|
128
|
+
# the object to create; this can be the name of the node, or an actual
|
129
|
+
# +Chef::Node+ object
|
130
|
+
# @param [Hash] data
|
131
|
+
# the list of data to populate the node with; this is ignored if an
|
132
|
+
# actual node object is given
|
133
|
+
#
|
134
|
+
def create_node(object, data = {})
|
135
|
+
if object.is_a?(Chef::Node)
|
136
|
+
name = object.name
|
137
|
+
data = object.to_json
|
138
|
+
else
|
139
|
+
name = object.to_s
|
140
|
+
data[:name] ||= name
|
141
|
+
data = JSON.fast_generate(data)
|
142
|
+
end
|
143
|
+
|
144
|
+
load_data(name, 'nodes', data)
|
145
|
+
end
|
146
|
+
|
147
|
+
#
|
148
|
+
# Shortcut method for loading data into Chef Zero.
|
149
|
+
#
|
150
|
+
# @param [String] name
|
151
|
+
# the name or id of the item to load
|
152
|
+
# @param [String, Symbol] key
|
153
|
+
# the key to load
|
154
|
+
# @param [Hash] data
|
155
|
+
# the data for the object, which will be converted to JSON and uploaded
|
156
|
+
# to the server
|
157
|
+
#
|
158
|
+
def load_data(name, key, data = {})
|
159
|
+
@server.load_data({ key => { name => data } })
|
160
|
+
end
|
161
|
+
|
162
|
+
#
|
163
|
+
# Get the path to an item in the data store.
|
164
|
+
#
|
165
|
+
def get(*args)
|
166
|
+
args.unshift('organizations', 'chef')
|
167
|
+
|
168
|
+
if args.size == 3
|
169
|
+
@server.data_store.list(args)
|
170
|
+
else
|
171
|
+
@server.data_store.get(args)
|
172
|
+
end
|
173
|
+
end
|
174
|
+
end
|
175
|
+
end
|
@@ -0,0 +1,86 @@
|
|
1
|
+
require 'chef_zero/server'
|
2
|
+
require 'chef/cookbook_loader'
|
3
|
+
require 'chef/cookbook_uploader'
|
4
|
+
|
5
|
+
require_relative 'server_methods'
|
6
|
+
require_relative 'solo_runner'
|
7
|
+
|
8
|
+
module ChefSpec
|
9
|
+
class ServerRunner < SoloRunner
|
10
|
+
include ChefSpec::ServerMethods
|
11
|
+
|
12
|
+
# @see (SoloRunner#initialize)
|
13
|
+
def initialize(options = {})
|
14
|
+
# Call super, but do not pass in the block because we want to customize
|
15
|
+
# our yielding.
|
16
|
+
super(options, &nil)
|
17
|
+
|
18
|
+
Chef::Config[:client_key] = client_key
|
19
|
+
Chef::Config[:client_name] = 'chefspec'
|
20
|
+
Chef::Config[:node_name] = 'chefspec'
|
21
|
+
Chef::Config[:solo] = false
|
22
|
+
|
23
|
+
Chef::Config[:chef_server_url] = server.url
|
24
|
+
Chef::Config[:http_retry_count] = 0
|
25
|
+
|
26
|
+
# Start the Chef Zero instance in the background
|
27
|
+
server.start_background
|
28
|
+
at_exit { server.stop if server.running? }
|
29
|
+
|
30
|
+
# Unlike the SoloRunner, the node AND server object are yielded for
|
31
|
+
# customization
|
32
|
+
yield node, self if block_given?
|
33
|
+
end
|
34
|
+
|
35
|
+
#
|
36
|
+
# Upload the cookbooks to the Chef Server.
|
37
|
+
#
|
38
|
+
def upload_cookbooks!
|
39
|
+
loader = Chef::CookbookLoader.new(Chef::Config[:cookbook_path])
|
40
|
+
loader.load_cookbooks
|
41
|
+
|
42
|
+
uploader = Chef::CookbookUploader.new(loader.cookbooks, loader.cookbook_paths)
|
43
|
+
uploader.upload_cookbooks
|
44
|
+
end
|
45
|
+
|
46
|
+
# @see (SoloRunner#converge)
|
47
|
+
def converge(*recipe_names)
|
48
|
+
upload_cookbooks!
|
49
|
+
super
|
50
|
+
end
|
51
|
+
|
52
|
+
private
|
53
|
+
|
54
|
+
#
|
55
|
+
# The path to the insecure Chef Zero private key on disk. Because Chef
|
56
|
+
# requires the path to a file instead of the contents of the key (why),
|
57
|
+
# this method dynamically writes the +ChefZero::PRIVATE_KEY+ to disk and
|
58
|
+
# then returns that path.
|
59
|
+
#
|
60
|
+
# @return [String]
|
61
|
+
# the path to the client key on disk
|
62
|
+
#
|
63
|
+
def client_key
|
64
|
+
tmp = Dir.mktmpdir
|
65
|
+
path = File.join(tmp, 'client.pem')
|
66
|
+
File.open(path, 'wb') { |f| f.write(ChefZero::PRIVATE_KEY) }
|
67
|
+
at_exit { FileUtils.rm_rf(tmp) }
|
68
|
+
path
|
69
|
+
end
|
70
|
+
|
71
|
+
#
|
72
|
+
# A randomly assigned, open port for run the Chef Zero server.
|
73
|
+
#
|
74
|
+
# @return [Fixnum]
|
75
|
+
#
|
76
|
+
def port
|
77
|
+
return @port if @port
|
78
|
+
|
79
|
+
@server = TCPServer.new('127.0.0.1', 0)
|
80
|
+
@port = @server.addr[1].to_i
|
81
|
+
@server.close
|
82
|
+
|
83
|
+
return @port
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
@@ -5,25 +5,22 @@ require 'chef/providers'
|
|
5
5
|
require 'chef/resources'
|
6
6
|
|
7
7
|
module ChefSpec
|
8
|
-
class
|
9
|
-
include ChefSpec::Normalize
|
10
|
-
|
8
|
+
class SoloRunner
|
11
9
|
#
|
12
|
-
#
|
10
|
+
# Handy class method for just converging a runner if you do not care about
|
11
|
+
# initializing the runner with custom options.
|
13
12
|
#
|
14
|
-
# @
|
15
|
-
#
|
13
|
+
# @example
|
14
|
+
# ChefSpec::SoloRunner.converge('cookbook::recipe')
|
16
15
|
#
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
define_method(resource_name) do |identity|
|
21
|
-
find_resource(resource_name, identity)
|
16
|
+
def self.converge(*recipe_names)
|
17
|
+
new.tap do |instance|
|
18
|
+
instance.converge(*recipe_names)
|
22
19
|
end
|
23
|
-
|
24
|
-
self
|
25
20
|
end
|
26
21
|
|
22
|
+
include ChefSpec::Normalize
|
23
|
+
|
27
24
|
# @return [Hash]
|
28
25
|
attr_reader :options
|
29
26
|
|
@@ -31,19 +28,19 @@ module ChefSpec
|
|
31
28
|
attr_reader :run_context
|
32
29
|
|
33
30
|
#
|
34
|
-
# Instantiate a new
|
31
|
+
# Instantiate a new SoloRunner to run examples with.
|
35
32
|
#
|
36
33
|
# @example Instantiate a new Runner
|
37
|
-
# ChefSpec::
|
34
|
+
# ChefSpec::SoloRunner.new
|
38
35
|
#
|
39
36
|
# @example Specifying the platform and version
|
40
|
-
# ChefSpec::
|
37
|
+
# ChefSpec::SoloRunner.new(platform: 'ubuntu', version: '12.04')
|
41
38
|
#
|
42
39
|
# @example Specifying the cookbook path
|
43
|
-
# ChefSpec::
|
40
|
+
# ChefSpec::SoloRunner.new(cookbook_path: ['/cookbooks'])
|
44
41
|
#
|
45
42
|
# @example Specifying the log level
|
46
|
-
# ChefSpec::
|
43
|
+
# ChefSpec::SoloRunner.new(log_level: :info)
|
47
44
|
#
|
48
45
|
#
|
49
46
|
# @param [Hash] options
|
@@ -62,35 +59,32 @@ module ChefSpec
|
|
62
59
|
#
|
63
60
|
# @yield [node] Configuration block for Chef::Node
|
64
61
|
#
|
65
|
-
def initialize(options = {}
|
66
|
-
@options = options
|
67
|
-
cookbook_path: RSpec.configuration.cookbook_path || calling_cookbook_path(caller),
|
68
|
-
role_path: RSpec.configuration.role_path || default_role_path,
|
69
|
-
log_level: RSpec.configuration.log_level,
|
70
|
-
path: RSpec.configuration.path,
|
71
|
-
platform: RSpec.configuration.platform,
|
72
|
-
version: RSpec.configuration.version,
|
73
|
-
}.merge(options)
|
62
|
+
def initialize(options = {})
|
63
|
+
@options = with_default_options(options)
|
74
64
|
|
75
|
-
Chef::Log.level = options[:log_level]
|
65
|
+
Chef::Log.level = @options[:log_level]
|
76
66
|
|
77
67
|
Chef::Config.reset!
|
78
68
|
Chef::Config.formatters.clear
|
79
69
|
Chef::Config.add_formatter('chefspec')
|
80
|
-
Chef::Config[:cache_type]
|
81
|
-
Chef::Config[:client_key]
|
82
|
-
Chef::Config[:
|
83
|
-
Chef::Config[:
|
84
|
-
Chef::Config[:
|
85
|
-
Chef::Config[:
|
86
|
-
Chef::Config[:
|
70
|
+
Chef::Config[:cache_type] = 'Memory'
|
71
|
+
Chef::Config[:client_key] = nil
|
72
|
+
Chef::Config[:client_name] = nil
|
73
|
+
Chef::Config[:node_name] = nil
|
74
|
+
Chef::Config[:file_cache_path] = file_cache_path
|
75
|
+
Chef::Config[:cookbook_path] = Array(@options[:cookbook_path])
|
76
|
+
Chef::Config[:no_lazy_load] = true
|
77
|
+
Chef::Config[:role_path] = Array(@options[:role_path])
|
78
|
+
Chef::Config[:force_logger] = true
|
79
|
+
Chef::Config[:solo] = true
|
87
80
|
|
88
81
|
yield node if block_given?
|
89
82
|
end
|
90
83
|
|
91
84
|
#
|
92
85
|
# Execute the given `run_list` on the node, without actually converging
|
93
|
-
# the node.
|
86
|
+
# the node. Each time {#converge} is called, the `run_list` is reset to the
|
87
|
+
# new value (it is **not** additive).
|
94
88
|
#
|
95
89
|
# @example Converging a single recipe
|
96
90
|
# chef_run.converge('example::default')
|
@@ -102,7 +96,7 @@ module ChefSpec
|
|
102
96
|
# @param [Array] recipe_names
|
103
97
|
# The names of the recipe or recipes to converge
|
104
98
|
#
|
105
|
-
# @return [ChefSpec::
|
99
|
+
# @return [ChefSpec::SoloRunner]
|
106
100
|
# A reference to the calling Runner (for chaining purposes)
|
107
101
|
#
|
108
102
|
def converge(*recipe_names)
|
@@ -203,7 +197,7 @@ module ChefSpec
|
|
203
197
|
# Boolean method to determine the current phase of the Chef run (compiling
|
204
198
|
# or converging)
|
205
199
|
#
|
206
|
-
# @return [
|
200
|
+
# @return [true, false]
|
207
201
|
#
|
208
202
|
def compiling?
|
209
203
|
!@converging
|
@@ -221,7 +215,7 @@ module ChefSpec
|
|
221
215
|
# @param [Chef::Resource] resource
|
222
216
|
# the Chef resource to try and step in to
|
223
217
|
#
|
224
|
-
# @return [
|
218
|
+
# @return [true, false]
|
225
219
|
#
|
226
220
|
def step_into?(resource)
|
227
221
|
key = resource_name(resource)
|
@@ -231,7 +225,7 @@ module ChefSpec
|
|
231
225
|
#
|
232
226
|
# Boolean method to determine if this Runner is in `dry_run` mode.
|
233
227
|
#
|
234
|
-
# @return [
|
228
|
+
# @return [true, false]
|
235
229
|
#
|
236
230
|
def dry_run?
|
237
231
|
!!options[:dry_run]
|
@@ -244,8 +238,7 @@ module ChefSpec
|
|
244
238
|
# may change between versions of this gem.
|
245
239
|
#
|
246
240
|
def to_s
|
247
|
-
|
248
|
-
'chef_run'
|
241
|
+
"#<#{self.class.name} run_list: [#{node.run_list}]>"
|
249
242
|
end
|
250
243
|
|
251
244
|
#
|
@@ -254,11 +247,67 @@ module ChefSpec
|
|
254
247
|
# @return [String]
|
255
248
|
#
|
256
249
|
def inspect
|
257
|
-
"#<#{self.class
|
250
|
+
"#<#{self.class.name}" \
|
251
|
+
" options: #{options.inspect}," \
|
252
|
+
" run_list: [#{node.run_list}]>"
|
253
|
+
end
|
254
|
+
|
255
|
+
#
|
256
|
+
# Respond to custom matchers defined by the user.
|
257
|
+
#
|
258
|
+
def method_missing(m, *args, &block)
|
259
|
+
if block = ChefSpec.matchers[resource_name(m.to_sym)]
|
260
|
+
instance_exec(args.first, &block)
|
261
|
+
else
|
262
|
+
super
|
263
|
+
end
|
264
|
+
end
|
265
|
+
|
266
|
+
#
|
267
|
+
# Inform Ruby that we respond to methods that are defined as custom
|
268
|
+
# matchers.
|
269
|
+
#
|
270
|
+
def respond_to_missing?(m, include_private = false)
|
271
|
+
ChefSpec.matchers.key?(m.to_sym) || super
|
258
272
|
end
|
259
273
|
|
260
274
|
private
|
261
275
|
|
276
|
+
#
|
277
|
+
# The path to cache files on disk. This value is created using
|
278
|
+
# {Dir.mktmpdir}. The method adds a {Kernel.at_exit} handler to ensure the
|
279
|
+
# temporary directory is deleted when the system exits.
|
280
|
+
#
|
281
|
+
# **This method creates a new temporary directory on each call!** As such,
|
282
|
+
# you should cache the result to a variable inside you system.
|
283
|
+
#
|
284
|
+
def file_cache_path
|
285
|
+
path = Dir.mktmpdir
|
286
|
+
at_exit { FileUtils.rm_rf(path) }
|
287
|
+
path
|
288
|
+
end
|
289
|
+
|
290
|
+
#
|
291
|
+
# Set the default options, with the given options taking precedence.
|
292
|
+
#
|
293
|
+
# @param [Hash] options
|
294
|
+
# the list of options to take precedence
|
295
|
+
#
|
296
|
+
# @return [Hash] options
|
297
|
+
#
|
298
|
+
def with_default_options(options)
|
299
|
+
config = RSpec.configuration
|
300
|
+
|
301
|
+
{
|
302
|
+
cookbook_path: config.cookbook_path || calling_cookbook_path(caller),
|
303
|
+
role_path: config.role_path || default_role_path,
|
304
|
+
log_level: config.log_level,
|
305
|
+
path: config.path,
|
306
|
+
platform: config.platform,
|
307
|
+
version: config.version,
|
308
|
+
}.merge(options)
|
309
|
+
end
|
310
|
+
|
262
311
|
#
|
263
312
|
# The inferred path from the calling spec.
|
264
313
|
#
|