test-kitchen 1.2.1 → 1.3.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 (114) hide show
  1. checksums.yaml +4 -4
  2. data/.cane +1 -1
  3. data/.rubocop.yml +3 -0
  4. data/.travis.yml +20 -9
  5. data/CHANGELOG.md +219 -108
  6. data/Gemfile +10 -6
  7. data/Guardfile +38 -9
  8. data/README.md +11 -1
  9. data/Rakefile +21 -37
  10. data/bin/kitchen +4 -4
  11. data/features/kitchen_action_commands.feature +161 -0
  12. data/features/kitchen_console_command.feature +34 -0
  13. data/features/kitchen_diagnose_command.feature +64 -0
  14. data/features/kitchen_init_command.feature +29 -17
  15. data/features/kitchen_list_command.feature +2 -2
  16. data/features/kitchen_login_command.feature +56 -0
  17. data/features/{sink_command.feature → kitchen_sink_command.feature} +0 -0
  18. data/features/kitchen_test_command.feature +88 -0
  19. data/features/step_definitions/gem_steps.rb +8 -6
  20. data/features/step_definitions/git_steps.rb +4 -2
  21. data/features/step_definitions/output_steps.rb +5 -0
  22. data/features/support/env.rb +12 -9
  23. data/lib/kitchen.rb +60 -38
  24. data/lib/kitchen/base64_stream.rb +55 -0
  25. data/lib/kitchen/busser.rb +124 -58
  26. data/lib/kitchen/cli.rb +121 -38
  27. data/lib/kitchen/collection.rb +3 -3
  28. data/lib/kitchen/color.rb +4 -4
  29. data/lib/kitchen/command.rb +78 -11
  30. data/lib/kitchen/command/action.rb +3 -2
  31. data/lib/kitchen/command/console.rb +12 -5
  32. data/lib/kitchen/command/diagnose.rb +17 -3
  33. data/lib/kitchen/command/driver_discover.rb +26 -7
  34. data/lib/kitchen/command/exec.rb +41 -0
  35. data/lib/kitchen/command/list.rb +44 -14
  36. data/lib/kitchen/command/login.rb +2 -1
  37. data/lib/kitchen/command/sink.rb +2 -1
  38. data/lib/kitchen/command/test.rb +5 -4
  39. data/lib/kitchen/config.rb +146 -14
  40. data/lib/kitchen/configurable.rb +314 -0
  41. data/lib/kitchen/data_munger.rb +522 -18
  42. data/lib/kitchen/diagnostic.rb +43 -4
  43. data/lib/kitchen/driver.rb +4 -4
  44. data/lib/kitchen/driver/base.rb +80 -115
  45. data/lib/kitchen/driver/dummy.rb +34 -6
  46. data/lib/kitchen/driver/proxy.rb +14 -3
  47. data/lib/kitchen/driver/ssh_base.rb +61 -7
  48. data/lib/kitchen/errors.rb +109 -9
  49. data/lib/kitchen/generator/driver_create.rb +39 -5
  50. data/lib/kitchen/generator/init.rb +130 -45
  51. data/lib/kitchen/instance.rb +162 -28
  52. data/lib/kitchen/lazy_hash.rb +79 -7
  53. data/lib/kitchen/loader/yaml.rb +159 -27
  54. data/lib/kitchen/logger.rb +267 -21
  55. data/lib/kitchen/logging.rb +30 -3
  56. data/lib/kitchen/login_command.rb +11 -2
  57. data/lib/kitchen/metadata_chopper.rb +2 -2
  58. data/lib/kitchen/provisioner.rb +4 -4
  59. data/lib/kitchen/provisioner/base.rb +107 -103
  60. data/lib/kitchen/provisioner/chef/berkshelf.rb +36 -8
  61. data/lib/kitchen/provisioner/chef/librarian.rb +40 -11
  62. data/lib/kitchen/provisioner/chef_base.rb +206 -167
  63. data/lib/kitchen/provisioner/chef_solo.rb +25 -7
  64. data/lib/kitchen/provisioner/chef_zero.rb +105 -29
  65. data/lib/kitchen/provisioner/dummy.rb +1 -1
  66. data/lib/kitchen/provisioner/shell.rb +21 -6
  67. data/lib/kitchen/rake_tasks.rb +8 -3
  68. data/lib/kitchen/shell_out.rb +15 -18
  69. data/lib/kitchen/ssh.rb +122 -27
  70. data/lib/kitchen/state_file.rb +24 -7
  71. data/lib/kitchen/thor_tasks.rb +9 -4
  72. data/lib/kitchen/util.rb +43 -118
  73. data/lib/kitchen/version.rb +1 -1
  74. data/lib/vendor/hash_recursive_merge.rb +10 -2
  75. data/spec/kitchen/base64_stream_spec.rb +77 -0
  76. data/spec/kitchen/busser_spec.rb +490 -0
  77. data/spec/kitchen/collection_spec.rb +10 -10
  78. data/spec/kitchen/color_spec.rb +2 -2
  79. data/spec/kitchen/config_spec.rb +234 -62
  80. data/spec/kitchen/configurable_spec.rb +490 -0
  81. data/spec/kitchen/data_munger_spec.rb +1070 -862
  82. data/spec/kitchen/diagnostic_spec.rb +79 -0
  83. data/spec/kitchen/driver/base_spec.rb +80 -85
  84. data/spec/kitchen/driver/dummy_spec.rb +43 -14
  85. data/spec/kitchen/driver/proxy_spec.rb +134 -0
  86. data/spec/kitchen/driver/ssh_base_spec.rb +644 -0
  87. data/spec/kitchen/driver_spec.rb +15 -15
  88. data/spec/kitchen/errors_spec.rb +309 -0
  89. data/spec/kitchen/instance_spec.rb +143 -46
  90. data/spec/kitchen/lazy_hash_spec.rb +36 -9
  91. data/spec/kitchen/loader/yaml_spec.rb +237 -226
  92. data/spec/kitchen/logger_spec.rb +419 -0
  93. data/spec/kitchen/logging_spec.rb +59 -0
  94. data/spec/kitchen/login_command_spec.rb +49 -0
  95. data/spec/kitchen/metadata_chopper_spec.rb +82 -0
  96. data/spec/kitchen/platform_spec.rb +4 -4
  97. data/spec/kitchen/provisioner/base_spec.rb +65 -125
  98. data/spec/kitchen/provisioner/chef_base_spec.rb +798 -0
  99. data/spec/kitchen/provisioner/chef_solo_spec.rb +316 -0
  100. data/spec/kitchen/provisioner/chef_zero_spec.rb +624 -0
  101. data/spec/kitchen/provisioner/shell_spec.rb +269 -0
  102. data/spec/kitchen/provisioner_spec.rb +6 -6
  103. data/spec/kitchen/shell_out_spec.rb +143 -0
  104. data/spec/kitchen/ssh_spec.rb +683 -0
  105. data/spec/kitchen/state_file_spec.rb +28 -21
  106. data/spec/kitchen/suite_spec.rb +7 -7
  107. data/spec/kitchen/util_spec.rb +68 -10
  108. data/spec/kitchen_spec.rb +107 -0
  109. data/spec/spec_helper.rb +18 -13
  110. data/support/chef-client-zero.rb +10 -9
  111. data/support/chef_helpers.sh +16 -0
  112. data/support/download_helpers.sh +109 -0
  113. data/test-kitchen.gemspec +42 -33
  114. metadata +107 -33
@@ -18,5 +18,5 @@
18
18
 
19
19
  module Kitchen
20
20
 
21
- VERSION = "1.2.1"
21
+ VERSION = "1.3.0"
22
22
  end
@@ -1,3 +1,4 @@
1
+ # -*- encoding: utf-8 -*-
1
2
  #
2
3
  # = Hash Recursive Merge
3
4
  #
@@ -24,16 +25,20 @@ module HashRecursiveMerge
24
25
  # When both +hsh+ and +other_hash+ contains an entry with the same key,
25
26
  # it merges and returns the values from both arrays.
26
27
  #
28
+ # @example
29
+ #
27
30
  # h1 = {"a" => 100, "b" => 200, "c" => {"c1" => 12, "c2" => 14}}
28
31
  # h2 = {"b" => 254, "c" => {"c1" => 16, "c3" => 94}}
29
32
  # h1.rmerge!(h2) #=> {"a" => 100, "b" => 254, "c" => {"c1" => 16, "c2" => 14, "c3" => 94}}
30
33
  #
31
34
  # Simply using Hash#merge! would return
32
35
  #
36
+ # @example
37
+ #
33
38
  # h1.merge!(h2) #=> {"a" => 100, "b" = >254, "c" => {"c1" => 16, "c3" => 94}}
34
39
  #
35
40
  def rmerge!(other_hash)
36
- merge!(other_hash) do |key, oldval, newval|
41
+ merge!(other_hash) do |_key, oldval, newval|
37
42
  oldval.class == self.class ? oldval.rmerge!(newval) : newval
38
43
  end
39
44
  end
@@ -51,12 +56,16 @@ module HashRecursiveMerge
51
56
  # includes the same key, the value is merged instead replaced with
52
57
  # +other_hash+ value.
53
58
  #
59
+ # @example
60
+ #
54
61
  # h1 = {"a" => 100, "b" => 200, "c" => {"c1" => 12, "c2" => 14}}
55
62
  # h2 = {"b" => 254, "c" => {"c1" => 16, "c3" => 94}}
56
63
  # h1.rmerge(h2) #=> {"a" => 100, "b" => 254, "c" => {"c1" => 16, "c2" => 14, "c3" => 94}}
57
64
  #
58
65
  # Simply using Hash#merge would return
59
66
  #
67
+ # @example
68
+ #
60
69
  # h1.merge(h2) #=> {"a" => 100, "b" = >254, "c" => {"c1" => 16, "c3" => 94}}
61
70
  #
62
71
  def rmerge(other_hash)
@@ -68,7 +77,6 @@ module HashRecursiveMerge
68
77
 
69
78
  end
70
79
 
71
-
72
80
  class Hash
73
81
  include HashRecursiveMerge
74
82
  end
@@ -0,0 +1,77 @@
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 "base64"
21
+ require "stringio"
22
+ require "securerandom"
23
+
24
+ require "kitchen/base64_stream"
25
+
26
+ describe Kitchen::Base64Stream do
27
+
28
+ SHORT_BODIES = %w[you test wakkawakkawakka]
29
+
30
+ describe ".strict_encode" do
31
+
32
+ SHORT_BODIES.each do |body|
33
+ it "encodes short payload ('#{body}') from input IO to output IO" do
34
+ output = StringIO.new("", "wb")
35
+ StringIO.open(body) do |input|
36
+ Kitchen::Base64Stream.strict_encode(input, output)
37
+ end
38
+
39
+ output.string.must_equal Base64.strict_encode64(body)
40
+ end
41
+ end
42
+
43
+ it "encodes a large payload from input IO to output IO" do
44
+ body = SecureRandom.random_bytes(1048576 * 8)
45
+ output = StringIO.new("", "wb")
46
+ StringIO.open(body) do |input|
47
+ Kitchen::Base64Stream.strict_encode(input, output)
48
+ end
49
+
50
+ output.string.must_equal Base64.strict_encode64(body)
51
+ end
52
+ end
53
+
54
+ describe ".strict_decode" do
55
+
56
+ SHORT_BODIES.map { |b| Base64.strict_encode64(b) }.each do |body|
57
+ it "decodes short payload ('#{body}') from input IO to output IO" do
58
+ output = StringIO.new("", "wb")
59
+ StringIO.open(body) do |input|
60
+ Kitchen::Base64Stream.strict_decode(input, output)
61
+ end
62
+
63
+ output.string.must_equal Base64.strict_decode64(body)
64
+ end
65
+ end
66
+
67
+ it "decodes a large payload from input IO to output IO" do
68
+ body = Base64.strict_encode64(SecureRandom.hex(1048576 * 8))
69
+ output = StringIO.new("", "wb")
70
+ StringIO.open(body) do |input|
71
+ Kitchen::Base64Stream.strict_decode(input, output)
72
+ end
73
+
74
+ output.string.must_equal Base64.strict_decode64(body)
75
+ end
76
+ end
77
+ end
@@ -0,0 +1,490 @@
1
+ # -*- encoding: utf-8 -*-
2
+ #
3
+ # Author:: Fletcher Nichol (<fnichol@nichol.ca>)
4
+ #
5
+ # Copyright (C) 2014, Fletcher Nichol
6
+ #
7
+ # Licensed under the Apache License, Version 2.0 (the "License");
8
+ # you may not use this file except in compliance with the License.
9
+ # You may obtain a copy of the License at
10
+ #
11
+ # http://www.apache.org/licenses/LICENSE-2.0
12
+ #
13
+ # Unless required by applicable law or agreed to in writing, software
14
+ # distributed under the License is distributed on an "AS IS" BASIS,
15
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
+ # See the License for the specific language governing permissions and
17
+ # limitations under the License.
18
+
19
+ require_relative "../spec_helper"
20
+
21
+ require "kitchen/busser"
22
+ # @TODO: this can be remove once Kitchen::DEFAULT_TEST_DIR is removed
23
+ require "kitchen"
24
+
25
+ describe Kitchen::Busser do
26
+
27
+ let(:suite_name) { "germany" }
28
+ let(:config) { Hash.new }
29
+
30
+ let(:busser) do
31
+ Kitchen::Busser.new(suite_name, config)
32
+ end
33
+
34
+ describe ".new" do
35
+
36
+ it "raises a ClientError if a suite name is not provided" do
37
+ proc {
38
+ Kitchen::Busser.new(nil, config)
39
+ }.must_raise Kitchen::ClientError
40
+ end
41
+
42
+ it "raises a UserError if the suite name is 'helper'" do
43
+ proc {
44
+ Kitchen::Busser.new("helper", config)
45
+ }.must_raise Kitchen::UserError
46
+ end
47
+ end
48
+
49
+ it "#name returns the name of the suite" do
50
+ busser.name.must_equal "germany"
51
+ end
52
+
53
+ it "#config_keys returns an array of config key names" do
54
+ busser.config_keys.sort.must_equal [
55
+ :busser_bin, :kitchen_root, :root_path, :ruby_bindir, :sudo,
56
+ :suite_name, :test_base_path, :version
57
+ ]
58
+ end
59
+
60
+ describe "configuration" do
61
+
62
+ it ":kitchen_root defaults to current directory" do
63
+ busser[:kitchen_root].must_equal Dir.pwd
64
+ end
65
+
66
+ it ":test_base_path defaults to an expanded path" do
67
+ busser[:test_base_path].must_equal File.join(Dir.pwd, "test/integration")
68
+ end
69
+
70
+ it ":suite_name defaults to the passed in suite name" do
71
+ busser[:suite_name].must_equal "germany"
72
+ end
73
+
74
+ it ":sudo defaults to true" do
75
+ busser[:sudo].must_equal true
76
+ end
77
+
78
+ it ":ruby_bindir defaults the an Omnibus Chef installation" do
79
+ busser[:ruby_bindir].must_equal "/opt/chef/embedded/bin"
80
+ end
81
+
82
+ it ":root_path defaults to '/tmp/busser'" do
83
+ busser[:root_path].must_equal "/tmp/busser"
84
+ end
85
+
86
+ it ":version defaults to 'busser'" do
87
+ busser[:version].must_equal "busser"
88
+ end
89
+
90
+ it ":busser_bin defaults to a binstub under :root_path" do
91
+ config[:root_path] = "/beep"
92
+
93
+ busser[:busser_bin].must_equal "/beep/bin/busser"
94
+ end
95
+ end
96
+
97
+ describe "#diagnose" do
98
+
99
+ it "returns a hash with sorted keys" do
100
+ busser.diagnose.keys.must_equal [
101
+ :busser_bin, :kitchen_root, :root_path, :ruby_bindir, :sudo,
102
+ :suite_name, :test_base_path, :version
103
+ ]
104
+ end
105
+ end
106
+
107
+ describe "#setup_cmd" do
108
+
109
+ before do
110
+ @root = Dir.mktmpdir
111
+ config[:test_base_path] = @root
112
+ end
113
+
114
+ after do
115
+ FileUtils.remove_entry(@root)
116
+ end
117
+
118
+ let(:cmd) { busser.setup_cmd }
119
+
120
+ describe "with no suite test files" do
121
+
122
+ it "returns nil" do
123
+ cmd.must_equal nil
124
+ end
125
+ end
126
+
127
+ describe "with suite test files" do
128
+
129
+ before do
130
+ base = "#{config[:test_base_path]}/germany"
131
+
132
+ FileUtils.mkdir_p "#{base}/mondospec"
133
+ File.open("#{base}/mondospec/charlie", "wb") { |f| f.write("charlie") }
134
+ FileUtils.mkdir_p "#{base}/minispec"
135
+ File.open("#{base}/minispec/beta", "wb") { |f| f.write("beta") }
136
+ FileUtils.mkdir_p "#{base}/abba"
137
+ File.open("#{base}/abba/alpha", "wb") { |f| f.write("alpha") }
138
+
139
+ config[:ruby_bindir] = "/r"
140
+ end
141
+
142
+ it "uses bourne shell" do
143
+ cmd.must_match(/\Ash -c '$/)
144
+ cmd.must_match(/'\Z/)
145
+ end
146
+
147
+ it "sets the BUSSER_ROOT environment variable" do
148
+ config[:root_path] = "/r"
149
+
150
+ cmd.must_match regexify(%{BUSSER_ROOT="/r"}, :partial_line)
151
+ end
152
+
153
+ it "sets the GEM_HOME environment variable" do
154
+ config[:root_path] = "/r"
155
+
156
+ cmd.must_match regexify(%{GEM_HOME="/r/gems" }, :partial_line)
157
+ end
158
+
159
+ it "sets the GEM_PATH environment variable" do
160
+ config[:root_path] = "/r"
161
+
162
+ cmd.must_match regexify(%{GEM_PATH="/r/gems" }, :partial_line)
163
+ end
164
+
165
+ it "sets the GEM_CACHE environment variable" do
166
+ config[:root_path] = "/r"
167
+
168
+ cmd.must_match regexify(%{GEM_CACHE="/r/gems/cache" }, :partial_line)
169
+ end
170
+
171
+ it "exports all the environment variables" do
172
+ cmd.must_match regexify(
173
+ "export BUSSER_ROOT GEM_HOME GEM_PATH GEM_CACHE", :partial_line)
174
+ end
175
+
176
+ it "checks if busser is installed" do
177
+ cmd.must_match regexify(
178
+ %{if ! sudo -E /r/gem list busser -i >/dev/null;}, :partial_line)
179
+ end
180
+
181
+ describe "installing busser" do
182
+
183
+ it "installs the latest busser gem by default" do
184
+ cmd.must_match regexify(
185
+ %{sudo -E /r/gem install busser --no-rdoc --no-ri}, :partial_line)
186
+ end
187
+
188
+ it "installs a specific busser version gem" do
189
+ config[:version] = "4.0.7"
190
+
191
+ cmd.must_match regexify(
192
+ %{sudo -E /r/gem install busser --version 4.0.7 --no-rdoc --no-ri},
193
+ :partial_line)
194
+ end
195
+
196
+ it "installs a specific busser version gem with @ syntax" do
197
+ config[:version] = "busser@1.2.3"
198
+
199
+ cmd.must_match regexify(
200
+ %{sudo -E /r/gem install busser --version 1.2.3 --no-rdoc --no-ri},
201
+ :partial_line)
202
+ end
203
+
204
+ it "installs an arbitrary gem and version with @ syntax" do
205
+ config[:version] = "foo@9.0.1"
206
+
207
+ cmd.must_match regexify(
208
+ %{sudo -E /r/gem install foo --version 9.0.1 --no-rdoc --no-ri},
209
+ :partial_line)
210
+ end
211
+ end
212
+
213
+ it "calculates RubyGem's bindir" do
214
+ cmd.must_match regexify(
215
+ %{gem_bindir=`/r/ruby -rrubygems -e "puts Gem.bindir"`},
216
+ :partial_line)
217
+ end
218
+
219
+ it "runs busser setup from the installed gem_bindir binstub" do
220
+ cmd.must_match regexify(
221
+ %{sudo -E ${gem_bindir}/busser setup}, :partial_line)
222
+ end
223
+
224
+ it "runs busser plugin install with the :busser_bindir command" do
225
+ config[:busser_bin] = "/b/b"
226
+
227
+ cmd.must_match regexify(
228
+ %{sudo -E /b/b plugin install } +
229
+ %{busser-abba busser-minispec busser-mondospec},
230
+ :partial_line)
231
+ end
232
+ end
233
+ end
234
+
235
+ describe "#sync_cmd" do
236
+
237
+ before do
238
+ @root = Dir.mktmpdir
239
+ config[:test_base_path] = @root
240
+ end
241
+
242
+ after do
243
+ FileUtils.remove_entry(@root)
244
+ end
245
+
246
+ let(:cmd) { busser.sync_cmd }
247
+
248
+ describe "with no suite test files" do
249
+
250
+ it "returns nil" do
251
+ cmd.must_equal nil
252
+ end
253
+ end
254
+
255
+ describe "with suite test files" do
256
+
257
+ before do
258
+ base = "#{config[:test_base_path]}/germany"
259
+ hbase = "#{config[:test_base_path]}/helpers"
260
+
261
+ files.map { |f, md| [File.join(base, f), md] }.each do |f, md|
262
+ create_file(f, md[:content], md[:perms])
263
+ end
264
+ helper_files.map { |f, md| [File.join(hbase, f), md] }.each do |f, md|
265
+ create_file(f, md[:content], md[:perms])
266
+ end
267
+
268
+ config[:ruby_bindir] = "/r"
269
+ end
270
+
271
+ let(:files) do
272
+ {
273
+ "mondospec/charlie" => {
274
+ :content => "charlie",
275
+ :perms => "0764",
276
+ :base64 => "Y2hhcmxpZQ==",
277
+ :md5 => "bf779e0933a882808585d19455cd7937"
278
+ },
279
+ "minispec/beta" => {
280
+ :content => "beta",
281
+ :perms => "0644",
282
+ :base64 => "YmV0YQ==",
283
+ :md5 => "987bcab01b929eb2c07877b224215c92"
284
+ },
285
+ "abba/alpha" => {
286
+ :content => "alpha",
287
+ :perms => "0440",
288
+ :base64 => "YWxwaGE=",
289
+ :md5 => "2c1743a391305fbf367df8e4f069f9f9"
290
+ }
291
+ }
292
+ end
293
+
294
+ let(:helper_files) do
295
+ {
296
+ "minispec/spec_helper" => {
297
+ :content => "helping",
298
+ :perms => "0644",
299
+ :base64 => "aGVscGluZw==",
300
+ :md5 => "111c081293c11cb7c2ac6fbf841805cb"
301
+ },
302
+ "abba/common" => {
303
+ :content => "yeppers",
304
+ :perms => "0664",
305
+ :base64 => "eWVwcGVycw==",
306
+ :md5 => "7c3157de4890b1abcb7a6a3695eb6dd2"
307
+ }
308
+ }
309
+ end
310
+
311
+ it "uses bourne shell" do
312
+ cmd.must_match(/\Ash -c '$/)
313
+ cmd.must_match(/'\Z/)
314
+ end
315
+
316
+ it "sets the BUSSER_ROOT environment variable" do
317
+ config[:root_path] = "/r"
318
+
319
+ cmd.must_match regexify(%{BUSSER_ROOT="/r"}, :partial_line)
320
+ end
321
+
322
+ it "sets the GEM_HOME environment variable" do
323
+ config[:root_path] = "/r"
324
+
325
+ cmd.must_match regexify(%{GEM_HOME="/r/gems" }, :partial_line)
326
+ end
327
+
328
+ it "sets the GEM_PATH environment variable" do
329
+ config[:root_path] = "/r"
330
+
331
+ cmd.must_match regexify(%{GEM_PATH="/r/gems" }, :partial_line)
332
+ end
333
+
334
+ it "sets the GEM_CACHE environment variable" do
335
+ config[:root_path] = "/r"
336
+
337
+ cmd.must_match regexify(%{GEM_CACHE="/r/gems/cache" }, :partial_line)
338
+ end
339
+
340
+ it "exports all the environment variables" do
341
+ cmd.must_match regexify(
342
+ "export BUSSER_ROOT GEM_HOME GEM_PATH GEM_CACHE", :partial_line)
343
+ end
344
+
345
+ it "logs a message for each file" do
346
+ config[:busser_bin] = "/b/busser"
347
+
348
+ files.each do |f, md|
349
+ cmd.must_match regexify([
350
+ %{echo "Uploading `sudo -E /b/busser suite path`/#{f}},
351
+ %{(mode=#{md[:perms]})"}
352
+ ].join(" "))
353
+ end
354
+ end
355
+
356
+ it "logs a message for each helper file" do
357
+ config[:busser_bin] = "/b/busser"
358
+
359
+ helper_files.each do |f, md|
360
+ cmd.must_match regexify([
361
+ %{echo "Uploading `sudo -E /b/busser suite path`/#{f}},
362
+ %{(mode=#{md[:perms]})"}
363
+ ].join(" "))
364
+ end
365
+ end
366
+
367
+ it "base64 encodes each file for deserializing with busser" do
368
+ config[:busser_bin] = "/b/busser"
369
+
370
+ files.each do |f, md|
371
+ cmd.must_match regexify([
372
+ %{echo "#{md[:base64]}" | sudo -E /b/busser deserialize},
373
+ %{--destination=`sudo -E /b/busser suite path`/#{f}},
374
+ %{--md5sum=#{md[:md5]} --perms=#{md[:perms]}}
375
+ ].join(" "))
376
+ end
377
+ end
378
+
379
+ it "base64 encodes each helper file for deserializing with busser" do
380
+ config[:busser_bin] = "/b/busser"
381
+
382
+ helper_files.each do |f, md|
383
+ cmd.must_match regexify([
384
+ %{echo "#{md[:base64]}" | sudo -E /b/busser deserialize},
385
+ %{--destination=`sudo -E /b/busser suite path`/#{f}},
386
+ %{--md5sum=#{md[:md5]} --perms=#{md[:perms]}}
387
+ ].join(" "))
388
+ end
389
+ end
390
+
391
+ def create_file(file, content, perms)
392
+ FileUtils.mkdir_p(File.dirname(file))
393
+ File.open(file, "wb") { |f| f.write(content) }
394
+ FileUtils.chmod(perms.to_i(8), file)
395
+ end
396
+ end
397
+ end
398
+
399
+ describe "#run_cmd" do
400
+
401
+ before do
402
+ @root = Dir.mktmpdir
403
+ config[:test_base_path] = @root
404
+ end
405
+
406
+ after do
407
+ FileUtils.remove_entry(@root)
408
+ end
409
+
410
+ let(:cmd) { busser.run_cmd }
411
+
412
+ describe "with no suite test files" do
413
+
414
+ it "returns nil" do
415
+ cmd.must_equal nil
416
+ end
417
+ end
418
+
419
+ describe "with suite test files" do
420
+
421
+ before do
422
+ base = "#{config[:test_base_path]}/germany"
423
+
424
+ FileUtils.mkdir_p "#{base}/mondospec"
425
+ File.open("#{base}/mondospec/charlie", "wb") { |f| f.write("charlie") }
426
+ FileUtils.mkdir_p "#{base}/minispec"
427
+ File.open("#{base}/minispec/beta", "wb") { |f| f.write("beta") }
428
+ FileUtils.mkdir_p "#{base}/abba"
429
+ File.open("#{base}/abba/alpha", "wb") { |f| f.write("alpha") }
430
+
431
+ config[:ruby_bindir] = "/r"
432
+ end
433
+
434
+ it "uses bourne shell" do
435
+ cmd.must_match(/\Ash -c '$/)
436
+ cmd.must_match(/'\Z/)
437
+ end
438
+
439
+ it "sets the BUSSER_ROOT environment variable" do
440
+ config[:root_path] = "/r"
441
+
442
+ cmd.must_match regexify(%{BUSSER_ROOT="/r"}, :partial_line)
443
+ end
444
+
445
+ it "sets the GEM_HOME environment variable" do
446
+ config[:root_path] = "/r"
447
+
448
+ cmd.must_match regexify(%{GEM_HOME="/r/gems" }, :partial_line)
449
+ end
450
+
451
+ it "sets the GEM_PATH environment variable" do
452
+ config[:root_path] = "/r"
453
+
454
+ cmd.must_match regexify(%{GEM_PATH="/r/gems" }, :partial_line)
455
+ end
456
+
457
+ it "sets the GEM_CACHE environment variable" do
458
+ config[:root_path] = "/r"
459
+
460
+ cmd.must_match regexify(%{GEM_CACHE="/r/gems/cache" }, :partial_line)
461
+ end
462
+
463
+ it "exports all the environment variables" do
464
+ cmd.must_match regexify(
465
+ "export BUSSER_ROOT GEM_HOME GEM_PATH GEM_CACHE", :partial_line)
466
+ end
467
+
468
+ it "uses sudo for busser test when configured" do
469
+ config[:sudo] = true
470
+ config[:busser_bin] = "/p/b"
471
+
472
+ cmd.must_match regexify("sudo -E /p/b test", :partial_line)
473
+ end
474
+
475
+ it "does not use sudo for busser test when configured" do
476
+ config[:sudo] = false
477
+ config[:busser_bin] = "/p/b"
478
+
479
+ cmd.must_match regexify("/p/b test", :partial_line)
480
+ cmd.wont_match regexify("sudo -E /p/b test", :partial_line)
481
+ end
482
+ end
483
+ end
484
+
485
+ def regexify(str, line = :whole_line)
486
+ r = Regexp.escape(str)
487
+ r = "^\s*#{r}$" if line == :whole_line
488
+ Regexp.new(r)
489
+ end
490
+ end