test-kitchen 1.6.0 → 1.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (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