chefspec 5.4.0 → 6.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (106) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +6 -2
  3. data/CHANGELOG.md +12 -1
  4. data/README.md +17 -3
  5. data/chefspec.gemspec +2 -3
  6. data/examples/apt_package/spec/install_spec.rb +1 -1
  7. data/examples/apt_package/spec/purge_spec.rb +1 -1
  8. data/examples/apt_package/spec/reconfig_spec.rb +1 -1
  9. data/examples/apt_package/spec/remove_spec.rb +1 -1
  10. data/examples/apt_package/spec/upgrade_spec.rb +1 -1
  11. data/examples/apt_repository/spec/add_spec.rb +1 -1
  12. data/examples/apt_repository/spec/remove_spec.rb +1 -1
  13. data/examples/apt_update/spec/periodic_spec.rb +1 -1
  14. data/examples/apt_update/spec/update_spec.rb +1 -1
  15. data/examples/batch/spec/run_spec.rb +1 -1
  16. data/examples/cab_package/recipes/install.rb +13 -0
  17. data/examples/cab_package/recipes/remove.rb +13 -0
  18. data/examples/cab_package/spec/install_spec.rb +26 -0
  19. data/examples/cab_package/spec/remove_spec.rb +22 -0
  20. data/examples/chocolatey_package/spec/install_spec.rb +1 -1
  21. data/examples/chocolatey_package/spec/remove_spec.rb +1 -1
  22. data/examples/chocolatey_package/spec/upgrade_spec.rb +1 -1
  23. data/examples/dnf_package/recipes/install.rb +13 -0
  24. data/examples/dnf_package/recipes/purge.rb +13 -0
  25. data/examples/dnf_package/recipes/remove.rb +13 -0
  26. data/examples/dnf_package/recipes/upgrade.rb +13 -0
  27. data/examples/dnf_package/spec/install_spec.rb +26 -0
  28. data/examples/dnf_package/spec/purge_spec.rb +22 -0
  29. data/examples/dnf_package/spec/remove_spec.rb +22 -0
  30. data/examples/dnf_package/spec/upgrade_spec.rb +22 -0
  31. data/examples/dpkg_package/spec/install_spec.rb +1 -1
  32. data/examples/dpkg_package/spec/purge_spec.rb +1 -1
  33. data/examples/dpkg_package/spec/remove_spec.rb +1 -1
  34. data/examples/dsc_resource/spec/run_spec.rb +4 -4
  35. data/examples/dsc_script/spec/run_spec.rb +1 -1
  36. data/examples/env/spec/create_spec.rb +1 -1
  37. data/examples/env/spec/delete_spec.rb +1 -1
  38. data/examples/env/spec/modify_spec.rb +1 -1
  39. data/examples/freebsd_package/spec/install_spec.rb +1 -1
  40. data/examples/freebsd_package/spec/remove_spec.rb +1 -1
  41. data/examples/ips_package/spec/install_spec.rb +1 -1
  42. data/examples/ips_package/spec/remove_spec.rb +1 -1
  43. data/examples/ips_package/spec/upgrade_spec.rb +1 -1
  44. data/examples/msu_package/recipes/install.rb +13 -0
  45. data/examples/msu_package/recipes/remove.rb +13 -0
  46. data/examples/msu_package/spec/install_spec.rb +26 -0
  47. data/examples/msu_package/spec/remove_spec.rb +22 -0
  48. data/examples/pacman_package/spec/install_spec.rb +1 -1
  49. data/examples/pacman_package/spec/purge_spec.rb +1 -1
  50. data/examples/pacman_package/spec/remove_spec.rb +1 -1
  51. data/examples/pacman_package/spec/upgrade_spec.rb +1 -1
  52. data/examples/portage_package/spec/install_spec.rb +1 -1
  53. data/examples/portage_package/spec/purge_spec.rb +1 -1
  54. data/examples/portage_package/spec/remove_spec.rb +1 -1
  55. data/examples/portage_package/spec/upgrade_spec.rb +1 -1
  56. data/examples/powershell_script/spec/run_spec.rb +1 -1
  57. data/examples/registry_key/spec/create_if_missing_spec.rb +1 -1
  58. data/examples/registry_key/spec/create_spec.rb +1 -1
  59. data/examples/registry_key/spec/delete_key_spec.rb +1 -1
  60. data/examples/registry_key/spec/delete_spec.rb +1 -1
  61. data/examples/roles/roles/role.rb +2 -2
  62. data/examples/rpm_package/spec/install_spec.rb +1 -1
  63. data/examples/rpm_package/spec/remove_spec.rb +1 -1
  64. data/examples/rpm_package/spec/upgrade_spec.rb +1 -1
  65. data/examples/server/spec/data_bag_spec.rb +9 -11
  66. data/examples/smartos_package/spec/install_spec.rb +1 -1
  67. data/examples/smartos_package/spec/remove_spec.rb +1 -1
  68. data/examples/smartos_package/spec/upgrade_spec.rb +1 -1
  69. data/examples/solaris_package/spec/install_spec.rb +1 -1
  70. data/examples/solaris_package/spec/remove_spec.rb +1 -1
  71. data/examples/step_into/spec/default_spec.rb +2 -2
  72. data/examples/use_inline_resources/spec/default_spec.rb +1 -1
  73. data/examples/windows_package/spec/install_spec.rb +1 -1
  74. data/examples/windows_package/spec/remove_spec.rb +1 -1
  75. data/examples/windows_service/spec/configure_startup_spec.rb +1 -1
  76. data/examples/windows_service/spec/disable_spec.rb +1 -1
  77. data/examples/windows_service/spec/enable_spec.rb +1 -1
  78. data/examples/windows_service/spec/reload_spec.rb +1 -1
  79. data/examples/windows_service/spec/restart_spec.rb +1 -1
  80. data/examples/windows_service/spec/start_spec.rb +1 -1
  81. data/examples/windows_service/spec/stop_spec.rb +1 -1
  82. data/examples/yum_package/spec/install_spec.rb +1 -1
  83. data/examples/yum_package/spec/purge_spec.rb +1 -1
  84. data/examples/yum_package/spec/remove_spec.rb +1 -1
  85. data/examples/yum_package/spec/upgrade_spec.rb +1 -1
  86. data/examples/yum_repository/spec/add_spec.rb +1 -1
  87. data/examples/yum_repository/spec/create_spec.rb +1 -1
  88. data/examples/yum_repository/spec/delete_spec.rb +1 -1
  89. data/examples/yum_repository/spec/makecache_spec.rb +1 -1
  90. data/examples/yum_repository/spec/remove_spec.rb +1 -1
  91. data/features/cab_package.feature +21 -0
  92. data/features/dnf_package.feature +26 -0
  93. data/features/msu_package.feature +23 -0
  94. data/features/support/env.rb +8 -0
  95. data/lib/chefspec.rb +0 -1
  96. data/lib/chefspec/api.rb +3 -0
  97. data/lib/chefspec/api/cab_package.rb +80 -0
  98. data/lib/chefspec/api/dnf_package.rb +154 -0
  99. data/lib/chefspec/api/msu_package.rb +81 -0
  100. data/lib/chefspec/rspec.rb +1 -0
  101. data/lib/chefspec/server_methods.rb +4 -35
  102. data/lib/chefspec/server_runner.rb +2 -42
  103. data/lib/chefspec/version.rb +1 -1
  104. data/lib/chefspec/zero_server.rb +139 -0
  105. metadata +31 -6
  106. 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
@@ -20,4 +20,5 @@ RSpec.configure do |config|
20
20
  config.add_setting :platform
21
21
  config.add_setting :version
22
22
  config.add_setting :server_runner_data_store, default: :in_memory
23
+ config.add_setting :server_runner_clear_cookbooks, default: true
23
24
  end
@@ -10,16 +10,7 @@ module ChefSpec
10
10
  # @return [ChefZero::Server]
11
11
  #
12
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
- # 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
- @server.load_data({ key => { name => data } })
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
- @server.data_store.list(args)
164
+ server.data_store.list(args)
174
165
  else
175
- @server.data_store.get(args)
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
@@ -1,3 +1,3 @@
1
1
  module ChefSpec
2
- VERSION = '5.4.0'
2
+ VERSION = '6.0.0'
3
3
  end
@@ -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