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.
- 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"
|