test-kitchen 1.2.1 → 1.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (114) hide show
  1. checksums.yaml +4 -4
  2. data/.cane +1 -1
  3. data/.rubocop.yml +3 -0
  4. data/.travis.yml +20 -9
  5. data/CHANGELOG.md +219 -108
  6. data/Gemfile +10 -6
  7. data/Guardfile +38 -9
  8. data/README.md +11 -1
  9. data/Rakefile +21 -37
  10. data/bin/kitchen +4 -4
  11. data/features/kitchen_action_commands.feature +161 -0
  12. data/features/kitchen_console_command.feature +34 -0
  13. data/features/kitchen_diagnose_command.feature +64 -0
  14. data/features/kitchen_init_command.feature +29 -17
  15. data/features/kitchen_list_command.feature +2 -2
  16. data/features/kitchen_login_command.feature +56 -0
  17. data/features/{sink_command.feature → kitchen_sink_command.feature} +0 -0
  18. data/features/kitchen_test_command.feature +88 -0
  19. data/features/step_definitions/gem_steps.rb +8 -6
  20. data/features/step_definitions/git_steps.rb +4 -2
  21. data/features/step_definitions/output_steps.rb +5 -0
  22. data/features/support/env.rb +12 -9
  23. data/lib/kitchen.rb +60 -38
  24. data/lib/kitchen/base64_stream.rb +55 -0
  25. data/lib/kitchen/busser.rb +124 -58
  26. data/lib/kitchen/cli.rb +121 -38
  27. data/lib/kitchen/collection.rb +3 -3
  28. data/lib/kitchen/color.rb +4 -4
  29. data/lib/kitchen/command.rb +78 -11
  30. data/lib/kitchen/command/action.rb +3 -2
  31. data/lib/kitchen/command/console.rb +12 -5
  32. data/lib/kitchen/command/diagnose.rb +17 -3
  33. data/lib/kitchen/command/driver_discover.rb +26 -7
  34. data/lib/kitchen/command/exec.rb +41 -0
  35. data/lib/kitchen/command/list.rb +44 -14
  36. data/lib/kitchen/command/login.rb +2 -1
  37. data/lib/kitchen/command/sink.rb +2 -1
  38. data/lib/kitchen/command/test.rb +5 -4
  39. data/lib/kitchen/config.rb +146 -14
  40. data/lib/kitchen/configurable.rb +314 -0
  41. data/lib/kitchen/data_munger.rb +522 -18
  42. data/lib/kitchen/diagnostic.rb +43 -4
  43. data/lib/kitchen/driver.rb +4 -4
  44. data/lib/kitchen/driver/base.rb +80 -115
  45. data/lib/kitchen/driver/dummy.rb +34 -6
  46. data/lib/kitchen/driver/proxy.rb +14 -3
  47. data/lib/kitchen/driver/ssh_base.rb +61 -7
  48. data/lib/kitchen/errors.rb +109 -9
  49. data/lib/kitchen/generator/driver_create.rb +39 -5
  50. data/lib/kitchen/generator/init.rb +130 -45
  51. data/lib/kitchen/instance.rb +162 -28
  52. data/lib/kitchen/lazy_hash.rb +79 -7
  53. data/lib/kitchen/loader/yaml.rb +159 -27
  54. data/lib/kitchen/logger.rb +267 -21
  55. data/lib/kitchen/logging.rb +30 -3
  56. data/lib/kitchen/login_command.rb +11 -2
  57. data/lib/kitchen/metadata_chopper.rb +2 -2
  58. data/lib/kitchen/provisioner.rb +4 -4
  59. data/lib/kitchen/provisioner/base.rb +107 -103
  60. data/lib/kitchen/provisioner/chef/berkshelf.rb +36 -8
  61. data/lib/kitchen/provisioner/chef/librarian.rb +40 -11
  62. data/lib/kitchen/provisioner/chef_base.rb +206 -167
  63. data/lib/kitchen/provisioner/chef_solo.rb +25 -7
  64. data/lib/kitchen/provisioner/chef_zero.rb +105 -29
  65. data/lib/kitchen/provisioner/dummy.rb +1 -1
  66. data/lib/kitchen/provisioner/shell.rb +21 -6
  67. data/lib/kitchen/rake_tasks.rb +8 -3
  68. data/lib/kitchen/shell_out.rb +15 -18
  69. data/lib/kitchen/ssh.rb +122 -27
  70. data/lib/kitchen/state_file.rb +24 -7
  71. data/lib/kitchen/thor_tasks.rb +9 -4
  72. data/lib/kitchen/util.rb +43 -118
  73. data/lib/kitchen/version.rb +1 -1
  74. data/lib/vendor/hash_recursive_merge.rb +10 -2
  75. data/spec/kitchen/base64_stream_spec.rb +77 -0
  76. data/spec/kitchen/busser_spec.rb +490 -0
  77. data/spec/kitchen/collection_spec.rb +10 -10
  78. data/spec/kitchen/color_spec.rb +2 -2
  79. data/spec/kitchen/config_spec.rb +234 -62
  80. data/spec/kitchen/configurable_spec.rb +490 -0
  81. data/spec/kitchen/data_munger_spec.rb +1070 -862
  82. data/spec/kitchen/diagnostic_spec.rb +79 -0
  83. data/spec/kitchen/driver/base_spec.rb +80 -85
  84. data/spec/kitchen/driver/dummy_spec.rb +43 -14
  85. data/spec/kitchen/driver/proxy_spec.rb +134 -0
  86. data/spec/kitchen/driver/ssh_base_spec.rb +644 -0
  87. data/spec/kitchen/driver_spec.rb +15 -15
  88. data/spec/kitchen/errors_spec.rb +309 -0
  89. data/spec/kitchen/instance_spec.rb +143 -46
  90. data/spec/kitchen/lazy_hash_spec.rb +36 -9
  91. data/spec/kitchen/loader/yaml_spec.rb +237 -226
  92. data/spec/kitchen/logger_spec.rb +419 -0
  93. data/spec/kitchen/logging_spec.rb +59 -0
  94. data/spec/kitchen/login_command_spec.rb +49 -0
  95. data/spec/kitchen/metadata_chopper_spec.rb +82 -0
  96. data/spec/kitchen/platform_spec.rb +4 -4
  97. data/spec/kitchen/provisioner/base_spec.rb +65 -125
  98. data/spec/kitchen/provisioner/chef_base_spec.rb +798 -0
  99. data/spec/kitchen/provisioner/chef_solo_spec.rb +316 -0
  100. data/spec/kitchen/provisioner/chef_zero_spec.rb +624 -0
  101. data/spec/kitchen/provisioner/shell_spec.rb +269 -0
  102. data/spec/kitchen/provisioner_spec.rb +6 -6
  103. data/spec/kitchen/shell_out_spec.rb +143 -0
  104. data/spec/kitchen/ssh_spec.rb +683 -0
  105. data/spec/kitchen/state_file_spec.rb +28 -21
  106. data/spec/kitchen/suite_spec.rb +7 -7
  107. data/spec/kitchen/util_spec.rb +68 -10
  108. data/spec/kitchen_spec.rb +107 -0
  109. data/spec/spec_helper.rb +18 -13
  110. data/support/chef-client-zero.rb +10 -9
  111. data/support/chef_helpers.sh +16 -0
  112. data/support/download_helpers.sh +109 -0
  113. data/test-kitchen.gemspec +42 -33
  114. metadata +107 -33
@@ -16,13 +16,13 @@
16
16
  # See the License for the specific language governing permissions and
17
17
  # limitations under the License.
18
18
 
19
- require_relative '../spec_helper'
19
+ require_relative "../spec_helper"
20
20
 
21
- require 'kitchen/errors'
22
- require 'kitchen/logging'
23
- require 'kitchen/shell_out'
24
- require 'kitchen/driver'
25
- require 'kitchen/driver/base'
21
+ require "kitchen/errors"
22
+ require "kitchen/logging"
23
+ require "kitchen/shell_out"
24
+ require "kitchen/driver"
25
+ require "kitchen/driver/base"
26
26
 
27
27
  module Kitchen
28
28
 
@@ -63,28 +63,28 @@ describe Kitchen::Driver do
63
63
  end
64
64
 
65
65
  it "returns a driver object of the correct class" do
66
- driver = Kitchen::Driver.for_plugin('coolbeans', {})
66
+ driver = Kitchen::Driver.for_plugin("coolbeans", {})
67
67
 
68
68
  driver.must_be_kind_of Kitchen::Driver::Coolbeans
69
69
  end
70
70
 
71
71
  it "returns a driver initialized with its config" do
72
- driver = Kitchen::Driver.for_plugin('coolbeans', { :jelly => 'beans' })
72
+ driver = Kitchen::Driver.for_plugin("coolbeans", :jelly => "beans")
73
73
 
74
- driver[:jelly].must_equal 'beans'
74
+ driver[:jelly].must_equal "beans"
75
75
  end
76
76
 
77
77
  it "calls #verify_dependencies on the driver object" do
78
- driver = Kitchen::Driver.for_plugin('it_depends', {})
78
+ driver = Kitchen::Driver.for_plugin("it_depends", {})
79
79
 
80
80
  driver.verify_call_count.must_equal 1
81
81
  end
82
82
 
83
83
  it "calls #verify_dependencies once per driver require" do
84
84
  Kitchen::Driver.stubs(:require).returns(true, false)
85
- driver1 = Kitchen::Driver.for_plugin('it_depends', {})
85
+ driver1 = Kitchen::Driver.for_plugin("it_depends", {})
86
86
  driver1.verify_call_count.must_equal 1
87
- driver2 = Kitchen::Driver.for_plugin('it_depends', {})
87
+ driver2 = Kitchen::Driver.for_plugin("it_depends", {})
88
88
 
89
89
  driver2.verify_call_count.must_equal 0
90
90
  end
@@ -92,19 +92,19 @@ describe Kitchen::Driver do
92
92
  it "raises ClientError if the driver could not be required" do
93
93
  Kitchen::Driver.stubs(:require).raises(LoadError)
94
94
 
95
- proc { Kitchen::Driver.for_plugin('coolbeans', {}) }.
95
+ proc { Kitchen::Driver.for_plugin("coolbeans", {}) }.
96
96
  must_raise Kitchen::ClientError
97
97
  end
98
98
 
99
99
  it "raises ClientError if the driver's class constant could not be found" do
100
100
  Kitchen::Driver.stubs(:require).returns(true) # pretend require worked
101
101
 
102
- proc { Kitchen::Driver.for_plugin('nope', {}) }.
102
+ proc { Kitchen::Driver.for_plugin("nope", {}) }.
103
103
  must_raise Kitchen::ClientError
104
104
  end
105
105
 
106
106
  it "raises UserError if #verify_dependencies fails" do
107
- proc { Kitchen::Driver.for_plugin('unstable_depends', {}) }.
107
+ proc { Kitchen::Driver.for_plugin("unstable_depends", {}) }.
108
108
  must_raise Kitchen::UserError
109
109
  end
110
110
  end
@@ -0,0 +1,309 @@
1
+ # -*- encoding: utf-8 -*-
2
+ #
3
+ # Author:: Fletcher Nichol (<fnichol@nichol.ca>)
4
+ #
5
+ # Copyright (C) 2014, Fletcher Nichol
6
+ #
7
+ # Licensed under the Apache License, Version 2.0 (the "License");
8
+ # you may not use this file except in compliance with the License.
9
+ # You may obtain a copy of the License at
10
+ #
11
+ # http://www.apache.org/licenses/LICENSE-2.0
12
+ #
13
+ # Unless required by applicable law or agreed to in writing, software
14
+ # distributed under the License is distributed on an "AS IS" BASIS,
15
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
+ # See the License for the specific language governing permissions and
17
+ # limitations under the License.
18
+
19
+ require_relative "../spec_helper"
20
+
21
+ require "kitchen"
22
+ require "kitchen/errors"
23
+
24
+ describe Kitchen::Error do
25
+
26
+ let(:exception) { Kitchen::StandardError.new("shoot") }
27
+
28
+ describe ".formatted_exception" do
29
+
30
+ it "returns an array of a formatted message" do
31
+ Kitchen::Error.formatted_exception(exception).must_equal([
32
+ "------Exception-------",
33
+ "Class: Kitchen::StandardError",
34
+ "Message: shoot",
35
+ "----------------------"
36
+ ])
37
+ end
38
+
39
+ it "takes a customized title" do
40
+ Kitchen::Error.formatted_exception(exception, "Trouble").first.
41
+ must_equal("-------Trouble--------")
42
+ end
43
+ end
44
+
45
+ describe ".formatted_exception" do
46
+
47
+ it "returns an array of a formatted message with a nil backtrace" do
48
+ Kitchen::Error.formatted_trace(exception).must_equal([
49
+ "------Exception-------",
50
+ "Class: Kitchen::StandardError",
51
+ "Message: shoot",
52
+ "------Backtrace-------",
53
+ nil,
54
+ "----------------------"
55
+ ])
56
+ end
57
+
58
+ it "returns an array containing the exception's backtrace" do
59
+ begin
60
+ raise Kitchen::StandardError, "shoot"
61
+ rescue => e
62
+ Kitchen::Error.formatted_trace(e)[4...-1].must_equal e.backtrace
63
+ end
64
+ end
65
+
66
+ it "returns an array containing a nested exception, if given" do
67
+ begin
68
+ raise IOError, "no disk, yo"
69
+ rescue
70
+ e = Kitchen::StandardError.new("shoot")
71
+
72
+ Kitchen::Error.formatted_trace(e).must_equal([
73
+ "------Exception-------",
74
+ "Class: Kitchen::StandardError",
75
+ "Message: shoot",
76
+ "---Nested Exception---",
77
+ "Class: IOError",
78
+ "Message: no disk, yo",
79
+ "------Backtrace-------",
80
+ nil,
81
+ "----------------------"
82
+ ])
83
+ end
84
+ end
85
+ end
86
+ end
87
+
88
+ describe Kitchen::StandardError do
89
+
90
+ it "is a kind of Kitchen::Error" do
91
+ Kitchen::StandardError.new("oops").must_be_kind_of Kitchen::Error
92
+ end
93
+
94
+ it "by default, sets original exception to the last raised exception" do
95
+ begin
96
+ raise IOError, "crap"
97
+ rescue
98
+ original = Kitchen::StandardError.new("oops").original
99
+ original.must_be_kind_of IOError
100
+ original.message.must_equal "crap"
101
+ end
102
+ end
103
+
104
+ it "can embed an exception when constructing" do
105
+ original = Kitchen::StandardError.new("durn", IOError.new("ack")).original
106
+ original.must_be_kind_of IOError
107
+ original.message.must_equal "ack"
108
+ end
109
+ end
110
+
111
+ [
112
+ Kitchen::UserError, Kitchen::ClientError, Kitchen::TransientFailure
113
+ ].each do |klass|
114
+ describe klass do
115
+
116
+ it "is a kind of Kitchen::StandardError" do
117
+ klass.new("oops").must_be_kind_of Kitchen::StandardError
118
+ end
119
+ end
120
+ end
121
+
122
+ [
123
+ Kitchen::ActionFailed, Kitchen::InstanceFailure
124
+ ].each do |klass|
125
+ describe klass do
126
+
127
+ it "is a kind of Kitchen::TransientFailure" do
128
+ klass.new("oops").must_be_kind_of Kitchen::TransientFailure
129
+ end
130
+ end
131
+ end
132
+
133
+ describe Kitchen do
134
+
135
+ describe ".with_friendly_errors" do
136
+
137
+ let(:logger_io) { StringIO.new }
138
+ let(:logger) { Kitchen::Logger.new(:logdev => logger_io) }
139
+
140
+ before do
141
+ Kitchen.stubs(:tty?).returns(true)
142
+ @orig_stderr = $stderr
143
+ $stderr = StringIO.new
144
+ @orig_logger = Kitchen.logger
145
+ Kitchen.logger = logger
146
+ end
147
+
148
+ after do
149
+ $stderr = @orig_stderr
150
+ Kitchen.logger = @orig_logger
151
+ end
152
+
153
+ describe "for instance failures" do
154
+
155
+ def go_boom
156
+ Kitchen.with_friendly_errors do
157
+ begin
158
+ raise IOError, "no stuff"
159
+ rescue
160
+ raise Kitchen::InstanceFailure, "cannot do that"
161
+ end
162
+ end
163
+ end
164
+
165
+ it "exits with 10" do
166
+ begin
167
+ go_boom
168
+ rescue SystemExit => e
169
+ e.status.must_equal 10
170
+ end
171
+ end
172
+
173
+ it "prints a message on STDERR" do
174
+ output = [
175
+ ">>>>>> cannot do that",
176
+ ">>>>>> ------Exception-------",
177
+ ">>>>>> Class: IOError",
178
+ ">>>>>> Message: no stuff",
179
+ ">>>>>> ----------------------"
180
+ ].map { |l| Kitchen::Color.colorize(l, :red) }.join("\n").concat("\n")
181
+
182
+ begin
183
+ go_boom
184
+ rescue SystemExit
185
+ $stderr.string.must_equal output
186
+ end
187
+ end
188
+
189
+ it "prints a message on STDERR without color" do
190
+ Kitchen.stubs(:tty?).returns(false)
191
+ output = [
192
+ ">>>>>> cannot do that",
193
+ ">>>>>> ------Exception-------",
194
+ ">>>>>> Class: IOError",
195
+ ">>>>>> Message: no stuff",
196
+ ">>>>>> ----------------------"
197
+ ].join("\n").concat("\n")
198
+
199
+ begin
200
+ go_boom
201
+ rescue SystemExit
202
+ $stderr.string.must_equal output
203
+ end
204
+ end
205
+
206
+ it "logs the exception message on the common logger's error severity" do
207
+ begin
208
+ go_boom
209
+ rescue SystemExit
210
+ logger_io.string.must_match(/ERROR -- Kitchen: cannot do that$/)
211
+ end
212
+ end
213
+
214
+ it "logs the exception message on debug, if set" do
215
+ logger.level = ::Logger::DEBUG
216
+
217
+ begin
218
+ go_boom
219
+ rescue SystemExit
220
+ logger_io.string.must_match(/DEBUG -- Kitchen: cannot do that$/)
221
+ end
222
+ end
223
+ end
224
+
225
+ describe "for unexpected failures" do
226
+
227
+ def go_boom
228
+ Kitchen.with_friendly_errors do
229
+ begin
230
+ raise IOError, "wtf?"
231
+ rescue
232
+ raise Kitchen::StandardError, "ah crap"
233
+ end
234
+ end
235
+ end
236
+
237
+ it "exits with 20" do
238
+ begin
239
+ go_boom
240
+ rescue SystemExit => e
241
+ e.status.must_equal 20
242
+ end
243
+ end
244
+
245
+ it "prints a message on STDERR" do
246
+ output = [
247
+ ">>>>>> ------Exception-------",
248
+ ">>>>>> Class: Kitchen::StandardError",
249
+ ">>>>>> Message: ah crap",
250
+ ">>>>>> ----------------------",
251
+ ">>>>>> Please see .kitchen/logs/kitchen.log for more details",
252
+ ">>>>>> Also try running `kitchen diagnose --all` for configuration\n"
253
+ ].map { |l| Kitchen::Color.colorize(l, :red) }.join("\n").concat("\n")
254
+
255
+ begin
256
+ go_boom
257
+ rescue SystemExit
258
+ $stderr.string.must_equal output
259
+ end
260
+ end
261
+
262
+ it "prints a message on STDERR without color" do
263
+ Kitchen.stubs(:tty?).returns(false)
264
+ output = [
265
+ ">>>>>> ------Exception-------",
266
+ ">>>>>> Class: Kitchen::StandardError",
267
+ ">>>>>> Message: ah crap",
268
+ ">>>>>> ----------------------",
269
+ ">>>>>> Please see .kitchen/logs/kitchen.log for more details",
270
+ ">>>>>> Also try running `kitchen diagnose --all` for configuration"
271
+ ].join("\n").concat("\n")
272
+
273
+ begin
274
+ go_boom
275
+ rescue SystemExit
276
+ $stderr.string.must_equal output
277
+ end
278
+ end
279
+
280
+ it "logs the exception message on the common logger's error severity" do
281
+ begin
282
+ go_boom
283
+ rescue SystemExit
284
+ logger_io.string.
285
+ must_match(/ERROR -- Kitchen: ------Exception-------$/)
286
+ logger_io.string.
287
+ must_match(/ERROR -- Kitchen: Class: Kitchen::StandardError$/)
288
+ logger_io.string.
289
+ must_match(/ERROR -- Kitchen: ------Backtrace-------$/)
290
+ end
291
+ end
292
+
293
+ it "logs the exception message on debug, if set" do
294
+ logger.level = ::Logger::DEBUG
295
+
296
+ begin
297
+ go_boom
298
+ rescue SystemExit
299
+ logger_io.string.
300
+ must_match(/DEBUG -- Kitchen: ------Exception-------$/)
301
+ logger_io.string.
302
+ must_match(/DEBUG -- Kitchen: Class: Kitchen::StandardError$/)
303
+ logger_io.string.
304
+ must_match(/DEBUG -- Kitchen: ------Backtrace-------$/)
305
+ end
306
+ end
307
+ end
308
+ end
309
+ end
@@ -16,21 +16,21 @@
16
16
  # See the License for the specific language governing permissions and
17
17
  # limitations under the License.
18
18
 
19
- require_relative '../spec_helper'
20
- require 'stringio'
21
-
22
- require 'kitchen/logging'
23
- require 'kitchen/instance'
24
- require 'kitchen/driver'
25
- require 'kitchen/driver/dummy'
26
- require 'kitchen/platform'
27
- require 'kitchen/provisioner'
28
- require 'kitchen/provisioner/dummy'
29
- require 'kitchen/suite'
19
+ require_relative "../spec_helper"
20
+ require "stringio"
21
+
22
+ require "kitchen/logging"
23
+ require "kitchen/instance"
24
+ require "kitchen/driver"
25
+ require "kitchen/driver/dummy"
26
+ require "kitchen/platform"
27
+ require "kitchen/provisioner"
28
+ require "kitchen/provisioner/dummy"
29
+ require "kitchen/suite"
30
30
 
31
31
  class DummyStateFile
32
32
 
33
- def initialize(*args) ; end
33
+ def initialize(*); end
34
34
 
35
35
  def read
36
36
  @_state = Hash.new unless @_state
@@ -44,6 +44,10 @@ class DummyStateFile
44
44
  def destroy
45
45
  @_state = nil
46
46
  end
47
+
48
+ def diagnose
49
+ Hash.new
50
+ end
47
51
  end
48
52
 
49
53
  class SerialDummyDriver < Kitchen::Driver::Dummy
@@ -100,11 +104,11 @@ describe Kitchen::Instance do
100
104
  end
101
105
 
102
106
  def suite(name = "suite")
103
- @suite ||= Kitchen::Suite.new({ :name => name })
107
+ @suite ||= Kitchen::Suite.new(:name => name)
104
108
  end
105
109
 
106
110
  def platform(name = "platform")
107
- @platform ||= Kitchen::Platform.new({ :name => name })
111
+ @platform ||= Kitchen::Platform.new(:name => name)
108
112
  end
109
113
 
110
114
  describe ".name_for" do
@@ -143,6 +147,21 @@ describe Kitchen::Instance do
143
147
  Kitchen::Instance.name_for(suite("_s__s_"), platform("pp_")).
144
148
  must_equal "-s--s--pp-"
145
149
  end
150
+
151
+ it "transforms forward slashes to dashes in suite name" do
152
+ Kitchen::Instance.name_for(suite("suite/ness"), platform("platform")).
153
+ must_equal "suite-ness-platform"
154
+ end
155
+
156
+ it "transforms forward slashes to dashes in platform name" do
157
+ Kitchen::Instance.name_for(suite("suite"), platform("platform/s")).
158
+ must_equal "suite-platform-s"
159
+ end
160
+
161
+ it "transforms forward slashes to dashes in suite and platform names" do
162
+ Kitchen::Instance.name_for(suite("/s//s/"), platform("pp/")).
163
+ must_equal "-s--s--pp-"
164
+ end
146
165
  end
147
166
 
148
167
  describe "#suite" do
@@ -244,13 +263,69 @@ describe Kitchen::Instance do
244
263
  end
245
264
 
246
265
  it "#login executes the driver's login_command" do
247
- driver.stubs(:login_command).with(Hash.new).
248
- returns(Kitchen::LoginCommand.new(["echo", "hello"], {:purple => true}))
249
- Kernel.expects(:exec).with("echo", "hello", {:purple => true})
266
+ state_file.write(:last_action => "create")
267
+ driver.stubs(:login_command).with(:last_action => "create").
268
+ returns(Kitchen::LoginCommand.new(%w[echo hello], :purple => true))
269
+ Kernel.expects(:exec).with("echo", "hello", :purple => true)
250
270
 
251
271
  instance.login
252
272
  end
253
273
 
274
+ it "#login raises a UserError if the instance is not created" do
275
+ state_file.write({})
276
+
277
+ proc { instance.login }.must_raise Kitchen::UserError
278
+ end
279
+
280
+ describe "#diagnose" do
281
+
282
+ it "returns a hash" do
283
+ instance.diagnose.must_be_instance_of Hash
284
+ end
285
+
286
+ it "sets :state_file key to state_file's diganose info" do
287
+ state_file.stubs(:diagnose).returns(:a => "b")
288
+
289
+ instance.diagnose[:state_file].must_equal(:a => "b")
290
+ end
291
+
292
+ it "sets :state_file key to :unknown if obj can't respond to #diagnose" do
293
+ opts[:state_file] = Class.new(state_file.class) {
294
+ undef_method :diagnose
295
+ }.new
296
+
297
+ instance.diagnose[:state_file].must_equal :unknown
298
+ end
299
+
300
+ it "sets :provisioner key to provisioner's diganose info" do
301
+ provisioner.stubs(:diagnose).returns(:a => "b")
302
+
303
+ instance.diagnose[:provisioner].must_equal(:a => "b")
304
+ end
305
+
306
+ it "sets :provisioner key to :unknown if obj can't respond to #diagnose" do
307
+ opts[:provisioner] = Class.new(provisioner.class) {
308
+ undef_method :diagnose
309
+ }.new
310
+
311
+ instance.diagnose[:provisioner].must_equal :unknown
312
+ end
313
+
314
+ it "sets :busser key to busser's diganose info" do
315
+ busser.stubs(:diagnose).returns(:a => "b")
316
+
317
+ instance.diagnose[:busser].must_equal(:a => "b")
318
+ end
319
+
320
+ it "sets :busser key to :unknown if obj can't respond to #diagnose" do
321
+ opts[:busser] = Class.new(busser.class) {
322
+ undef_method :diagnose
323
+ }.new(suite.name, {})
324
+
325
+ instance.diagnose[:busser].must_equal :unknown
326
+ end
327
+ end
328
+
254
329
  describe "performing actions" do
255
330
 
256
331
  describe "#create" do
@@ -286,7 +361,7 @@ describe Kitchen::Instance do
286
361
 
287
362
  describe "with last_action of create" do
288
363
 
289
- before { state_file.write({ :last_action => "create"}) }
364
+ before { state_file.write(:last_action => "create") }
290
365
 
291
366
  it "calls Driver#create with state hash" do
292
367
  driver.expects(:create).
@@ -337,7 +412,7 @@ describe Kitchen::Instance do
337
412
 
338
413
  describe "with last action of create" do
339
414
 
340
- before { state_file.write({ :last_action => "create"}) }
415
+ before { state_file.write(:last_action => "create") }
341
416
 
342
417
  it "calls Driver#converge with state hash" do
343
418
  driver.expects(:converge).
@@ -355,7 +430,7 @@ describe Kitchen::Instance do
355
430
 
356
431
  describe "with last action of converge" do
357
432
 
358
- before { state_file.write({ :last_action => "converge"}) }
433
+ before { state_file.write(:last_action => "converge") }
359
434
 
360
435
  it "calls Driver#converge with state hash" do
361
436
  driver.expects(:converge).
@@ -408,7 +483,7 @@ describe Kitchen::Instance do
408
483
 
409
484
  describe "with last action of create" do
410
485
 
411
- before { state_file.write({ :last_action => "create"}) }
486
+ before { state_file.write(:last_action => "create") }
412
487
 
413
488
  it "calls Driver#converge and setup with state hash" do
414
489
  driver.expects(:converge).
@@ -428,7 +503,7 @@ describe Kitchen::Instance do
428
503
 
429
504
  describe "with last action of converge" do
430
505
 
431
- before { state_file.write({ :last_action => "converge"}) }
506
+ before { state_file.write(:last_action => "converge") }
432
507
 
433
508
  it "calls Driver#setup with state hash" do
434
509
  driver.expects(:setup).
@@ -446,7 +521,7 @@ describe Kitchen::Instance do
446
521
 
447
522
  describe "with last action of setup" do
448
523
 
449
- before { state_file.write({ :last_action => "setup"}) }
524
+ before { state_file.write(:last_action => "setup") }
450
525
 
451
526
  it "calls Driver#setup with state hash" do
452
527
  driver.expects(:setup).
@@ -501,7 +576,7 @@ describe Kitchen::Instance do
501
576
 
502
577
  describe "with last of create" do
503
578
 
504
- before { state_file.write({ :last_action => "create"}) }
579
+ before { state_file.write(:last_action => "create") }
505
580
 
506
581
  it "calls Driver#converge, setup, and verify with state hash" do
507
582
  driver.expects(:converge).
@@ -523,7 +598,7 @@ describe Kitchen::Instance do
523
598
 
524
599
  describe "with last of converge" do
525
600
 
526
- before { state_file.write({ :last_action => "converge"}) }
601
+ before { state_file.write(:last_action => "converge") }
527
602
 
528
603
  it "calls Driver#setup, and verify with state hash" do
529
604
  driver.expects(:setup).
@@ -543,7 +618,7 @@ describe Kitchen::Instance do
543
618
 
544
619
  describe "with last of setup" do
545
620
 
546
- before { state_file.write({ :last_action => "setup"}) }
621
+ before { state_file.write(:last_action => "setup") }
547
622
 
548
623
  it "calls Driver#verify with state hash" do
549
624
  driver.expects(:verify).
@@ -561,7 +636,7 @@ describe Kitchen::Instance do
561
636
 
562
637
  describe "with last of verify" do
563
638
 
564
- before { state_file.write({ :last_action => "verify"}) }
639
+ before { state_file.write(:last_action => "verify") }
565
640
 
566
641
  it "calls Driver#verify with state hash" do
567
642
  driver.expects(:verify).
@@ -613,7 +688,7 @@ describe Kitchen::Instance do
613
688
 
614
689
  describe "with last_action of #{action}" do
615
690
 
616
- before { state_file.write({ :last_action => action}) }
691
+ before { state_file.write(:last_action => action) }
617
692
 
618
693
  it "calls Driver#create with state hash" do
619
694
  driver.expects(:destroy).
@@ -664,7 +739,7 @@ describe Kitchen::Instance do
664
739
 
665
740
  describe "with last action of #{action}" do
666
741
 
667
- before { state_file.write({ :last_action => action}) }
742
+ before { state_file.write(:last_action => action) }
668
743
 
669
744
  it "calls Driver#destroy, create, converge, setup, verify, destroy" do
670
745
  driver.expects(:destroy)
@@ -695,28 +770,44 @@ describe Kitchen::Instance do
695
770
  describe "with destroy mode of always" do
696
771
 
697
772
  it "calls Driver#destroy at even when action fails" do
698
- driver.stubs(:converge).raises(Kitchen::ActionFailed)
699
-
700
773
  driver.expects(:destroy)
701
774
  driver.expects(:create)
702
- driver.expects(:converge)
775
+ driver.expects(:converge).raises(Kitchen::ActionFailed)
703
776
  driver.expects(:destroy)
704
777
 
705
- instance.test(:always)
778
+ begin
779
+ instance.test(:always)
780
+ rescue # rubocop:disable Lint/HandleExceptions
781
+ end
706
782
  end
707
783
  end
708
784
 
709
785
  describe "with destroy mode of passing" do
710
786
 
711
787
  it "doesn't call Driver#destroy at when action fails" do
712
- skip "figure this one out"
713
- driver.stubs(:create).raises(Kitchen::ActionFailed, "death")
788
+ driver.stubs(:create).raises(Kitchen::ActionFailed)
714
789
 
715
- driver.expects(:destroy)
716
- driver.expects(:create)
790
+ driver.expects(:destroy).once
717
791
 
718
- instance.test(:passing)
792
+ begin
793
+ instance.test(:passing)
794
+ rescue # rubocop:disable Lint/HandleExceptions
795
+ end
796
+ end
797
+ end
798
+ end
799
+
800
+ describe "#remote_exec" do
801
+
802
+ before { state_file.write(:last_action => "create") }
803
+
804
+ it "calls Driver#remote_command with state and command" do
805
+ driver.expects(:remote_command).with do |state, command|
806
+ state.must_equal(:last_action => "create")
807
+ command.must_equal "uptime"
719
808
  end
809
+
810
+ instance.remote_exec("uptime")
720
811
  end
721
812
  end
722
813
 
@@ -731,7 +822,8 @@ describe Kitchen::Instance do
731
822
  it "write the state file with last action" do
732
823
  begin
733
824
  instance.public_send(action)
734
- rescue Kitchen::Error => e
825
+ rescue Kitchen::Error
826
+ true # no need to act here
735
827
  end
736
828
 
737
829
  state_file.read[:last_action].must_be_nil
@@ -754,7 +846,8 @@ describe Kitchen::Instance do
754
846
  it "logs the failure" do
755
847
  begin
756
848
  instance.public_send(action)
757
- rescue Kitchen::Error => e
849
+ rescue Kitchen::Error
850
+ true # no need to act here
758
851
  end
759
852
 
760
853
  logger_io.string.must_match regex_for(
@@ -771,7 +864,8 @@ describe Kitchen::Instance do
771
864
  it "write the state file with last action" do
772
865
  begin
773
866
  instance.public_send(action)
774
- rescue Kitchen::Error => e
867
+ rescue Kitchen::Error
868
+ true # no need to act here
775
869
  end
776
870
 
777
871
  state_file.read[:last_action].must_be_nil
@@ -794,7 +888,8 @@ describe Kitchen::Instance do
794
888
  it "logs the failure" do
795
889
  begin
796
890
  instance.public_send(action)
797
- rescue Kitchen::Error => e
891
+ rescue Kitchen::Error
892
+ true # no need to act here
798
893
  end
799
894
 
800
895
  logger_io.string.must_match regex_for(
@@ -812,10 +907,11 @@ describe Kitchen::Instance do
812
907
  [:create, :converge, :setup].each do |action|
813
908
 
814
909
  it "for last state #{action}" do
815
- state_file.write({ :last_action => action.to_s })
910
+ state_file.write(:last_action => action.to_s)
816
911
  begin
817
912
  instance.verify
818
- rescue Kitchen::Error => e
913
+ rescue Kitchen::Error
914
+ true # no need to act here
819
915
  end
820
916
 
821
917
  state_file.read[:last_action].must_equal "setup"
@@ -823,10 +919,11 @@ describe Kitchen::Instance do
823
919
  end
824
920
 
825
921
  it "for last state verify" do
826
- state_file.write({ :last_action => "verify" })
922
+ state_file.write(:last_action => "verify")
827
923
  begin
828
924
  instance.verify
829
- rescue Kitchen::Error => e
925
+ rescue Kitchen::Error
926
+ true # no need to act here
830
927
  end
831
928
 
832
929
  state_file.read[:last_action].must_equal "verify"