chefspec 5.4.0 → 6.0.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 +6 -2
- data/CHANGELOG.md +12 -1
- data/README.md +17 -3
- data/chefspec.gemspec +2 -3
- 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/apt_repository/spec/add_spec.rb +1 -1
- data/examples/apt_repository/spec/remove_spec.rb +1 -1
- data/examples/apt_update/spec/periodic_spec.rb +1 -1
- data/examples/apt_update/spec/update_spec.rb +1 -1
- data/examples/batch/spec/run_spec.rb +1 -1
- data/examples/cab_package/recipes/install.rb +13 -0
- data/examples/cab_package/recipes/remove.rb +13 -0
- data/examples/cab_package/spec/install_spec.rb +26 -0
- data/examples/cab_package/spec/remove_spec.rb +22 -0
- data/examples/chocolatey_package/spec/install_spec.rb +1 -1
- data/examples/chocolatey_package/spec/remove_spec.rb +1 -1
- data/examples/chocolatey_package/spec/upgrade_spec.rb +1 -1
- data/examples/dnf_package/recipes/install.rb +13 -0
- data/examples/dnf_package/recipes/purge.rb +13 -0
- data/examples/dnf_package/recipes/remove.rb +13 -0
- data/examples/dnf_package/recipes/upgrade.rb +13 -0
- data/examples/dnf_package/spec/install_spec.rb +26 -0
- data/examples/dnf_package/spec/purge_spec.rb +22 -0
- data/examples/dnf_package/spec/remove_spec.rb +22 -0
- data/examples/dnf_package/spec/upgrade_spec.rb +22 -0
- 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/dsc_resource/spec/run_spec.rb +4 -4
- data/examples/dsc_script/spec/run_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/freebsd_package/spec/install_spec.rb +1 -1
- data/examples/freebsd_package/spec/remove_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/msu_package/recipes/install.rb +13 -0
- data/examples/msu_package/recipes/remove.rb +13 -0
- data/examples/msu_package/spec/install_spec.rb +26 -0
- data/examples/msu_package/spec/remove_spec.rb +22 -0
- 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/roles/roles/role.rb +2 -2
- 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/server/spec/data_bag_spec.rb +9 -11
- 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/step_into/spec/default_spec.rb +2 -2
- data/examples/use_inline_resources/spec/default_spec.rb +1 -1
- data/examples/windows_package/spec/install_spec.rb +1 -1
- data/examples/windows_package/spec/remove_spec.rb +1 -1
- data/examples/windows_service/spec/configure_startup_spec.rb +1 -1
- data/examples/windows_service/spec/disable_spec.rb +1 -1
- data/examples/windows_service/spec/enable_spec.rb +1 -1
- data/examples/windows_service/spec/reload_spec.rb +1 -1
- data/examples/windows_service/spec/restart_spec.rb +1 -1
- data/examples/windows_service/spec/start_spec.rb +1 -1
- data/examples/windows_service/spec/stop_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/examples/yum_repository/spec/add_spec.rb +1 -1
- data/examples/yum_repository/spec/create_spec.rb +1 -1
- data/examples/yum_repository/spec/delete_spec.rb +1 -1
- data/examples/yum_repository/spec/makecache_spec.rb +1 -1
- data/examples/yum_repository/spec/remove_spec.rb +1 -1
- data/features/cab_package.feature +21 -0
- data/features/dnf_package.feature +26 -0
- data/features/msu_package.feature +23 -0
- data/features/support/env.rb +8 -0
- data/lib/chefspec.rb +0 -1
- data/lib/chefspec/api.rb +3 -0
- data/lib/chefspec/api/cab_package.rb +80 -0
- data/lib/chefspec/api/dnf_package.rb +154 -0
- data/lib/chefspec/api/msu_package.rb +81 -0
- data/lib/chefspec/rspec.rb +1 -0
- data/lib/chefspec/server_methods.rb +4 -35
- data/lib/chefspec/server_runner.rb +2 -42
- data/lib/chefspec/version.rb +1 -1
- data/lib/chefspec/zero_server.rb +139 -0
- metadata +31 -6
- data/lib/chefspec/chef_backwards_compat.rb +0 -79
@@ -0,0 +1,154 @@
|
|
1
|
+
module ChefSpec::API
|
2
|
+
# @since 6.0.0
|
3
|
+
module DnfPackageMatchers
|
4
|
+
ChefSpec.define_matcher :dnf_package
|
5
|
+
|
6
|
+
#
|
7
|
+
# Assert that a +dnf_package+ resource exists in the Chef run with the
|
8
|
+
# action +:install+. Given a Chef Recipe that installs "apache2" as a
|
9
|
+
# +dnf_package+:
|
10
|
+
#
|
11
|
+
# dnf_package 'apache2' do
|
12
|
+
# action :install
|
13
|
+
# end
|
14
|
+
#
|
15
|
+
# The Examples section demonstrates the different ways to test a
|
16
|
+
# +dnf_package+ resource with ChefSpec.
|
17
|
+
#
|
18
|
+
# @example Assert that a +dnf_package+ was installed
|
19
|
+
# expect(chef_run).to install_dnf_package('apache2')
|
20
|
+
#
|
21
|
+
# @example Assert that a +dnf_package+ was installed with predicate matchers
|
22
|
+
# expect(chef_run).to install_dnf_package('apache2').with_version('1.2.3')
|
23
|
+
#
|
24
|
+
# @example Assert that a +dnf_package+ was installed with attributes
|
25
|
+
# expect(chef_run).to install_dnf_package('apache2').with(version: '1.2.3')
|
26
|
+
#
|
27
|
+
# @example Assert that a +dnf_package+ was installed using a regex
|
28
|
+
# expect(chef_run).to install_dnf_package('apache2').with(version: /(\d+\.){2}\.\d+/)
|
29
|
+
#
|
30
|
+
# @example Assert that a +dnf_package+ was _not_ installed
|
31
|
+
# expect(chef_run).to_not install_dnf_package('apache2')
|
32
|
+
#
|
33
|
+
#
|
34
|
+
# @param [String, Regex] resource_name
|
35
|
+
# the name of the resource to match
|
36
|
+
#
|
37
|
+
# @return [ChefSpec::Matchers::ResourceMatcher]
|
38
|
+
#
|
39
|
+
def install_dnf_package(resource_name)
|
40
|
+
ChefSpec::Matchers::ResourceMatcher.new(:dnf_package, :install, resource_name)
|
41
|
+
end
|
42
|
+
|
43
|
+
#
|
44
|
+
# Assert that a +dnf_package+ resource exists in the Chef run with the
|
45
|
+
# action +:purge+. Given a Chef Recipe that purges "apache2" as a
|
46
|
+
# +dnf_package+:
|
47
|
+
#
|
48
|
+
# dnf_package 'apache2' do
|
49
|
+
# action :purge
|
50
|
+
# end
|
51
|
+
#
|
52
|
+
# The Examples section demonstrates the different ways to test a
|
53
|
+
# +dnf_package+ resource with ChefSpec.
|
54
|
+
#
|
55
|
+
# @example Assert that a +dnf_package+ was purged
|
56
|
+
# expect(chef_run).to purge_dnf_package('apache2')
|
57
|
+
#
|
58
|
+
# @example Assert that a +dnf_package+ was purged with predicate matchers
|
59
|
+
# expect(chef_run).to purge_dnf_package('apache2').with_version('1.2.3')
|
60
|
+
#
|
61
|
+
# @example Assert that a +dnf_package+ was purged with attributes
|
62
|
+
# expect(chef_run).to purge_dnf_package('apache2').with(version: '1.2.3')
|
63
|
+
#
|
64
|
+
# @example Assert that a +dnf_package+ was purged using a regex
|
65
|
+
# expect(chef_run).to purge_dnf_package('apache2').with(version: /(\d+\.){2}\.\d+/)
|
66
|
+
#
|
67
|
+
# @example Assert that a +dnf_package+ was _not_ purged
|
68
|
+
# expect(chef_run).to_not purge_dnf_package('apache2')
|
69
|
+
#
|
70
|
+
#
|
71
|
+
# @param [String, Regex] resource_name
|
72
|
+
# the name of the resource to match
|
73
|
+
#
|
74
|
+
# @return [ChefSpec::Matchers::ResourceMatcher]
|
75
|
+
#
|
76
|
+
def purge_dnf_package(resource_name)
|
77
|
+
ChefSpec::Matchers::ResourceMatcher.new(:dnf_package, :purge, resource_name)
|
78
|
+
end
|
79
|
+
|
80
|
+
#
|
81
|
+
# Assert that a +dnf_package+ resource exists in the Chef run with the
|
82
|
+
# action +:remove+. Given a Chef Recipe that removes "apache2" as a
|
83
|
+
# +dnf_package+:
|
84
|
+
#
|
85
|
+
# dnf_package 'apache2' do
|
86
|
+
# action :remove
|
87
|
+
# end
|
88
|
+
#
|
89
|
+
# The Examples section demonstrates the different ways to test a
|
90
|
+
# +dnf_package+ resource with ChefSpec.
|
91
|
+
#
|
92
|
+
# @example Assert that a +dnf_package+ was removed
|
93
|
+
# expect(chef_run).to remove_dnf_package('apache2')
|
94
|
+
#
|
95
|
+
# @example Assert that a +dnf_package+ was removed with predicate matchers
|
96
|
+
# expect(chef_run).to remove_dnf_package('apache2').with_version('1.2.3')
|
97
|
+
#
|
98
|
+
# @example Assert that a +dnf_package+ was removed with attributes
|
99
|
+
# expect(chef_run).to remove_dnf_package('apache2').with(version: '1.2.3')
|
100
|
+
#
|
101
|
+
# @example Assert that a +dnf_package+ was removed using a regex
|
102
|
+
# expect(chef_run).to remove_dnf_package('apache2').with(version: /(\d+\.){2}\.\d+/)
|
103
|
+
#
|
104
|
+
# @example Assert that a +dnf_package+ was _not_ removed
|
105
|
+
# expect(chef_run).to_not remove_dnf_package('apache2')
|
106
|
+
#
|
107
|
+
#
|
108
|
+
# @param [String, Regex] resource_name
|
109
|
+
# the name of the resource to match
|
110
|
+
#
|
111
|
+
# @return [ChefSpec::Matchers::ResourceMatcher]
|
112
|
+
#
|
113
|
+
def remove_dnf_package(resource_name)
|
114
|
+
ChefSpec::Matchers::ResourceMatcher.new(:dnf_package, :remove, resource_name)
|
115
|
+
end
|
116
|
+
|
117
|
+
#
|
118
|
+
# Assert that a +dnf_package+ resource exists in the Chef run with the
|
119
|
+
# action +:upgrade+. Given a Chef Recipe that upgrades "apache2" as a
|
120
|
+
# +dnf_package+:
|
121
|
+
#
|
122
|
+
# dnf_package 'apache2' do
|
123
|
+
# action :upgrade
|
124
|
+
# end
|
125
|
+
#
|
126
|
+
# The Examples section demonstrates the different ways to test a
|
127
|
+
# +dnf_package+ resource with ChefSpec.
|
128
|
+
#
|
129
|
+
# @example Assert that a +dnf_package+ was upgraded
|
130
|
+
# expect(chef_run).to upgrade_dnf_package('apache2')
|
131
|
+
#
|
132
|
+
# @example Assert that a +dnf_package+ was upgraded with predicate matchers
|
133
|
+
# expect(chef_run).to upgrade_dnf_package('apache2').with_version('1.2.3')
|
134
|
+
#
|
135
|
+
# @example Assert that a +dnf_package+ was upgraded with attributes
|
136
|
+
# expect(chef_run).to upgrade_dnf_package('apache2').with(version: '1.2.3')
|
137
|
+
#
|
138
|
+
# @example Assert that a +dnf_package+ was upgraded using a regex
|
139
|
+
# expect(chef_run).to upgrade_dnf_package('apache2').with(version: /(\d+\.){2}\.\d+/)
|
140
|
+
#
|
141
|
+
# @example Assert that a +dnf_package+ was _not_ upgraded
|
142
|
+
# expect(chef_run).to_not upgrade_dnf_package('apache2')
|
143
|
+
#
|
144
|
+
#
|
145
|
+
# @param [String, Regex] resource_name
|
146
|
+
# the name of the resource to match
|
147
|
+
#
|
148
|
+
# @return [ChefSpec::Matchers::ResourceMatcher]
|
149
|
+
#
|
150
|
+
def upgrade_dnf_package(resource_name)
|
151
|
+
ChefSpec::Matchers::ResourceMatcher.new(:dnf_package, :upgrade, resource_name)
|
152
|
+
end
|
153
|
+
end
|
154
|
+
end
|
@@ -0,0 +1,81 @@
|
|
1
|
+
module ChefSpec::API
|
2
|
+
# @since 6.0.0
|
3
|
+
module MsuPackageMatchers
|
4
|
+
ChefSpec.define_matcher :msu_package
|
5
|
+
|
6
|
+
#
|
7
|
+
# Assert that a +msu_package+ resource exists in the Chef run with the
|
8
|
+
# action +:install+. Given a Chef Recipe that installs "KB2959977" as a
|
9
|
+
# +msu_package+:
|
10
|
+
#
|
11
|
+
# msu_package 'KB2959977' do
|
12
|
+
# source 'C:\Windows8.1-KB2959977-x64.msu'
|
13
|
+
# action :install
|
14
|
+
# end
|
15
|
+
#
|
16
|
+
# The Examples section demonstrates the different ways to test a
|
17
|
+
# +msu_package+ resource with ChefSpec.
|
18
|
+
#
|
19
|
+
# @example Assert that a +msu_package+ was installed
|
20
|
+
# expect(chef_run).to install_msu_package('KB2959977')
|
21
|
+
#
|
22
|
+
# @example Assert that a +msu_package+ was installed with predicate matchers
|
23
|
+
# expect(chef_run).to install_msu_package('KB2959977').with_source('C:\Windows8.1-KB2959977-x64.msu')
|
24
|
+
#
|
25
|
+
# @example Assert that a +msu_package+ was installed with attributes
|
26
|
+
# expect(chef_run).to install_msu_package('KB2959977').with(source: 'C:\Windows8.1-KB2959977-x64.msu')
|
27
|
+
#
|
28
|
+
# @example Assert that a +msu_package+ was installed using a regex
|
29
|
+
# expect(chef_run).to install_msu_package('KB2959977').with(source: /.*KB2959977.*/)
|
30
|
+
#
|
31
|
+
# @example Assert that a +msu_package+ was _not_ installed
|
32
|
+
# expect(chef_run).to_not install_msu_package('KB2959977')
|
33
|
+
#
|
34
|
+
#
|
35
|
+
# @param [String, Regex] resource_name
|
36
|
+
# the name of the resource to match
|
37
|
+
#
|
38
|
+
# @return [ChefSpec::Matchers::ResourceMatcher]
|
39
|
+
#
|
40
|
+
def install_msu_package(resource_name)
|
41
|
+
ChefSpec::Matchers::ResourceMatcher.new(:msu_package, :install, resource_name)
|
42
|
+
end
|
43
|
+
|
44
|
+
#
|
45
|
+
# Assert that a +msu_package+ resource exists in the Chef run with the
|
46
|
+
# action +:remove+. Given a Chef Recipe that removes "KB2959977" as a
|
47
|
+
# +msu_package+:
|
48
|
+
#
|
49
|
+
# msu_package 'KB2959977' do
|
50
|
+
# action :remove
|
51
|
+
# end
|
52
|
+
#
|
53
|
+
# The Examples section demonstrates the different ways to test a
|
54
|
+
# +msu_package+ resource with ChefSpec.
|
55
|
+
#
|
56
|
+
# @example Assert that a +msu_package+ was removed
|
57
|
+
# expect(chef_run).to remove_msu_package('KB2959977')
|
58
|
+
#
|
59
|
+
# @example Assert that a +msu_package+ was removed with predicate matchers
|
60
|
+
# expect(chef_run).to remove_msu_package('KB2959977').with_source('C:\Windows8.1-KB2959977-x64.msu')
|
61
|
+
#
|
62
|
+
# @example Assert that a +msu_package+ was removed with attributes
|
63
|
+
# expect(chef_run).to remove_msu_package('KB2959977').with(source: 'C:\Windows8.1-KB2959977-x64.msu')
|
64
|
+
#
|
65
|
+
# @example Assert that a +msu_package+ was removed using a regex
|
66
|
+
# expect(chef_run).to remove_msu_package('KB2959977').with(source: /.*KB2959977.*/)
|
67
|
+
#
|
68
|
+
# @example Assert that a +msu_package+ was _not_ removed
|
69
|
+
# expect(chef_run).to_not remove_msu_package('KB2959977')
|
70
|
+
#
|
71
|
+
#
|
72
|
+
# @param [String, Regex] resource_name
|
73
|
+
# the name of the resource to match
|
74
|
+
#
|
75
|
+
# @return [ChefSpec::Matchers::ResourceMatcher]
|
76
|
+
#
|
77
|
+
def remove_msu_package(resource_name)
|
78
|
+
ChefSpec::Matchers::ResourceMatcher.new(:msu_package, :remove, resource_name)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
data/lib/chefspec/rspec.rb
CHANGED
@@ -10,16 +10,7 @@ module ChefSpec
|
|
10
10
|
# @return [ChefZero::Server]
|
11
11
|
#
|
12
12
|
def server
|
13
|
-
|
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
|
-
# Set the data store
|
21
|
-
data_store: data_store(RSpec.configuration.server_runner_data_store),
|
22
|
-
)
|
13
|
+
ChefSpec::ZeroServer.server
|
23
14
|
end
|
24
15
|
|
25
16
|
#
|
@@ -160,7 +151,7 @@ module ChefSpec
|
|
160
151
|
# to the server
|
161
152
|
#
|
162
153
|
def load_data(name, key, data = {})
|
163
|
-
|
154
|
+
ChefSpec::ZeroServer.load_data(name, key, data)
|
164
155
|
end
|
165
156
|
|
166
157
|
#
|
@@ -170,32 +161,10 @@ module ChefSpec
|
|
170
161
|
args.unshift('organizations', 'chef')
|
171
162
|
|
172
163
|
if args.size == 3
|
173
|
-
|
164
|
+
server.data_store.list(args)
|
174
165
|
else
|
175
|
-
|
166
|
+
server.data_store.get(args)
|
176
167
|
end
|
177
168
|
end
|
178
|
-
|
179
|
-
#
|
180
|
-
# Generate the DataStore object to be passed in to the ChefZero::Server object
|
181
|
-
#
|
182
|
-
def data_store(option)
|
183
|
-
require "chef_zero/data_store/default_facade"
|
184
|
-
|
185
|
-
store = case option
|
186
|
-
when :in_memory
|
187
|
-
require "chef_zero/data_store/memory_store_v2"
|
188
|
-
ChefZero::DataStore::MemoryStoreV2.new
|
189
|
-
when :on_disk
|
190
|
-
require "tmpdir"
|
191
|
-
require "chef_zero/data_store/raw_file_store"
|
192
|
-
tmpdir = Dir.mktmpdir
|
193
|
-
ChefZero::DataStore::RawFileStore.new(Dir.mktmpdir)
|
194
|
-
else
|
195
|
-
raise ArgumentError, ":#{option} is not a valid server_runner_data_store option. Please use either :in_memory or :on_disk."
|
196
|
-
end
|
197
|
-
|
198
|
-
ChefZero::DataStore::DefaultFacade.new(store, "chef", true)
|
199
|
-
end
|
200
169
|
end
|
201
170
|
end
|
@@ -1,7 +1,7 @@
|
|
1
|
-
require 'chef_zero/server'
|
2
1
|
require 'chef/cookbook_loader'
|
3
2
|
require 'chef/cookbook_uploader'
|
4
3
|
|
4
|
+
require_relative 'zero_server'
|
5
5
|
require_relative 'file_cache_path_proxy'
|
6
6
|
require_relative 'server_methods'
|
7
7
|
require_relative 'solo_runner'
|
@@ -32,39 +32,14 @@ module ChefSpec
|
|
32
32
|
Chef::Config[:chef_server_url] = server.url
|
33
33
|
Chef::Config[:http_retry_count] = 0
|
34
34
|
|
35
|
-
# Start the Chef Zero instance in the background
|
36
|
-
server.start_background
|
37
|
-
at_exit { server.stop if server.running? }
|
38
|
-
|
39
35
|
# Unlike the SoloRunner, the node AND server object are yielded for
|
40
36
|
# customization
|
41
37
|
yield node, self if block_given?
|
42
38
|
end
|
43
39
|
|
44
|
-
#
|
45
|
-
# Upload the cookbooks to the Chef Server.
|
46
|
-
#
|
47
|
-
def upload_cookbooks!
|
48
|
-
loader = Chef::CookbookLoader.new(Chef::Config[:cookbook_path])
|
49
|
-
loader.load_cookbooks
|
50
|
-
cookbook_uploader_for(loader).upload_cookbooks
|
51
|
-
end
|
52
|
-
|
53
|
-
#
|
54
|
-
# The uploader for the cookbooks.
|
55
|
-
#
|
56
|
-
# @param [Chef::CookbookLoader] loader
|
57
|
-
# the Chef cookbook loader
|
58
|
-
#
|
59
|
-
# @return [Chef::CookbookUploader]
|
60
|
-
#
|
61
|
-
def cookbook_uploader_for(loader)
|
62
|
-
Chef::CookbookUploader.new(loader.cookbooks)
|
63
|
-
end
|
64
|
-
|
65
40
|
# @see (SoloRunner#converge)
|
66
41
|
def converge(*recipe_names)
|
67
|
-
upload_cookbooks!
|
42
|
+
ChefSpec::ZeroServer.upload_cookbooks!
|
68
43
|
|
69
44
|
super do
|
70
45
|
yield if block_given?
|
@@ -93,20 +68,5 @@ module ChefSpec
|
|
93
68
|
at_exit { FileUtils.rm_rf(tmp) }
|
94
69
|
path
|
95
70
|
end
|
96
|
-
|
97
|
-
#
|
98
|
-
# A randomly assigned, open port for run the Chef Zero server.
|
99
|
-
#
|
100
|
-
# @return [Fixnum]
|
101
|
-
#
|
102
|
-
def port
|
103
|
-
return @port if @port
|
104
|
-
|
105
|
-
@server = TCPServer.new('127.0.0.1', 0)
|
106
|
-
@port = @server.addr[1].to_i
|
107
|
-
@server.close
|
108
|
-
|
109
|
-
return @port
|
110
|
-
end
|
111
71
|
end
|
112
72
|
end
|
data/lib/chefspec/version.rb
CHANGED
@@ -0,0 +1,139 @@
|
|
1
|
+
require 'chef_zero/server'
|
2
|
+
|
3
|
+
module ChefSpec
|
4
|
+
# Rather than create a ChefZero instance per test case, simply create one
|
5
|
+
# ChefZero instance and reset it for every test case.
|
6
|
+
class ZeroServer
|
7
|
+
class << self
|
8
|
+
extend Forwardable
|
9
|
+
def_delegators :instance, :setup!, :teardown!, :reset!, :upload_cookbooks!, :server, :load_data
|
10
|
+
end
|
11
|
+
|
12
|
+
include Singleton
|
13
|
+
|
14
|
+
# Create the ChefZero Server
|
15
|
+
def initialize
|
16
|
+
@server ||= ChefZero::Server.new(
|
17
|
+
# Set the log level from RSpec, defaulting to warn
|
18
|
+
log_level: RSpec.configuration.log_level || :warn,
|
19
|
+
|
20
|
+
# Set the data store
|
21
|
+
data_store: data_store(RSpec.configuration.server_runner_data_store),
|
22
|
+
)
|
23
|
+
@cookbooks_uploaded = false
|
24
|
+
@data_loaded = {}
|
25
|
+
end
|
26
|
+
|
27
|
+
#
|
28
|
+
# Start the ChefZero Server
|
29
|
+
#
|
30
|
+
def setup!
|
31
|
+
@server.start_background unless @server.running?
|
32
|
+
end
|
33
|
+
|
34
|
+
#
|
35
|
+
# Remove all the data we just loaded from the ChefZero server
|
36
|
+
#
|
37
|
+
def reset!
|
38
|
+
if RSpec.configuration.server_runner_clear_cookbooks
|
39
|
+
@server.clear_data
|
40
|
+
@cookbooks_uploaded = false
|
41
|
+
else
|
42
|
+
# If we don't want to do a full clear, iterate through each value that we
|
43
|
+
# set and manually remove it.
|
44
|
+
@data_loaded.each do |key, names|
|
45
|
+
if key == "data"
|
46
|
+
names.each { |n| @server.data_store.delete_dir(["organizations", "chef", key, n]) }
|
47
|
+
else
|
48
|
+
names.each { |n| @server.data_store.delete(["organizations", "chef", key, n]) }
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
@data_loaded = {}
|
53
|
+
end
|
54
|
+
|
55
|
+
#
|
56
|
+
# Teardown the ChefZero Server
|
57
|
+
#
|
58
|
+
def teardown!
|
59
|
+
@server.stop if @server.running?
|
60
|
+
end
|
61
|
+
|
62
|
+
#
|
63
|
+
# Upload the cookbooks to the Chef Server.
|
64
|
+
#
|
65
|
+
def upload_cookbooks!
|
66
|
+
return if @cookbooks_uploaded
|
67
|
+
loader = Chef::CookbookLoader.new(Chef::Config[:cookbook_path])
|
68
|
+
loader.load_cookbooks
|
69
|
+
cookbook_uploader_for(loader).upload_cookbooks
|
70
|
+
@cookbooks_uploaded = true
|
71
|
+
end
|
72
|
+
|
73
|
+
#
|
74
|
+
# The URL for the ChefZero Server
|
75
|
+
#
|
76
|
+
def server
|
77
|
+
@server
|
78
|
+
end
|
79
|
+
|
80
|
+
#
|
81
|
+
# Load (and track) data sent to the server
|
82
|
+
#
|
83
|
+
# @param [String] name
|
84
|
+
# the name or id of the item to load
|
85
|
+
# @param [String, Symbol] key
|
86
|
+
# the key to load
|
87
|
+
# @param [Hash] data
|
88
|
+
# the data for the object, which will be converted to JSON and uploaded
|
89
|
+
# to the server
|
90
|
+
#
|
91
|
+
def load_data(name, key, data)
|
92
|
+
@data_loaded[key] ||= []
|
93
|
+
@data_loaded[key] << name
|
94
|
+
@server.load_data({ key => { name => data } })
|
95
|
+
end
|
96
|
+
|
97
|
+
private
|
98
|
+
|
99
|
+
#
|
100
|
+
# The uploader for the cookbooks.
|
101
|
+
#
|
102
|
+
# @param [Chef::CookbookLoader] loader
|
103
|
+
# the Chef cookbook loader
|
104
|
+
#
|
105
|
+
# @return [Chef::CookbookUploader]
|
106
|
+
#
|
107
|
+
def cookbook_uploader_for(loader)
|
108
|
+
Chef::CookbookUploader.new(loader.cookbooks)
|
109
|
+
end
|
110
|
+
|
111
|
+
#
|
112
|
+
# Generate the DataStore object to be passed in to the ChefZero::Server object
|
113
|
+
#
|
114
|
+
def data_store(option)
|
115
|
+
require "chef_zero/data_store/default_facade"
|
116
|
+
|
117
|
+
store = case option
|
118
|
+
when :in_memory
|
119
|
+
require "chef_zero/data_store/memory_store_v2"
|
120
|
+
ChefZero::DataStore::MemoryStoreV2.new
|
121
|
+
when :on_disk
|
122
|
+
require "tmpdir"
|
123
|
+
require "chef_zero/data_store/raw_file_store"
|
124
|
+
tmpdir = Dir.mktmpdir
|
125
|
+
ChefZero::DataStore::RawFileStore.new(Dir.mktmpdir)
|
126
|
+
else
|
127
|
+
raise ArgumentError, ":#{option} is not a valid server_runner_data_store option. Please use either :in_memory or :on_disk."
|
128
|
+
end
|
129
|
+
|
130
|
+
ChefZero::DataStore::DefaultFacade.new(store, "chef", true)
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
RSpec.configure do |config|
|
136
|
+
config.before(:suite) { ChefSpec::ZeroServer.setup! }
|
137
|
+
config.after(:each) { ChefSpec::ZeroServer.reset! }
|
138
|
+
config.after(:suite) { ChefSpec::ZeroServer.teardown! }
|
139
|
+
end
|