test-kitchen 1.2.1 → 1.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (114) hide show
  1. checksums.yaml +4 -4
  2. data/.cane +1 -1
  3. data/.rubocop.yml +3 -0
  4. data/.travis.yml +20 -9
  5. data/CHANGELOG.md +219 -108
  6. data/Gemfile +10 -6
  7. data/Guardfile +38 -9
  8. data/README.md +11 -1
  9. data/Rakefile +21 -37
  10. data/bin/kitchen +4 -4
  11. data/features/kitchen_action_commands.feature +161 -0
  12. data/features/kitchen_console_command.feature +34 -0
  13. data/features/kitchen_diagnose_command.feature +64 -0
  14. data/features/kitchen_init_command.feature +29 -17
  15. data/features/kitchen_list_command.feature +2 -2
  16. data/features/kitchen_login_command.feature +56 -0
  17. data/features/{sink_command.feature → kitchen_sink_command.feature} +0 -0
  18. data/features/kitchen_test_command.feature +88 -0
  19. data/features/step_definitions/gem_steps.rb +8 -6
  20. data/features/step_definitions/git_steps.rb +4 -2
  21. data/features/step_definitions/output_steps.rb +5 -0
  22. data/features/support/env.rb +12 -9
  23. data/lib/kitchen.rb +60 -38
  24. data/lib/kitchen/base64_stream.rb +55 -0
  25. data/lib/kitchen/busser.rb +124 -58
  26. data/lib/kitchen/cli.rb +121 -38
  27. data/lib/kitchen/collection.rb +3 -3
  28. data/lib/kitchen/color.rb +4 -4
  29. data/lib/kitchen/command.rb +78 -11
  30. data/lib/kitchen/command/action.rb +3 -2
  31. data/lib/kitchen/command/console.rb +12 -5
  32. data/lib/kitchen/command/diagnose.rb +17 -3
  33. data/lib/kitchen/command/driver_discover.rb +26 -7
  34. data/lib/kitchen/command/exec.rb +41 -0
  35. data/lib/kitchen/command/list.rb +44 -14
  36. data/lib/kitchen/command/login.rb +2 -1
  37. data/lib/kitchen/command/sink.rb +2 -1
  38. data/lib/kitchen/command/test.rb +5 -4
  39. data/lib/kitchen/config.rb +146 -14
  40. data/lib/kitchen/configurable.rb +314 -0
  41. data/lib/kitchen/data_munger.rb +522 -18
  42. data/lib/kitchen/diagnostic.rb +43 -4
  43. data/lib/kitchen/driver.rb +4 -4
  44. data/lib/kitchen/driver/base.rb +80 -115
  45. data/lib/kitchen/driver/dummy.rb +34 -6
  46. data/lib/kitchen/driver/proxy.rb +14 -3
  47. data/lib/kitchen/driver/ssh_base.rb +61 -7
  48. data/lib/kitchen/errors.rb +109 -9
  49. data/lib/kitchen/generator/driver_create.rb +39 -5
  50. data/lib/kitchen/generator/init.rb +130 -45
  51. data/lib/kitchen/instance.rb +162 -28
  52. data/lib/kitchen/lazy_hash.rb +79 -7
  53. data/lib/kitchen/loader/yaml.rb +159 -27
  54. data/lib/kitchen/logger.rb +267 -21
  55. data/lib/kitchen/logging.rb +30 -3
  56. data/lib/kitchen/login_command.rb +11 -2
  57. data/lib/kitchen/metadata_chopper.rb +2 -2
  58. data/lib/kitchen/provisioner.rb +4 -4
  59. data/lib/kitchen/provisioner/base.rb +107 -103
  60. data/lib/kitchen/provisioner/chef/berkshelf.rb +36 -8
  61. data/lib/kitchen/provisioner/chef/librarian.rb +40 -11
  62. data/lib/kitchen/provisioner/chef_base.rb +206 -167
  63. data/lib/kitchen/provisioner/chef_solo.rb +25 -7
  64. data/lib/kitchen/provisioner/chef_zero.rb +105 -29
  65. data/lib/kitchen/provisioner/dummy.rb +1 -1
  66. data/lib/kitchen/provisioner/shell.rb +21 -6
  67. data/lib/kitchen/rake_tasks.rb +8 -3
  68. data/lib/kitchen/shell_out.rb +15 -18
  69. data/lib/kitchen/ssh.rb +122 -27
  70. data/lib/kitchen/state_file.rb +24 -7
  71. data/lib/kitchen/thor_tasks.rb +9 -4
  72. data/lib/kitchen/util.rb +43 -118
  73. data/lib/kitchen/version.rb +1 -1
  74. data/lib/vendor/hash_recursive_merge.rb +10 -2
  75. data/spec/kitchen/base64_stream_spec.rb +77 -0
  76. data/spec/kitchen/busser_spec.rb +490 -0
  77. data/spec/kitchen/collection_spec.rb +10 -10
  78. data/spec/kitchen/color_spec.rb +2 -2
  79. data/spec/kitchen/config_spec.rb +234 -62
  80. data/spec/kitchen/configurable_spec.rb +490 -0
  81. data/spec/kitchen/data_munger_spec.rb +1070 -862
  82. data/spec/kitchen/diagnostic_spec.rb +79 -0
  83. data/spec/kitchen/driver/base_spec.rb +80 -85
  84. data/spec/kitchen/driver/dummy_spec.rb +43 -14
  85. data/spec/kitchen/driver/proxy_spec.rb +134 -0
  86. data/spec/kitchen/driver/ssh_base_spec.rb +644 -0
  87. data/spec/kitchen/driver_spec.rb +15 -15
  88. data/spec/kitchen/errors_spec.rb +309 -0
  89. data/spec/kitchen/instance_spec.rb +143 -46
  90. data/spec/kitchen/lazy_hash_spec.rb +36 -9
  91. data/spec/kitchen/loader/yaml_spec.rb +237 -226
  92. data/spec/kitchen/logger_spec.rb +419 -0
  93. data/spec/kitchen/logging_spec.rb +59 -0
  94. data/spec/kitchen/login_command_spec.rb +49 -0
  95. data/spec/kitchen/metadata_chopper_spec.rb +82 -0
  96. data/spec/kitchen/platform_spec.rb +4 -4
  97. data/spec/kitchen/provisioner/base_spec.rb +65 -125
  98. data/spec/kitchen/provisioner/chef_base_spec.rb +798 -0
  99. data/spec/kitchen/provisioner/chef_solo_spec.rb +316 -0
  100. data/spec/kitchen/provisioner/chef_zero_spec.rb +624 -0
  101. data/spec/kitchen/provisioner/shell_spec.rb +269 -0
  102. data/spec/kitchen/provisioner_spec.rb +6 -6
  103. data/spec/kitchen/shell_out_spec.rb +143 -0
  104. data/spec/kitchen/ssh_spec.rb +683 -0
  105. data/spec/kitchen/state_file_spec.rb +28 -21
  106. data/spec/kitchen/suite_spec.rb +7 -7
  107. data/spec/kitchen/util_spec.rb +68 -10
  108. data/spec/kitchen_spec.rb +107 -0
  109. data/spec/spec_helper.rb +18 -13
  110. data/support/chef-client-zero.rb +10 -9
  111. data/support/chef_helpers.sh +16 -0
  112. data/support/download_helpers.sh +109 -0
  113. data/test-kitchen.gemspec +42 -33
  114. metadata +107 -33
@@ -0,0 +1,316 @@
1
+ # -*- encoding: utf-8 -*-
2
+ #
3
+ # Author:: Fletcher Nichol (<fnichol@nichol.ca>)
4
+ #
5
+ # Copyright (C) 2014, Fletcher Nichol
6
+ #
7
+ # Licensed under the Apache License, Version 2.0 (the "License");
8
+ # you may not use this file except in compliance with the License.
9
+ # You may obtain a copy of the License at
10
+ #
11
+ # http://www.apache.org/licenses/LICENSE-2.0
12
+ #
13
+ # Unless required by applicable law or agreed to in writing, software
14
+ # distributed under the License is distributed on an "AS IS" BASIS,
15
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
+ # See the License for the specific language governing permissions and
17
+ # limitations under the License.
18
+
19
+ require_relative "../../spec_helper"
20
+
21
+ require "kitchen"
22
+ require "kitchen/provisioner/chef_solo"
23
+
24
+ describe Kitchen::Provisioner::ChefSolo do
25
+
26
+ let(:logged_output) { StringIO.new }
27
+ let(:logger) { Logger.new(logged_output) }
28
+
29
+ let(:config) do
30
+ { :test_base_path => "/b", :kitchen_root => "/r", :log_level => :info }
31
+ end
32
+
33
+ let(:suite) do
34
+ stub(:name => "fries")
35
+ end
36
+
37
+ let(:instance) do
38
+ stub(:name => "coolbeans", :logger => logger, :suite => suite)
39
+ end
40
+
41
+ let(:provisioner) do
42
+ Kitchen::Provisioner::ChefSolo.new(config).finalize_config!(instance)
43
+ end
44
+
45
+ describe "default config" do
46
+
47
+ it "sets :solo_rb to an empty Hash" do
48
+ provisioner[:solo_rb].must_equal Hash.new
49
+ end
50
+
51
+ it "sets :chef_solo_path to a path using :chef_omnibus_root" do
52
+ config[:chef_omnibus_root] = "/nice/place"
53
+
54
+ provisioner[:chef_solo_path].must_equal "/nice/place/bin/chef-solo"
55
+ end
56
+ end
57
+
58
+ describe "#create_sandbox" do
59
+
60
+ before do
61
+ @root = Dir.mktmpdir
62
+ config[:kitchen_root] = @root
63
+ end
64
+
65
+ after do
66
+ FileUtils.remove_entry(@root)
67
+ begin
68
+ provisioner.cleanup_sandbox
69
+ rescue # rubocop:disable Lint/HandleExceptions
70
+ end
71
+ end
72
+
73
+ describe "solo.rb file" do
74
+
75
+ let(:file) do
76
+ IO.read(sandbox_path("solo.rb")).lines.map(&:chomp)
77
+ end
78
+
79
+ it "creates a solo.rb" do
80
+ provisioner.create_sandbox
81
+
82
+ sandbox_path("solo.rb").file?.must_equal true
83
+ end
84
+
85
+ it "logs a message on info" do
86
+ provisioner.create_sandbox
87
+
88
+ logged_output.string.must_match info_line("Preparing solo.rb")
89
+ end
90
+
91
+ it "logs a message on debug" do
92
+ provisioner.create_sandbox
93
+
94
+ logged_output.string.
95
+ must_match debug_line_starting_with("Creating solo.rb from {")
96
+ end
97
+
98
+ describe "defaults" do
99
+
100
+ before { provisioner.create_sandbox }
101
+
102
+ it "sets node_name to the instance name" do
103
+ file.must_include %{node_name "#{instance.name}"}
104
+ end
105
+
106
+ it "sets checksum_path" do
107
+ file.must_include %{checksum_path "/tmp/kitchen/checksums"}
108
+ end
109
+
110
+ it "sets file_backup_path" do
111
+ file.must_include %{file_backup_path "/tmp/kitchen/backup"}
112
+ end
113
+
114
+ it "sets cookbook_path" do
115
+ file.must_include %{cookbook_path } +
116
+ %{["/tmp/kitchen/cookbooks", "/tmp/kitchen/site-cookbooks"]}
117
+ end
118
+
119
+ it "sets data_bag_path" do
120
+ file.must_include %{data_bag_path "/tmp/kitchen/data_bags"}
121
+ end
122
+
123
+ it "sets environment_path" do
124
+ file.must_include %{environment_path "/tmp/kitchen/environments"}
125
+ end
126
+
127
+ it "sets node_path" do
128
+ file.must_include %{node_path "/tmp/kitchen/nodes"}
129
+ end
130
+
131
+ it "sets role_path" do
132
+ file.must_include %{role_path "/tmp/kitchen/roles"}
133
+ end
134
+
135
+ it "sets client_path" do
136
+ file.must_include %{client_path "/tmp/kitchen/clients"}
137
+ end
138
+
139
+ it "sets user_path" do
140
+ file.must_include %{user_path "/tmp/kitchen/users"}
141
+ end
142
+
143
+ it "sets validation_key" do
144
+ file.must_include %{validation_key "/tmp/kitchen/validation.pem"}
145
+ end
146
+
147
+ it "sets client_key" do
148
+ file.must_include %{client_key "/tmp/kitchen/client.pem"}
149
+ end
150
+
151
+ it "sets chef_server_url" do
152
+ file.must_include %{chef_server_url "http://127.0.0.1:8889"}
153
+ end
154
+
155
+ it "sets encrypted_data_bag_secret" do
156
+ file.must_include %{encrypted_data_bag_secret } +
157
+ %{"/tmp/kitchen/encrypted_data_bag_secret"}
158
+ end
159
+ end
160
+
161
+ it "supports overwriting defaults" do
162
+ config[:solo_rb] = {
163
+ :node_name => "eagles",
164
+ :user_path => "/a/b/c/u",
165
+ :client_key => "lol"
166
+ }
167
+ provisioner.create_sandbox
168
+
169
+ file.must_include %{node_name "eagles"}
170
+ file.must_include %{user_path "/a/b/c/u"}
171
+ file.must_include %{client_key "lol"}
172
+ end
173
+
174
+ it " supports adding new configuration" do
175
+ config[:solo_rb] = {
176
+ :dark_secret => "golang"
177
+ }
178
+ provisioner.create_sandbox
179
+
180
+ file.must_include %{dark_secret "golang"}
181
+ end
182
+
183
+ it "formats array values correctly" do
184
+ config[:solo_rb] = {
185
+ :foos => %w[foo1 foo2]
186
+ }
187
+ provisioner.create_sandbox
188
+
189
+ file.must_include %{foos ["foo1", "foo2"]}
190
+ end
191
+
192
+ it "formats integer values correctly" do
193
+ config[:solo_rb] = {
194
+ :foo => 7
195
+ }
196
+ provisioner.create_sandbox
197
+
198
+ file.must_include %{foo 7}
199
+ end
200
+
201
+ it "formats symbol values correctly" do
202
+ config[:solo_rb] = {
203
+ :foo => :bar
204
+ }
205
+ provisioner.create_sandbox
206
+
207
+ file.must_include %{foo :bar}
208
+ end
209
+
210
+ it "formats boolean values correctly" do
211
+ config[:solo_rb] = {
212
+ :foo => false,
213
+ :bar => true
214
+ }
215
+ provisioner.create_sandbox
216
+
217
+ file.must_include %{foo false}
218
+ file.must_include %{bar true}
219
+ end
220
+ end
221
+
222
+ def sandbox_path(path)
223
+ Pathname.new(provisioner.sandbox_path).join(path)
224
+ end
225
+
226
+ end
227
+
228
+ describe "#run_command" do
229
+
230
+ let(:cmd) { provisioner.run_command }
231
+
232
+ it "uses bourne shell" do
233
+ cmd.must_match(/\Ash -c '$/)
234
+ cmd.must_match(/'\Z/)
235
+ end
236
+
237
+ it "uses sudo for chef-solo when configured" do
238
+ config[:chef_omnibus_root] = "/c"
239
+ config[:sudo] = true
240
+
241
+ cmd.must_match regexify("sudo -E /c/bin/chef-solo ", :partial_line)
242
+ end
243
+
244
+ it "does not use sudo for chef-solo when configured" do
245
+ config[:chef_omnibus_root] = "/c"
246
+ config[:sudo] = false
247
+
248
+ cmd.must_match regexify("chef-solo ", :partial_line)
249
+ cmd.wont_match regexify("sudo -E /c/bin/chef-solo ", :partial_line)
250
+ end
251
+
252
+ it "sets config flag on chef-solo" do
253
+ cmd.must_match regexify(" --config /tmp/kitchen/solo.rb", :partial_line)
254
+ end
255
+
256
+ it "sets config flag for custom root_path" do
257
+ config[:root_path] = "/a/b"
258
+
259
+ cmd.must_match regexify(" --config /a/b/solo.rb", :partial_line)
260
+ end
261
+
262
+ it "sets json attributes flag on chef-solo" do
263
+ cmd.must_match regexify(
264
+ " --json-attributes /tmp/kitchen/dna.json", :partial_line)
265
+ end
266
+
267
+ it "sets json attribtes flag for custom root_path" do
268
+ config[:root_path] = "/booyah"
269
+
270
+ cmd.must_match regexify(
271
+ " --json-attributes /booyah/dna.json", :partial_line)
272
+ end
273
+
274
+ it "sets log level flag on chef-solo to auto by default" do
275
+ cmd.must_match regexify(" --log_level auto", :partial_line)
276
+ end
277
+
278
+ it "set log level flag for custom level" do
279
+ config[:log_level] = :extreme
280
+
281
+ cmd.must_match regexify(" --log_level extreme", :partial_line)
282
+ end
283
+
284
+ it "sets force formatter flag on chef-solo" do
285
+ cmd.must_match regexify(" --force-formatter", :partial_line)
286
+ end
287
+
288
+ it "sets no color flag on chef-solo" do
289
+ cmd.must_match regexify(" --no-color", :partial_line)
290
+ end
291
+
292
+ it "does not set logfile flag by default" do
293
+ cmd.wont_match regexify(" --logfile ", :partial_line)
294
+ end
295
+
296
+ it "sets logfile flag for custom value" do
297
+ config[:log_file] = "/a/out.log"
298
+
299
+ cmd.must_match regexify(" --logfile /a/out.log", :partial_line)
300
+ end
301
+ end
302
+
303
+ def info_line(msg)
304
+ %r{^I, .* : #{Regexp.escape(msg)}$}
305
+ end
306
+
307
+ def debug_line_starting_with(msg)
308
+ %r{^D, .* : #{Regexp.escape(msg)}}
309
+ end
310
+
311
+ def regexify(str, line = :whole_line)
312
+ r = Regexp.escape(str)
313
+ r = "^\s*#{r}$" if line == :whole_line
314
+ Regexp.new(r)
315
+ end
316
+ end
@@ -0,0 +1,624 @@
1
+ # -*- encoding: utf-8 -*-
2
+ #
3
+ # Author:: Fletcher Nichol (<fnichol@nichol.ca>)
4
+ #
5
+ # Copyright (C) 2014, Fletcher Nichol
6
+ #
7
+ # Licensed under the Apache License, Version 2.0 (the "License");
8
+ # you may not use this file except in compliance with the License.
9
+ # You may obtain a copy of the License at
10
+ #
11
+ # http://www.apache.org/licenses/LICENSE-2.0
12
+ #
13
+ # Unless required by applicable law or agreed to in writing, software
14
+ # distributed under the License is distributed on an "AS IS" BASIS,
15
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
+ # See the License for the specific language governing permissions and
17
+ # limitations under the License.
18
+
19
+ require_relative "../../spec_helper"
20
+
21
+ require "kitchen"
22
+ require "kitchen/provisioner/chef_zero"
23
+
24
+ describe Kitchen::Provisioner::ChefZero do
25
+
26
+ let(:logged_output) { StringIO.new }
27
+ let(:logger) { Logger.new(logged_output) }
28
+
29
+ let(:config) do
30
+ { :test_base_path => "/b", :kitchen_root => "/r", :log_level => :info }
31
+ end
32
+
33
+ let(:suite) do
34
+ stub(:name => "fries")
35
+ end
36
+
37
+ let(:instance) do
38
+ stub(:name => "coolbeans", :logger => logger, :suite => suite)
39
+ end
40
+
41
+ let(:provisioner) do
42
+ Kitchen::Provisioner::ChefZero.new(config).finalize_config!(instance)
43
+ end
44
+
45
+ describe "default config" do
46
+
47
+ it "sets :client_rb to an empty Hash" do
48
+ provisioner[:client_rb].must_equal Hash.new
49
+ end
50
+
51
+ it "sets :chef_client_path to a path using :chef_omnibus_root" do
52
+ config[:chef_omnibus_root] = "/nice/place"
53
+
54
+ provisioner[:chef_client_path].must_equal "/nice/place/bin/chef-client"
55
+ end
56
+
57
+ it "sets :ruby_bindir to use an Omnibus Ruby" do
58
+ provisioner[:ruby_bindir].must_equal "/opt/chef/embedded/bin"
59
+ end
60
+
61
+ it "sets :json_attributes to true" do
62
+ provisioner[:json_attributes].must_equal true
63
+ end
64
+
65
+ it "does not set :chef_zero_host" do
66
+ provisioner[:chef_zero_host].must_equal nil
67
+ end
68
+
69
+ it "sets :chef_zero_port to 8889" do
70
+ provisioner[:chef_zero_port].must_equal 8889
71
+ end
72
+ end
73
+
74
+ describe "#create_sandbox" do
75
+
76
+ before do
77
+ @root = Dir.mktmpdir
78
+ config[:kitchen_root] = @root
79
+ end
80
+
81
+ after do
82
+ FileUtils.remove_entry(@root)
83
+ begin
84
+ provisioner.cleanup_sandbox
85
+ rescue # rubocop:disable Lint/HandleExceptions
86
+ end
87
+ end
88
+
89
+ describe "client.rb file" do
90
+
91
+ let(:file) do
92
+ IO.read(sandbox_path("client.rb")).lines.map(&:chomp)
93
+ end
94
+
95
+ it "creates a client.rb" do
96
+ provisioner.create_sandbox
97
+
98
+ sandbox_path("client.rb").file?.must_equal true
99
+ end
100
+
101
+ it "logs a message on info" do
102
+ provisioner.create_sandbox
103
+
104
+ logged_output.string.must_match info_line("Preparing client.rb")
105
+ end
106
+
107
+ it "logs a message on debug" do
108
+ provisioner.create_sandbox
109
+
110
+ logged_output.string.
111
+ must_match debug_line_starting_with("Creating client.rb from {")
112
+ end
113
+
114
+ describe "defaults" do
115
+
116
+ before { provisioner.create_sandbox }
117
+
118
+ it "sets node_name to the instance name" do
119
+ file.must_include %{node_name "#{instance.name}"}
120
+ end
121
+
122
+ it "sets checksum_path" do
123
+ file.must_include %{checksum_path "/tmp/kitchen/checksums"}
124
+ end
125
+
126
+ it "sets file_backup_path" do
127
+ file.must_include %{file_backup_path "/tmp/kitchen/backup"}
128
+ end
129
+
130
+ it "sets cookbook_path" do
131
+ file.must_include %{cookbook_path } +
132
+ %{["/tmp/kitchen/cookbooks", "/tmp/kitchen/site-cookbooks"]}
133
+ end
134
+
135
+ it "sets data_bag_path" do
136
+ file.must_include %{data_bag_path "/tmp/kitchen/data_bags"}
137
+ end
138
+
139
+ it "sets environment_path" do
140
+ file.must_include %{environment_path "/tmp/kitchen/environments"}
141
+ end
142
+
143
+ it "sets node_path" do
144
+ file.must_include %{node_path "/tmp/kitchen/nodes"}
145
+ end
146
+
147
+ it "sets role_path" do
148
+ file.must_include %{role_path "/tmp/kitchen/roles"}
149
+ end
150
+
151
+ it "sets client_path" do
152
+ file.must_include %{client_path "/tmp/kitchen/clients"}
153
+ end
154
+
155
+ it "sets user_path" do
156
+ file.must_include %{user_path "/tmp/kitchen/users"}
157
+ end
158
+
159
+ it "sets validation_key" do
160
+ file.must_include %{validation_key "/tmp/kitchen/validation.pem"}
161
+ end
162
+
163
+ it "sets client_key" do
164
+ file.must_include %{client_key "/tmp/kitchen/client.pem"}
165
+ end
166
+
167
+ it "sets chef_server_url" do
168
+ file.must_include %{chef_server_url "http://127.0.0.1:8889"}
169
+ end
170
+
171
+ it "sets encrypted_data_bag_secret" do
172
+ file.must_include %{encrypted_data_bag_secret } +
173
+ %{"/tmp/kitchen/encrypted_data_bag_secret"}
174
+ end
175
+ end
176
+
177
+ it "supports overwriting defaults" do
178
+ config[:client_rb] = {
179
+ :node_name => "eagles",
180
+ :user_path => "/a/b/c/u",
181
+ :client_key => "lol"
182
+ }
183
+ provisioner.create_sandbox
184
+
185
+ file.must_include %{node_name "eagles"}
186
+ file.must_include %{user_path "/a/b/c/u"}
187
+ file.must_include %{client_key "lol"}
188
+ end
189
+
190
+ it " supports adding new configuration" do
191
+ config[:client_rb] = {
192
+ :dark_secret => "golang"
193
+ }
194
+ provisioner.create_sandbox
195
+
196
+ file.must_include %{dark_secret "golang"}
197
+ end
198
+
199
+ it "formats array values correctly" do
200
+ config[:client_rb] = {
201
+ :foos => %w[foo1 foo2]
202
+ }
203
+ provisioner.create_sandbox
204
+
205
+ file.must_include %{foos ["foo1", "foo2"]}
206
+ end
207
+
208
+ it "formats integer values correctly" do
209
+ config[:client_rb] = {
210
+ :foo => 7
211
+ }
212
+ provisioner.create_sandbox
213
+
214
+ file.must_include %{foo 7}
215
+ end
216
+
217
+ it "formats symbol values correctly" do
218
+ config[:client_rb] = {
219
+ :foo => :bar
220
+ }
221
+ provisioner.create_sandbox
222
+
223
+ file.must_include %{foo :bar}
224
+ end
225
+
226
+ it "formats boolean values correctly" do
227
+ config[:client_rb] = {
228
+ :foo => false,
229
+ :bar => true
230
+ }
231
+ provisioner.create_sandbox
232
+
233
+ file.must_include %{foo false}
234
+ file.must_include %{bar true}
235
+ end
236
+ end
237
+
238
+ describe "validation.pem file" do
239
+
240
+ it "creates file" do
241
+ provisioner.create_sandbox
242
+
243
+ sandbox_path("validation.pem").file?.must_equal true
244
+ end
245
+
246
+ it "logs a message on info" do
247
+ provisioner.create_sandbox
248
+
249
+ logged_output.string.must_match info_line("Preparing validation.pem")
250
+ end
251
+
252
+ it "logs a message on debug" do
253
+ provisioner.create_sandbox
254
+
255
+ logged_output.string.
256
+ must_match debug_line_starting_with("Using a dummy validation.pem")
257
+ end
258
+ end
259
+
260
+ describe "chef-client-zero.rb file" do
261
+
262
+ describe "for modern Chef versions" do
263
+
264
+ before { config[:require_chef_omnibus] = "11.10" }
265
+
266
+ it "does not create the file" do
267
+ provisioner.create_sandbox
268
+
269
+ sandbox_path("chef-client-zero.rb").file?.must_equal false
270
+ end
271
+ end
272
+
273
+ describe "for old Chef versions" do
274
+
275
+ before { config[:require_chef_omnibus] = "10.20" }
276
+
277
+ it "creates the file when using an old Chef version" do
278
+ provisioner.create_sandbox
279
+
280
+ sandbox_path("chef-client-zero.rb").file?.must_equal true
281
+ end
282
+
283
+ it "logs a message on info" do
284
+ provisioner.create_sandbox
285
+
286
+ logged_output.string.
287
+ must_match info_line("Preparing chef-client-zero.rb")
288
+ end
289
+
290
+ it "logs a message on debug" do
291
+ provisioner.create_sandbox
292
+
293
+ logged_output.string.must_match debug_line_starting_with(
294
+ "Using a vendored chef-client-zero.rb")
295
+ end
296
+ end
297
+ end
298
+
299
+ def sandbox_path(path)
300
+ Pathname.new(provisioner.sandbox_path).join(path)
301
+ end
302
+ end
303
+
304
+ describe "#prepare_command" do
305
+
306
+ let(:cmd) { provisioner.prepare_command }
307
+
308
+ describe "for modern Chef versions" do
309
+
310
+ before { config[:require_chef_omnibus] = "11.10" }
311
+
312
+ it "returns nil" do
313
+ cmd.must_equal nil
314
+ end
315
+ end
316
+
317
+ describe "for old Chef versions" do
318
+
319
+ before do
320
+ config[:require_chef_omnibus] = "10.20"
321
+ config[:ruby_bindir] = "/rbd"
322
+ end
323
+
324
+ it "uses bourne shell" do
325
+ cmd.must_match(/\Ash -c '$/)
326
+ cmd.must_match(/'\Z/)
327
+ end
328
+
329
+ it "sets the CHEF_REPO_PATH environment variable" do
330
+ config[:root_path] = "/r"
331
+
332
+ cmd.must_match regexify(%{CHEF_REPO_PATH="/r" }, :partial_line)
333
+ end
334
+
335
+ it "sets the GEM_HOME environment variable" do
336
+ config[:root_path] = "/r"
337
+
338
+ cmd.must_match regexify(
339
+ %{GEM_HOME="/r/chef-client-zero-gems" }, :partial_line)
340
+ end
341
+
342
+ it "sets the GEM_PATH environment variable" do
343
+ config[:root_path] = "/r"
344
+
345
+ cmd.must_match regexify(
346
+ %{GEM_PATH="/r/chef-client-zero-gems" }, :partial_line)
347
+ end
348
+
349
+ it "sets the GEM_CACHE environment variable" do
350
+ config[:root_path] = "/r"
351
+
352
+ cmd.must_match regexify(
353
+ %{GEM_CACHE="/r/chef-client-zero-gems/cache" }, :partial_line)
354
+ end
355
+
356
+ it "exports all the environment variables" do
357
+ cmd.must_match regexify(
358
+ "export CHEF_REPO_PATH GEM_HOME GEM_PATH GEM_CACHE;", :partial_line)
359
+ end
360
+
361
+ it "checks if chef-zero is installed" do
362
+ cmd.must_match regexify(
363
+ %{if ! sudo -E /rbd/gem list chef-zero -i >/dev/null; then})
364
+ end
365
+
366
+ it "installs the chef gem" do
367
+ cmd.must_match regexify(
368
+ %{sudo -E /rbd/gem install chef --no-ri --no-rdoc --conservative})
369
+ end
370
+ end
371
+ end
372
+
373
+ describe "#run_command" do
374
+
375
+ let(:cmd) { provisioner.run_command }
376
+
377
+ describe "for modern Chef versions" do
378
+
379
+ before { config[:require_chef_omnibus] = "11.10" }
380
+
381
+ it "uses bourne shell" do
382
+ cmd.must_match(/\Ash -c '$/)
383
+ cmd.must_match(/'\Z/)
384
+ end
385
+
386
+ it "uses sudo for chef-client when configured" do
387
+ config[:chef_omnibus_root] = "/c"
388
+ config[:sudo] = true
389
+
390
+ cmd.must_match regexify("sudo -E /c/bin/chef-client ", :partial_line)
391
+ end
392
+
393
+ it "does not use sudo for chef-client when configured" do
394
+ config[:chef_omnibus_root] = "/c"
395
+ config[:sudo] = false
396
+
397
+ cmd.must_match regexify("/c/bin/chef-client ", :partial_line)
398
+ cmd.wont_match regexify("sudo -E /c/bin/chef-client ", :partial_line)
399
+ end
400
+
401
+ it "sets local mode flag on chef-client" do
402
+ cmd.must_match regexify(" --local-mode", :partial_line)
403
+ end
404
+
405
+ it "sets config flag on chef-client" do
406
+ cmd.must_match regexify(
407
+ " --config /tmp/kitchen/client.rb", :partial_line)
408
+ end
409
+
410
+ it "sets config flag for custom root_path" do
411
+ config[:root_path] = "/a/b"
412
+
413
+ cmd.must_match regexify(" --config /a/b/client.rb", :partial_line)
414
+ end
415
+
416
+ it "sets log level flag on chef-client to auto by default" do
417
+ cmd.must_match regexify(" --log_level auto", :partial_line)
418
+ end
419
+
420
+ it "set log level flag for custom level" do
421
+ config[:log_level] = :extreme
422
+
423
+ cmd.must_match regexify(" --log_level extreme", :partial_line)
424
+ end
425
+
426
+ it "sets force formatter flag on chef-solo" do
427
+ cmd.must_match regexify(" --force-formatter", :partial_line)
428
+ end
429
+
430
+ it "sets no color flag on chef-solo" do
431
+ cmd.must_match regexify(" --no-color", :partial_line)
432
+ end
433
+
434
+ it "sets chef zero port flag on chef-client" do
435
+ cmd.must_match regexify(" --chef-zero-port 8889", :partial_line)
436
+ end
437
+
438
+ it "sets chef zero host flag for custom host" do
439
+ config[:chef_zero_host] = "192.168.0.1"
440
+
441
+ cmd.must_match regexify(" --chef-zero-host 192.168.0.1", :partial_line)
442
+ end
443
+
444
+ it "sets chef zero port flag for custom port" do
445
+ config[:chef_zero_port] = 123
446
+
447
+ cmd.must_match regexify(" --chef-zero-port 123", :partial_line)
448
+ end
449
+
450
+ it "does not set chef zero host flag when value is falsey" do
451
+ config[:chef_zero_host] = nil
452
+
453
+ cmd.wont_match regexify(" --chef-zero-host ", :partial_line)
454
+ end
455
+
456
+ it "does not set chef zero port flag when value is falsey" do
457
+ config[:chef_zero_port] = nil
458
+
459
+ cmd.wont_match regexify(" --chef-zero-port ", :partial_line)
460
+ end
461
+
462
+ it "sets json attributes flag on chef-client" do
463
+ cmd.must_match regexify(
464
+ " --json-attributes /tmp/kitchen/dna.json", :partial_line)
465
+ end
466
+
467
+ it "sets json attribtes flag for custom root_path" do
468
+ config[:root_path] = "/booyah"
469
+
470
+ cmd.must_match regexify(
471
+ " --json-attributes /booyah/dna.json", :partial_line)
472
+ end
473
+
474
+ it "does not set json attributes flag if config is falsey" do
475
+ config[:json_attributes] = false
476
+
477
+ cmd.wont_match regexify(" --json-attributes ", :partial_line)
478
+ end
479
+
480
+ it "does not set logfile flag by default" do
481
+ cmd.wont_match regexify(" --logfile ", :partial_line)
482
+ end
483
+
484
+ it "sets logfile flag for custom value" do
485
+ config[:log_file] = "/a/out.log"
486
+
487
+ cmd.must_match regexify(" --logfile /a/out.log", :partial_line)
488
+ end
489
+ end
490
+
491
+ describe "for old Chef versions" do
492
+
493
+ before do
494
+ config[:require_chef_omnibus] = "10.20"
495
+ config[:ruby_bindir] = "/r/bin"
496
+ end
497
+
498
+ it "uses bourne shell" do
499
+ cmd.must_match(/\Ash -c '$/)
500
+ cmd.must_match(/'\Z/)
501
+ end
502
+
503
+ it "uses sudo for ruby when configured" do
504
+ config[:root_path] = "/x"
505
+ config[:sudo] = true
506
+
507
+ cmd.must_match regexify(
508
+ "sudo -E /r/bin/ruby /x/chef-client-zero.rb ", :partial_line)
509
+ end
510
+
511
+ it "does not use sudo for ruby when configured" do
512
+ config[:root_path] = "/x"
513
+ config[:sudo] = false
514
+
515
+ cmd.must_match regexify(
516
+ "/r/bin/ruby /x/chef-client-zero.rb ", :partial_line)
517
+ cmd.wont_match regexify(
518
+ "sudo -E /r/bin/ruby /x/chef-client-zero.rb ", :partial_line)
519
+ end
520
+
521
+ it "does not set local mode flag" do
522
+ cmd.wont_match regexify(" --local-mode", :partial_line)
523
+ end
524
+
525
+ it "sets config flag on chef-client" do
526
+ cmd.must_match regexify(
527
+ " --config /tmp/kitchen/client.rb", :partial_line)
528
+ end
529
+
530
+ it "sets config flag for custom root_path" do
531
+ config[:root_path] = "/a/b"
532
+
533
+ cmd.must_match regexify(" --config /a/b/client.rb", :partial_line)
534
+ end
535
+
536
+ it "sets log level flag on chef-client to auto by default" do
537
+ cmd.must_match regexify(" --log_level auto", :partial_line)
538
+ end
539
+
540
+ it "set log level flag for custom level" do
541
+ config[:log_level] = :extreme
542
+
543
+ cmd.must_match regexify(" --log_level extreme", :partial_line)
544
+ end
545
+
546
+ it "sets force formatter flag on chef-solo" do
547
+ cmd.must_match regexify(" --force-formatter", :partial_line)
548
+ end
549
+
550
+ it "sets no color flag on chef-solo" do
551
+ cmd.must_match regexify(" --no-color", :partial_line)
552
+ end
553
+
554
+ it "sets json attributes flag on chef-client" do
555
+ cmd.must_match regexify(
556
+ " --json-attributes /tmp/kitchen/dna.json", :partial_line)
557
+ end
558
+
559
+ it "sets json attribtes flag for custom root_path" do
560
+ config[:root_path] = "/booyah"
561
+
562
+ cmd.must_match regexify(
563
+ " --json-attributes /booyah/dna.json", :partial_line)
564
+ end
565
+
566
+ it "does not set json attributes flag if config is falsey" do
567
+ config[:json_attributes] = false
568
+
569
+ cmd.wont_match regexify(" --json-attributes ", :partial_line)
570
+ end
571
+
572
+ it "does not set logfile flag by default" do
573
+ cmd.wont_match regexify(" --logfile ", :partial_line)
574
+ end
575
+
576
+ it "sets logfile flag for custom value" do
577
+ config[:log_file] = "/a/out.log"
578
+
579
+ cmd.must_match regexify(" --logfile /a/out.log", :partial_line)
580
+ end
581
+
582
+ it "sets the CHEF_REPO_PATH environment variable" do
583
+ config[:root_path] = "/r"
584
+
585
+ cmd.must_match regexify(%{CHEF_REPO_PATH="/r" }, :partial_line)
586
+ end
587
+
588
+ it "sets the GEM_HOME environment variable" do
589
+ config[:root_path] = "/r"
590
+
591
+ cmd.must_match regexify(
592
+ %{GEM_HOME="/r/chef-client-zero-gems" }, :partial_line)
593
+ end
594
+
595
+ it "sets the GEM_PATH environment variable" do
596
+ config[:root_path] = "/r"
597
+
598
+ cmd.must_match regexify(
599
+ %{GEM_PATH="/r/chef-client-zero-gems" }, :partial_line)
600
+ end
601
+
602
+ it "sets the GEM_CACHE environment variable" do
603
+ config[:root_path] = "/r"
604
+
605
+ cmd.must_match regexify(
606
+ %{GEM_CACHE="/r/chef-client-zero-gems/cache" }, :partial_line)
607
+ end
608
+ end
609
+ end
610
+
611
+ def info_line(msg)
612
+ %r{^I, .* : #{Regexp.escape(msg)}$}
613
+ end
614
+
615
+ def debug_line_starting_with(msg)
616
+ %r{^D, .* : #{Regexp.escape(msg)}}
617
+ end
618
+
619
+ def regexify(str, line = :whole_line)
620
+ r = Regexp.escape(str)
621
+ r = "^\s*#{r}$" if line == :whole_line
622
+ Regexp.new(r)
623
+ end
624
+ end