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.
- checksums.yaml +4 -4
- data/.cane +1 -1
- data/.rubocop.yml +3 -0
- data/.travis.yml +20 -9
- data/CHANGELOG.md +219 -108
- data/Gemfile +10 -6
- data/Guardfile +38 -9
- data/README.md +11 -1
- data/Rakefile +21 -37
- data/bin/kitchen +4 -4
- data/features/kitchen_action_commands.feature +161 -0
- data/features/kitchen_console_command.feature +34 -0
- data/features/kitchen_diagnose_command.feature +64 -0
- data/features/kitchen_init_command.feature +29 -17
- data/features/kitchen_list_command.feature +2 -2
- data/features/kitchen_login_command.feature +56 -0
- data/features/{sink_command.feature → kitchen_sink_command.feature} +0 -0
- data/features/kitchen_test_command.feature +88 -0
- data/features/step_definitions/gem_steps.rb +8 -6
- data/features/step_definitions/git_steps.rb +4 -2
- data/features/step_definitions/output_steps.rb +5 -0
- data/features/support/env.rb +12 -9
- data/lib/kitchen.rb +60 -38
- data/lib/kitchen/base64_stream.rb +55 -0
- data/lib/kitchen/busser.rb +124 -58
- data/lib/kitchen/cli.rb +121 -38
- data/lib/kitchen/collection.rb +3 -3
- data/lib/kitchen/color.rb +4 -4
- data/lib/kitchen/command.rb +78 -11
- data/lib/kitchen/command/action.rb +3 -2
- data/lib/kitchen/command/console.rb +12 -5
- data/lib/kitchen/command/diagnose.rb +17 -3
- data/lib/kitchen/command/driver_discover.rb +26 -7
- data/lib/kitchen/command/exec.rb +41 -0
- data/lib/kitchen/command/list.rb +44 -14
- data/lib/kitchen/command/login.rb +2 -1
- data/lib/kitchen/command/sink.rb +2 -1
- data/lib/kitchen/command/test.rb +5 -4
- data/lib/kitchen/config.rb +146 -14
- data/lib/kitchen/configurable.rb +314 -0
- data/lib/kitchen/data_munger.rb +522 -18
- data/lib/kitchen/diagnostic.rb +43 -4
- data/lib/kitchen/driver.rb +4 -4
- data/lib/kitchen/driver/base.rb +80 -115
- data/lib/kitchen/driver/dummy.rb +34 -6
- data/lib/kitchen/driver/proxy.rb +14 -3
- data/lib/kitchen/driver/ssh_base.rb +61 -7
- data/lib/kitchen/errors.rb +109 -9
- data/lib/kitchen/generator/driver_create.rb +39 -5
- data/lib/kitchen/generator/init.rb +130 -45
- data/lib/kitchen/instance.rb +162 -28
- data/lib/kitchen/lazy_hash.rb +79 -7
- data/lib/kitchen/loader/yaml.rb +159 -27
- data/lib/kitchen/logger.rb +267 -21
- data/lib/kitchen/logging.rb +30 -3
- data/lib/kitchen/login_command.rb +11 -2
- data/lib/kitchen/metadata_chopper.rb +2 -2
- data/lib/kitchen/provisioner.rb +4 -4
- data/lib/kitchen/provisioner/base.rb +107 -103
- data/lib/kitchen/provisioner/chef/berkshelf.rb +36 -8
- data/lib/kitchen/provisioner/chef/librarian.rb +40 -11
- data/lib/kitchen/provisioner/chef_base.rb +206 -167
- data/lib/kitchen/provisioner/chef_solo.rb +25 -7
- data/lib/kitchen/provisioner/chef_zero.rb +105 -29
- data/lib/kitchen/provisioner/dummy.rb +1 -1
- data/lib/kitchen/provisioner/shell.rb +21 -6
- data/lib/kitchen/rake_tasks.rb +8 -3
- data/lib/kitchen/shell_out.rb +15 -18
- data/lib/kitchen/ssh.rb +122 -27
- data/lib/kitchen/state_file.rb +24 -7
- data/lib/kitchen/thor_tasks.rb +9 -4
- data/lib/kitchen/util.rb +43 -118
- data/lib/kitchen/version.rb +1 -1
- data/lib/vendor/hash_recursive_merge.rb +10 -2
- data/spec/kitchen/base64_stream_spec.rb +77 -0
- data/spec/kitchen/busser_spec.rb +490 -0
- data/spec/kitchen/collection_spec.rb +10 -10
- data/spec/kitchen/color_spec.rb +2 -2
- data/spec/kitchen/config_spec.rb +234 -62
- data/spec/kitchen/configurable_spec.rb +490 -0
- data/spec/kitchen/data_munger_spec.rb +1070 -862
- data/spec/kitchen/diagnostic_spec.rb +79 -0
- data/spec/kitchen/driver/base_spec.rb +80 -85
- data/spec/kitchen/driver/dummy_spec.rb +43 -14
- data/spec/kitchen/driver/proxy_spec.rb +134 -0
- data/spec/kitchen/driver/ssh_base_spec.rb +644 -0
- data/spec/kitchen/driver_spec.rb +15 -15
- data/spec/kitchen/errors_spec.rb +309 -0
- data/spec/kitchen/instance_spec.rb +143 -46
- data/spec/kitchen/lazy_hash_spec.rb +36 -9
- data/spec/kitchen/loader/yaml_spec.rb +237 -226
- data/spec/kitchen/logger_spec.rb +419 -0
- data/spec/kitchen/logging_spec.rb +59 -0
- data/spec/kitchen/login_command_spec.rb +49 -0
- data/spec/kitchen/metadata_chopper_spec.rb +82 -0
- data/spec/kitchen/platform_spec.rb +4 -4
- data/spec/kitchen/provisioner/base_spec.rb +65 -125
- data/spec/kitchen/provisioner/chef_base_spec.rb +798 -0
- data/spec/kitchen/provisioner/chef_solo_spec.rb +316 -0
- data/spec/kitchen/provisioner/chef_zero_spec.rb +624 -0
- data/spec/kitchen/provisioner/shell_spec.rb +269 -0
- data/spec/kitchen/provisioner_spec.rb +6 -6
- data/spec/kitchen/shell_out_spec.rb +143 -0
- data/spec/kitchen/ssh_spec.rb +683 -0
- data/spec/kitchen/state_file_spec.rb +28 -21
- data/spec/kitchen/suite_spec.rb +7 -7
- data/spec/kitchen/util_spec.rb +68 -10
- data/spec/kitchen_spec.rb +107 -0
- data/spec/spec_helper.rb +18 -13
- data/support/chef-client-zero.rb +10 -9
- data/support/chef_helpers.sh +16 -0
- data/support/download_helpers.sh +109 -0
- data/test-kitchen.gemspec +42 -33
- metadata +107 -33
data/spec/kitchen/driver_spec.rb
CHANGED
@@ -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
|
19
|
+
require_relative "../spec_helper"
|
20
20
|
|
21
|
-
require
|
22
|
-
require
|
23
|
-
require
|
24
|
-
require
|
25
|
-
require
|
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(
|
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(
|
72
|
+
driver = Kitchen::Driver.for_plugin("coolbeans", :jelly => "beans")
|
73
73
|
|
74
|
-
driver[:jelly].must_equal
|
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(
|
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(
|
85
|
+
driver1 = Kitchen::Driver.for_plugin("it_depends", {})
|
86
86
|
driver1.verify_call_count.must_equal 1
|
87
|
-
driver2 = Kitchen::Driver.for_plugin(
|
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(
|
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(
|
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(
|
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
|
20
|
-
require
|
21
|
-
|
22
|
-
require
|
23
|
-
require
|
24
|
-
require
|
25
|
-
require
|
26
|
-
require
|
27
|
-
require
|
28
|
-
require
|
29
|
-
require
|
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(*
|
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(
|
107
|
+
@suite ||= Kitchen::Suite.new(:name => name)
|
104
108
|
end
|
105
109
|
|
106
110
|
def platform(name = "platform")
|
107
|
-
@platform ||= Kitchen::Platform.new(
|
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
|
-
|
248
|
-
|
249
|
-
|
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(
|
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(
|
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(
|
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(
|
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(
|
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(
|
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(
|
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(
|
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(
|
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(
|
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(
|
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(
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
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
|
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
|
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
|
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(
|
910
|
+
state_file.write(:last_action => action.to_s)
|
816
911
|
begin
|
817
912
|
instance.verify
|
818
|
-
rescue Kitchen::Error
|
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(
|
922
|
+
state_file.write(:last_action => "verify")
|
827
923
|
begin
|
828
924
|
instance.verify
|
829
|
-
rescue Kitchen::Error
|
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"
|