test-kitchen 1.6.0 → 1.7.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (180) hide show
  1. checksums.yaml +4 -4
  2. data/.cane +8 -7
  3. data/.github/ISSUE_TEMPLATE.md +56 -0
  4. data/.gitignore +28 -27
  5. data/.kitchen.ci.yml +23 -0
  6. data/.kitchen.proxy.yml +27 -0
  7. data/.rubocop.yml +3 -3
  8. data/.travis.yml +70 -53
  9. data/.yardopts +3 -3
  10. data/Berksfile +3 -0
  11. data/CHANGELOG.md +1083 -1051
  12. data/CONTRIBUTING.md +14 -14
  13. data/Gemfile +19 -14
  14. data/Gemfile.proxy_tests +4 -5
  15. data/Guardfile +42 -42
  16. data/LICENSE +15 -15
  17. data/MAINTAINERS.md +23 -24
  18. data/README.md +135 -135
  19. data/Rakefile +61 -76
  20. data/appveyor.yml +44 -34
  21. data/features/kitchen_action_commands.feature +164 -164
  22. data/features/kitchen_command.feature +16 -16
  23. data/features/kitchen_console_command.feature +34 -34
  24. data/features/kitchen_defaults.feature +38 -38
  25. data/features/kitchen_diagnose_command.feature +96 -96
  26. data/features/kitchen_driver_create_command.feature +64 -64
  27. data/features/kitchen_driver_discover_command.feature +25 -25
  28. data/features/kitchen_help_command.feature +16 -16
  29. data/features/kitchen_init_command.feature +274 -274
  30. data/features/kitchen_list_command.feature +104 -104
  31. data/features/kitchen_login_command.feature +62 -62
  32. data/features/kitchen_sink_command.feature +30 -30
  33. data/features/kitchen_test_command.feature +88 -88
  34. data/features/step_definitions/gem_steps.rb +36 -36
  35. data/features/step_definitions/git_steps.rb +5 -5
  36. data/features/step_definitions/output_steps.rb +5 -5
  37. data/features/support/env.rb +75 -75
  38. data/lib/kitchen.rb +150 -150
  39. data/lib/kitchen/base64_stream.rb +55 -55
  40. data/lib/kitchen/cli.rb +419 -419
  41. data/lib/kitchen/collection.rb +55 -55
  42. data/lib/kitchen/color.rb +65 -65
  43. data/lib/kitchen/command.rb +185 -185
  44. data/lib/kitchen/command/action.rb +45 -45
  45. data/lib/kitchen/command/console.rb +58 -58
  46. data/lib/kitchen/command/diagnose.rb +92 -92
  47. data/lib/kitchen/command/driver_discover.rb +105 -105
  48. data/lib/kitchen/command/exec.rb +41 -41
  49. data/lib/kitchen/command/list.rb +119 -119
  50. data/lib/kitchen/command/login.rb +43 -43
  51. data/lib/kitchen/command/sink.rb +54 -54
  52. data/lib/kitchen/command/test.rb +51 -51
  53. data/lib/kitchen/config.rb +322 -322
  54. data/lib/kitchen/configurable.rb +529 -529
  55. data/lib/kitchen/data_munger.rb +959 -960
  56. data/lib/kitchen/diagnostic.rb +141 -141
  57. data/lib/kitchen/driver.rb +56 -56
  58. data/lib/kitchen/driver/base.rb +134 -134
  59. data/lib/kitchen/driver/dummy.rb +108 -108
  60. data/lib/kitchen/driver/proxy.rb +72 -72
  61. data/lib/kitchen/driver/ssh_base.rb +357 -357
  62. data/lib/kitchen/errors.rb +229 -229
  63. data/lib/kitchen/generator/driver_create.rb +177 -177
  64. data/lib/kitchen/generator/init.rb +296 -296
  65. data/lib/kitchen/instance.rb +662 -662
  66. data/lib/kitchen/lazy_hash.rb +142 -142
  67. data/lib/kitchen/loader/yaml.rb +349 -349
  68. data/lib/kitchen/logger.rb +423 -423
  69. data/lib/kitchen/logging.rb +56 -56
  70. data/lib/kitchen/login_command.rb +52 -52
  71. data/lib/kitchen/metadata_chopper.rb +52 -52
  72. data/lib/kitchen/platform.rb +67 -67
  73. data/lib/kitchen/provisioner.rb +54 -54
  74. data/lib/kitchen/provisioner/base.rb +236 -236
  75. data/lib/kitchen/provisioner/chef/berkshelf.rb +114 -114
  76. data/lib/kitchen/provisioner/chef/common_sandbox.rb +322 -322
  77. data/lib/kitchen/provisioner/chef/librarian.rb +112 -112
  78. data/lib/kitchen/provisioner/chef_apply.rb +124 -125
  79. data/lib/kitchen/provisioner/chef_base.rb +341 -294
  80. data/lib/kitchen/provisioner/chef_solo.rb +88 -89
  81. data/lib/kitchen/provisioner/chef_zero.rb +245 -245
  82. data/lib/kitchen/provisioner/dummy.rb +79 -79
  83. data/lib/kitchen/provisioner/shell.rb +138 -138
  84. data/lib/kitchen/rake_tasks.rb +63 -63
  85. data/lib/kitchen/shell_out.rb +93 -93
  86. data/lib/kitchen/ssh.rb +276 -276
  87. data/lib/kitchen/state_file.rb +120 -120
  88. data/lib/kitchen/suite.rb +51 -51
  89. data/lib/kitchen/thor_tasks.rb +66 -66
  90. data/lib/kitchen/transport.rb +54 -54
  91. data/lib/kitchen/transport/base.rb +176 -176
  92. data/lib/kitchen/transport/dummy.rb +79 -79
  93. data/lib/kitchen/transport/ssh.rb +364 -364
  94. data/lib/kitchen/transport/winrm.rb +486 -486
  95. data/lib/kitchen/util.rb +147 -147
  96. data/lib/kitchen/verifier.rb +55 -55
  97. data/lib/kitchen/verifier/base.rb +235 -235
  98. data/lib/kitchen/verifier/busser.rb +277 -277
  99. data/lib/kitchen/verifier/dummy.rb +79 -79
  100. data/lib/kitchen/verifier/shell.rb +101 -101
  101. data/lib/kitchen/version.rb +21 -21
  102. data/lib/vendor/hash_recursive_merge.rb +82 -82
  103. data/spec/kitchen/base64_stream_spec.rb +77 -77
  104. data/spec/kitchen/cli_spec.rb +56 -56
  105. data/spec/kitchen/collection_spec.rb +80 -80
  106. data/spec/kitchen/color_spec.rb +54 -54
  107. data/spec/kitchen/config_spec.rb +408 -408
  108. data/spec/kitchen/configurable_spec.rb +1095 -1062
  109. data/spec/kitchen/data_munger_spec.rb +2694 -2383
  110. data/spec/kitchen/diagnostic_spec.rb +129 -129
  111. data/spec/kitchen/driver/base_spec.rb +121 -121
  112. data/spec/kitchen/driver/dummy_spec.rb +199 -199
  113. data/spec/kitchen/driver/proxy_spec.rb +138 -138
  114. data/spec/kitchen/driver/ssh_base_spec.rb +1115 -1115
  115. data/spec/kitchen/driver_spec.rb +112 -112
  116. data/spec/kitchen/errors_spec.rb +309 -309
  117. data/spec/kitchen/instance_spec.rb +1419 -1419
  118. data/spec/kitchen/lazy_hash_spec.rb +117 -117
  119. data/spec/kitchen/loader/yaml_spec.rb +774 -774
  120. data/spec/kitchen/logger_spec.rb +429 -429
  121. data/spec/kitchen/logging_spec.rb +59 -59
  122. data/spec/kitchen/login_command_spec.rb +68 -68
  123. data/spec/kitchen/metadata_chopper_spec.rb +82 -82
  124. data/spec/kitchen/platform_spec.rb +89 -89
  125. data/spec/kitchen/provisioner/base_spec.rb +386 -386
  126. data/spec/kitchen/provisioner/chef_apply_spec.rb +136 -136
  127. data/spec/kitchen/provisioner/chef_base_spec.rb +1161 -1067
  128. data/spec/kitchen/provisioner/chef_solo_spec.rb +557 -557
  129. data/spec/kitchen/provisioner/chef_zero_spec.rb +1001 -1001
  130. data/spec/kitchen/provisioner/dummy_spec.rb +99 -99
  131. data/spec/kitchen/provisioner/shell_spec.rb +566 -566
  132. data/spec/kitchen/provisioner_spec.rb +107 -107
  133. data/spec/kitchen/shell_out_spec.rb +150 -150
  134. data/spec/kitchen/ssh_spec.rb +693 -693
  135. data/spec/kitchen/state_file_spec.rb +129 -129
  136. data/spec/kitchen/suite_spec.rb +62 -62
  137. data/spec/kitchen/transport/base_spec.rb +89 -89
  138. data/spec/kitchen/transport/ssh_spec.rb +1255 -1255
  139. data/spec/kitchen/transport/winrm_spec.rb +1143 -1143
  140. data/spec/kitchen/transport_spec.rb +112 -112
  141. data/spec/kitchen/util_spec.rb +165 -165
  142. data/spec/kitchen/verifier/base_spec.rb +362 -362
  143. data/spec/kitchen/verifier/busser_spec.rb +610 -610
  144. data/spec/kitchen/verifier/dummy_spec.rb +99 -99
  145. data/spec/kitchen/verifier/shell_spec.rb +160 -158
  146. data/spec/kitchen/verifier_spec.rb +120 -120
  147. data/spec/kitchen_spec.rb +114 -114
  148. data/spec/spec_helper.rb +85 -85
  149. data/spec/support/powershell_max_size_spec.rb +40 -40
  150. data/support/busser_install_command.ps1 +14 -14
  151. data/support/busser_install_command.sh +14 -14
  152. data/support/chef-client-zero.rb +77 -77
  153. data/support/chef_base_init_command.ps1 +18 -18
  154. data/support/chef_base_init_command.sh +2 -2
  155. data/support/chef_base_install_command.ps1 +85 -85
  156. data/support/chef_base_install_command.sh +229 -229
  157. data/support/chef_zero_prepare_command_legacy.ps1 +9 -9
  158. data/support/chef_zero_prepare_command_legacy.sh +10 -10
  159. data/support/download_helpers.sh +109 -109
  160. data/support/dummy-validation.pem +27 -27
  161. data/templates/driver/CHANGELOG.md.erb +3 -3
  162. data/templates/driver/Gemfile.erb +3 -3
  163. data/templates/driver/README.md.erb +64 -64
  164. data/templates/driver/Rakefile.erb +21 -21
  165. data/templates/driver/driver.rb.erb +23 -23
  166. data/templates/driver/gemspec.erb +29 -29
  167. data/templates/driver/gitignore.erb +17 -17
  168. data/templates/driver/license_apachev2.erb +15 -15
  169. data/templates/driver/license_lgplv3.erb +16 -16
  170. data/templates/driver/license_mit.erb +22 -22
  171. data/templates/driver/license_reserved.erb +5 -5
  172. data/templates/driver/tailor.erb +4 -4
  173. data/templates/driver/travis.yml.erb +11 -11
  174. data/templates/driver/version.rb.erb +12 -12
  175. data/templates/init/chefignore.erb +1 -1
  176. data/templates/init/kitchen.yml.erb +18 -18
  177. data/test-kitchen.gemspec +62 -62
  178. data/test/integration/default/default_spec.rb +3 -0
  179. data/testing_windows.md +37 -37
  180. metadata +23 -11
@@ -1,1062 +1,1095 @@
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
- require "stringio"
21
-
22
- require "kitchen"
23
- require "kitchen/errors"
24
- require "kitchen/configurable"
25
-
26
- module Kitchen
27
-
28
- module Thing
29
-
30
- class Tiny
31
-
32
- include Kitchen::Configurable
33
-
34
- attr_reader :instance
35
-
36
- def initialize(config = {})
37
- init_config(config)
38
- @instance = config[:instance]
39
- end
40
- end
41
-
42
- class Versioned < Tiny
43
-
44
- plugin_version "1.8.17"
45
- end
46
-
47
- class StaticDefaults
48
-
49
- include Kitchen::Configurable
50
-
51
- default_config :beans, "kidney"
52
- default_config :tunables, "flimflam" => "positate"
53
- default_config :edible, true
54
- default_config :fetch_command, "curl"
55
- default_config :success_path, "./success"
56
- default_config :bunch_of_paths, %W[./a ./b ./c]
57
- default_config :beans_url do |subject|
58
- "http://gim.me/#{subject[:beans]}"
59
- end
60
- default_config :command do |subject|
61
- "#{subject[:fetch_command]} #{subject[:beans_url]}"
62
- end
63
- default_config :fetch_url do |subject|
64
- "http://gim.me/beans-for/#{subject.instance.name}"
65
- end
66
-
67
- required_config :need_it
68
- required_config :a_default
69
- required_config :no_nuts do |attr, value, _subject|
70
- raise UserError, "NO NUTS FOR #{attr}!" if value == "nuts"
71
- end
72
-
73
- expand_path_for :success_path
74
- expand_path_for :bunch_of_paths
75
- expand_path_for :relative_path, false
76
- expand_path_for :another_path
77
- expand_path_for :complex_path do |subject|
78
- subject[:something_else] == "is_set"
79
- end
80
-
81
- def initialize(config = {})
82
- init_config(config)
83
- end
84
- end
85
-
86
- class SubclassDefaults < StaticDefaults
87
-
88
- default_config :yea, "ya"
89
- default_config :fetch_command, "wget"
90
- default_config :fetch_url, "http://no.beans"
91
-
92
- required_config :a_default do |_attr, value, _subject|
93
- raise UserError, "Overriding a_default is fun" unless value == "please"
94
- end
95
-
96
- expand_path_for :another_path, false
97
- end
98
- end
99
- end
100
-
101
- describe Kitchen::Configurable do
102
-
103
- let(:config) { Hash.new }
104
- let(:platform) { stub }
105
- let(:instance) do
106
- stub(:name => "coolbeans", :to_str => "<instance>", :platform => platform)
107
- end
108
-
109
- let(:subject) do
110
- Kitchen::Thing::Tiny.new(config).finalize_config!(instance)
111
- end
112
-
113
- describe "creation and setup" do
114
-
115
- it "#instance returns its instance" do
116
- subject.instance.must_equal instance
117
- end
118
-
119
- it "#finalize_config! raises ClientError if instance is nil" do
120
- proc { Kitchen::Thing::Tiny.new({}).finalize_config!(nil) }.
121
- must_raise(Kitchen::ClientError)
122
- end
123
-
124
- it "#finalize_config! returns self for chaining" do
125
- t = Kitchen::Thing::Tiny.new({})
126
- t.finalize_config!(instance).must_equal t
127
- end
128
- end
129
-
130
- describe "configuration" do
131
-
132
- describe "provided from the outside" do
133
-
134
- it "returns provided config" do
135
- config[:fruit] = %w[apples oranges]
136
- config[:cool_enough] = true
137
-
138
- subject[:fruit].must_equal %w[apples oranges]
139
- subject[:cool_enough].must_equal true
140
- end
141
- end
142
-
143
- describe "using static default_config statements" do
144
-
145
- let(:config) do
146
- { :need_it => true, :a_default => true }
147
- end
148
-
149
- let(:subject) do
150
- Kitchen::Thing::StaticDefaults.new(config).finalize_config!(instance)
151
- end
152
-
153
- it "uses defaults" do
154
- subject[:beans].must_equal "kidney"
155
- subject[:tunables]["flimflam"].must_equal "positate"
156
- subject[:edible].must_equal true
157
- end
158
-
159
- it "uses provided config over default_config" do
160
- config[:beans] = "pinto"
161
- config[:edible] = false
162
-
163
- subject[:beans].must_equal "pinto"
164
- subject[:edible].must_equal false
165
- end
166
-
167
- it "uses other config values to compute values" do
168
- subject[:beans_url].must_equal "http://gim.me/kidney"
169
- subject[:command].must_equal "curl http://gim.me/kidney"
170
- end
171
-
172
- it "computed value blocks have access to instance object" do
173
- subject[:fetch_url].must_equal "http://gim.me/beans-for/coolbeans"
174
- end
175
-
176
- it "uses provided config over default_config for computed values" do
177
- config[:command] = "echo listentome"
178
- config[:beans] = "pinto"
179
-
180
- subject[:command].must_equal "echo listentome"
181
- subject[:beans_url].must_equal "http://gim.me/pinto"
182
- end
183
- end
184
-
185
- describe "using inherited static default_config statements" do
186
-
187
- let(:config) do
188
- { :need_it => true, :a_default => "please" }
189
- end
190
-
191
- let(:subject) do
192
- Kitchen::Thing::SubclassDefaults.new(config).finalize_config!(instance)
193
- end
194
-
195
- it "contains defaults from superclass" do
196
- subject[:beans].must_equal "kidney"
197
- subject[:tunables]["flimflam"].must_equal "positate"
198
- subject[:edible].must_equal true
199
- subject[:yea].must_equal "ya"
200
- end
201
-
202
- it "uses provided config over default config" do
203
- config[:beans] = "pinto"
204
- config[:edible] = false
205
-
206
- subject[:beans].must_equal "pinto"
207
- subject[:edible].must_equal false
208
- subject[:yea].must_equal "ya"
209
- subject[:beans_url].must_equal "http://gim.me/pinto"
210
- end
211
-
212
- it "uses its own default_config over inherited default_config" do
213
- subject[:fetch_url].must_equal "http://no.beans"
214
- subject[:command].must_equal "wget http://gim.me/kidney"
215
- end
216
- end
217
-
218
- describe "using static required_config statements" do
219
-
220
- let(:config) do
221
- { :a_default => true }
222
- end
223
-
224
- let(:subject) do
225
- Kitchen::Thing::StaticDefaults.new(config).finalize_config!(instance)
226
- end
227
-
228
- it "uses a value when provided" do
229
- config[:need_it] = "okay"
230
-
231
- subject[:need_it].must_equal "okay"
232
- end
233
-
234
- it "without a block, raises a UserError if attr is nil" do
235
- config[:need_it] = nil
236
-
237
- begin
238
- subject
239
- flunk "UserError must be raised"
240
- rescue Kitchen::UserError => e
241
- attr = "Kitchen::Thing::StaticDefaults<instance>#config[:need_it]"
242
- e.message.must_equal "#{attr} cannot be blank"
243
- end
244
- end
245
-
246
- it "without a block, raises a UserError if attr is an empty string" do
247
- config[:need_it] = ""
248
-
249
- begin
250
- subject
251
- flunk "UserError must be raised"
252
- rescue Kitchen::UserError => e
253
- attr = "Kitchen::Thing::StaticDefaults<instance>#config[:need_it]"
254
- e.message.must_equal "#{attr} cannot be blank"
255
- end
256
- end
257
-
258
- it "with a block, it is saved and invoked" do
259
- config[:need_it] = "okay"
260
- config[:no_nuts] = "nuts"
261
-
262
- begin
263
- subject
264
- flunk "UserError must be raised"
265
- rescue Kitchen::UserError => e
266
- e.message.must_equal "NO NUTS FOR no_nuts!"
267
- end
268
- end
269
- end
270
-
271
- describe "using inherited static require_config statements" do
272
-
273
- let(:subject) do
274
- Kitchen::Thing::SubclassDefaults.new(config).finalize_config!(instance)
275
- end
276
-
277
- it "contains required config from superclass" do
278
- config[:a_default] = nil
279
- config[:need_it] = nil
280
-
281
- begin
282
- subject
283
- flunk "UserError must be raised"
284
- rescue Kitchen::UserError => e
285
- attr = "Kitchen::Thing::StaticDefaults<instance>#config[:need_it]"
286
- e.message.must_equal "#{attr} cannot be blank"
287
- end
288
- end
289
-
290
- it "uses its own require_config over inherited require_config" do
291
- config[:need_it] = true
292
- config[:a_default] = nil
293
-
294
- begin
295
- subject
296
- flunk "UserError must be raised"
297
- rescue Kitchen::UserError => e
298
- e.message.must_equal "Overriding a_default is fun"
299
- end
300
- end
301
- end
302
-
303
- describe "using static expand_path_for statements" do
304
-
305
- let(:config) do
306
- { :need_it => "a", :a_default => "b", :kitchen_root => "/tmp/yo/self" }
307
- end
308
-
309
- let(:subject) do
310
- Kitchen::Thing::StaticDefaults.new(config).finalize_config!(instance)
311
- end
312
-
313
- it "expands a default value" do
314
- subject[:success_path].must_equal os_safe_root_path("/tmp/yo/self/success")
315
- end
316
-
317
- it "uses provided config over default_config" do
318
- config[:success_path] = "mine"
319
-
320
- subject[:success_path].must_equal os_safe_root_path("/tmp/yo/self/mine")
321
- end
322
-
323
- it "leaves a full path expanded" do
324
- config[:success_path] = "/the/other/one"
325
-
326
- subject[:success_path].must_equal os_safe_root_path("/the/other/one")
327
- end
328
-
329
- it "expands all items if path is an array" do
330
- paths = %W[
331
- /tmp/yo/self/a /tmp/yo/self/b /tmp/yo/self/c
332
- ]
333
- os_safe_paths = paths.collect { |path| os_safe_root_path(path) }
334
- subject[:bunch_of_paths].must_equal os_safe_paths
335
- end
336
-
337
- it "doesn't expand path with a falsy expand_path_for value" do
338
- config[:relative_path] = "./rel"
339
-
340
- subject[:relative_path].must_equal "./rel"
341
- end
342
-
343
- it "expands a path if a lambda returns truthy" do
344
- config[:something_else] = "is_set"
345
- config[:complex_path] = "./complex"
346
-
347
- subject[:complex_path].must_equal os_safe_root_path("/tmp/yo/self/complex")
348
- end
349
-
350
- it "leaves a nil config value as nil" do
351
- config[:success_path] = nil
352
-
353
- subject[:success_path].must_equal nil
354
- end
355
-
356
- it "leaves a false config value as false" do
357
- config[:success_path] = false
358
-
359
- subject[:success_path].must_equal false
360
- end
361
- end
362
-
363
- describe "using inherited static expand_path_for statements" do
364
-
365
- let(:config) do
366
- { :need_it => "a", :a_default => "please", :kitchen_root => "/rooty" }
367
- end
368
-
369
- let(:subject) do
370
- Kitchen::Thing::SubclassDefaults.new(config).finalize_config!(instance)
371
- end
372
-
373
- it "contains expand_path_for from superclass" do
374
- subject[:success_path].must_equal os_safe_root_path("/rooty/success")
375
- end
376
-
377
- it "uses its own expand_path_for over inherited expand_path_for" do
378
- config[:another_path] = "./pp"
379
-
380
- subject[:another_path].must_equal "./pp"
381
- end
382
- end
383
-
384
- it "#config_keys returns an array of config key names" do
385
- subject = Kitchen::Thing::Tiny.new(:ice_cream => "dragon")
386
-
387
- subject.config_keys.sort.must_equal [:ice_cream]
388
- end
389
- end
390
-
391
- it "#name returns the name of the plugin" do
392
- subject.name.must_equal "Tiny"
393
- end
394
-
395
- describe "#diagnose" do
396
-
397
- it "returns an empty hash for no config" do
398
- subject.diagnose.must_equal Hash.new
399
- end
400
-
401
- it "returns a hash of config" do
402
- config[:alpha] = "beta"
403
- subject.diagnose.must_equal(:alpha => "beta")
404
- end
405
-
406
- it "returns a hash with sorted keys" do
407
- config[:zebra] = true
408
- config[:elephant] = true
409
-
410
- subject.diagnose.keys.must_equal [:elephant, :zebra]
411
- end
412
- end
413
-
414
- describe "#diagnose_plugin" do
415
-
416
- it "returns a plugin hash for a plugin without version" do
417
- subject.diagnose_plugin.must_equal(
418
- :name => "Tiny", :class => "Kitchen::Thing::Tiny",
419
- :version => nil, :api_version => nil
420
- )
421
- end
422
-
423
- it "returns a plugin hash for a plugin with version" do
424
- subject = Kitchen::Thing::Versioned.new(config).finalize_config!(instance)
425
- subject.diagnose_plugin.must_equal(
426
- :name => "Versioned", :class => "Kitchen::Thing::Versioned",
427
- :version => "1.8.17", :api_version => nil
428
- )
429
- end
430
- end
431
-
432
- describe "#calculate_path" do
433
-
434
- let(:config) do
435
- { :test_base_path => "/the/basest" }
436
- end
437
-
438
- let(:suite) do
439
- stub(:name => "ultimate")
440
- end
441
-
442
- let(:instance) do
443
- stub(:name => "coolbeans", :to_str => "<instance>", :suite => suite)
444
- end
445
-
446
- let(:subject) do
447
- Kitchen::Thing::Tiny.new(config).finalize_config!(instance)
448
- end
449
-
450
- before do
451
- FakeFS.activate!
452
- end
453
-
454
- after do
455
- FakeFS.deactivate!
456
- FakeFS::FileSystem.clear
457
- end
458
-
459
- describe "for directories" do
460
-
461
- before do
462
- FileUtils.mkdir_p(File.join(Dir.pwd, "winner"))
463
- FileUtils.mkdir_p("/the/basest/winner")
464
- FileUtils.mkdir_p("/the/basest/ultimate/winner")
465
- end
466
-
467
- it "prefers a path containing base path and suite name if it exists" do
468
- subject.calculate_path("winner").
469
- must_equal "/the/basest/ultimate/winner"
470
- end
471
-
472
- it "prefers a path containing base path if it exists" do
473
- FileUtils.rm_rf("/the/basest/ultimate/winner")
474
-
475
- subject.calculate_path("winner").must_equal "/the/basest/winner"
476
- end
477
-
478
- it "prefers a path in the current working directory if it exists" do
479
- FileUtils.rm_rf("/the/basest/ultimate/winner")
480
- FileUtils.rm_rf("/the/basest/winner")
481
- pwd_dir = File.join(Dir.pwd, "winner")
482
-
483
- subject.calculate_path("winner").must_equal pwd_dir
484
- end
485
-
486
- it "raises a UserError if test_base_path key is not set" do
487
- config.delete(:test_base_path)
488
-
489
- proc { subject.calculate_path("winner") }.must_raise Kitchen::UserError
490
- end
491
-
492
- it "uses a custom base path" do
493
- FileUtils.mkdir_p("/custom/ultimate/winner")
494
-
495
- subject.calculate_path("winner", :base_path => "/custom").
496
- must_equal "/custom/ultimate/winner"
497
- end
498
- end
499
-
500
- describe "for files" do
501
-
502
- before do
503
- FileUtils.mkdir_p(Dir.pwd)
504
- FileUtils.touch(File.join(Dir.pwd, "winner"))
505
- FileUtils.mkdir_p("/the/basest")
506
- FileUtils.touch(File.join("/the/basest", "winner"))
507
- FileUtils.mkdir_p("/the/basest/ultimate")
508
- FileUtils.touch(File.join("/the/basest/ultimate", "winner"))
509
- end
510
-
511
- it "prefers a path containing base path and suite name if it exists" do
512
- subject.calculate_path("winner", :type => :file).
513
- must_equal "/the/basest/ultimate/winner"
514
- end
515
-
516
- it "prefers a path containing base path if it exists" do
517
- FileUtils.rm_rf("/the/basest/ultimate/winner")
518
-
519
- subject.calculate_path("winner", :type => :file).
520
- must_equal "/the/basest/winner"
521
- end
522
-
523
- it "prefers a path in the current working directory if it exists" do
524
- FileUtils.rm_rf("/the/basest/ultimate/winner")
525
- FileUtils.rm_rf("/the/basest/winner")
526
- pwd_dir = File.join(Dir.pwd, "winner")
527
-
528
- subject.calculate_path("winner", :type => :file).must_equal pwd_dir
529
- end
530
-
531
- it "raises a UserError if test_base_path key is not set" do
532
- config.delete(:test_base_path)
533
-
534
- proc { subject.calculate_path("winner") }.must_raise Kitchen::UserError
535
- end
536
-
537
- it "uses a custom base path" do
538
- FileUtils.mkdir_p("/custom/ultimate")
539
- FileUtils.touch(File.join("/custom/ultimate", "winner"))
540
-
541
- subject.calculate_path("winner", :type => :file, :base_path => "/custom").
542
- must_equal "/custom/ultimate/winner"
543
- end
544
- end
545
- end
546
-
547
- describe "#remote_path_join" do
548
-
549
- it "returns unix style path separators for unix os_type" do
550
- platform.stubs(:os_type).returns("unix")
551
-
552
- subject.remote_path_join("a", "b", "c").must_equal "a/b/c"
553
- end
554
-
555
- it "returns windows style path separators for windows os_type" do
556
- platform.stubs(:os_type).returns("windows")
557
-
558
- subject.remote_path_join("a", "b", "c").must_equal "a\\b\\c"
559
- end
560
-
561
- it "accepts combinations of strings and arrays" do
562
- platform.stubs(:os_type).returns("unix")
563
-
564
- subject.remote_path_join(%W[a b], "c", %W[d e]).must_equal "a/b/c/d/e"
565
- end
566
-
567
- it "accepts a single array" do
568
- platform.stubs(:os_type).returns("windows")
569
-
570
- subject.remote_path_join(%W[a b]).must_equal "a\\b"
571
- end
572
-
573
- it "converts all windows path separators to unix for unix os_type" do
574
- platform.stubs(:os_type).returns("unix")
575
-
576
- subject.remote_path_join("\\a\\b", "c/d").must_equal "/a/b/c/d"
577
- end
578
-
579
- it "converts all unix path separators to windows for windows os_type" do
580
- platform.stubs(:os_type).returns("windows")
581
-
582
- subject.remote_path_join("/a/b", "c\\d").must_equal "\\a\\b\\c\\d"
583
- end
584
- end
585
-
586
- describe "#windows_os?" do
587
-
588
- it "for windows type platform returns true" do
589
- platform.stubs(:os_type).returns("windows")
590
-
591
- subject.windows_os?.must_equal true
592
- end
593
-
594
- it "for unix type platform returns false" do
595
- platform.stubs(:os_type).returns("unix")
596
-
597
- subject.windows_os?.must_equal false
598
- end
599
-
600
- it "for newfangled type platform return false" do
601
- platform.stubs(:os_type).returns("internet_cat")
602
-
603
- subject.windows_os?.must_equal false
604
- end
605
-
606
- it "for unset type platform returns false" do
607
- platform.stubs(:os_type).returns(nil)
608
-
609
- subject.windows_os?.must_equal false
610
- end
611
- end
612
-
613
- describe "#unix_os?" do
614
-
615
- it "for windows type platform returns false" do
616
- platform.stubs(:os_type).returns("windows")
617
-
618
- subject.unix_os?.must_equal false
619
- end
620
-
621
- it "for unix type platform returns true" do
622
- platform.stubs(:os_type).returns("unix")
623
-
624
- subject.unix_os?.must_equal true
625
- end
626
-
627
- it "for newfangled type platform return false" do
628
- platform.stubs(:os_type).returns("internet_cat")
629
-
630
- subject.unix_os?.must_equal false
631
- end
632
-
633
- it "for unset type platform returns true" do
634
- platform.stubs(:os_type).returns(nil)
635
-
636
- subject.unix_os?.must_equal true
637
- end
638
- end
639
-
640
- describe "#powershell_shell?" do
641
-
642
- it "for powershell type shell returns true" do
643
- platform.stubs(:shell_type).returns("powershell")
644
-
645
- subject.powershell_shell?.must_equal true
646
- end
647
-
648
- it "for bourne type shell returns false" do
649
- platform.stubs(:shell_type).returns("bourne")
650
-
651
- subject.powershell_shell?.must_equal false
652
- end
653
-
654
- it "for newfangled type shell return false" do
655
- platform.stubs(:shell_type).returns("internet_cat")
656
-
657
- subject.powershell_shell?.must_equal false
658
- end
659
-
660
- it "for unset type shell returns false" do
661
- platform.stubs(:shell_type).returns(nil)
662
-
663
- subject.powershell_shell?.must_equal false
664
- end
665
- end
666
-
667
- describe "#bourne_shell?" do
668
-
669
- it "for powershell type shell returns false" do
670
- platform.stubs(:shell_type).returns("powershell")
671
-
672
- subject.bourne_shell?.must_equal false
673
- end
674
-
675
- it "for bourne type shell returns true" do
676
- platform.stubs(:shell_type).returns("bourne")
677
-
678
- subject.bourne_shell?.must_equal true
679
- end
680
-
681
- it "for newfangled type shell return false" do
682
- platform.stubs(:shell_type).returns("internet_cat")
683
-
684
- subject.bourne_shell?.must_equal false
685
- end
686
-
687
- it "for unset type shell returns true" do
688
- platform.stubs(:shell_type).returns(nil)
689
-
690
- subject.bourne_shell?.must_equal true
691
- end
692
- end
693
-
694
- describe "#shell_env_var" do
695
-
696
- it "for powershell type shells returns a powershell environment variable" do
697
- platform.stubs(:shell_type).returns("powershell")
698
-
699
- subject.send(:shell_env_var, "foo", "bar").
700
- must_equal %{$env:foo = "bar"}
701
- end
702
-
703
- it "for bourne type shells returns a bourne environment variable" do
704
- platform.stubs(:shell_type).returns("bourne")
705
-
706
- subject.send(:shell_env_var, "foo", "bar").
707
- must_equal %{foo="bar"; export foo}
708
- end
709
- end
710
-
711
- describe "#shell_var" do
712
-
713
- it "for powershell type shells returns a powershell variable" do
714
- platform.stubs(:shell_type).returns("powershell")
715
-
716
- subject.send(:shell_var, "foo", "bar").must_equal %{$foo = "bar"}
717
- end
718
-
719
- it "for bourne type shells returns a bourne variable" do
720
- platform.stubs(:shell_type).returns("bourne")
721
-
722
- subject.send(:shell_var, "foo", "bar").must_equal %{foo="bar"}
723
- end
724
- end
725
-
726
- describe "#wrap_shell_code" do
727
-
728
- let(:cmd) { subject.send(:wrap_shell_code, "mkdir foo") }
729
-
730
- before do
731
- @original_env = ENV.to_hash
732
- ENV.replace("http_proxy" => nil, "HTTP_PROXY" => nil,
733
- "https_proxy" => nil, "HTTPS_PROXY" => nil,
734
- "ftp_proxy" => nil, "FTP_PROXY" => nil,
735
- "no_proxy" => nil, "NO_PROXY" => nil)
736
- end
737
-
738
- after do
739
- ENV.clear
740
- ENV.replace(@original_env)
741
- end
742
-
743
- describe "for bourne shells" do
744
-
745
- before { platform.stubs(:shell_type).returns("bourne") }
746
-
747
- it "uses bourne shell (sh)" do
748
- cmd.must_equal(outdent!(<<-CODE.chomp))
749
- sh -c '
750
-
751
- mkdir foo
752
- '
753
- CODE
754
- end
755
-
756
- it "exports http_proxy & HTTP_PROXY when :http_proxy is set" do
757
- config[:http_proxy] = "http://proxy"
758
-
759
- cmd.must_equal(outdent!(<<-CODE.chomp))
760
- sh -c '
761
- http_proxy="http://proxy"; export http_proxy
762
- HTTP_PROXY="http://proxy"; export HTTP_PROXY
763
- mkdir foo
764
- '
765
- CODE
766
- end
767
-
768
- it "exports https_proxy & HTTPS_PROXY when :https_proxy is set" do
769
- config[:https_proxy] = "https://proxy"
770
-
771
- cmd.must_equal(outdent!(<<-CODE.chomp))
772
- sh -c '
773
- https_proxy="https://proxy"; export https_proxy
774
- HTTPS_PROXY="https://proxy"; export HTTPS_PROXY
775
- mkdir foo
776
- '
777
- CODE
778
- end
779
-
780
- it "exports ftp_proxy & FTP_PROXY when :ftp_proxy is set" do
781
- config[:ftp_proxy] = "ftp://proxy"
782
-
783
- cmd.must_equal(outdent!(<<-CODE.chomp))
784
- sh -c '
785
- ftp_proxy="ftp://proxy"; export ftp_proxy
786
- FTP_PROXY="ftp://proxy"; export FTP_PROXY
787
- mkdir foo
788
- '
789
- CODE
790
- end
791
-
792
- it "exports all http proxy variables when all are set" do
793
- config[:http_proxy] = "http://proxy"
794
- config[:https_proxy] = "https://proxy"
795
- config[:ftp_proxy] = "ftp://proxy"
796
-
797
- cmd.must_equal(outdent!(<<-CODE.chomp))
798
- sh -c '
799
- http_proxy="http://proxy"; export http_proxy
800
- HTTP_PROXY="http://proxy"; export HTTP_PROXY
801
- https_proxy="https://proxy"; export https_proxy
802
- HTTPS_PROXY="https://proxy"; export HTTPS_PROXY
803
- ftp_proxy="ftp://proxy"; export ftp_proxy
804
- FTP_PROXY="ftp://proxy"; export FTP_PROXY
805
- mkdir foo
806
- '
807
- CODE
808
- end
809
-
810
- it "exports http_proxy & HTTP_PROXY from workstation when :http_proxy isn't set" do
811
- ENV["http_proxy"] = "http://proxy"
812
- ENV["HTTP_PROXY"] = "http://proxy"
813
-
814
- cmd.must_equal(outdent!(<<-CODE.chomp))
815
- sh -c '
816
- http_proxy="http://proxy"; export http_proxy
817
- HTTP_PROXY="http://proxy"; export HTTP_PROXY
818
- mkdir foo
819
- '
820
- CODE
821
- end
822
-
823
- it "exports https_proxy & HTTPS_PROXY from workstation when :https_proxy isn't set" do
824
- ENV["https_proxy"] = "https://proxy"
825
- ENV["HTTPS_PROXY"] = "https://proxy"
826
-
827
- cmd.must_equal(outdent!(<<-CODE.chomp))
828
- sh -c '
829
- https_proxy="https://proxy"; export https_proxy
830
- HTTPS_PROXY="https://proxy"; export HTTPS_PROXY
831
- mkdir foo
832
- '
833
- CODE
834
- end
835
-
836
- it "exports ftp_proxy & FTP_PROXY from workstation when :ftp_proxy isn't set" do
837
- ENV["ftp_proxy"] = "ftp://proxy"
838
- ENV["FTP_PROXY"] = "ftp://proxy"
839
-
840
- cmd.must_equal(outdent!(<<-CODE.chomp))
841
- sh -c '
842
- ftp_proxy="ftp://proxy"; export ftp_proxy
843
- FTP_PROXY="ftp://proxy"; export FTP_PROXY
844
- mkdir foo
845
- '
846
- CODE
847
- end
848
-
849
- it "exports no_proxy & NO_PROXY from workstation when http_proxy is set from workstation" do
850
- ENV["http_proxy"] = "http://proxy"
851
- ENV["HTTP_PROXY"] = "http://proxy"
852
- ENV["no_proxy"] = "http://no"
853
- ENV["NO_PROXY"] = "http://no"
854
-
855
- cmd.must_equal(outdent!(<<-CODE.chomp))
856
- sh -c '
857
- http_proxy="http://proxy"; export http_proxy
858
- HTTP_PROXY="http://proxy"; export HTTP_PROXY
859
- no_proxy="http://no"; export no_proxy
860
- NO_PROXY="http://no"; export NO_PROXY
861
- mkdir foo
862
- '
863
- CODE
864
- end
865
-
866
- it "exports no_proxy & NO_PROXY from workstation when https_proxy is set from workstation" do
867
- ENV["https_proxy"] = "https://proxy"
868
- ENV["HTTPS_PROXY"] = "https://proxy"
869
- ENV["no_proxy"] = "http://no"
870
- ENV["NO_PROXY"] = "http://no"
871
-
872
- cmd.must_equal(outdent!(<<-CODE.chomp))
873
- sh -c '
874
- https_proxy="https://proxy"; export https_proxy
875
- HTTPS_PROXY="https://proxy"; export HTTPS_PROXY
876
- no_proxy="http://no"; export no_proxy
877
- NO_PROXY="http://no"; export NO_PROXY
878
- mkdir foo
879
- '
880
- CODE
881
- end
882
-
883
- it "exports no_proxy & NO_PROXY from workstation when ftp_proxy is set from workstation" do
884
- ENV["ftp_proxy"] = "ftp://proxy"
885
- ENV["FTP_PROXY"] = "ftp://proxy"
886
- ENV["no_proxy"] = "http://no"
887
- ENV["NO_PROXY"] = "http://no"
888
-
889
- cmd.must_equal(outdent!(<<-CODE.chomp))
890
- sh -c '
891
- ftp_proxy="ftp://proxy"; export ftp_proxy
892
- FTP_PROXY="ftp://proxy"; export FTP_PROXY
893
- no_proxy="http://no"; export no_proxy
894
- NO_PROXY="http://no"; export NO_PROXY
895
- mkdir foo
896
- '
897
- CODE
898
- end
899
- end
900
-
901
- describe "for powershell shells" do
902
-
903
- before { platform.stubs(:shell_type).returns("powershell") }
904
-
905
- it "uses powershell shell" do
906
- cmd.must_equal("\nmkdir foo")
907
- end
908
-
909
- it "exports http_proxy & HTTP_PROXY when :http_proxy is set" do
910
- config[:http_proxy] = "http://proxy"
911
-
912
- cmd.must_equal(outdent!(<<-CODE.chomp))
913
- $env:http_proxy = "http://proxy"
914
- $env:HTTP_PROXY = "http://proxy"
915
- mkdir foo
916
- CODE
917
- end
918
-
919
- it "exports https_proxy & HTTPS_PROXY when :https_proxy is set" do
920
- config[:https_proxy] = "https://proxy"
921
-
922
- cmd.must_equal(outdent!(<<-CODE.chomp))
923
- $env:https_proxy = "https://proxy"
924
- $env:HTTPS_PROXY = "https://proxy"
925
- mkdir foo
926
- CODE
927
- end
928
-
929
- it "exports ftp_proxy & FTP_PROXY when :ftp_proxy is set" do
930
- config[:ftp_proxy] = "ftp://proxy"
931
-
932
- cmd.must_equal(outdent!(<<-CODE.chomp))
933
- $env:ftp_proxy = "ftp://proxy"
934
- $env:FTP_PROXY = "ftp://proxy"
935
- mkdir foo
936
- CODE
937
- end
938
-
939
- it "exports all http proxy variables when all are set" do
940
- config[:http_proxy] = "http://proxy"
941
- config[:https_proxy] = "https://proxy"
942
- config[:ftp_proxy] = "ftp://proxy"
943
-
944
- cmd.must_equal(outdent!(<<-CODE.chomp))
945
- $env:http_proxy = "http://proxy"
946
- $env:HTTP_PROXY = "http://proxy"
947
- $env:https_proxy = "https://proxy"
948
- $env:HTTPS_PROXY = "https://proxy"
949
- $env:ftp_proxy = "ftp://proxy"
950
- $env:FTP_PROXY = "ftp://proxy"
951
- mkdir foo
952
- CODE
953
- end
954
-
955
- it "exports http_proxy & HTTP_PROXY from workstation when :http_proxy isn't set" do
956
- ENV["http_proxy"] = "http://proxy"
957
- ENV["HTTP_PROXY"] = "http://proxy"
958
-
959
- cmd.must_equal(outdent!(<<-CODE.chomp))
960
- $env:http_proxy = "http://proxy"
961
- $env:HTTP_PROXY = "http://proxy"
962
- mkdir foo
963
- CODE
964
- end
965
-
966
- it "exports https_proxy & HTTPS_PROXY from workstation when :https_proxy isn't set" do
967
- ENV["https_proxy"] = "https://proxy"
968
- ENV["HTTPS_PROXY"] = "https://proxy"
969
-
970
- cmd.must_equal(outdent!(<<-CODE.chomp))
971
- $env:https_proxy = "https://proxy"
972
- $env:HTTPS_PROXY = "https://proxy"
973
- mkdir foo
974
- CODE
975
- end
976
-
977
- it "exports ftp_proxy & FTP_PROXY from workstation when :ftp_proxy isn't set" do
978
- ENV["ftp_proxy"] = "ftp://proxy"
979
- ENV["FTP_PROXY"] = "ftp://proxy"
980
-
981
- cmd.must_equal(outdent!(<<-CODE.chomp))
982
- $env:ftp_proxy = "ftp://proxy"
983
- $env:FTP_PROXY = "ftp://proxy"
984
- mkdir foo
985
- CODE
986
- end
987
-
988
- it "exports no_proxy & NO_PROXY from workstation when http_proxy is set from workstation" do
989
- ENV["http_proxy"] = "http://proxy"
990
- ENV["HTTP_PROXY"] = "http://proxy"
991
- ENV["no_proxy"] = "http://no"
992
- ENV["NO_PROXY"] = "http://no"
993
-
994
- cmd.must_equal(outdent!(<<-CODE.chomp))
995
- $env:http_proxy = "http://proxy"
996
- $env:HTTP_PROXY = "http://proxy"
997
- $env:no_proxy = "http://no"
998
- $env:NO_PROXY = "http://no"
999
- mkdir foo
1000
- CODE
1001
- end
1002
-
1003
- it "exports no_proxy & NO_PROXY from workstation when https_proxy is set from workstation" do
1004
- ENV["https_proxy"] = "https://proxy"
1005
- ENV["HTTPS_PROXY"] = "https://proxy"
1006
- ENV["no_proxy"] = "http://no"
1007
- ENV["NO_PROXY"] = "http://no"
1008
-
1009
- cmd.must_equal(outdent!(<<-CODE.chomp))
1010
- $env:https_proxy = "https://proxy"
1011
- $env:HTTPS_PROXY = "https://proxy"
1012
- $env:no_proxy = "http://no"
1013
- $env:NO_PROXY = "http://no"
1014
- mkdir foo
1015
- CODE
1016
- end
1017
-
1018
- it "exports no_proxy & NO_PROXY from workstation when ftp_proxy is set from workstation" do
1019
- ENV["ftp_proxy"] = "ftp://proxy"
1020
- ENV["FTP_PROXY"] = "ftp://proxy"
1021
- ENV["no_proxy"] = "http://no"
1022
- ENV["NO_PROXY"] = "http://no"
1023
-
1024
- cmd.must_equal(outdent!(<<-CODE.chomp))
1025
- $env:ftp_proxy = "ftp://proxy"
1026
- $env:FTP_PROXY = "ftp://proxy"
1027
- $env:no_proxy = "http://no"
1028
- $env:NO_PROXY = "http://no"
1029
- mkdir foo
1030
- CODE
1031
- end
1032
- end
1033
- end
1034
-
1035
- it "has a default verify dependencies method" do
1036
- subject.verify_dependencies.must_be_nil
1037
- end
1038
-
1039
- describe "#logger" do
1040
-
1041
- before { @klog = Kitchen.logger }
1042
- after { Kitchen.logger = @klog }
1043
-
1044
- it "returns the instance's logger" do
1045
- logger = stub("logger")
1046
- instance = stub(:logger => logger)
1047
- subject = Kitchen::Thing::Tiny.new(config.merge(:instance => instance))
1048
- subject.send(:logger).must_equal logger
1049
- end
1050
-
1051
- it "returns the default logger if instance's logger is not set" do
1052
- subject = Kitchen::Thing::Tiny.new(config)
1053
- Kitchen.logger = "yep"
1054
-
1055
- subject.send(:logger).must_equal Kitchen.logger
1056
- end
1057
- end
1058
-
1059
- def outdent!(*args)
1060
- Kitchen::Util.outdent!(*args)
1061
- end
1062
- end
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
+ require "stringio"
21
+
22
+ require "kitchen"
23
+ require "kitchen/errors"
24
+ require "kitchen/configurable"
25
+
26
+ module Kitchen
27
+
28
+ module Thing
29
+
30
+ class Tiny
31
+
32
+ include Kitchen::Configurable
33
+
34
+ attr_reader :instance
35
+
36
+ def initialize(config = {})
37
+ init_config(config)
38
+ @instance = config[:instance]
39
+ end
40
+ end
41
+
42
+ class Versioned < Tiny
43
+
44
+ plugin_version "1.8.17"
45
+ end
46
+
47
+ class StaticDefaults
48
+
49
+ include Kitchen::Configurable
50
+
51
+ default_config :beans, "kidney"
52
+ default_config :tunables, "flimflam" => "positate"
53
+ default_config :edible, true
54
+ default_config :fetch_command, "curl"
55
+ default_config :success_path, "./success"
56
+ default_config :bunch_of_paths, %W[./a ./b ./c]
57
+ default_config :beans_url do |subject|
58
+ "http://gim.me/#{subject[:beans]}"
59
+ end
60
+ default_config :command do |subject|
61
+ "#{subject[:fetch_command]} #{subject[:beans_url]}"
62
+ end
63
+ default_config :fetch_url do |subject|
64
+ "http://gim.me/beans-for/#{subject.instance.name}"
65
+ end
66
+
67
+ required_config :need_it
68
+ required_config :a_default
69
+ required_config :no_nuts do |attr, value, _subject|
70
+ raise UserError, "NO NUTS FOR #{attr}!" if value == "nuts"
71
+ end
72
+
73
+ expand_path_for :success_path
74
+ expand_path_for :bunch_of_paths
75
+ expand_path_for :relative_path, false
76
+ expand_path_for :another_path
77
+ expand_path_for :complex_path do |subject|
78
+ subject[:something_else] == "is_set"
79
+ end
80
+
81
+ def initialize(config = {})
82
+ init_config(config)
83
+ end
84
+ end
85
+
86
+ class SubclassDefaults < StaticDefaults
87
+
88
+ default_config :yea, "ya"
89
+ default_config :fetch_command, "wget"
90
+ default_config :fetch_url, "http://no.beans"
91
+
92
+ required_config :a_default do |_attr, value, _subject|
93
+ raise UserError, "Overriding a_default is fun" unless value == "please"
94
+ end
95
+
96
+ expand_path_for :another_path, false
97
+ end
98
+ end
99
+ end
100
+
101
+ describe Kitchen::Configurable do
102
+
103
+ let(:config) { Hash.new }
104
+ let(:platform) { stub }
105
+ let(:instance) do
106
+ stub(:name => "coolbeans", :to_str => "<instance>", :platform => platform)
107
+ end
108
+
109
+ let(:subject) do
110
+ Kitchen::Thing::Tiny.new(config).finalize_config!(instance)
111
+ end
112
+
113
+ describe "creation and setup" do
114
+
115
+ it "#instance returns its instance" do
116
+ subject.instance.must_equal instance
117
+ end
118
+
119
+ it "#finalize_config! raises ClientError if instance is nil" do
120
+ proc { Kitchen::Thing::Tiny.new({}).finalize_config!(nil) }.
121
+ must_raise(Kitchen::ClientError)
122
+ end
123
+
124
+ it "#finalize_config! returns self for chaining" do
125
+ t = Kitchen::Thing::Tiny.new({})
126
+ t.finalize_config!(instance).must_equal t
127
+ end
128
+ end
129
+
130
+ describe "configuration" do
131
+
132
+ describe "provided from the outside" do
133
+
134
+ it "returns provided config" do
135
+ config[:fruit] = %w[apples oranges]
136
+ config[:cool_enough] = true
137
+
138
+ subject[:fruit].must_equal %w[apples oranges]
139
+ subject[:cool_enough].must_equal true
140
+ end
141
+ end
142
+
143
+ describe "using static default_config statements" do
144
+
145
+ let(:config) do
146
+ { :need_it => true, :a_default => true }
147
+ end
148
+
149
+ let(:subject) do
150
+ Kitchen::Thing::StaticDefaults.new(config).finalize_config!(instance)
151
+ end
152
+
153
+ it "uses defaults" do
154
+ subject[:beans].must_equal "kidney"
155
+ subject[:tunables]["flimflam"].must_equal "positate"
156
+ subject[:edible].must_equal true
157
+ end
158
+
159
+ it "uses provided config over default_config" do
160
+ config[:beans] = "pinto"
161
+ config[:edible] = false
162
+
163
+ subject[:beans].must_equal "pinto"
164
+ subject[:edible].must_equal false
165
+ end
166
+
167
+ it "uses other config values to compute values" do
168
+ subject[:beans_url].must_equal "http://gim.me/kidney"
169
+ subject[:command].must_equal "curl http://gim.me/kidney"
170
+ end
171
+
172
+ it "computed value blocks have access to instance object" do
173
+ subject[:fetch_url].must_equal "http://gim.me/beans-for/coolbeans"
174
+ end
175
+
176
+ it "uses provided config over default_config for computed values" do
177
+ config[:command] = "echo listentome"
178
+ config[:beans] = "pinto"
179
+
180
+ subject[:command].must_equal "echo listentome"
181
+ subject[:beans_url].must_equal "http://gim.me/pinto"
182
+ end
183
+ end
184
+
185
+ describe "using inherited static default_config statements" do
186
+
187
+ let(:config) do
188
+ { :need_it => true, :a_default => "please" }
189
+ end
190
+
191
+ let(:subject) do
192
+ Kitchen::Thing::SubclassDefaults.new(config).finalize_config!(instance)
193
+ end
194
+
195
+ it "contains defaults from superclass" do
196
+ subject[:beans].must_equal "kidney"
197
+ subject[:tunables]["flimflam"].must_equal "positate"
198
+ subject[:edible].must_equal true
199
+ subject[:yea].must_equal "ya"
200
+ end
201
+
202
+ it "uses provided config over default config" do
203
+ config[:beans] = "pinto"
204
+ config[:edible] = false
205
+
206
+ subject[:beans].must_equal "pinto"
207
+ subject[:edible].must_equal false
208
+ subject[:yea].must_equal "ya"
209
+ subject[:beans_url].must_equal "http://gim.me/pinto"
210
+ end
211
+
212
+ it "uses its own default_config over inherited default_config" do
213
+ subject[:fetch_url].must_equal "http://no.beans"
214
+ subject[:command].must_equal "wget http://gim.me/kidney"
215
+ end
216
+ end
217
+
218
+ describe "using static required_config statements" do
219
+
220
+ let(:config) do
221
+ { :a_default => true }
222
+ end
223
+
224
+ let(:subject) do
225
+ Kitchen::Thing::StaticDefaults.new(config).finalize_config!(instance)
226
+ end
227
+
228
+ it "uses a value when provided" do
229
+ config[:need_it] = "okay"
230
+
231
+ subject[:need_it].must_equal "okay"
232
+ end
233
+
234
+ it "without a block, raises a UserError if attr is nil" do
235
+ config[:need_it] = nil
236
+
237
+ begin
238
+ subject
239
+ flunk "UserError must be raised"
240
+ rescue Kitchen::UserError => e
241
+ attr = "Kitchen::Thing::StaticDefaults<instance>#config[:need_it]"
242
+ e.message.must_equal "#{attr} cannot be blank"
243
+ end
244
+ end
245
+
246
+ it "without a block, raises a UserError if attr is an empty string" do
247
+ config[:need_it] = ""
248
+
249
+ begin
250
+ subject
251
+ flunk "UserError must be raised"
252
+ rescue Kitchen::UserError => e
253
+ attr = "Kitchen::Thing::StaticDefaults<instance>#config[:need_it]"
254
+ e.message.must_equal "#{attr} cannot be blank"
255
+ end
256
+ end
257
+
258
+ it "with a block, it is saved and invoked" do
259
+ config[:need_it] = "okay"
260
+ config[:no_nuts] = "nuts"
261
+
262
+ begin
263
+ subject
264
+ flunk "UserError must be raised"
265
+ rescue Kitchen::UserError => e
266
+ e.message.must_equal "NO NUTS FOR no_nuts!"
267
+ end
268
+ end
269
+ end
270
+
271
+ describe "using inherited static require_config statements" do
272
+
273
+ let(:subject) do
274
+ Kitchen::Thing::SubclassDefaults.new(config).finalize_config!(instance)
275
+ end
276
+
277
+ it "contains required config from superclass" do
278
+ config[:a_default] = nil
279
+ config[:need_it] = nil
280
+
281
+ begin
282
+ subject
283
+ flunk "UserError must be raised"
284
+ rescue Kitchen::UserError => e
285
+ attr = "Kitchen::Thing::StaticDefaults<instance>#config[:need_it]"
286
+ e.message.must_equal "#{attr} cannot be blank"
287
+ end
288
+ end
289
+
290
+ it "uses its own require_config over inherited require_config" do
291
+ config[:need_it] = true
292
+ config[:a_default] = nil
293
+
294
+ begin
295
+ subject
296
+ flunk "UserError must be raised"
297
+ rescue Kitchen::UserError => e
298
+ e.message.must_equal "Overriding a_default is fun"
299
+ end
300
+ end
301
+ end
302
+
303
+ describe "using static expand_path_for statements" do
304
+
305
+ let(:config) do
306
+ { :need_it => "a", :a_default => "b", :kitchen_root => "/tmp/yo/self" }
307
+ end
308
+
309
+ let(:subject) do
310
+ Kitchen::Thing::StaticDefaults.new(config).finalize_config!(instance)
311
+ end
312
+
313
+ it "expands a default value" do
314
+ subject[:success_path].must_equal os_safe_root_path("/tmp/yo/self/success")
315
+ end
316
+
317
+ it "uses provided config over default_config" do
318
+ config[:success_path] = "mine"
319
+
320
+ subject[:success_path].must_equal os_safe_root_path("/tmp/yo/self/mine")
321
+ end
322
+
323
+ it "leaves a full path expanded" do
324
+ config[:success_path] = "/the/other/one"
325
+
326
+ subject[:success_path].must_equal os_safe_root_path("/the/other/one")
327
+ end
328
+
329
+ it "expands all items if path is an array" do
330
+ paths = %W[
331
+ /tmp/yo/self/a /tmp/yo/self/b /tmp/yo/self/c
332
+ ]
333
+ os_safe_paths = paths.collect { |path| os_safe_root_path(path) }
334
+ subject[:bunch_of_paths].must_equal os_safe_paths
335
+ end
336
+
337
+ it "doesn't expand path with a falsy expand_path_for value" do
338
+ config[:relative_path] = "./rel"
339
+
340
+ subject[:relative_path].must_equal "./rel"
341
+ end
342
+
343
+ it "expands a path if a lambda returns truthy" do
344
+ config[:something_else] = "is_set"
345
+ config[:complex_path] = "./complex"
346
+
347
+ subject[:complex_path].must_equal os_safe_root_path("/tmp/yo/self/complex")
348
+ end
349
+
350
+ it "leaves a nil config value as nil" do
351
+ config[:success_path] = nil
352
+
353
+ subject[:success_path].must_equal nil
354
+ end
355
+
356
+ it "leaves a false config value as false" do
357
+ config[:success_path] = false
358
+
359
+ subject[:success_path].must_equal false
360
+ end
361
+ end
362
+
363
+ describe "using inherited static expand_path_for statements" do
364
+
365
+ let(:config) do
366
+ { :need_it => "a", :a_default => "please", :kitchen_root => "/rooty" }
367
+ end
368
+
369
+ let(:subject) do
370
+ Kitchen::Thing::SubclassDefaults.new(config).finalize_config!(instance)
371
+ end
372
+
373
+ it "contains expand_path_for from superclass" do
374
+ subject[:success_path].must_equal os_safe_root_path("/rooty/success")
375
+ end
376
+
377
+ it "uses its own expand_path_for over inherited expand_path_for" do
378
+ config[:another_path] = "./pp"
379
+
380
+ subject[:another_path].must_equal "./pp"
381
+ end
382
+ end
383
+
384
+ it "#config_keys returns an array of config key names" do
385
+ subject = Kitchen::Thing::Tiny.new(:ice_cream => "dragon")
386
+
387
+ subject.config_keys.sort.must_equal [:ice_cream]
388
+ end
389
+ end
390
+
391
+ it "#name returns the name of the plugin" do
392
+ subject.name.must_equal "Tiny"
393
+ end
394
+
395
+ describe "#diagnose" do
396
+
397
+ it "returns an empty hash for no config" do
398
+ subject.diagnose.must_equal Hash.new
399
+ end
400
+
401
+ it "returns a hash of config" do
402
+ config[:alpha] = "beta"
403
+ subject.diagnose.must_equal(:alpha => "beta")
404
+ end
405
+
406
+ it "returns a hash with sorted keys" do
407
+ config[:zebra] = true
408
+ config[:elephant] = true
409
+
410
+ subject.diagnose.keys.must_equal [:elephant, :zebra]
411
+ end
412
+ end
413
+
414
+ describe "#diagnose_plugin" do
415
+
416
+ it "returns a plugin hash for a plugin without version" do
417
+ subject.diagnose_plugin.must_equal(
418
+ :name => "Tiny", :class => "Kitchen::Thing::Tiny",
419
+ :version => nil, :api_version => nil
420
+ )
421
+ end
422
+
423
+ it "returns a plugin hash for a plugin with version" do
424
+ subject = Kitchen::Thing::Versioned.new(config).finalize_config!(instance)
425
+ subject.diagnose_plugin.must_equal(
426
+ :name => "Versioned", :class => "Kitchen::Thing::Versioned",
427
+ :version => "1.8.17", :api_version => nil
428
+ )
429
+ end
430
+ end
431
+
432
+ describe "#calculate_path" do
433
+
434
+ let(:config) do
435
+ { :test_base_path => "/the/basest" }
436
+ end
437
+
438
+ let(:suite) do
439
+ stub(:name => "ultimate")
440
+ end
441
+
442
+ let(:instance) do
443
+ stub(:name => "coolbeans", :to_str => "<instance>", :suite => suite)
444
+ end
445
+
446
+ let(:subject) do
447
+ Kitchen::Thing::Tiny.new(config).finalize_config!(instance)
448
+ end
449
+
450
+ before do
451
+ FakeFS.activate!
452
+ end
453
+
454
+ after do
455
+ FakeFS.deactivate!
456
+ FakeFS::FileSystem.clear
457
+ end
458
+
459
+ describe "for directories" do
460
+
461
+ before do
462
+ FileUtils.mkdir_p(File.join(Dir.pwd, "winner"))
463
+ FileUtils.mkdir_p("/the/basest/winner")
464
+ FileUtils.mkdir_p("/the/basest/ultimate/winner")
465
+ end
466
+
467
+ it "prefers a path containing base path and suite name if it exists" do
468
+ subject.calculate_path("winner").
469
+ must_equal "/the/basest/ultimate/winner"
470
+ end
471
+
472
+ it "prefers a path containing base path if it exists" do
473
+ FileUtils.rm_rf("/the/basest/ultimate/winner")
474
+
475
+ subject.calculate_path("winner").must_equal "/the/basest/winner"
476
+ end
477
+
478
+ it "prefers a path in the current working directory if it exists" do
479
+ FileUtils.rm_rf("/the/basest/ultimate/winner")
480
+ FileUtils.rm_rf("/the/basest/winner")
481
+ pwd_dir = File.join(Dir.pwd, "winner")
482
+
483
+ subject.calculate_path("winner").must_equal pwd_dir
484
+ end
485
+
486
+ it "raises a UserError if test_base_path key is not set" do
487
+ config.delete(:test_base_path)
488
+
489
+ proc { subject.calculate_path("winner") }.must_raise Kitchen::UserError
490
+ end
491
+
492
+ it "uses a custom base path" do
493
+ FileUtils.mkdir_p("/custom/ultimate/winner")
494
+
495
+ subject.calculate_path("winner", :base_path => "/custom").
496
+ must_equal "/custom/ultimate/winner"
497
+ end
498
+ end
499
+
500
+ describe "for files" do
501
+
502
+ before do
503
+ FileUtils.mkdir_p(Dir.pwd)
504
+ FileUtils.touch(File.join(Dir.pwd, "winner"))
505
+ FileUtils.mkdir_p("/the/basest")
506
+ FileUtils.touch(File.join("/the/basest", "winner"))
507
+ FileUtils.mkdir_p("/the/basest/ultimate")
508
+ FileUtils.touch(File.join("/the/basest/ultimate", "winner"))
509
+ end
510
+
511
+ it "prefers a path containing base path and suite name if it exists" do
512
+ subject.calculate_path("winner", :type => :file).
513
+ must_equal "/the/basest/ultimate/winner"
514
+ end
515
+
516
+ it "prefers a path containing base path if it exists" do
517
+ FileUtils.rm_rf("/the/basest/ultimate/winner")
518
+
519
+ subject.calculate_path("winner", :type => :file).
520
+ must_equal "/the/basest/winner"
521
+ end
522
+
523
+ it "prefers a path in the current working directory if it exists" do
524
+ FileUtils.rm_rf("/the/basest/ultimate/winner")
525
+ FileUtils.rm_rf("/the/basest/winner")
526
+ pwd_dir = File.join(Dir.pwd, "winner")
527
+
528
+ subject.calculate_path("winner", :type => :file).must_equal pwd_dir
529
+ end
530
+
531
+ it "raises a UserError if test_base_path key is not set" do
532
+ config.delete(:test_base_path)
533
+
534
+ proc { subject.calculate_path("winner") }.must_raise Kitchen::UserError
535
+ end
536
+
537
+ it "uses a custom base path" do
538
+ FileUtils.mkdir_p("/custom/ultimate")
539
+ FileUtils.touch(File.join("/custom/ultimate", "winner"))
540
+
541
+ subject.calculate_path("winner", :type => :file, :base_path => "/custom").
542
+ must_equal "/custom/ultimate/winner"
543
+ end
544
+ end
545
+ end
546
+
547
+ describe "#remote_path_join" do
548
+
549
+ it "returns unix style path separators for unix os_type" do
550
+ platform.stubs(:os_type).returns("unix")
551
+
552
+ subject.remote_path_join("a", "b", "c").must_equal "a/b/c"
553
+ end
554
+
555
+ it "returns windows style path separators for windows os_type" do
556
+ platform.stubs(:os_type).returns("windows")
557
+
558
+ subject.remote_path_join("a", "b", "c").must_equal "a\\b\\c"
559
+ end
560
+
561
+ it "accepts combinations of strings and arrays" do
562
+ platform.stubs(:os_type).returns("unix")
563
+
564
+ subject.remote_path_join(%W[a b], "c", %W[d e]).must_equal "a/b/c/d/e"
565
+ end
566
+
567
+ it "accepts a single array" do
568
+ platform.stubs(:os_type).returns("windows")
569
+
570
+ subject.remote_path_join(%W[a b]).must_equal "a\\b"
571
+ end
572
+
573
+ it "converts all windows path separators to unix for unix os_type" do
574
+ platform.stubs(:os_type).returns("unix")
575
+
576
+ subject.remote_path_join("\\a\\b", "c/d").must_equal "/a/b/c/d"
577
+ end
578
+
579
+ it "converts all unix path separators to windows for windows os_type" do
580
+ platform.stubs(:os_type).returns("windows")
581
+
582
+ subject.remote_path_join("/a/b", "c\\d").must_equal "\\a\\b\\c\\d"
583
+ end
584
+ end
585
+
586
+ describe "#windows_os?" do
587
+
588
+ it "for windows type platform returns true" do
589
+ platform.stubs(:os_type).returns("windows")
590
+
591
+ subject.windows_os?.must_equal true
592
+ end
593
+
594
+ it "for unix type platform returns false" do
595
+ platform.stubs(:os_type).returns("unix")
596
+
597
+ subject.windows_os?.must_equal false
598
+ end
599
+
600
+ it "for newfangled type platform return false" do
601
+ platform.stubs(:os_type).returns("internet_cat")
602
+
603
+ subject.windows_os?.must_equal false
604
+ end
605
+
606
+ it "for unset type platform returns false" do
607
+ platform.stubs(:os_type).returns(nil)
608
+
609
+ subject.windows_os?.must_equal false
610
+ end
611
+ end
612
+
613
+ describe "#unix_os?" do
614
+
615
+ it "for windows type platform returns false" do
616
+ platform.stubs(:os_type).returns("windows")
617
+
618
+ subject.unix_os?.must_equal false
619
+ end
620
+
621
+ it "for unix type platform returns true" do
622
+ platform.stubs(:os_type).returns("unix")
623
+
624
+ subject.unix_os?.must_equal true
625
+ end
626
+
627
+ it "for newfangled type platform return false" do
628
+ platform.stubs(:os_type).returns("internet_cat")
629
+
630
+ subject.unix_os?.must_equal false
631
+ end
632
+
633
+ it "for unset type platform returns true" do
634
+ platform.stubs(:os_type).returns(nil)
635
+
636
+ subject.unix_os?.must_equal true
637
+ end
638
+ end
639
+
640
+ describe "#powershell_shell?" do
641
+
642
+ it "for powershell type shell returns true" do
643
+ platform.stubs(:shell_type).returns("powershell")
644
+
645
+ subject.powershell_shell?.must_equal true
646
+ end
647
+
648
+ it "for bourne type shell returns false" do
649
+ platform.stubs(:shell_type).returns("bourne")
650
+
651
+ subject.powershell_shell?.must_equal false
652
+ end
653
+
654
+ it "for newfangled type shell return false" do
655
+ platform.stubs(:shell_type).returns("internet_cat")
656
+
657
+ subject.powershell_shell?.must_equal false
658
+ end
659
+
660
+ it "for unset type shell returns false" do
661
+ platform.stubs(:shell_type).returns(nil)
662
+
663
+ subject.powershell_shell?.must_equal false
664
+ end
665
+ end
666
+
667
+ describe "#bourne_shell?" do
668
+
669
+ it "for powershell type shell returns false" do
670
+ platform.stubs(:shell_type).returns("powershell")
671
+
672
+ subject.bourne_shell?.must_equal false
673
+ end
674
+
675
+ it "for bourne type shell returns true" do
676
+ platform.stubs(:shell_type).returns("bourne")
677
+
678
+ subject.bourne_shell?.must_equal true
679
+ end
680
+
681
+ it "for newfangled type shell return false" do
682
+ platform.stubs(:shell_type).returns("internet_cat")
683
+
684
+ subject.bourne_shell?.must_equal false
685
+ end
686
+
687
+ it "for unset type shell returns true" do
688
+ platform.stubs(:shell_type).returns(nil)
689
+
690
+ subject.bourne_shell?.must_equal true
691
+ end
692
+ end
693
+
694
+ describe "#shell_env_var" do
695
+
696
+ it "for powershell type shells returns a powershell environment variable" do
697
+ platform.stubs(:shell_type).returns("powershell")
698
+
699
+ subject.send(:shell_env_var, "foo", "bar").
700
+ must_equal %{$env:foo = "bar"}
701
+ end
702
+
703
+ it "for bourne type shells returns a bourne environment variable" do
704
+ platform.stubs(:shell_type).returns("bourne")
705
+
706
+ subject.send(:shell_env_var, "foo", "bar").
707
+ must_equal %{foo="bar"; export foo}
708
+ end
709
+ end
710
+
711
+ describe "#shell_var" do
712
+
713
+ it "for powershell type shells returns a powershell variable" do
714
+ platform.stubs(:shell_type).returns("powershell")
715
+
716
+ subject.send(:shell_var, "foo", "bar").must_equal %{$foo = "bar"}
717
+ end
718
+
719
+ it "for bourne type shells returns a bourne variable" do
720
+ platform.stubs(:shell_type).returns("bourne")
721
+
722
+ subject.send(:shell_var, "foo", "bar").must_equal %{foo="bar"}
723
+ end
724
+ end
725
+
726
+ describe "#wrap_shell_code" do
727
+
728
+ let(:cmd) { subject.send(:wrap_shell_code, "mkdir foo") }
729
+
730
+ before do
731
+ @original_env = ENV.to_hash
732
+ ENV.replace("http_proxy" => nil, "HTTP_PROXY" => nil,
733
+ "https_proxy" => nil, "HTTPS_PROXY" => nil,
734
+ "ftp_proxy" => nil, "FTP_PROXY" => nil,
735
+ "no_proxy" => nil, "NO_PROXY" => nil)
736
+ end
737
+
738
+ after do
739
+ ENV.clear
740
+ ENV.replace(@original_env)
741
+ end
742
+
743
+ describe "for bourne shells" do
744
+
745
+ before { platform.stubs(:shell_type).returns("bourne") }
746
+
747
+ it "uses bourne shell (sh)" do
748
+ cmd.must_equal(outdent!(<<-CODE.chomp))
749
+ sh -c '
750
+
751
+ mkdir foo
752
+ '
753
+ CODE
754
+ end
755
+
756
+ it "exports http_proxy & HTTP_PROXY when :http_proxy is set" do
757
+ config[:http_proxy] = "http://proxy"
758
+
759
+ cmd.must_equal(outdent!(<<-CODE.chomp))
760
+ sh -c '
761
+ http_proxy="http://proxy"; export http_proxy
762
+ HTTP_PROXY="http://proxy"; export HTTP_PROXY
763
+ mkdir foo
764
+ '
765
+ CODE
766
+ end
767
+
768
+ it "exports https_proxy & HTTPS_PROXY when :https_proxy is set" do
769
+ config[:https_proxy] = "https://proxy"
770
+
771
+ cmd.must_equal(outdent!(<<-CODE.chomp))
772
+ sh -c '
773
+ https_proxy="https://proxy"; export https_proxy
774
+ HTTPS_PROXY="https://proxy"; export HTTPS_PROXY
775
+ mkdir foo
776
+ '
777
+ CODE
778
+ end
779
+
780
+ it "exports ftp_proxy & FTP_PROXY when :ftp_proxy is set" do
781
+ config[:ftp_proxy] = "ftp://proxy"
782
+
783
+ cmd.must_equal(outdent!(<<-CODE.chomp))
784
+ sh -c '
785
+ ftp_proxy="ftp://proxy"; export ftp_proxy
786
+ FTP_PROXY="ftp://proxy"; export FTP_PROXY
787
+ mkdir foo
788
+ '
789
+ CODE
790
+ end
791
+
792
+ it "exports all http proxy variables when all are set" do
793
+ config[:http_proxy] = "http://proxy"
794
+ config[:https_proxy] = "https://proxy"
795
+ config[:ftp_proxy] = "ftp://proxy"
796
+
797
+ cmd.must_equal(outdent!(<<-CODE.chomp))
798
+ sh -c '
799
+ http_proxy="http://proxy"; export http_proxy
800
+ HTTP_PROXY="http://proxy"; export HTTP_PROXY
801
+ https_proxy="https://proxy"; export https_proxy
802
+ HTTPS_PROXY="https://proxy"; export HTTPS_PROXY
803
+ ftp_proxy="ftp://proxy"; export ftp_proxy
804
+ FTP_PROXY="ftp://proxy"; export FTP_PROXY
805
+ mkdir foo
806
+ '
807
+ CODE
808
+ end
809
+
810
+ it "exports http_proxy & HTTP_PROXY from workstation when :http_proxy isn't set" do
811
+ ENV["http_proxy"] = "http://proxy"
812
+ ENV["HTTP_PROXY"] = "http://proxy"
813
+
814
+ cmd.must_equal(outdent!(<<-CODE.chomp))
815
+ sh -c '
816
+ http_proxy="http://proxy"; export http_proxy
817
+ HTTP_PROXY="http://proxy"; export HTTP_PROXY
818
+ mkdir foo
819
+ '
820
+ CODE
821
+ end
822
+
823
+ it "exports https_proxy & HTTPS_PROXY from workstation when :https_proxy isn't set" do
824
+ ENV["https_proxy"] = "https://proxy"
825
+ ENV["HTTPS_PROXY"] = "https://proxy"
826
+
827
+ cmd.must_equal(outdent!(<<-CODE.chomp))
828
+ sh -c '
829
+ https_proxy="https://proxy"; export https_proxy
830
+ HTTPS_PROXY="https://proxy"; export HTTPS_PROXY
831
+ mkdir foo
832
+ '
833
+ CODE
834
+ end
835
+
836
+ it "does not export http_proxy or HTTP_PROXY when :http_proxy is empty" do
837
+ config[:http_proxy] = ""
838
+
839
+ cmd.must_equal(outdent!(<<-CODE.chomp))
840
+ sh -c '
841
+
842
+ mkdir foo
843
+ '
844
+ CODE
845
+ end
846
+
847
+ it "does not export https_proxy or HTTPS_PROXY when :https_proxy is empty" do
848
+ config[:https_proxy] = ""
849
+
850
+ cmd.must_equal(outdent!(<<-CODE.chomp))
851
+ sh -c '
852
+
853
+ mkdir foo
854
+ '
855
+ CODE
856
+ end
857
+
858
+ it "exports ftp_proxy & FTP_PROXY from workstation when :ftp_proxy isn't set" do
859
+ ENV["ftp_proxy"] = "ftp://proxy"
860
+ ENV["FTP_PROXY"] = "ftp://proxy"
861
+
862
+ cmd.must_equal(outdent!(<<-CODE.chomp))
863
+ sh -c '
864
+ ftp_proxy="ftp://proxy"; export ftp_proxy
865
+ FTP_PROXY="ftp://proxy"; export FTP_PROXY
866
+ mkdir foo
867
+ '
868
+ CODE
869
+ end
870
+
871
+ it "does not export ftp_proxy or FTP_PROXY when :ftp_proxy is empty" do
872
+ config[:ftp_proxy] = ""
873
+
874
+ cmd.must_equal(outdent!(<<-CODE.chomp))
875
+ sh -c '
876
+
877
+ mkdir foo
878
+ '
879
+ CODE
880
+ end
881
+
882
+ it "exports no_proxy & NO_PROXY from workstation when http_proxy is set from workstation" do
883
+ ENV["http_proxy"] = "http://proxy"
884
+ ENV["HTTP_PROXY"] = "http://proxy"
885
+ ENV["no_proxy"] = "http://no"
886
+ ENV["NO_PROXY"] = "http://no"
887
+
888
+ cmd.must_equal(outdent!(<<-CODE.chomp))
889
+ sh -c '
890
+ http_proxy="http://proxy"; export http_proxy
891
+ HTTP_PROXY="http://proxy"; export HTTP_PROXY
892
+ no_proxy="http://no"; export no_proxy
893
+ NO_PROXY="http://no"; export NO_PROXY
894
+ mkdir foo
895
+ '
896
+ CODE
897
+ end
898
+
899
+ it "exports no_proxy & NO_PROXY from workstation when https_proxy is set from workstation" do
900
+ ENV["https_proxy"] = "https://proxy"
901
+ ENV["HTTPS_PROXY"] = "https://proxy"
902
+ ENV["no_proxy"] = "http://no"
903
+ ENV["NO_PROXY"] = "http://no"
904
+
905
+ cmd.must_equal(outdent!(<<-CODE.chomp))
906
+ sh -c '
907
+ https_proxy="https://proxy"; export https_proxy
908
+ HTTPS_PROXY="https://proxy"; export HTTPS_PROXY
909
+ no_proxy="http://no"; export no_proxy
910
+ NO_PROXY="http://no"; export NO_PROXY
911
+ mkdir foo
912
+ '
913
+ CODE
914
+ end
915
+
916
+ it "exports no_proxy & NO_PROXY from workstation when ftp_proxy is set from workstation" do
917
+ ENV["ftp_proxy"] = "ftp://proxy"
918
+ ENV["FTP_PROXY"] = "ftp://proxy"
919
+ ENV["no_proxy"] = "http://no"
920
+ ENV["NO_PROXY"] = "http://no"
921
+
922
+ cmd.must_equal(outdent!(<<-CODE.chomp))
923
+ sh -c '
924
+ ftp_proxy="ftp://proxy"; export ftp_proxy
925
+ FTP_PROXY="ftp://proxy"; export FTP_PROXY
926
+ no_proxy="http://no"; export no_proxy
927
+ NO_PROXY="http://no"; export NO_PROXY
928
+ mkdir foo
929
+ '
930
+ CODE
931
+ end
932
+ end
933
+
934
+ describe "for powershell shells" do
935
+
936
+ before { platform.stubs(:shell_type).returns("powershell") }
937
+
938
+ it "uses powershell shell" do
939
+ cmd.must_equal("\nmkdir foo")
940
+ end
941
+
942
+ it "exports http_proxy & HTTP_PROXY when :http_proxy is set" do
943
+ config[:http_proxy] = "http://proxy"
944
+
945
+ cmd.must_equal(outdent!(<<-CODE.chomp))
946
+ $env:http_proxy = "http://proxy"
947
+ $env:HTTP_PROXY = "http://proxy"
948
+ mkdir foo
949
+ CODE
950
+ end
951
+
952
+ it "exports https_proxy & HTTPS_PROXY when :https_proxy is set" do
953
+ config[:https_proxy] = "https://proxy"
954
+
955
+ cmd.must_equal(outdent!(<<-CODE.chomp))
956
+ $env:https_proxy = "https://proxy"
957
+ $env:HTTPS_PROXY = "https://proxy"
958
+ mkdir foo
959
+ CODE
960
+ end
961
+
962
+ it "exports ftp_proxy & FTP_PROXY when :ftp_proxy is set" do
963
+ config[:ftp_proxy] = "ftp://proxy"
964
+
965
+ cmd.must_equal(outdent!(<<-CODE.chomp))
966
+ $env:ftp_proxy = "ftp://proxy"
967
+ $env:FTP_PROXY = "ftp://proxy"
968
+ mkdir foo
969
+ CODE
970
+ end
971
+
972
+ it "exports all http proxy variables when all are set" do
973
+ config[:http_proxy] = "http://proxy"
974
+ config[:https_proxy] = "https://proxy"
975
+ config[:ftp_proxy] = "ftp://proxy"
976
+
977
+ cmd.must_equal(outdent!(<<-CODE.chomp))
978
+ $env:http_proxy = "http://proxy"
979
+ $env:HTTP_PROXY = "http://proxy"
980
+ $env:https_proxy = "https://proxy"
981
+ $env:HTTPS_PROXY = "https://proxy"
982
+ $env:ftp_proxy = "ftp://proxy"
983
+ $env:FTP_PROXY = "ftp://proxy"
984
+ mkdir foo
985
+ CODE
986
+ end
987
+
988
+ it "exports http_proxy & HTTP_PROXY from workstation when :http_proxy isn't set" do
989
+ ENV["http_proxy"] = "http://proxy"
990
+ ENV["HTTP_PROXY"] = "http://proxy"
991
+
992
+ cmd.must_equal(outdent!(<<-CODE.chomp))
993
+ $env:http_proxy = "http://proxy"
994
+ $env:HTTP_PROXY = "http://proxy"
995
+ mkdir foo
996
+ CODE
997
+ end
998
+
999
+ it "exports https_proxy & HTTPS_PROXY from workstation when :https_proxy isn't set" do
1000
+ ENV["https_proxy"] = "https://proxy"
1001
+ ENV["HTTPS_PROXY"] = "https://proxy"
1002
+
1003
+ cmd.must_equal(outdent!(<<-CODE.chomp))
1004
+ $env:https_proxy = "https://proxy"
1005
+ $env:HTTPS_PROXY = "https://proxy"
1006
+ mkdir foo
1007
+ CODE
1008
+ end
1009
+
1010
+ it "exports ftp_proxy & FTP_PROXY from workstation when :ftp_proxy isn't set" do
1011
+ ENV["ftp_proxy"] = "ftp://proxy"
1012
+ ENV["FTP_PROXY"] = "ftp://proxy"
1013
+
1014
+ cmd.must_equal(outdent!(<<-CODE.chomp))
1015
+ $env:ftp_proxy = "ftp://proxy"
1016
+ $env:FTP_PROXY = "ftp://proxy"
1017
+ mkdir foo
1018
+ CODE
1019
+ end
1020
+
1021
+ it "exports no_proxy & NO_PROXY from workstation when http_proxy is set from workstation" do
1022
+ ENV["http_proxy"] = "http://proxy"
1023
+ ENV["HTTP_PROXY"] = "http://proxy"
1024
+ ENV["no_proxy"] = "http://no"
1025
+ ENV["NO_PROXY"] = "http://no"
1026
+
1027
+ cmd.must_equal(outdent!(<<-CODE.chomp))
1028
+ $env:http_proxy = "http://proxy"
1029
+ $env:HTTP_PROXY = "http://proxy"
1030
+ $env:no_proxy = "http://no"
1031
+ $env:NO_PROXY = "http://no"
1032
+ mkdir foo
1033
+ CODE
1034
+ end
1035
+
1036
+ it "exports no_proxy & NO_PROXY from workstation when https_proxy is set from workstation" do
1037
+ ENV["https_proxy"] = "https://proxy"
1038
+ ENV["HTTPS_PROXY"] = "https://proxy"
1039
+ ENV["no_proxy"] = "http://no"
1040
+ ENV["NO_PROXY"] = "http://no"
1041
+
1042
+ cmd.must_equal(outdent!(<<-CODE.chomp))
1043
+ $env:https_proxy = "https://proxy"
1044
+ $env:HTTPS_PROXY = "https://proxy"
1045
+ $env:no_proxy = "http://no"
1046
+ $env:NO_PROXY = "http://no"
1047
+ mkdir foo
1048
+ CODE
1049
+ end
1050
+
1051
+ it "exports no_proxy & NO_PROXY from workstation when ftp_proxy is set from workstation" do
1052
+ ENV["ftp_proxy"] = "ftp://proxy"
1053
+ ENV["FTP_PROXY"] = "ftp://proxy"
1054
+ ENV["no_proxy"] = "http://no"
1055
+ ENV["NO_PROXY"] = "http://no"
1056
+
1057
+ cmd.must_equal(outdent!(<<-CODE.chomp))
1058
+ $env:ftp_proxy = "ftp://proxy"
1059
+ $env:FTP_PROXY = "ftp://proxy"
1060
+ $env:no_proxy = "http://no"
1061
+ $env:NO_PROXY = "http://no"
1062
+ mkdir foo
1063
+ CODE
1064
+ end
1065
+ end
1066
+ end
1067
+
1068
+ it "has a default verify dependencies method" do
1069
+ subject.verify_dependencies.must_be_nil
1070
+ end
1071
+
1072
+ describe "#logger" do
1073
+
1074
+ before { @klog = Kitchen.logger }
1075
+ after { Kitchen.logger = @klog }
1076
+
1077
+ it "returns the instance's logger" do
1078
+ logger = stub("logger")
1079
+ instance = stub(:logger => logger)
1080
+ subject = Kitchen::Thing::Tiny.new(config.merge(:instance => instance))
1081
+ subject.send(:logger).must_equal logger
1082
+ end
1083
+
1084
+ it "returns the default logger if instance's logger is not set" do
1085
+ subject = Kitchen::Thing::Tiny.new(config)
1086
+ Kitchen.logger = "yep"
1087
+
1088
+ subject.send(:logger).must_equal Kitchen.logger
1089
+ end
1090
+ end
1091
+
1092
+ def outdent!(*args)
1093
+ Kitchen::Util.outdent!(*args)
1094
+ end
1095
+ end