test-kitchen 1.7.0 → 1.7.1.dev
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 +8 -8
- data/.gitattributes +3 -0
- data/.github/ISSUE_TEMPLATE.md +55 -55
- data/.gitignore +28 -28
- data/.kitchen.ci.yml +23 -23
- data/.kitchen.proxy.yml +27 -27
- data/.rubocop.yml +3 -3
- data/.travis.yml +70 -70
- data/.yardopts +3 -3
- data/Berksfile +3 -3
- data/CHANGELOG.md +1090 -1083
- data/CONTRIBUTING.md +14 -14
- data/Gemfile +19 -19
- data/Gemfile.proxy_tests +4 -4
- data/Guardfile +42 -42
- data/LICENSE +15 -15
- data/MAINTAINERS.md +23 -23
- data/README.md +135 -135
- data/Rakefile +61 -61
- data/appveyor.yml +44 -44
- data/features/kitchen_action_commands.feature +164 -164
- data/features/kitchen_command.feature +16 -16
- data/features/kitchen_console_command.feature +34 -34
- data/features/kitchen_defaults.feature +38 -38
- data/features/kitchen_diagnose_command.feature +96 -96
- data/features/kitchen_driver_create_command.feature +64 -64
- data/features/kitchen_driver_discover_command.feature +25 -25
- data/features/kitchen_help_command.feature +16 -16
- data/features/kitchen_init_command.feature +274 -274
- data/features/kitchen_list_command.feature +104 -104
- data/features/kitchen_login_command.feature +62 -62
- data/features/kitchen_sink_command.feature +30 -30
- data/features/kitchen_test_command.feature +88 -88
- data/features/step_definitions/gem_steps.rb +36 -36
- data/features/step_definitions/git_steps.rb +5 -5
- data/features/step_definitions/output_steps.rb +5 -5
- data/features/support/env.rb +75 -75
- data/lib/kitchen.rb +150 -150
- data/lib/kitchen/base64_stream.rb +55 -55
- data/lib/kitchen/cli.rb +419 -419
- data/lib/kitchen/collection.rb +55 -55
- data/lib/kitchen/color.rb +65 -65
- data/lib/kitchen/command.rb +185 -185
- data/lib/kitchen/command/action.rb +45 -45
- data/lib/kitchen/command/console.rb +58 -58
- data/lib/kitchen/command/diagnose.rb +92 -92
- data/lib/kitchen/command/driver_discover.rb +105 -105
- data/lib/kitchen/command/exec.rb +41 -41
- data/lib/kitchen/command/list.rb +119 -119
- data/lib/kitchen/command/login.rb +43 -43
- data/lib/kitchen/command/sink.rb +54 -54
- data/lib/kitchen/command/test.rb +51 -51
- data/lib/kitchen/config.rb +322 -322
- data/lib/kitchen/configurable.rb +529 -529
- data/lib/kitchen/data_munger.rb +959 -959
- data/lib/kitchen/diagnostic.rb +141 -141
- data/lib/kitchen/driver.rb +56 -56
- data/lib/kitchen/driver/base.rb +134 -134
- data/lib/kitchen/driver/dummy.rb +108 -108
- data/lib/kitchen/driver/proxy.rb +72 -72
- data/lib/kitchen/driver/ssh_base.rb +357 -357
- data/lib/kitchen/errors.rb +229 -229
- data/lib/kitchen/generator/driver_create.rb +177 -177
- data/lib/kitchen/generator/init.rb +296 -296
- data/lib/kitchen/instance.rb +662 -662
- data/lib/kitchen/lazy_hash.rb +142 -142
- data/lib/kitchen/loader/yaml.rb +349 -349
- data/lib/kitchen/logger.rb +423 -423
- data/lib/kitchen/logging.rb +56 -56
- data/lib/kitchen/login_command.rb +52 -52
- data/lib/kitchen/metadata_chopper.rb +52 -52
- data/lib/kitchen/platform.rb +67 -67
- data/lib/kitchen/provisioner.rb +54 -54
- data/lib/kitchen/provisioner/base.rb +236 -236
- data/lib/kitchen/provisioner/chef/berkshelf.rb +114 -114
- data/lib/kitchen/provisioner/chef/common_sandbox.rb +322 -322
- data/lib/kitchen/provisioner/chef/librarian.rb +112 -112
- data/lib/kitchen/provisioner/chef_apply.rb +124 -124
- data/lib/kitchen/provisioner/chef_base.rb +341 -341
- data/lib/kitchen/provisioner/chef_solo.rb +88 -88
- data/lib/kitchen/provisioner/chef_zero.rb +245 -245
- data/lib/kitchen/provisioner/dummy.rb +79 -79
- data/lib/kitchen/provisioner/shell.rb +138 -138
- data/lib/kitchen/rake_tasks.rb +63 -63
- data/lib/kitchen/shell_out.rb +93 -93
- data/lib/kitchen/ssh.rb +276 -276
- data/lib/kitchen/state_file.rb +120 -120
- data/lib/kitchen/suite.rb +51 -51
- data/lib/kitchen/thor_tasks.rb +66 -66
- data/lib/kitchen/transport.rb +54 -54
- data/lib/kitchen/transport/base.rb +176 -176
- data/lib/kitchen/transport/dummy.rb +79 -79
- data/lib/kitchen/transport/ssh.rb +364 -364
- data/lib/kitchen/transport/winrm.rb +486 -486
- data/lib/kitchen/util.rb +147 -147
- data/lib/kitchen/verifier.rb +55 -55
- data/lib/kitchen/verifier/base.rb +235 -235
- data/lib/kitchen/verifier/busser.rb +277 -277
- data/lib/kitchen/verifier/dummy.rb +79 -79
- data/lib/kitchen/verifier/shell.rb +101 -101
- data/lib/kitchen/version.rb +21 -21
- data/lib/vendor/hash_recursive_merge.rb +82 -82
- data/spec/kitchen/base64_stream_spec.rb +77 -77
- data/spec/kitchen/cli_spec.rb +56 -56
- data/spec/kitchen/collection_spec.rb +80 -80
- data/spec/kitchen/color_spec.rb +54 -54
- data/spec/kitchen/config_spec.rb +408 -408
- data/spec/kitchen/configurable_spec.rb +1095 -1095
- data/spec/kitchen/data_munger_spec.rb +2694 -2694
- data/spec/kitchen/diagnostic_spec.rb +129 -129
- data/spec/kitchen/driver/base_spec.rb +121 -121
- data/spec/kitchen/driver/dummy_spec.rb +199 -199
- data/spec/kitchen/driver/proxy_spec.rb +138 -138
- data/spec/kitchen/driver/ssh_base_spec.rb +1115 -1115
- data/spec/kitchen/driver_spec.rb +112 -112
- data/spec/kitchen/errors_spec.rb +309 -309
- data/spec/kitchen/instance_spec.rb +1419 -1419
- data/spec/kitchen/lazy_hash_spec.rb +117 -117
- data/spec/kitchen/loader/yaml_spec.rb +774 -774
- data/spec/kitchen/logger_spec.rb +429 -429
- data/spec/kitchen/logging_spec.rb +59 -59
- data/spec/kitchen/login_command_spec.rb +68 -68
- data/spec/kitchen/metadata_chopper_spec.rb +82 -82
- data/spec/kitchen/platform_spec.rb +89 -89
- data/spec/kitchen/provisioner/base_spec.rb +386 -386
- data/spec/kitchen/provisioner/chef_apply_spec.rb +136 -136
- data/spec/kitchen/provisioner/chef_base_spec.rb +1161 -1161
- data/spec/kitchen/provisioner/chef_solo_spec.rb +557 -557
- data/spec/kitchen/provisioner/chef_zero_spec.rb +1001 -1001
- data/spec/kitchen/provisioner/dummy_spec.rb +99 -99
- data/spec/kitchen/provisioner/shell_spec.rb +566 -566
- data/spec/kitchen/provisioner_spec.rb +107 -107
- data/spec/kitchen/shell_out_spec.rb +150 -150
- data/spec/kitchen/ssh_spec.rb +693 -693
- data/spec/kitchen/state_file_spec.rb +129 -129
- data/spec/kitchen/suite_spec.rb +62 -62
- data/spec/kitchen/transport/base_spec.rb +89 -89
- data/spec/kitchen/transport/ssh_spec.rb +1255 -1255
- data/spec/kitchen/transport/winrm_spec.rb +1143 -1143
- data/spec/kitchen/transport_spec.rb +112 -112
- data/spec/kitchen/util_spec.rb +165 -165
- data/spec/kitchen/verifier/base_spec.rb +362 -362
- data/spec/kitchen/verifier/busser_spec.rb +610 -610
- data/spec/kitchen/verifier/dummy_spec.rb +99 -99
- data/spec/kitchen/verifier/shell_spec.rb +160 -160
- data/spec/kitchen/verifier_spec.rb +120 -120
- data/spec/kitchen_spec.rb +114 -114
- data/spec/spec_helper.rb +85 -85
- data/spec/support/powershell_max_size_spec.rb +40 -40
- data/support/busser_install_command.ps1 +14 -14
- data/support/busser_install_command.sh +14 -14
- data/support/chef-client-zero.rb +77 -77
- data/support/chef_base_init_command.ps1 +18 -18
- data/support/chef_base_init_command.sh +2 -2
- data/support/chef_base_install_command.ps1 +85 -85
- data/support/chef_base_install_command.sh +229 -229
- data/support/chef_zero_prepare_command_legacy.ps1 +9 -9
- data/support/chef_zero_prepare_command_legacy.sh +10 -10
- data/support/download_helpers.sh +109 -109
- data/support/dummy-validation.pem +27 -27
- data/templates/driver/CHANGELOG.md.erb +3 -3
- data/templates/driver/Gemfile.erb +3 -3
- data/templates/driver/README.md.erb +64 -64
- data/templates/driver/Rakefile.erb +21 -21
- data/templates/driver/driver.rb.erb +23 -23
- data/templates/driver/gemspec.erb +29 -29
- data/templates/driver/gitignore.erb +17 -17
- data/templates/driver/license_apachev2.erb +15 -15
- data/templates/driver/license_lgplv3.erb +16 -16
- data/templates/driver/license_mit.erb +22 -22
- data/templates/driver/license_reserved.erb +5 -5
- data/templates/driver/tailor.erb +4 -4
- data/templates/driver/travis.yml.erb +11 -11
- data/templates/driver/version.rb.erb +12 -12
- data/templates/init/chefignore.erb +1 -1
- data/templates/init/kitchen.yml.erb +18 -18
- data/test-kitchen.gemspec +62 -62
- data/test/integration/default/default_spec.rb +3 -3
- data/testing_windows.md +37 -37
- metadata +5 -4
|
@@ -1,1419 +1,1419 @@
|
|
|
1
|
-
# -*- encoding: utf-8 -*-
|
|
2
|
-
#
|
|
3
|
-
# Author:: Fletcher Nichol (<fnichol@nichol.ca>)
|
|
4
|
-
#
|
|
5
|
-
# Copyright (C) 2012, Fletcher Nichol
|
|
6
|
-
#
|
|
7
|
-
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
8
|
-
# you may not use this file except in compliance with the License.
|
|
9
|
-
# You may obtain a copy of the License at
|
|
10
|
-
#
|
|
11
|
-
# http://www.apache.org/licenses/LICENSE-2.0
|
|
12
|
-
#
|
|
13
|
-
# Unless required by applicable law or agreed to in writing, software
|
|
14
|
-
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
15
|
-
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
16
|
-
# See the License for the specific language governing permissions and
|
|
17
|
-
# limitations under the License.
|
|
18
|
-
|
|
19
|
-
require_relative "../spec_helper"
|
|
20
|
-
require "stringio"
|
|
21
|
-
|
|
22
|
-
require "kitchen/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
|
-
require "kitchen/transport/dummy"
|
|
31
|
-
require "kitchen/verifier/dummy"
|
|
32
|
-
|
|
33
|
-
class DummyStateFile
|
|
34
|
-
|
|
35
|
-
def initialize(*); end
|
|
36
|
-
|
|
37
|
-
def read
|
|
38
|
-
@_state = Hash.new unless @_state
|
|
39
|
-
@_state.dup
|
|
40
|
-
end
|
|
41
|
-
|
|
42
|
-
def write(state)
|
|
43
|
-
@_state = state.dup
|
|
44
|
-
end
|
|
45
|
-
|
|
46
|
-
def destroy
|
|
47
|
-
@_state = nil
|
|
48
|
-
end
|
|
49
|
-
|
|
50
|
-
def diagnose
|
|
51
|
-
Hash.new
|
|
52
|
-
end
|
|
53
|
-
end
|
|
54
|
-
|
|
55
|
-
class SerialDummyDriver < Kitchen::Driver::Dummy
|
|
56
|
-
|
|
57
|
-
no_parallel_for :create, :destroy
|
|
58
|
-
|
|
59
|
-
attr_reader :action_in_mutex
|
|
60
|
-
|
|
61
|
-
def track_locked(action)
|
|
62
|
-
@action_in_mutex = Hash.new unless @action_in_mutex
|
|
63
|
-
@action_in_mutex[action] = Kitchen::Instance.mutexes[self.class].locked?
|
|
64
|
-
end
|
|
65
|
-
|
|
66
|
-
def create(state)
|
|
67
|
-
track_locked(:create)
|
|
68
|
-
super
|
|
69
|
-
end
|
|
70
|
-
|
|
71
|
-
def destroy(state)
|
|
72
|
-
track_locked(:destroy)
|
|
73
|
-
super
|
|
74
|
-
end
|
|
75
|
-
end
|
|
76
|
-
|
|
77
|
-
class LegacyDriver < Kitchen::Driver::SSHBase
|
|
78
|
-
|
|
79
|
-
attr_reader :called_converge, :called_setup, :called_verify
|
|
80
|
-
|
|
81
|
-
def converge(_)
|
|
82
|
-
@called_converge
|
|
83
|
-
end
|
|
84
|
-
|
|
85
|
-
def setup(_)
|
|
86
|
-
@called_setup
|
|
87
|
-
end
|
|
88
|
-
|
|
89
|
-
def verify(_)
|
|
90
|
-
@called_verify
|
|
91
|
-
end
|
|
92
|
-
end
|
|
93
|
-
|
|
94
|
-
describe Kitchen::Instance do
|
|
95
|
-
|
|
96
|
-
let(:driver) { Kitchen::Driver::Dummy.new({}) }
|
|
97
|
-
let(:logger_io) { StringIO.new }
|
|
98
|
-
let(:logger) { Kitchen::Logger.new(:logdev => logger_io) }
|
|
99
|
-
let(:instance) { Kitchen::Instance.new(opts) }
|
|
100
|
-
let(:provisioner) { Kitchen::Provisioner::Dummy.new({}) }
|
|
101
|
-
let(:state_file) { DummyStateFile.new }
|
|
102
|
-
let(:transport) { Kitchen::Transport::Dummy.new({}) }
|
|
103
|
-
let(:verifier) { Kitchen::Verifier::Dummy.new({}) }
|
|
104
|
-
|
|
105
|
-
let(:opts) do
|
|
106
|
-
{ :suite => suite, :platform => platform, :driver => driver,
|
|
107
|
-
:provisioner => provisioner, :verifier => verifier,
|
|
108
|
-
:logger => logger, :state_file => state_file, :transport => transport }
|
|
109
|
-
end
|
|
110
|
-
|
|
111
|
-
def suite(name = "suite")
|
|
112
|
-
@suite ||= Kitchen::Suite.new(:name => name)
|
|
113
|
-
end
|
|
114
|
-
|
|
115
|
-
def platform(name = "platform")
|
|
116
|
-
@platform ||= Kitchen::Platform.new(:name => name)
|
|
117
|
-
end
|
|
118
|
-
|
|
119
|
-
describe ".name_for" do
|
|
120
|
-
|
|
121
|
-
it "combines the suite and platform names with a dash" do
|
|
122
|
-
Kitchen::Instance.name_for(suite("suite"), platform("platform")).
|
|
123
|
-
must_equal "suite-platform"
|
|
124
|
-
end
|
|
125
|
-
|
|
126
|
-
it "squashes periods in suite name" do
|
|
127
|
-
Kitchen::Instance.name_for(suite("suite.ness"), platform("platform")).
|
|
128
|
-
must_equal "suiteness-platform"
|
|
129
|
-
end
|
|
130
|
-
|
|
131
|
-
it "squashes periods in platform name" do
|
|
132
|
-
Kitchen::Instance.name_for(suite("suite"), platform("platform.s")).
|
|
133
|
-
must_equal "suite-platforms"
|
|
134
|
-
end
|
|
135
|
-
|
|
136
|
-
it "squashes periods in suite and platform names" do
|
|
137
|
-
Kitchen::Instance.name_for(suite("s.s"), platform("p.p")).
|
|
138
|
-
must_equal "ss-pp"
|
|
139
|
-
end
|
|
140
|
-
|
|
141
|
-
it "transforms underscores to dashes in suite name" do
|
|
142
|
-
Kitchen::Instance.name_for(suite("suite_ness"), platform("platform")).
|
|
143
|
-
must_equal "suite-ness-platform"
|
|
144
|
-
end
|
|
145
|
-
|
|
146
|
-
it "transforms underscores to dashes in platform name" do
|
|
147
|
-
Kitchen::Instance.name_for(suite("suite"), platform("platform_s")).
|
|
148
|
-
must_equal "suite-platform-s"
|
|
149
|
-
end
|
|
150
|
-
|
|
151
|
-
it "transforms underscores to dashes in suite and platform names" do
|
|
152
|
-
Kitchen::Instance.name_for(suite("_s__s_"), platform("pp_")).
|
|
153
|
-
must_equal "-s--s--pp-"
|
|
154
|
-
end
|
|
155
|
-
|
|
156
|
-
it "transforms forward slashes to dashes in suite name" do
|
|
157
|
-
Kitchen::Instance.name_for(suite("suite/ness"), platform("platform")).
|
|
158
|
-
must_equal "suite-ness-platform"
|
|
159
|
-
end
|
|
160
|
-
|
|
161
|
-
it "transforms forward slashes to dashes in platform name" do
|
|
162
|
-
Kitchen::Instance.name_for(suite("suite"), platform("platform/s")).
|
|
163
|
-
must_equal "suite-platform-s"
|
|
164
|
-
end
|
|
165
|
-
|
|
166
|
-
it "transforms forward slashes to dashes in suite and platform names" do
|
|
167
|
-
Kitchen::Instance.name_for(suite("/s//s/"), platform("pp/")).
|
|
168
|
-
must_equal "-s--s--pp-"
|
|
169
|
-
end
|
|
170
|
-
end
|
|
171
|
-
|
|
172
|
-
describe "#suite" do
|
|
173
|
-
|
|
174
|
-
it "returns its suite" do
|
|
175
|
-
instance.suite.must_equal suite
|
|
176
|
-
end
|
|
177
|
-
|
|
178
|
-
it "raises an ArgumentError if missing" do
|
|
179
|
-
opts.delete(:suite)
|
|
180
|
-
proc { Kitchen::Instance.new(opts) }.must_raise Kitchen::ClientError
|
|
181
|
-
end
|
|
182
|
-
end
|
|
183
|
-
|
|
184
|
-
describe "#platform" do
|
|
185
|
-
|
|
186
|
-
it "returns its platform" do
|
|
187
|
-
instance.platform.must_equal platform
|
|
188
|
-
end
|
|
189
|
-
|
|
190
|
-
it "raises an ArgumentError if missing" do
|
|
191
|
-
opts.delete(:platform)
|
|
192
|
-
proc { Kitchen::Instance.new(opts) }.must_raise Kitchen::ClientError
|
|
193
|
-
end
|
|
194
|
-
end
|
|
195
|
-
|
|
196
|
-
describe "#driver" do
|
|
197
|
-
|
|
198
|
-
it "returns its driver" do
|
|
199
|
-
instance.driver.must_equal driver
|
|
200
|
-
end
|
|
201
|
-
|
|
202
|
-
it "raises an ArgumentError if missing" do
|
|
203
|
-
opts.delete(:driver)
|
|
204
|
-
proc { Kitchen::Instance.new(opts) }.must_raise Kitchen::ClientError
|
|
205
|
-
end
|
|
206
|
-
|
|
207
|
-
it "sets Driver#instance to itself" do
|
|
208
|
-
# it's mind-bottling
|
|
209
|
-
instance.driver.instance.must_equal instance
|
|
210
|
-
end
|
|
211
|
-
end
|
|
212
|
-
|
|
213
|
-
describe "#logger" do
|
|
214
|
-
|
|
215
|
-
it "returns its logger" do
|
|
216
|
-
instance.logger.must_equal logger
|
|
217
|
-
end
|
|
218
|
-
|
|
219
|
-
it "uses Kitchen.logger by default" do
|
|
220
|
-
opts.delete(:logger)
|
|
221
|
-
instance.logger.must_equal Kitchen.logger
|
|
222
|
-
end
|
|
223
|
-
end
|
|
224
|
-
|
|
225
|
-
describe "#provisioner" do
|
|
226
|
-
|
|
227
|
-
it "returns its provisioner" do
|
|
228
|
-
instance.provisioner.must_equal provisioner
|
|
229
|
-
end
|
|
230
|
-
|
|
231
|
-
it "raises an ArgumentError if missing" do
|
|
232
|
-
opts.delete(:provisioner)
|
|
233
|
-
proc { Kitchen::Instance.new(opts) }.must_raise Kitchen::ClientError
|
|
234
|
-
end
|
|
235
|
-
|
|
236
|
-
it "sets Provisioner#instance to itself" do
|
|
237
|
-
# it's mind-bottling
|
|
238
|
-
instance.provisioner.instance.must_equal instance
|
|
239
|
-
end
|
|
240
|
-
end
|
|
241
|
-
|
|
242
|
-
describe "#transport" do
|
|
243
|
-
|
|
244
|
-
it "returns its transport" do
|
|
245
|
-
instance.transport.must_equal transport
|
|
246
|
-
end
|
|
247
|
-
|
|
248
|
-
it "raises an ArgumentError if missing" do
|
|
249
|
-
opts.delete(:transport)
|
|
250
|
-
proc { Kitchen::Instance.new(opts) }.must_raise Kitchen::ClientError
|
|
251
|
-
end
|
|
252
|
-
|
|
253
|
-
it "sets Transport#instance to itself" do
|
|
254
|
-
# it's mind-bottling
|
|
255
|
-
instance.transport.instance.must_equal instance
|
|
256
|
-
end
|
|
257
|
-
end
|
|
258
|
-
|
|
259
|
-
describe "#verifier" do
|
|
260
|
-
|
|
261
|
-
it "returns its verifier" do
|
|
262
|
-
instance.verifier.must_equal verifier
|
|
263
|
-
end
|
|
264
|
-
|
|
265
|
-
it "raises and ArgumentError if missing" do
|
|
266
|
-
opts.delete(:verifier)
|
|
267
|
-
proc { Kitchen::Instance.new(opts) }.must_raise Kitchen::ClientError
|
|
268
|
-
end
|
|
269
|
-
|
|
270
|
-
it "sets Verifier#instance to itself" do
|
|
271
|
-
# it's mind-bottling
|
|
272
|
-
instance.verifier.instance.must_equal instance
|
|
273
|
-
end
|
|
274
|
-
end
|
|
275
|
-
|
|
276
|
-
describe "#state_file" do
|
|
277
|
-
|
|
278
|
-
it "raises an ArgumentError if missing" do
|
|
279
|
-
opts.delete(:state_file)
|
|
280
|
-
proc { Kitchen::Instance.new(opts) }.must_raise Kitchen::ClientError
|
|
281
|
-
end
|
|
282
|
-
end
|
|
283
|
-
|
|
284
|
-
it "#name returns it name" do
|
|
285
|
-
instance.name.must_equal "suite-platform"
|
|
286
|
-
end
|
|
287
|
-
|
|
288
|
-
it "#to_str returns a string representation with its name" do
|
|
289
|
-
instance.to_str.must_equal "<suite-platform>"
|
|
290
|
-
end
|
|
291
|
-
|
|
292
|
-
it "#login executes the transport's login_command" do
|
|
293
|
-
conn = stub("connection")
|
|
294
|
-
state_file.write(:last_action => "create")
|
|
295
|
-
transport.stubs(:connection).with(:last_action => "create").
|
|
296
|
-
returns(conn)
|
|
297
|
-
conn.stubs(:login_command).
|
|
298
|
-
returns(Kitchen::LoginCommand.new("echo", ["hello"], :purple => true))
|
|
299
|
-
Kernel.expects(:exec).with("echo", "hello", :purple => true)
|
|
300
|
-
|
|
301
|
-
instance.login
|
|
302
|
-
end
|
|
303
|
-
|
|
304
|
-
it "#login raises a UserError if the instance is not created" do
|
|
305
|
-
state_file.write({})
|
|
306
|
-
|
|
307
|
-
proc { instance.login }.must_raise Kitchen::UserError
|
|
308
|
-
end
|
|
309
|
-
|
|
310
|
-
describe "#diagnose" do
|
|
311
|
-
|
|
312
|
-
it "returns a hash" do
|
|
313
|
-
instance.diagnose.must_be_instance_of Hash
|
|
314
|
-
end
|
|
315
|
-
|
|
316
|
-
it "sets :platform key to platform's diagnose info" do
|
|
317
|
-
platform.stubs(:diagnose).returns(:a => "b")
|
|
318
|
-
|
|
319
|
-
instance.diagnose[:platform].must_equal(:a => "b")
|
|
320
|
-
end
|
|
321
|
-
|
|
322
|
-
it "sets :platform key to :unknown if obj can't respond to #diagnose" do
|
|
323
|
-
opts[:platform] = Class.new(platform.class) {
|
|
324
|
-
undef_method :diagnose
|
|
325
|
-
}.new(:name => "whoop")
|
|
326
|
-
|
|
327
|
-
instance.diagnose[:platform].must_equal :unknown
|
|
328
|
-
end
|
|
329
|
-
|
|
330
|
-
it "sets :state_file key to state_file's diganose info" do
|
|
331
|
-
state_file.stubs(:diagnose).returns(:a => "b")
|
|
332
|
-
|
|
333
|
-
instance.diagnose[:state_file].must_equal(:a => "b")
|
|
334
|
-
end
|
|
335
|
-
|
|
336
|
-
it "sets :state_file key to :unknown if obj can't respond to #diagnose" do
|
|
337
|
-
opts[:state_file] = Class.new(state_file.class) {
|
|
338
|
-
undef_method :diagnose
|
|
339
|
-
}.new
|
|
340
|
-
|
|
341
|
-
instance.diagnose[:state_file].must_equal :unknown
|
|
342
|
-
end
|
|
343
|
-
|
|
344
|
-
it "sets :provisioner key to provisioner's diganose info" do
|
|
345
|
-
provisioner.stubs(:diagnose).returns(:a => "b")
|
|
346
|
-
|
|
347
|
-
instance.diagnose[:provisioner].must_equal(:a => "b")
|
|
348
|
-
end
|
|
349
|
-
|
|
350
|
-
it "sets :provisioner key to :unknown if obj can't respond to #diagnose" do
|
|
351
|
-
opts[:provisioner] = Class.new(provisioner.class) {
|
|
352
|
-
undef_method :diagnose
|
|
353
|
-
}.new
|
|
354
|
-
|
|
355
|
-
instance.diagnose[:provisioner].must_equal :unknown
|
|
356
|
-
end
|
|
357
|
-
|
|
358
|
-
it "sets :verifier key to verifier's diganose info" do
|
|
359
|
-
verifier.stubs(:diagnose).returns(:a => "b")
|
|
360
|
-
|
|
361
|
-
instance.diagnose[:verifier].must_equal(:a => "b")
|
|
362
|
-
end
|
|
363
|
-
|
|
364
|
-
it "sets :verifier key to :unknown if obj can't respond to #diagnose" do
|
|
365
|
-
opts[:verifier] = Class.new(verifier.class) {
|
|
366
|
-
undef_method :diagnose
|
|
367
|
-
}.new({})
|
|
368
|
-
|
|
369
|
-
instance.diagnose[:verifier].must_equal :unknown
|
|
370
|
-
end
|
|
371
|
-
|
|
372
|
-
it "sets :transport key to transport's diganose info" do
|
|
373
|
-
transport.stubs(:diagnose).returns(:a => "b")
|
|
374
|
-
|
|
375
|
-
instance.diagnose[:transport].must_equal(:a => "b")
|
|
376
|
-
end
|
|
377
|
-
|
|
378
|
-
it "sets :transport key to :unknown if obj can't respond to #diagnose" do
|
|
379
|
-
opts[:transport] = Class.new(transport.class) {
|
|
380
|
-
undef_method :diagnose
|
|
381
|
-
}.new
|
|
382
|
-
|
|
383
|
-
instance.diagnose[:transport].must_equal :unknown
|
|
384
|
-
end
|
|
385
|
-
end
|
|
386
|
-
|
|
387
|
-
describe "#diagnose_plugins" do
|
|
388
|
-
|
|
389
|
-
it "returns a hash" do
|
|
390
|
-
instance.diagnose_plugins.must_be_instance_of Hash
|
|
391
|
-
end
|
|
392
|
-
|
|
393
|
-
it "sets :driver key to driver's plugin_diagnose info" do
|
|
394
|
-
driver.class.stubs(:diagnose).returns(:a => "b")
|
|
395
|
-
|
|
396
|
-
instance.diagnose_plugins[:driver].must_equal(
|
|
397
|
-
:name => "Dummy",
|
|
398
|
-
:a => "b"
|
|
399
|
-
)
|
|
400
|
-
end
|
|
401
|
-
|
|
402
|
-
it "sets :driver key to :unknown if class doesn't have #diagnose" do
|
|
403
|
-
opts[:driver] = Class.new(driver.class) {
|
|
404
|
-
undef_method :diagnose_plugin
|
|
405
|
-
}.new({})
|
|
406
|
-
|
|
407
|
-
instance.diagnose_plugins[:driver].must_equal(:unknown)
|
|
408
|
-
end
|
|
409
|
-
|
|
410
|
-
it "sets :provisioner key to provisioner's plugin_diagnose info" do
|
|
411
|
-
provisioner.class.stubs(:diagnose).returns(:a => "b")
|
|
412
|
-
|
|
413
|
-
instance.diagnose_plugins[:provisioner].must_equal(
|
|
414
|
-
:name => "Dummy",
|
|
415
|
-
:a => "b"
|
|
416
|
-
)
|
|
417
|
-
end
|
|
418
|
-
|
|
419
|
-
it "sets :provisioner key to :unknown if class doesn't have #diagnose" do
|
|
420
|
-
opts[:provisioner] = Class.new(driver.class) {
|
|
421
|
-
undef_method :diagnose_plugin
|
|
422
|
-
}.new({})
|
|
423
|
-
|
|
424
|
-
instance.diagnose_plugins[:provisioner].must_equal(:unknown)
|
|
425
|
-
end
|
|
426
|
-
|
|
427
|
-
it "sets :verifier key to verifier's plugin_diagnose info" do
|
|
428
|
-
verifier.class.stubs(:diagnose).returns(:a => "b")
|
|
429
|
-
|
|
430
|
-
instance.diagnose_plugins[:verifier].must_equal(
|
|
431
|
-
:name => "Dummy",
|
|
432
|
-
:a => "b"
|
|
433
|
-
)
|
|
434
|
-
end
|
|
435
|
-
|
|
436
|
-
it "sets :verifier key to :unknown if class doesn't have #diagnose" do
|
|
437
|
-
opts[:verifier] = Class.new(verifier.class) {
|
|
438
|
-
undef_method :diagnose_plugin
|
|
439
|
-
}.new({})
|
|
440
|
-
|
|
441
|
-
instance.diagnose_plugins[:verifier].must_equal(:unknown)
|
|
442
|
-
end
|
|
443
|
-
|
|
444
|
-
it "sets :transport key to transport's plugin_diagnose info" do
|
|
445
|
-
transport.class.stubs(:diagnose).returns(:a => "b")
|
|
446
|
-
|
|
447
|
-
instance.diagnose_plugins[:transport].must_equal(
|
|
448
|
-
:name => "Dummy",
|
|
449
|
-
:a => "b"
|
|
450
|
-
)
|
|
451
|
-
end
|
|
452
|
-
|
|
453
|
-
it "sets :transport key to :unknown if class doesn't have #diagnose" do
|
|
454
|
-
opts[:transport] = Class.new(transport.class) {
|
|
455
|
-
undef_method :diagnose_plugin
|
|
456
|
-
}.new({})
|
|
457
|
-
|
|
458
|
-
instance.diagnose_plugins[:transport].must_equal(:unknown)
|
|
459
|
-
end
|
|
460
|
-
end
|
|
461
|
-
|
|
462
|
-
describe "performing actions" do
|
|
463
|
-
|
|
464
|
-
describe "#create" do
|
|
465
|
-
|
|
466
|
-
describe "with no state" do
|
|
467
|
-
|
|
468
|
-
it "calls Driver#create with empty state hash" do
|
|
469
|
-
driver.expects(:create).with(Hash.new)
|
|
470
|
-
|
|
471
|
-
instance.create
|
|
472
|
-
end
|
|
473
|
-
|
|
474
|
-
it "writes the state file with last_action" do
|
|
475
|
-
instance.create
|
|
476
|
-
|
|
477
|
-
state_file.read[:last_action].must_equal "create"
|
|
478
|
-
end
|
|
479
|
-
|
|
480
|
-
it "logs the action start" do
|
|
481
|
-
instance.create
|
|
482
|
-
|
|
483
|
-
logger_io.string.must_match regex_for("Creating #{instance.to_str}")
|
|
484
|
-
end
|
|
485
|
-
|
|
486
|
-
it "logs the action finish" do
|
|
487
|
-
instance.create
|
|
488
|
-
|
|
489
|
-
logger_io.string.
|
|
490
|
-
must_match regex_for("Finished creating #{instance.to_str}")
|
|
491
|
-
end
|
|
492
|
-
|
|
493
|
-
end
|
|
494
|
-
|
|
495
|
-
describe "with last_action of create" do
|
|
496
|
-
|
|
497
|
-
before { state_file.write(:last_action => "create") }
|
|
498
|
-
|
|
499
|
-
it "calls Driver#create with state hash" do
|
|
500
|
-
driver.expects(:create).
|
|
501
|
-
with { |state| state[:last_action] == "create" }
|
|
502
|
-
|
|
503
|
-
instance.create
|
|
504
|
-
end
|
|
505
|
-
|
|
506
|
-
it "writes the state file with last_action" do
|
|
507
|
-
instance.create
|
|
508
|
-
|
|
509
|
-
state_file.read[:last_action].must_equal "create"
|
|
510
|
-
end
|
|
511
|
-
end
|
|
512
|
-
end
|
|
513
|
-
|
|
514
|
-
describe "#converge" do
|
|
515
|
-
|
|
516
|
-
describe "with no state" do
|
|
517
|
-
|
|
518
|
-
it "calls Driver#create and Provisioner#call with empty state hash" do
|
|
519
|
-
driver.expects(:create).with(Hash.new)
|
|
520
|
-
provisioner.expects(:call).
|
|
521
|
-
with { |state| state[:last_action] == "create" }
|
|
522
|
-
|
|
523
|
-
instance.converge
|
|
524
|
-
end
|
|
525
|
-
|
|
526
|
-
it "writes the state file with last_action" do
|
|
527
|
-
instance.converge
|
|
528
|
-
|
|
529
|
-
state_file.read[:last_action].must_equal "converge"
|
|
530
|
-
end
|
|
531
|
-
|
|
532
|
-
it "logs the action start" do
|
|
533
|
-
instance.converge
|
|
534
|
-
|
|
535
|
-
logger_io.string.must_match regex_for("Converging #{instance.to_str}")
|
|
536
|
-
end
|
|
537
|
-
|
|
538
|
-
it "logs the action finish" do
|
|
539
|
-
instance.converge
|
|
540
|
-
|
|
541
|
-
logger_io.string.
|
|
542
|
-
must_match regex_for("Finished converging #{instance.to_str}")
|
|
543
|
-
end
|
|
544
|
-
end
|
|
545
|
-
|
|
546
|
-
describe "with last action of create" do
|
|
547
|
-
|
|
548
|
-
before { state_file.write(:last_action => "create") }
|
|
549
|
-
|
|
550
|
-
it "calls Provisioner#call with state hash" do
|
|
551
|
-
provisioner.expects(:call).
|
|
552
|
-
with { |state| state[:last_action] == "create" }
|
|
553
|
-
|
|
554
|
-
instance.converge
|
|
555
|
-
end
|
|
556
|
-
|
|
557
|
-
it "writes the state file with last_action" do
|
|
558
|
-
instance.converge
|
|
559
|
-
|
|
560
|
-
state_file.read[:last_action].must_equal "converge"
|
|
561
|
-
end
|
|
562
|
-
end
|
|
563
|
-
|
|
564
|
-
describe "with last action of converge" do
|
|
565
|
-
|
|
566
|
-
before { state_file.write(:last_action => "converge") }
|
|
567
|
-
|
|
568
|
-
it "calls Provisioner#call with state hash" do
|
|
569
|
-
provisioner.expects(:call).
|
|
570
|
-
with { |state| state[:last_action] == "converge" }
|
|
571
|
-
|
|
572
|
-
instance.converge
|
|
573
|
-
end
|
|
574
|
-
|
|
575
|
-
it "writes the state file with last_action" do
|
|
576
|
-
instance.converge
|
|
577
|
-
|
|
578
|
-
state_file.read[:last_action].must_equal "converge"
|
|
579
|
-
end
|
|
580
|
-
end
|
|
581
|
-
end
|
|
582
|
-
|
|
583
|
-
describe "#setup" do
|
|
584
|
-
|
|
585
|
-
describe "with no state" do
|
|
586
|
-
|
|
587
|
-
it "calls create and converge with empty state hash" do
|
|
588
|
-
driver.expects(:create).with(Hash.new)
|
|
589
|
-
provisioner.expects(:call).
|
|
590
|
-
with { |state| state[:last_action] == "create" }
|
|
591
|
-
driver.expects(:setup).
|
|
592
|
-
with { |state| state[:last_action] == "converge" }.
|
|
593
|
-
never
|
|
594
|
-
|
|
595
|
-
instance.setup
|
|
596
|
-
end
|
|
597
|
-
|
|
598
|
-
it "writes the state file with last_action" do
|
|
599
|
-
instance.setup
|
|
600
|
-
|
|
601
|
-
state_file.read[:last_action].must_equal "setup"
|
|
602
|
-
end
|
|
603
|
-
|
|
604
|
-
it "logs the action start" do
|
|
605
|
-
instance.setup
|
|
606
|
-
|
|
607
|
-
logger_io.string.must_match regex_for("Setting up #{instance.to_str}")
|
|
608
|
-
end
|
|
609
|
-
|
|
610
|
-
it "logs the action finish" do
|
|
611
|
-
instance.setup
|
|
612
|
-
|
|
613
|
-
logger_io.string.
|
|
614
|
-
must_match regex_for("Finished setting up #{instance.to_str}")
|
|
615
|
-
end
|
|
616
|
-
end
|
|
617
|
-
|
|
618
|
-
describe "with last action of create" do
|
|
619
|
-
|
|
620
|
-
before { state_file.write(:last_action => "create") }
|
|
621
|
-
|
|
622
|
-
it "calls Provisioner#call with state hash" do
|
|
623
|
-
provisioner.expects(:call).
|
|
624
|
-
with { |state| state[:last_action] == "create" }
|
|
625
|
-
driver.expects(:setup).
|
|
626
|
-
with { |state| state[:last_action] == "converge" }.
|
|
627
|
-
never
|
|
628
|
-
|
|
629
|
-
instance.setup
|
|
630
|
-
end
|
|
631
|
-
|
|
632
|
-
it "writes the state file with last_action" do
|
|
633
|
-
instance.setup
|
|
634
|
-
|
|
635
|
-
state_file.read[:last_action].must_equal "setup"
|
|
636
|
-
end
|
|
637
|
-
end
|
|
638
|
-
|
|
639
|
-
describe "with last action of converge" do
|
|
640
|
-
|
|
641
|
-
before { state_file.write(:last_action => "converge") }
|
|
642
|
-
|
|
643
|
-
it "calls nothing with state hash" do
|
|
644
|
-
driver.expects(:setup).
|
|
645
|
-
with { |state| state[:last_action] == "converge" }.
|
|
646
|
-
never
|
|
647
|
-
|
|
648
|
-
instance.setup
|
|
649
|
-
end
|
|
650
|
-
|
|
651
|
-
it "writes the state file with last_action" do
|
|
652
|
-
instance.setup
|
|
653
|
-
|
|
654
|
-
state_file.read[:last_action].must_equal "setup"
|
|
655
|
-
end
|
|
656
|
-
end
|
|
657
|
-
|
|
658
|
-
describe "with last action of setup" do
|
|
659
|
-
|
|
660
|
-
before { state_file.write(:last_action => "setup") }
|
|
661
|
-
|
|
662
|
-
it "calls nothing with state hash" do
|
|
663
|
-
driver.expects(:setup).
|
|
664
|
-
with { |state| state[:last_action] == "setup" }.
|
|
665
|
-
never
|
|
666
|
-
|
|
667
|
-
instance.setup
|
|
668
|
-
end
|
|
669
|
-
|
|
670
|
-
it "writes the state file with last_action" do
|
|
671
|
-
instance.setup
|
|
672
|
-
|
|
673
|
-
state_file.read[:last_action].must_equal "setup"
|
|
674
|
-
end
|
|
675
|
-
end
|
|
676
|
-
end
|
|
677
|
-
|
|
678
|
-
describe "#verify" do
|
|
679
|
-
|
|
680
|
-
describe "with no state" do
|
|
681
|
-
|
|
682
|
-
it "calls create, converge, and verify with empty state hash" do
|
|
683
|
-
driver.expects(:create).with(Hash.new)
|
|
684
|
-
provisioner.expects(:call).
|
|
685
|
-
with { |state| state[:last_action] == "create" }
|
|
686
|
-
driver.expects(:setup).
|
|
687
|
-
with { |state| state[:last_action] == "converge" }.
|
|
688
|
-
never
|
|
689
|
-
verifier.expects(:call).
|
|
690
|
-
with { |state| state[:last_action] == "setup" }
|
|
691
|
-
|
|
692
|
-
instance.verify
|
|
693
|
-
end
|
|
694
|
-
|
|
695
|
-
it "writes the state file with last_action" do
|
|
696
|
-
instance.verify
|
|
697
|
-
|
|
698
|
-
state_file.read[:last_action].must_equal "verify"
|
|
699
|
-
end
|
|
700
|
-
|
|
701
|
-
it "logs the action start" do
|
|
702
|
-
instance.verify
|
|
703
|
-
|
|
704
|
-
logger_io.string.must_match regex_for("Verifying #{instance.to_str}")
|
|
705
|
-
end
|
|
706
|
-
|
|
707
|
-
it "logs the action finish" do
|
|
708
|
-
instance.verify
|
|
709
|
-
|
|
710
|
-
logger_io.string.
|
|
711
|
-
must_match regex_for("Finished verifying #{instance.to_str}")
|
|
712
|
-
end
|
|
713
|
-
end
|
|
714
|
-
|
|
715
|
-
describe "with last of create" do
|
|
716
|
-
|
|
717
|
-
before { state_file.write(:last_action => "create") }
|
|
718
|
-
|
|
719
|
-
it "calls converge, and verify with state hash" do
|
|
720
|
-
provisioner.expects(:call).
|
|
721
|
-
with { |state| state[:last_action] == "create" }
|
|
722
|
-
driver.expects(:setup).
|
|
723
|
-
with { |state| state[:last_action] == "converge" }.
|
|
724
|
-
never
|
|
725
|
-
verifier.expects(:call).
|
|
726
|
-
with { |state| state[:last_action] == "setup" }
|
|
727
|
-
|
|
728
|
-
instance.verify
|
|
729
|
-
end
|
|
730
|
-
|
|
731
|
-
it "writes the state file with last_action" do
|
|
732
|
-
instance.verify
|
|
733
|
-
|
|
734
|
-
state_file.read[:last_action].must_equal "verify"
|
|
735
|
-
end
|
|
736
|
-
end
|
|
737
|
-
|
|
738
|
-
describe "with last of converge" do
|
|
739
|
-
|
|
740
|
-
before { state_file.write(:last_action => "converge") }
|
|
741
|
-
|
|
742
|
-
it "calls Verifier#call with state hash" do
|
|
743
|
-
driver.expects(:setup).
|
|
744
|
-
with { |state| state[:last_action] == "converge" }.
|
|
745
|
-
never
|
|
746
|
-
verifier.expects(:call).
|
|
747
|
-
with { |state| state[:last_action] == "setup" }
|
|
748
|
-
|
|
749
|
-
instance.verify
|
|
750
|
-
end
|
|
751
|
-
|
|
752
|
-
it "writes the state file with last_action" do
|
|
753
|
-
instance.verify
|
|
754
|
-
|
|
755
|
-
state_file.read[:last_action].must_equal "verify"
|
|
756
|
-
end
|
|
757
|
-
end
|
|
758
|
-
|
|
759
|
-
describe "with last of setup" do
|
|
760
|
-
|
|
761
|
-
before { state_file.write(:last_action => "setup") }
|
|
762
|
-
|
|
763
|
-
it "calls Verifier#call with state hash" do
|
|
764
|
-
verifier.expects(:call).
|
|
765
|
-
with { |state| state[:last_action] == "setup" }
|
|
766
|
-
|
|
767
|
-
instance.verify
|
|
768
|
-
end
|
|
769
|
-
|
|
770
|
-
it "writes the state file with last_action" do
|
|
771
|
-
instance.verify
|
|
772
|
-
|
|
773
|
-
state_file.read[:last_action].must_equal "verify"
|
|
774
|
-
end
|
|
775
|
-
end
|
|
776
|
-
|
|
777
|
-
describe "with last of verify" do
|
|
778
|
-
|
|
779
|
-
before { state_file.write(:last_action => "verify") }
|
|
780
|
-
|
|
781
|
-
it "calls Verifier#call with state hash" do
|
|
782
|
-
verifier.expects(:call).
|
|
783
|
-
with { |state| state[:last_action] == "verify" }
|
|
784
|
-
|
|
785
|
-
instance.verify
|
|
786
|
-
end
|
|
787
|
-
|
|
788
|
-
it "writes the state file with last_action" do
|
|
789
|
-
instance.verify
|
|
790
|
-
|
|
791
|
-
state_file.read[:last_action].must_equal "verify"
|
|
792
|
-
end
|
|
793
|
-
end
|
|
794
|
-
end
|
|
795
|
-
|
|
796
|
-
describe "#destroy" do
|
|
797
|
-
|
|
798
|
-
describe "with no state" do
|
|
799
|
-
|
|
800
|
-
it "calls Driver#destroy with empty state hash" do
|
|
801
|
-
driver.expects(:destroy).with(Hash.new)
|
|
802
|
-
|
|
803
|
-
instance.destroy
|
|
804
|
-
end
|
|
805
|
-
|
|
806
|
-
it "destroys the state file" do
|
|
807
|
-
state_file.expects(:destroy)
|
|
808
|
-
|
|
809
|
-
instance.destroy
|
|
810
|
-
end
|
|
811
|
-
|
|
812
|
-
it "logs the action start" do
|
|
813
|
-
instance.destroy
|
|
814
|
-
|
|
815
|
-
logger_io.string.
|
|
816
|
-
must_match regex_for("Destroying #{instance.to_str}")
|
|
817
|
-
end
|
|
818
|
-
|
|
819
|
-
it "logs the create finish" do
|
|
820
|
-
instance.destroy
|
|
821
|
-
|
|
822
|
-
logger_io.string.
|
|
823
|
-
must_match regex_for("Finished destroying #{instance.to_str}")
|
|
824
|
-
end
|
|
825
|
-
end
|
|
826
|
-
|
|
827
|
-
[:create, :converge, :setup, :verify].each do |action|
|
|
828
|
-
|
|
829
|
-
describe "with last_action of #{action}" do
|
|
830
|
-
|
|
831
|
-
before { state_file.write(:last_action => action) }
|
|
832
|
-
|
|
833
|
-
it "calls Driver#create with state hash" do
|
|
834
|
-
driver.expects(:destroy).
|
|
835
|
-
with { |state| state[:last_action] == action }
|
|
836
|
-
|
|
837
|
-
instance.destroy
|
|
838
|
-
end
|
|
839
|
-
|
|
840
|
-
it "destroys the state file" do
|
|
841
|
-
state_file.expects(:destroy)
|
|
842
|
-
|
|
843
|
-
instance.destroy
|
|
844
|
-
end
|
|
845
|
-
end
|
|
846
|
-
end
|
|
847
|
-
end
|
|
848
|
-
|
|
849
|
-
describe "#test" do
|
|
850
|
-
|
|
851
|
-
describe "with no state" do
|
|
852
|
-
|
|
853
|
-
it "calls destroy, create, converge, setup, verify, destroy" do
|
|
854
|
-
driver.expects(:destroy)
|
|
855
|
-
driver.expects(:create)
|
|
856
|
-
provisioner.expects(:call)
|
|
857
|
-
verifier.expects(:call)
|
|
858
|
-
driver.expects(:destroy)
|
|
859
|
-
|
|
860
|
-
instance.test
|
|
861
|
-
end
|
|
862
|
-
|
|
863
|
-
it "logs the action start" do
|
|
864
|
-
instance.test
|
|
865
|
-
|
|
866
|
-
logger_io.string.must_match regex_for("Testing #{instance.to_str}")
|
|
867
|
-
end
|
|
868
|
-
|
|
869
|
-
it "logs the action finish" do
|
|
870
|
-
instance.test
|
|
871
|
-
|
|
872
|
-
logger_io.string.
|
|
873
|
-
must_match regex_for("Finished testing #{instance.to_str}")
|
|
874
|
-
end
|
|
875
|
-
end
|
|
876
|
-
|
|
877
|
-
[:create, :converge, :setup, :verify].each do |action|
|
|
878
|
-
|
|
879
|
-
describe "with last action of #{action}" do
|
|
880
|
-
|
|
881
|
-
before { state_file.write(:last_action => action) }
|
|
882
|
-
|
|
883
|
-
it "calls destroy, create, converge, setup, verify, destroy" do
|
|
884
|
-
driver.expects(:destroy)
|
|
885
|
-
driver.expects(:create)
|
|
886
|
-
provisioner.expects(:call)
|
|
887
|
-
verifier.expects(:call)
|
|
888
|
-
driver.expects(:destroy)
|
|
889
|
-
|
|
890
|
-
instance.test
|
|
891
|
-
end
|
|
892
|
-
end
|
|
893
|
-
end
|
|
894
|
-
|
|
895
|
-
describe "with destroy mode of never" do
|
|
896
|
-
|
|
897
|
-
it "calls destroy, create, converge, setup, verify" do
|
|
898
|
-
driver.expects(:destroy).once
|
|
899
|
-
driver.expects(:create)
|
|
900
|
-
provisioner.expects(:call)
|
|
901
|
-
verifier.expects(:call)
|
|
902
|
-
|
|
903
|
-
instance.test(:never)
|
|
904
|
-
end
|
|
905
|
-
end
|
|
906
|
-
|
|
907
|
-
describe "with destroy mode of always" do
|
|
908
|
-
|
|
909
|
-
it "calls destroy at even when action fails" do
|
|
910
|
-
driver.expects(:destroy)
|
|
911
|
-
driver.expects(:create)
|
|
912
|
-
provisioner.expects(:call).raises(Kitchen::ActionFailed)
|
|
913
|
-
driver.expects(:destroy)
|
|
914
|
-
|
|
915
|
-
begin
|
|
916
|
-
instance.test(:always)
|
|
917
|
-
rescue # rubocop:disable Lint/HandleExceptions
|
|
918
|
-
end
|
|
919
|
-
end
|
|
920
|
-
end
|
|
921
|
-
|
|
922
|
-
describe "with destroy mode of passing" do
|
|
923
|
-
|
|
924
|
-
it "doesn't call Driver#destroy at when action fails" do
|
|
925
|
-
driver.stubs(:create).raises(Kitchen::ActionFailed)
|
|
926
|
-
|
|
927
|
-
driver.expects(:destroy).once
|
|
928
|
-
|
|
929
|
-
begin
|
|
930
|
-
instance.test(:passing)
|
|
931
|
-
rescue # rubocop:disable Lint/HandleExceptions
|
|
932
|
-
end
|
|
933
|
-
end
|
|
934
|
-
end
|
|
935
|
-
end
|
|
936
|
-
|
|
937
|
-
describe "#remote_exec" do
|
|
938
|
-
|
|
939
|
-
before { state_file.write(:last_action => "create") }
|
|
940
|
-
|
|
941
|
-
it "calls Transport#execute with command" do
|
|
942
|
-
connection = mock("connection")
|
|
943
|
-
connection.expects(:execute).with("uptime")
|
|
944
|
-
transport.stubs(:connection).yields(connection)
|
|
945
|
-
|
|
946
|
-
instance.remote_exec("uptime")
|
|
947
|
-
end
|
|
948
|
-
end
|
|
949
|
-
|
|
950
|
-
[:create, :converge, :setup, :verify, :test].each do |action|
|
|
951
|
-
|
|
952
|
-
describe "#{action} on driver crash with ActionFailed" do
|
|
953
|
-
|
|
954
|
-
before do
|
|
955
|
-
driver.stubs(:create).raises(Kitchen::ActionFailed, "death")
|
|
956
|
-
end
|
|
957
|
-
|
|
958
|
-
it "write the state file with last action" do
|
|
959
|
-
begin
|
|
960
|
-
instance.public_send(action)
|
|
961
|
-
rescue Kitchen::Error
|
|
962
|
-
true # no need to act here
|
|
963
|
-
end
|
|
964
|
-
|
|
965
|
-
state_file.read[:last_action].must_be_nil
|
|
966
|
-
end
|
|
967
|
-
|
|
968
|
-
it "raises an InstanceFailure" do
|
|
969
|
-
proc { instance.public_send(action) }.
|
|
970
|
-
must_raise Kitchen::InstanceFailure
|
|
971
|
-
end
|
|
972
|
-
|
|
973
|
-
it "populates the InstanceFailure message" do
|
|
974
|
-
begin
|
|
975
|
-
instance.public_send(action)
|
|
976
|
-
rescue Kitchen::Error => e
|
|
977
|
-
e.message.must_match regex_for(
|
|
978
|
-
"Create failed on instance #{instance.to_str}")
|
|
979
|
-
end
|
|
980
|
-
end
|
|
981
|
-
|
|
982
|
-
it "logs the failure" do
|
|
983
|
-
begin
|
|
984
|
-
instance.public_send(action)
|
|
985
|
-
rescue Kitchen::Error
|
|
986
|
-
true # no need to act here
|
|
987
|
-
end
|
|
988
|
-
|
|
989
|
-
logger_io.string.must_match regex_for(
|
|
990
|
-
"Create failed on instance #{instance.to_str}")
|
|
991
|
-
end
|
|
992
|
-
end
|
|
993
|
-
|
|
994
|
-
describe "on driver crash with unexpected exception class" do
|
|
995
|
-
|
|
996
|
-
before do
|
|
997
|
-
driver.stubs(:create).raises(RuntimeError, "watwat")
|
|
998
|
-
end
|
|
999
|
-
|
|
1000
|
-
it "write the state file with last action" do
|
|
1001
|
-
begin
|
|
1002
|
-
instance.public_send(action)
|
|
1003
|
-
rescue Kitchen::Error
|
|
1004
|
-
true # no need to act here
|
|
1005
|
-
end
|
|
1006
|
-
|
|
1007
|
-
state_file.read[:last_action].must_be_nil
|
|
1008
|
-
end
|
|
1009
|
-
|
|
1010
|
-
it "raises an ActionFailed" do
|
|
1011
|
-
proc { instance.public_send(action) }.
|
|
1012
|
-
must_raise Kitchen::ActionFailed
|
|
1013
|
-
end
|
|
1014
|
-
|
|
1015
|
-
it "populates the ActionFailed message" do
|
|
1016
|
-
begin
|
|
1017
|
-
instance.public_send(action)
|
|
1018
|
-
rescue Kitchen::Error => e
|
|
1019
|
-
e.message.must_match regex_for(
|
|
1020
|
-
"Failed to complete #create action: [watwat]")
|
|
1021
|
-
end
|
|
1022
|
-
end
|
|
1023
|
-
|
|
1024
|
-
it "logs the failure" do
|
|
1025
|
-
begin
|
|
1026
|
-
instance.public_send(action)
|
|
1027
|
-
rescue Kitchen::Error
|
|
1028
|
-
true # no need to act here
|
|
1029
|
-
end
|
|
1030
|
-
|
|
1031
|
-
logger_io.string.must_match regex_for(
|
|
1032
|
-
"Create failed on instance #{instance.to_str}")
|
|
1033
|
-
end
|
|
1034
|
-
end
|
|
1035
|
-
end
|
|
1036
|
-
|
|
1037
|
-
describe "crashes preserve last action for desired verify action" do
|
|
1038
|
-
|
|
1039
|
-
before do
|
|
1040
|
-
verifier.stubs(:call).raises(Kitchen::ActionFailed, "death")
|
|
1041
|
-
end
|
|
1042
|
-
|
|
1043
|
-
[:create, :converge, :setup].each do |action|
|
|
1044
|
-
|
|
1045
|
-
it "for last state #{action}" do
|
|
1046
|
-
state_file.write(:last_action => action.to_s)
|
|
1047
|
-
begin
|
|
1048
|
-
instance.verify
|
|
1049
|
-
rescue Kitchen::Error
|
|
1050
|
-
true # no need to act here
|
|
1051
|
-
end
|
|
1052
|
-
|
|
1053
|
-
state_file.read[:last_action].must_equal "setup"
|
|
1054
|
-
end
|
|
1055
|
-
end
|
|
1056
|
-
|
|
1057
|
-
it "for last state verify" do
|
|
1058
|
-
state_file.write(:last_action => "verify")
|
|
1059
|
-
begin
|
|
1060
|
-
instance.verify
|
|
1061
|
-
rescue Kitchen::Error
|
|
1062
|
-
true # no need to act here
|
|
1063
|
-
end
|
|
1064
|
-
|
|
1065
|
-
state_file.read[:last_action].must_equal "verify"
|
|
1066
|
-
end
|
|
1067
|
-
end
|
|
1068
|
-
|
|
1069
|
-
describe "on drivers with serial actions" do
|
|
1070
|
-
|
|
1071
|
-
let(:driver) { SerialDummyDriver.new({}) }
|
|
1072
|
-
|
|
1073
|
-
it "runs in a synchronized block for serial actions" do
|
|
1074
|
-
instance.test
|
|
1075
|
-
|
|
1076
|
-
driver.action_in_mutex[:create].must_equal true
|
|
1077
|
-
driver.action_in_mutex[:destroy].must_equal true
|
|
1078
|
-
end
|
|
1079
|
-
end
|
|
1080
|
-
|
|
1081
|
-
describe "with legacy Driver::SSHBase subclasses" do
|
|
1082
|
-
|
|
1083
|
-
let(:driver) { LegacyDriver.new({}) }
|
|
1084
|
-
|
|
1085
|
-
describe "#converge" do
|
|
1086
|
-
|
|
1087
|
-
describe "with no state" do
|
|
1088
|
-
|
|
1089
|
-
it "calls Driver#create and Driver#converge with empty state hash" do
|
|
1090
|
-
driver.expects(:create).with(Hash.new)
|
|
1091
|
-
driver.expects(:converge).
|
|
1092
|
-
with { |state| state[:last_action] == "create" }
|
|
1093
|
-
|
|
1094
|
-
instance.converge
|
|
1095
|
-
end
|
|
1096
|
-
end
|
|
1097
|
-
|
|
1098
|
-
describe "with last action of create" do
|
|
1099
|
-
|
|
1100
|
-
before { state_file.write(:last_action => "create") }
|
|
1101
|
-
|
|
1102
|
-
it "calls Driver#converge with state hash" do
|
|
1103
|
-
driver.expects(:converge).
|
|
1104
|
-
with { |state| state[:last_action] == "create" }
|
|
1105
|
-
|
|
1106
|
-
instance.converge
|
|
1107
|
-
end
|
|
1108
|
-
end
|
|
1109
|
-
|
|
1110
|
-
describe "with last action of converge" do
|
|
1111
|
-
|
|
1112
|
-
before { state_file.write(:last_action => "converge") }
|
|
1113
|
-
|
|
1114
|
-
it "calls Driver#converge with state hash" do
|
|
1115
|
-
driver.expects(:converge).
|
|
1116
|
-
with { |state| state[:last_action] == "converge" }
|
|
1117
|
-
|
|
1118
|
-
instance.converge
|
|
1119
|
-
end
|
|
1120
|
-
end
|
|
1121
|
-
end
|
|
1122
|
-
|
|
1123
|
-
describe "#setup" do
|
|
1124
|
-
|
|
1125
|
-
describe "with no state" do
|
|
1126
|
-
|
|
1127
|
-
it "calls create, converge, and setup with empty state hash" do
|
|
1128
|
-
driver.expects(:create).with(Hash.new)
|
|
1129
|
-
driver.expects(:converge).
|
|
1130
|
-
with { |state| state[:last_action] == "create" }
|
|
1131
|
-
driver.expects(:setup).
|
|
1132
|
-
with { |state| state[:last_action] == "converge" }
|
|
1133
|
-
|
|
1134
|
-
instance.setup
|
|
1135
|
-
end
|
|
1136
|
-
end
|
|
1137
|
-
|
|
1138
|
-
describe "with last action of create" do
|
|
1139
|
-
|
|
1140
|
-
before { state_file.write(:last_action => "create") }
|
|
1141
|
-
|
|
1142
|
-
it "calls Provisioner#call and setup with state hash" do
|
|
1143
|
-
driver.expects(:converge).
|
|
1144
|
-
with { |state| state[:last_action] == "create" }
|
|
1145
|
-
driver.expects(:setup).
|
|
1146
|
-
with { |state| state[:last_action] == "converge" }
|
|
1147
|
-
|
|
1148
|
-
instance.setup
|
|
1149
|
-
end
|
|
1150
|
-
end
|
|
1151
|
-
|
|
1152
|
-
describe "with last action of converge" do
|
|
1153
|
-
|
|
1154
|
-
before { state_file.write(:last_action => "converge") }
|
|
1155
|
-
|
|
1156
|
-
it "calls Driver#setup with state hash" do
|
|
1157
|
-
driver.expects(:setup).
|
|
1158
|
-
with { |state| state[:last_action] == "converge" }
|
|
1159
|
-
|
|
1160
|
-
instance.setup
|
|
1161
|
-
end
|
|
1162
|
-
end
|
|
1163
|
-
|
|
1164
|
-
describe "with last action of setup" do
|
|
1165
|
-
|
|
1166
|
-
before { state_file.write(:last_action => "setup") }
|
|
1167
|
-
|
|
1168
|
-
it "calls Driver#setup with state hash" do
|
|
1169
|
-
driver.expects(:setup).
|
|
1170
|
-
with { |state| state[:last_action] == "setup" }
|
|
1171
|
-
|
|
1172
|
-
instance.setup
|
|
1173
|
-
end
|
|
1174
|
-
end
|
|
1175
|
-
end
|
|
1176
|
-
|
|
1177
|
-
describe "#verify" do
|
|
1178
|
-
|
|
1179
|
-
describe "with no state" do
|
|
1180
|
-
|
|
1181
|
-
it "calls create, converge, setup, and verify with empty state hash" do
|
|
1182
|
-
driver.expects(:create).with(Hash.new)
|
|
1183
|
-
driver.expects(:converge).
|
|
1184
|
-
with { |state| state[:last_action] == "create" }
|
|
1185
|
-
driver.expects(:setup).
|
|
1186
|
-
with { |state| state[:last_action] == "converge" }
|
|
1187
|
-
driver.expects(:verify).
|
|
1188
|
-
with { |state| state[:last_action] == "setup" }
|
|
1189
|
-
|
|
1190
|
-
instance.verify
|
|
1191
|
-
end
|
|
1192
|
-
end
|
|
1193
|
-
|
|
1194
|
-
describe "with last of create" do
|
|
1195
|
-
|
|
1196
|
-
before { state_file.write(:last_action => "create") }
|
|
1197
|
-
|
|
1198
|
-
it "calls converge, setup, and verify with state hash" do
|
|
1199
|
-
driver.expects(:converge).
|
|
1200
|
-
with { |state| state[:last_action] == "create" }
|
|
1201
|
-
driver.expects(:setup).
|
|
1202
|
-
with { |state| state[:last_action] == "converge" }
|
|
1203
|
-
driver.expects(:verify).
|
|
1204
|
-
with { |state| state[:last_action] == "setup" }
|
|
1205
|
-
|
|
1206
|
-
instance.verify
|
|
1207
|
-
end
|
|
1208
|
-
end
|
|
1209
|
-
|
|
1210
|
-
describe "with last of converge" do
|
|
1211
|
-
|
|
1212
|
-
before { state_file.write(:last_action => "converge") }
|
|
1213
|
-
|
|
1214
|
-
it "calls Driver#setup, and verify with state hash" do
|
|
1215
|
-
driver.expects(:setup).
|
|
1216
|
-
with { |state| state[:last_action] == "converge" }
|
|
1217
|
-
driver.expects(:verify).
|
|
1218
|
-
with { |state| state[:last_action] == "setup" }
|
|
1219
|
-
|
|
1220
|
-
instance.verify
|
|
1221
|
-
end
|
|
1222
|
-
end
|
|
1223
|
-
|
|
1224
|
-
describe "with last of setup" do
|
|
1225
|
-
|
|
1226
|
-
before { state_file.write(:last_action => "setup") }
|
|
1227
|
-
|
|
1228
|
-
it "calls Driver#verify with state hash" do
|
|
1229
|
-
driver.expects(:verify).
|
|
1230
|
-
with { |state| state[:last_action] == "setup" }
|
|
1231
|
-
|
|
1232
|
-
instance.verify
|
|
1233
|
-
end
|
|
1234
|
-
end
|
|
1235
|
-
|
|
1236
|
-
describe "with last of verify" do
|
|
1237
|
-
|
|
1238
|
-
before { state_file.write(:last_action => "verify") }
|
|
1239
|
-
|
|
1240
|
-
it "calls Driver#verify with state hash" do
|
|
1241
|
-
driver.expects(:verify).
|
|
1242
|
-
with { |state| state[:last_action] == "verify" }
|
|
1243
|
-
|
|
1244
|
-
instance.verify
|
|
1245
|
-
end
|
|
1246
|
-
end
|
|
1247
|
-
end
|
|
1248
|
-
|
|
1249
|
-
describe "#test" do
|
|
1250
|
-
|
|
1251
|
-
describe "with no state" do
|
|
1252
|
-
|
|
1253
|
-
it "calls destroy, create, converge, setup, verify, destroy" do
|
|
1254
|
-
driver.expects(:destroy)
|
|
1255
|
-
driver.expects(:create)
|
|
1256
|
-
driver.expects(:converge)
|
|
1257
|
-
driver.expects(:setup)
|
|
1258
|
-
driver.expects(:verify)
|
|
1259
|
-
driver.expects(:destroy)
|
|
1260
|
-
|
|
1261
|
-
instance.test
|
|
1262
|
-
end
|
|
1263
|
-
end
|
|
1264
|
-
|
|
1265
|
-
[:create, :converge, :setup, :verify].each do |action|
|
|
1266
|
-
|
|
1267
|
-
describe "with last action of #{action}" do
|
|
1268
|
-
|
|
1269
|
-
before { state_file.write(:last_action => action) }
|
|
1270
|
-
|
|
1271
|
-
it "calls destroy, create, converge, setup, verify, destroy" do
|
|
1272
|
-
driver.expects(:destroy)
|
|
1273
|
-
driver.expects(:create)
|
|
1274
|
-
driver.expects(:converge)
|
|
1275
|
-
driver.expects(:setup)
|
|
1276
|
-
driver.expects(:verify)
|
|
1277
|
-
driver.expects(:destroy)
|
|
1278
|
-
|
|
1279
|
-
instance.test
|
|
1280
|
-
end
|
|
1281
|
-
end
|
|
1282
|
-
end
|
|
1283
|
-
|
|
1284
|
-
describe "with destroy mode of never" do
|
|
1285
|
-
|
|
1286
|
-
it "calls destroy, create, converge, setup, verify" do
|
|
1287
|
-
driver.expects(:destroy).once
|
|
1288
|
-
driver.expects(:create)
|
|
1289
|
-
driver.expects(:converge)
|
|
1290
|
-
driver.expects(:setup)
|
|
1291
|
-
driver.expects(:verify)
|
|
1292
|
-
|
|
1293
|
-
instance.test(:never)
|
|
1294
|
-
end
|
|
1295
|
-
end
|
|
1296
|
-
|
|
1297
|
-
describe "with destroy mode of always" do
|
|
1298
|
-
|
|
1299
|
-
it "calls destroy at even when action fails" do
|
|
1300
|
-
driver.expects(:destroy)
|
|
1301
|
-
driver.expects(:create)
|
|
1302
|
-
driver.expects(:converge).raises(Kitchen::ActionFailed)
|
|
1303
|
-
driver.expects(:destroy)
|
|
1304
|
-
|
|
1305
|
-
begin
|
|
1306
|
-
instance.test(:always)
|
|
1307
|
-
rescue # rubocop:disable Lint/HandleExceptions
|
|
1308
|
-
end
|
|
1309
|
-
end
|
|
1310
|
-
end
|
|
1311
|
-
end
|
|
1312
|
-
|
|
1313
|
-
it "#login executes the driver's login_command" do
|
|
1314
|
-
state_file.write(:last_action => "create")
|
|
1315
|
-
driver.stubs(:login_command).with(:last_action => "create").
|
|
1316
|
-
returns(Kitchen::LoginCommand.new("echo", ["hello"], :purple => true))
|
|
1317
|
-
Kernel.expects(:exec).with("echo", "hello", :purple => true)
|
|
1318
|
-
|
|
1319
|
-
instance.login
|
|
1320
|
-
end
|
|
1321
|
-
end
|
|
1322
|
-
end
|
|
1323
|
-
|
|
1324
|
-
describe Kitchen::Instance::FSM do
|
|
1325
|
-
|
|
1326
|
-
let(:fsm) { Kitchen::Instance::FSM }
|
|
1327
|
-
|
|
1328
|
-
describe ".actions" do
|
|
1329
|
-
|
|
1330
|
-
it "passing nils returns destroy" do
|
|
1331
|
-
fsm.actions(nil, nil).must_equal [:destroy]
|
|
1332
|
-
end
|
|
1333
|
-
|
|
1334
|
-
it "accepts a string for desired argument" do
|
|
1335
|
-
fsm.actions(nil, "create").must_equal [:create]
|
|
1336
|
-
end
|
|
1337
|
-
|
|
1338
|
-
it "accepts a symbol for desired argument" do
|
|
1339
|
-
fsm.actions(nil, :create).must_equal [:create]
|
|
1340
|
-
end
|
|
1341
|
-
|
|
1342
|
-
it "starting from no state to create returns create" do
|
|
1343
|
-
fsm.actions(nil, :create).must_equal [:create]
|
|
1344
|
-
end
|
|
1345
|
-
|
|
1346
|
-
it "starting from :create to create returns create" do
|
|
1347
|
-
fsm.actions(:create, :create).must_equal [:create]
|
|
1348
|
-
end
|
|
1349
|
-
|
|
1350
|
-
it "starting from no state to converge returns create, converge" do
|
|
1351
|
-
fsm.actions(nil, :converge).must_equal [:create, :converge]
|
|
1352
|
-
end
|
|
1353
|
-
|
|
1354
|
-
it "starting from create to converge returns converge" do
|
|
1355
|
-
fsm.actions(:create, :converge).must_equal [:converge]
|
|
1356
|
-
end
|
|
1357
|
-
|
|
1358
|
-
it "starting from converge to converge returns converge" do
|
|
1359
|
-
fsm.actions(:converge, :converge).must_equal [:converge]
|
|
1360
|
-
end
|
|
1361
|
-
|
|
1362
|
-
it "starting from no state to setup returns create, converge, setup" do
|
|
1363
|
-
fsm.actions(nil, :setup).must_equal [:create, :converge, :setup]
|
|
1364
|
-
end
|
|
1365
|
-
|
|
1366
|
-
it "starting from create to setup returns converge, setup" do
|
|
1367
|
-
fsm.actions(:create, :setup).must_equal [:converge, :setup]
|
|
1368
|
-
end
|
|
1369
|
-
|
|
1370
|
-
it "starting from converge to setup returns setup" do
|
|
1371
|
-
fsm.actions(:converge, :setup).must_equal [:setup]
|
|
1372
|
-
end
|
|
1373
|
-
|
|
1374
|
-
it "starting from setup to setup return setup" do
|
|
1375
|
-
fsm.actions(:setup, :setup).must_equal [:setup]
|
|
1376
|
-
end
|
|
1377
|
-
|
|
1378
|
-
it "starting from no state to verify returns create, converge, setup, verify" do
|
|
1379
|
-
fsm.actions(nil, :verify).must_equal [:create, :converge, :setup, :verify]
|
|
1380
|
-
end
|
|
1381
|
-
|
|
1382
|
-
it "starting from create to verify returns converge, setup, verify" do
|
|
1383
|
-
fsm.actions(:create, :verify).must_equal [:converge, :setup, :verify]
|
|
1384
|
-
end
|
|
1385
|
-
|
|
1386
|
-
it "starting from converge to verify returns setup, verify" do
|
|
1387
|
-
fsm.actions(:converge, :verify).must_equal [:setup, :verify]
|
|
1388
|
-
end
|
|
1389
|
-
|
|
1390
|
-
it "starting from setup to verify returns verify" do
|
|
1391
|
-
fsm.actions(:setup, :verify).must_equal [:verify]
|
|
1392
|
-
end
|
|
1393
|
-
|
|
1394
|
-
it "starting from verify to verify returns verify" do
|
|
1395
|
-
fsm.actions(:verify, :verify).must_equal [:verify]
|
|
1396
|
-
end
|
|
1397
|
-
|
|
1398
|
-
[:verify, :setup, :converge].each do |s|
|
|
1399
|
-
it "starting from #{s} to create returns create" do
|
|
1400
|
-
fsm.actions(s, :create).must_equal [:create]
|
|
1401
|
-
end
|
|
1402
|
-
end
|
|
1403
|
-
|
|
1404
|
-
[:verify, :setup].each do |s|
|
|
1405
|
-
it "starting from #{s} to converge returns converge" do
|
|
1406
|
-
fsm.actions(s, :converge).must_equal [:converge]
|
|
1407
|
-
end
|
|
1408
|
-
end
|
|
1409
|
-
|
|
1410
|
-
it "starting from verify to setup returns setup" do
|
|
1411
|
-
fsm.actions(:verify, :setup).must_equal [:setup]
|
|
1412
|
-
end
|
|
1413
|
-
end
|
|
1414
|
-
end
|
|
1415
|
-
|
|
1416
|
-
def regex_for(string)
|
|
1417
|
-
Regexp.new(Regexp.escape(string))
|
|
1418
|
-
end
|
|
1419
|
-
end
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
|
2
|
+
#
|
|
3
|
+
# Author:: Fletcher Nichol (<fnichol@nichol.ca>)
|
|
4
|
+
#
|
|
5
|
+
# Copyright (C) 2012, Fletcher Nichol
|
|
6
|
+
#
|
|
7
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
8
|
+
# you may not use this file except in compliance with the License.
|
|
9
|
+
# You may obtain a copy of the License at
|
|
10
|
+
#
|
|
11
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
12
|
+
#
|
|
13
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
14
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
15
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
16
|
+
# See the License for the specific language governing permissions and
|
|
17
|
+
# limitations under the License.
|
|
18
|
+
|
|
19
|
+
require_relative "../spec_helper"
|
|
20
|
+
require "stringio"
|
|
21
|
+
|
|
22
|
+
require "kitchen/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
|
+
require "kitchen/transport/dummy"
|
|
31
|
+
require "kitchen/verifier/dummy"
|
|
32
|
+
|
|
33
|
+
class DummyStateFile
|
|
34
|
+
|
|
35
|
+
def initialize(*); end
|
|
36
|
+
|
|
37
|
+
def read
|
|
38
|
+
@_state = Hash.new unless @_state
|
|
39
|
+
@_state.dup
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def write(state)
|
|
43
|
+
@_state = state.dup
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def destroy
|
|
47
|
+
@_state = nil
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def diagnose
|
|
51
|
+
Hash.new
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
class SerialDummyDriver < Kitchen::Driver::Dummy
|
|
56
|
+
|
|
57
|
+
no_parallel_for :create, :destroy
|
|
58
|
+
|
|
59
|
+
attr_reader :action_in_mutex
|
|
60
|
+
|
|
61
|
+
def track_locked(action)
|
|
62
|
+
@action_in_mutex = Hash.new unless @action_in_mutex
|
|
63
|
+
@action_in_mutex[action] = Kitchen::Instance.mutexes[self.class].locked?
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def create(state)
|
|
67
|
+
track_locked(:create)
|
|
68
|
+
super
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
def destroy(state)
|
|
72
|
+
track_locked(:destroy)
|
|
73
|
+
super
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
class LegacyDriver < Kitchen::Driver::SSHBase
|
|
78
|
+
|
|
79
|
+
attr_reader :called_converge, :called_setup, :called_verify
|
|
80
|
+
|
|
81
|
+
def converge(_)
|
|
82
|
+
@called_converge
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
def setup(_)
|
|
86
|
+
@called_setup
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
def verify(_)
|
|
90
|
+
@called_verify
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
describe Kitchen::Instance do
|
|
95
|
+
|
|
96
|
+
let(:driver) { Kitchen::Driver::Dummy.new({}) }
|
|
97
|
+
let(:logger_io) { StringIO.new }
|
|
98
|
+
let(:logger) { Kitchen::Logger.new(:logdev => logger_io) }
|
|
99
|
+
let(:instance) { Kitchen::Instance.new(opts) }
|
|
100
|
+
let(:provisioner) { Kitchen::Provisioner::Dummy.new({}) }
|
|
101
|
+
let(:state_file) { DummyStateFile.new }
|
|
102
|
+
let(:transport) { Kitchen::Transport::Dummy.new({}) }
|
|
103
|
+
let(:verifier) { Kitchen::Verifier::Dummy.new({}) }
|
|
104
|
+
|
|
105
|
+
let(:opts) do
|
|
106
|
+
{ :suite => suite, :platform => platform, :driver => driver,
|
|
107
|
+
:provisioner => provisioner, :verifier => verifier,
|
|
108
|
+
:logger => logger, :state_file => state_file, :transport => transport }
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
def suite(name = "suite")
|
|
112
|
+
@suite ||= Kitchen::Suite.new(:name => name)
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
def platform(name = "platform")
|
|
116
|
+
@platform ||= Kitchen::Platform.new(:name => name)
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
describe ".name_for" do
|
|
120
|
+
|
|
121
|
+
it "combines the suite and platform names with a dash" do
|
|
122
|
+
Kitchen::Instance.name_for(suite("suite"), platform("platform")).
|
|
123
|
+
must_equal "suite-platform"
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
it "squashes periods in suite name" do
|
|
127
|
+
Kitchen::Instance.name_for(suite("suite.ness"), platform("platform")).
|
|
128
|
+
must_equal "suiteness-platform"
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
it "squashes periods in platform name" do
|
|
132
|
+
Kitchen::Instance.name_for(suite("suite"), platform("platform.s")).
|
|
133
|
+
must_equal "suite-platforms"
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
it "squashes periods in suite and platform names" do
|
|
137
|
+
Kitchen::Instance.name_for(suite("s.s"), platform("p.p")).
|
|
138
|
+
must_equal "ss-pp"
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
it "transforms underscores to dashes in suite name" do
|
|
142
|
+
Kitchen::Instance.name_for(suite("suite_ness"), platform("platform")).
|
|
143
|
+
must_equal "suite-ness-platform"
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
it "transforms underscores to dashes in platform name" do
|
|
147
|
+
Kitchen::Instance.name_for(suite("suite"), platform("platform_s")).
|
|
148
|
+
must_equal "suite-platform-s"
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
it "transforms underscores to dashes in suite and platform names" do
|
|
152
|
+
Kitchen::Instance.name_for(suite("_s__s_"), platform("pp_")).
|
|
153
|
+
must_equal "-s--s--pp-"
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
it "transforms forward slashes to dashes in suite name" do
|
|
157
|
+
Kitchen::Instance.name_for(suite("suite/ness"), platform("platform")).
|
|
158
|
+
must_equal "suite-ness-platform"
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
it "transforms forward slashes to dashes in platform name" do
|
|
162
|
+
Kitchen::Instance.name_for(suite("suite"), platform("platform/s")).
|
|
163
|
+
must_equal "suite-platform-s"
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
it "transforms forward slashes to dashes in suite and platform names" do
|
|
167
|
+
Kitchen::Instance.name_for(suite("/s//s/"), platform("pp/")).
|
|
168
|
+
must_equal "-s--s--pp-"
|
|
169
|
+
end
|
|
170
|
+
end
|
|
171
|
+
|
|
172
|
+
describe "#suite" do
|
|
173
|
+
|
|
174
|
+
it "returns its suite" do
|
|
175
|
+
instance.suite.must_equal suite
|
|
176
|
+
end
|
|
177
|
+
|
|
178
|
+
it "raises an ArgumentError if missing" do
|
|
179
|
+
opts.delete(:suite)
|
|
180
|
+
proc { Kitchen::Instance.new(opts) }.must_raise Kitchen::ClientError
|
|
181
|
+
end
|
|
182
|
+
end
|
|
183
|
+
|
|
184
|
+
describe "#platform" do
|
|
185
|
+
|
|
186
|
+
it "returns its platform" do
|
|
187
|
+
instance.platform.must_equal platform
|
|
188
|
+
end
|
|
189
|
+
|
|
190
|
+
it "raises an ArgumentError if missing" do
|
|
191
|
+
opts.delete(:platform)
|
|
192
|
+
proc { Kitchen::Instance.new(opts) }.must_raise Kitchen::ClientError
|
|
193
|
+
end
|
|
194
|
+
end
|
|
195
|
+
|
|
196
|
+
describe "#driver" do
|
|
197
|
+
|
|
198
|
+
it "returns its driver" do
|
|
199
|
+
instance.driver.must_equal driver
|
|
200
|
+
end
|
|
201
|
+
|
|
202
|
+
it "raises an ArgumentError if missing" do
|
|
203
|
+
opts.delete(:driver)
|
|
204
|
+
proc { Kitchen::Instance.new(opts) }.must_raise Kitchen::ClientError
|
|
205
|
+
end
|
|
206
|
+
|
|
207
|
+
it "sets Driver#instance to itself" do
|
|
208
|
+
# it's mind-bottling
|
|
209
|
+
instance.driver.instance.must_equal instance
|
|
210
|
+
end
|
|
211
|
+
end
|
|
212
|
+
|
|
213
|
+
describe "#logger" do
|
|
214
|
+
|
|
215
|
+
it "returns its logger" do
|
|
216
|
+
instance.logger.must_equal logger
|
|
217
|
+
end
|
|
218
|
+
|
|
219
|
+
it "uses Kitchen.logger by default" do
|
|
220
|
+
opts.delete(:logger)
|
|
221
|
+
instance.logger.must_equal Kitchen.logger
|
|
222
|
+
end
|
|
223
|
+
end
|
|
224
|
+
|
|
225
|
+
describe "#provisioner" do
|
|
226
|
+
|
|
227
|
+
it "returns its provisioner" do
|
|
228
|
+
instance.provisioner.must_equal provisioner
|
|
229
|
+
end
|
|
230
|
+
|
|
231
|
+
it "raises an ArgumentError if missing" do
|
|
232
|
+
opts.delete(:provisioner)
|
|
233
|
+
proc { Kitchen::Instance.new(opts) }.must_raise Kitchen::ClientError
|
|
234
|
+
end
|
|
235
|
+
|
|
236
|
+
it "sets Provisioner#instance to itself" do
|
|
237
|
+
# it's mind-bottling
|
|
238
|
+
instance.provisioner.instance.must_equal instance
|
|
239
|
+
end
|
|
240
|
+
end
|
|
241
|
+
|
|
242
|
+
describe "#transport" do
|
|
243
|
+
|
|
244
|
+
it "returns its transport" do
|
|
245
|
+
instance.transport.must_equal transport
|
|
246
|
+
end
|
|
247
|
+
|
|
248
|
+
it "raises an ArgumentError if missing" do
|
|
249
|
+
opts.delete(:transport)
|
|
250
|
+
proc { Kitchen::Instance.new(opts) }.must_raise Kitchen::ClientError
|
|
251
|
+
end
|
|
252
|
+
|
|
253
|
+
it "sets Transport#instance to itself" do
|
|
254
|
+
# it's mind-bottling
|
|
255
|
+
instance.transport.instance.must_equal instance
|
|
256
|
+
end
|
|
257
|
+
end
|
|
258
|
+
|
|
259
|
+
describe "#verifier" do
|
|
260
|
+
|
|
261
|
+
it "returns its verifier" do
|
|
262
|
+
instance.verifier.must_equal verifier
|
|
263
|
+
end
|
|
264
|
+
|
|
265
|
+
it "raises and ArgumentError if missing" do
|
|
266
|
+
opts.delete(:verifier)
|
|
267
|
+
proc { Kitchen::Instance.new(opts) }.must_raise Kitchen::ClientError
|
|
268
|
+
end
|
|
269
|
+
|
|
270
|
+
it "sets Verifier#instance to itself" do
|
|
271
|
+
# it's mind-bottling
|
|
272
|
+
instance.verifier.instance.must_equal instance
|
|
273
|
+
end
|
|
274
|
+
end
|
|
275
|
+
|
|
276
|
+
describe "#state_file" do
|
|
277
|
+
|
|
278
|
+
it "raises an ArgumentError if missing" do
|
|
279
|
+
opts.delete(:state_file)
|
|
280
|
+
proc { Kitchen::Instance.new(opts) }.must_raise Kitchen::ClientError
|
|
281
|
+
end
|
|
282
|
+
end
|
|
283
|
+
|
|
284
|
+
it "#name returns it name" do
|
|
285
|
+
instance.name.must_equal "suite-platform"
|
|
286
|
+
end
|
|
287
|
+
|
|
288
|
+
it "#to_str returns a string representation with its name" do
|
|
289
|
+
instance.to_str.must_equal "<suite-platform>"
|
|
290
|
+
end
|
|
291
|
+
|
|
292
|
+
it "#login executes the transport's login_command" do
|
|
293
|
+
conn = stub("connection")
|
|
294
|
+
state_file.write(:last_action => "create")
|
|
295
|
+
transport.stubs(:connection).with(:last_action => "create").
|
|
296
|
+
returns(conn)
|
|
297
|
+
conn.stubs(:login_command).
|
|
298
|
+
returns(Kitchen::LoginCommand.new("echo", ["hello"], :purple => true))
|
|
299
|
+
Kernel.expects(:exec).with("echo", "hello", :purple => true)
|
|
300
|
+
|
|
301
|
+
instance.login
|
|
302
|
+
end
|
|
303
|
+
|
|
304
|
+
it "#login raises a UserError if the instance is not created" do
|
|
305
|
+
state_file.write({})
|
|
306
|
+
|
|
307
|
+
proc { instance.login }.must_raise Kitchen::UserError
|
|
308
|
+
end
|
|
309
|
+
|
|
310
|
+
describe "#diagnose" do
|
|
311
|
+
|
|
312
|
+
it "returns a hash" do
|
|
313
|
+
instance.diagnose.must_be_instance_of Hash
|
|
314
|
+
end
|
|
315
|
+
|
|
316
|
+
it "sets :platform key to platform's diagnose info" do
|
|
317
|
+
platform.stubs(:diagnose).returns(:a => "b")
|
|
318
|
+
|
|
319
|
+
instance.diagnose[:platform].must_equal(:a => "b")
|
|
320
|
+
end
|
|
321
|
+
|
|
322
|
+
it "sets :platform key to :unknown if obj can't respond to #diagnose" do
|
|
323
|
+
opts[:platform] = Class.new(platform.class) {
|
|
324
|
+
undef_method :diagnose
|
|
325
|
+
}.new(:name => "whoop")
|
|
326
|
+
|
|
327
|
+
instance.diagnose[:platform].must_equal :unknown
|
|
328
|
+
end
|
|
329
|
+
|
|
330
|
+
it "sets :state_file key to state_file's diganose info" do
|
|
331
|
+
state_file.stubs(:diagnose).returns(:a => "b")
|
|
332
|
+
|
|
333
|
+
instance.diagnose[:state_file].must_equal(:a => "b")
|
|
334
|
+
end
|
|
335
|
+
|
|
336
|
+
it "sets :state_file key to :unknown if obj can't respond to #diagnose" do
|
|
337
|
+
opts[:state_file] = Class.new(state_file.class) {
|
|
338
|
+
undef_method :diagnose
|
|
339
|
+
}.new
|
|
340
|
+
|
|
341
|
+
instance.diagnose[:state_file].must_equal :unknown
|
|
342
|
+
end
|
|
343
|
+
|
|
344
|
+
it "sets :provisioner key to provisioner's diganose info" do
|
|
345
|
+
provisioner.stubs(:diagnose).returns(:a => "b")
|
|
346
|
+
|
|
347
|
+
instance.diagnose[:provisioner].must_equal(:a => "b")
|
|
348
|
+
end
|
|
349
|
+
|
|
350
|
+
it "sets :provisioner key to :unknown if obj can't respond to #diagnose" do
|
|
351
|
+
opts[:provisioner] = Class.new(provisioner.class) {
|
|
352
|
+
undef_method :diagnose
|
|
353
|
+
}.new
|
|
354
|
+
|
|
355
|
+
instance.diagnose[:provisioner].must_equal :unknown
|
|
356
|
+
end
|
|
357
|
+
|
|
358
|
+
it "sets :verifier key to verifier's diganose info" do
|
|
359
|
+
verifier.stubs(:diagnose).returns(:a => "b")
|
|
360
|
+
|
|
361
|
+
instance.diagnose[:verifier].must_equal(:a => "b")
|
|
362
|
+
end
|
|
363
|
+
|
|
364
|
+
it "sets :verifier key to :unknown if obj can't respond to #diagnose" do
|
|
365
|
+
opts[:verifier] = Class.new(verifier.class) {
|
|
366
|
+
undef_method :diagnose
|
|
367
|
+
}.new({})
|
|
368
|
+
|
|
369
|
+
instance.diagnose[:verifier].must_equal :unknown
|
|
370
|
+
end
|
|
371
|
+
|
|
372
|
+
it "sets :transport key to transport's diganose info" do
|
|
373
|
+
transport.stubs(:diagnose).returns(:a => "b")
|
|
374
|
+
|
|
375
|
+
instance.diagnose[:transport].must_equal(:a => "b")
|
|
376
|
+
end
|
|
377
|
+
|
|
378
|
+
it "sets :transport key to :unknown if obj can't respond to #diagnose" do
|
|
379
|
+
opts[:transport] = Class.new(transport.class) {
|
|
380
|
+
undef_method :diagnose
|
|
381
|
+
}.new
|
|
382
|
+
|
|
383
|
+
instance.diagnose[:transport].must_equal :unknown
|
|
384
|
+
end
|
|
385
|
+
end
|
|
386
|
+
|
|
387
|
+
describe "#diagnose_plugins" do
|
|
388
|
+
|
|
389
|
+
it "returns a hash" do
|
|
390
|
+
instance.diagnose_plugins.must_be_instance_of Hash
|
|
391
|
+
end
|
|
392
|
+
|
|
393
|
+
it "sets :driver key to driver's plugin_diagnose info" do
|
|
394
|
+
driver.class.stubs(:diagnose).returns(:a => "b")
|
|
395
|
+
|
|
396
|
+
instance.diagnose_plugins[:driver].must_equal(
|
|
397
|
+
:name => "Dummy",
|
|
398
|
+
:a => "b"
|
|
399
|
+
)
|
|
400
|
+
end
|
|
401
|
+
|
|
402
|
+
it "sets :driver key to :unknown if class doesn't have #diagnose" do
|
|
403
|
+
opts[:driver] = Class.new(driver.class) {
|
|
404
|
+
undef_method :diagnose_plugin
|
|
405
|
+
}.new({})
|
|
406
|
+
|
|
407
|
+
instance.diagnose_plugins[:driver].must_equal(:unknown)
|
|
408
|
+
end
|
|
409
|
+
|
|
410
|
+
it "sets :provisioner key to provisioner's plugin_diagnose info" do
|
|
411
|
+
provisioner.class.stubs(:diagnose).returns(:a => "b")
|
|
412
|
+
|
|
413
|
+
instance.diagnose_plugins[:provisioner].must_equal(
|
|
414
|
+
:name => "Dummy",
|
|
415
|
+
:a => "b"
|
|
416
|
+
)
|
|
417
|
+
end
|
|
418
|
+
|
|
419
|
+
it "sets :provisioner key to :unknown if class doesn't have #diagnose" do
|
|
420
|
+
opts[:provisioner] = Class.new(driver.class) {
|
|
421
|
+
undef_method :diagnose_plugin
|
|
422
|
+
}.new({})
|
|
423
|
+
|
|
424
|
+
instance.diagnose_plugins[:provisioner].must_equal(:unknown)
|
|
425
|
+
end
|
|
426
|
+
|
|
427
|
+
it "sets :verifier key to verifier's plugin_diagnose info" do
|
|
428
|
+
verifier.class.stubs(:diagnose).returns(:a => "b")
|
|
429
|
+
|
|
430
|
+
instance.diagnose_plugins[:verifier].must_equal(
|
|
431
|
+
:name => "Dummy",
|
|
432
|
+
:a => "b"
|
|
433
|
+
)
|
|
434
|
+
end
|
|
435
|
+
|
|
436
|
+
it "sets :verifier key to :unknown if class doesn't have #diagnose" do
|
|
437
|
+
opts[:verifier] = Class.new(verifier.class) {
|
|
438
|
+
undef_method :diagnose_plugin
|
|
439
|
+
}.new({})
|
|
440
|
+
|
|
441
|
+
instance.diagnose_plugins[:verifier].must_equal(:unknown)
|
|
442
|
+
end
|
|
443
|
+
|
|
444
|
+
it "sets :transport key to transport's plugin_diagnose info" do
|
|
445
|
+
transport.class.stubs(:diagnose).returns(:a => "b")
|
|
446
|
+
|
|
447
|
+
instance.diagnose_plugins[:transport].must_equal(
|
|
448
|
+
:name => "Dummy",
|
|
449
|
+
:a => "b"
|
|
450
|
+
)
|
|
451
|
+
end
|
|
452
|
+
|
|
453
|
+
it "sets :transport key to :unknown if class doesn't have #diagnose" do
|
|
454
|
+
opts[:transport] = Class.new(transport.class) {
|
|
455
|
+
undef_method :diagnose_plugin
|
|
456
|
+
}.new({})
|
|
457
|
+
|
|
458
|
+
instance.diagnose_plugins[:transport].must_equal(:unknown)
|
|
459
|
+
end
|
|
460
|
+
end
|
|
461
|
+
|
|
462
|
+
describe "performing actions" do
|
|
463
|
+
|
|
464
|
+
describe "#create" do
|
|
465
|
+
|
|
466
|
+
describe "with no state" do
|
|
467
|
+
|
|
468
|
+
it "calls Driver#create with empty state hash" do
|
|
469
|
+
driver.expects(:create).with(Hash.new)
|
|
470
|
+
|
|
471
|
+
instance.create
|
|
472
|
+
end
|
|
473
|
+
|
|
474
|
+
it "writes the state file with last_action" do
|
|
475
|
+
instance.create
|
|
476
|
+
|
|
477
|
+
state_file.read[:last_action].must_equal "create"
|
|
478
|
+
end
|
|
479
|
+
|
|
480
|
+
it "logs the action start" do
|
|
481
|
+
instance.create
|
|
482
|
+
|
|
483
|
+
logger_io.string.must_match regex_for("Creating #{instance.to_str}")
|
|
484
|
+
end
|
|
485
|
+
|
|
486
|
+
it "logs the action finish" do
|
|
487
|
+
instance.create
|
|
488
|
+
|
|
489
|
+
logger_io.string.
|
|
490
|
+
must_match regex_for("Finished creating #{instance.to_str}")
|
|
491
|
+
end
|
|
492
|
+
|
|
493
|
+
end
|
|
494
|
+
|
|
495
|
+
describe "with last_action of create" do
|
|
496
|
+
|
|
497
|
+
before { state_file.write(:last_action => "create") }
|
|
498
|
+
|
|
499
|
+
it "calls Driver#create with state hash" do
|
|
500
|
+
driver.expects(:create).
|
|
501
|
+
with { |state| state[:last_action] == "create" }
|
|
502
|
+
|
|
503
|
+
instance.create
|
|
504
|
+
end
|
|
505
|
+
|
|
506
|
+
it "writes the state file with last_action" do
|
|
507
|
+
instance.create
|
|
508
|
+
|
|
509
|
+
state_file.read[:last_action].must_equal "create"
|
|
510
|
+
end
|
|
511
|
+
end
|
|
512
|
+
end
|
|
513
|
+
|
|
514
|
+
describe "#converge" do
|
|
515
|
+
|
|
516
|
+
describe "with no state" do
|
|
517
|
+
|
|
518
|
+
it "calls Driver#create and Provisioner#call with empty state hash" do
|
|
519
|
+
driver.expects(:create).with(Hash.new)
|
|
520
|
+
provisioner.expects(:call).
|
|
521
|
+
with { |state| state[:last_action] == "create" }
|
|
522
|
+
|
|
523
|
+
instance.converge
|
|
524
|
+
end
|
|
525
|
+
|
|
526
|
+
it "writes the state file with last_action" do
|
|
527
|
+
instance.converge
|
|
528
|
+
|
|
529
|
+
state_file.read[:last_action].must_equal "converge"
|
|
530
|
+
end
|
|
531
|
+
|
|
532
|
+
it "logs the action start" do
|
|
533
|
+
instance.converge
|
|
534
|
+
|
|
535
|
+
logger_io.string.must_match regex_for("Converging #{instance.to_str}")
|
|
536
|
+
end
|
|
537
|
+
|
|
538
|
+
it "logs the action finish" do
|
|
539
|
+
instance.converge
|
|
540
|
+
|
|
541
|
+
logger_io.string.
|
|
542
|
+
must_match regex_for("Finished converging #{instance.to_str}")
|
|
543
|
+
end
|
|
544
|
+
end
|
|
545
|
+
|
|
546
|
+
describe "with last action of create" do
|
|
547
|
+
|
|
548
|
+
before { state_file.write(:last_action => "create") }
|
|
549
|
+
|
|
550
|
+
it "calls Provisioner#call with state hash" do
|
|
551
|
+
provisioner.expects(:call).
|
|
552
|
+
with { |state| state[:last_action] == "create" }
|
|
553
|
+
|
|
554
|
+
instance.converge
|
|
555
|
+
end
|
|
556
|
+
|
|
557
|
+
it "writes the state file with last_action" do
|
|
558
|
+
instance.converge
|
|
559
|
+
|
|
560
|
+
state_file.read[:last_action].must_equal "converge"
|
|
561
|
+
end
|
|
562
|
+
end
|
|
563
|
+
|
|
564
|
+
describe "with last action of converge" do
|
|
565
|
+
|
|
566
|
+
before { state_file.write(:last_action => "converge") }
|
|
567
|
+
|
|
568
|
+
it "calls Provisioner#call with state hash" do
|
|
569
|
+
provisioner.expects(:call).
|
|
570
|
+
with { |state| state[:last_action] == "converge" }
|
|
571
|
+
|
|
572
|
+
instance.converge
|
|
573
|
+
end
|
|
574
|
+
|
|
575
|
+
it "writes the state file with last_action" do
|
|
576
|
+
instance.converge
|
|
577
|
+
|
|
578
|
+
state_file.read[:last_action].must_equal "converge"
|
|
579
|
+
end
|
|
580
|
+
end
|
|
581
|
+
end
|
|
582
|
+
|
|
583
|
+
describe "#setup" do
|
|
584
|
+
|
|
585
|
+
describe "with no state" do
|
|
586
|
+
|
|
587
|
+
it "calls create and converge with empty state hash" do
|
|
588
|
+
driver.expects(:create).with(Hash.new)
|
|
589
|
+
provisioner.expects(:call).
|
|
590
|
+
with { |state| state[:last_action] == "create" }
|
|
591
|
+
driver.expects(:setup).
|
|
592
|
+
with { |state| state[:last_action] == "converge" }.
|
|
593
|
+
never
|
|
594
|
+
|
|
595
|
+
instance.setup
|
|
596
|
+
end
|
|
597
|
+
|
|
598
|
+
it "writes the state file with last_action" do
|
|
599
|
+
instance.setup
|
|
600
|
+
|
|
601
|
+
state_file.read[:last_action].must_equal "setup"
|
|
602
|
+
end
|
|
603
|
+
|
|
604
|
+
it "logs the action start" do
|
|
605
|
+
instance.setup
|
|
606
|
+
|
|
607
|
+
logger_io.string.must_match regex_for("Setting up #{instance.to_str}")
|
|
608
|
+
end
|
|
609
|
+
|
|
610
|
+
it "logs the action finish" do
|
|
611
|
+
instance.setup
|
|
612
|
+
|
|
613
|
+
logger_io.string.
|
|
614
|
+
must_match regex_for("Finished setting up #{instance.to_str}")
|
|
615
|
+
end
|
|
616
|
+
end
|
|
617
|
+
|
|
618
|
+
describe "with last action of create" do
|
|
619
|
+
|
|
620
|
+
before { state_file.write(:last_action => "create") }
|
|
621
|
+
|
|
622
|
+
it "calls Provisioner#call with state hash" do
|
|
623
|
+
provisioner.expects(:call).
|
|
624
|
+
with { |state| state[:last_action] == "create" }
|
|
625
|
+
driver.expects(:setup).
|
|
626
|
+
with { |state| state[:last_action] == "converge" }.
|
|
627
|
+
never
|
|
628
|
+
|
|
629
|
+
instance.setup
|
|
630
|
+
end
|
|
631
|
+
|
|
632
|
+
it "writes the state file with last_action" do
|
|
633
|
+
instance.setup
|
|
634
|
+
|
|
635
|
+
state_file.read[:last_action].must_equal "setup"
|
|
636
|
+
end
|
|
637
|
+
end
|
|
638
|
+
|
|
639
|
+
describe "with last action of converge" do
|
|
640
|
+
|
|
641
|
+
before { state_file.write(:last_action => "converge") }
|
|
642
|
+
|
|
643
|
+
it "calls nothing with state hash" do
|
|
644
|
+
driver.expects(:setup).
|
|
645
|
+
with { |state| state[:last_action] == "converge" }.
|
|
646
|
+
never
|
|
647
|
+
|
|
648
|
+
instance.setup
|
|
649
|
+
end
|
|
650
|
+
|
|
651
|
+
it "writes the state file with last_action" do
|
|
652
|
+
instance.setup
|
|
653
|
+
|
|
654
|
+
state_file.read[:last_action].must_equal "setup"
|
|
655
|
+
end
|
|
656
|
+
end
|
|
657
|
+
|
|
658
|
+
describe "with last action of setup" do
|
|
659
|
+
|
|
660
|
+
before { state_file.write(:last_action => "setup") }
|
|
661
|
+
|
|
662
|
+
it "calls nothing with state hash" do
|
|
663
|
+
driver.expects(:setup).
|
|
664
|
+
with { |state| state[:last_action] == "setup" }.
|
|
665
|
+
never
|
|
666
|
+
|
|
667
|
+
instance.setup
|
|
668
|
+
end
|
|
669
|
+
|
|
670
|
+
it "writes the state file with last_action" do
|
|
671
|
+
instance.setup
|
|
672
|
+
|
|
673
|
+
state_file.read[:last_action].must_equal "setup"
|
|
674
|
+
end
|
|
675
|
+
end
|
|
676
|
+
end
|
|
677
|
+
|
|
678
|
+
describe "#verify" do
|
|
679
|
+
|
|
680
|
+
describe "with no state" do
|
|
681
|
+
|
|
682
|
+
it "calls create, converge, and verify with empty state hash" do
|
|
683
|
+
driver.expects(:create).with(Hash.new)
|
|
684
|
+
provisioner.expects(:call).
|
|
685
|
+
with { |state| state[:last_action] == "create" }
|
|
686
|
+
driver.expects(:setup).
|
|
687
|
+
with { |state| state[:last_action] == "converge" }.
|
|
688
|
+
never
|
|
689
|
+
verifier.expects(:call).
|
|
690
|
+
with { |state| state[:last_action] == "setup" }
|
|
691
|
+
|
|
692
|
+
instance.verify
|
|
693
|
+
end
|
|
694
|
+
|
|
695
|
+
it "writes the state file with last_action" do
|
|
696
|
+
instance.verify
|
|
697
|
+
|
|
698
|
+
state_file.read[:last_action].must_equal "verify"
|
|
699
|
+
end
|
|
700
|
+
|
|
701
|
+
it "logs the action start" do
|
|
702
|
+
instance.verify
|
|
703
|
+
|
|
704
|
+
logger_io.string.must_match regex_for("Verifying #{instance.to_str}")
|
|
705
|
+
end
|
|
706
|
+
|
|
707
|
+
it "logs the action finish" do
|
|
708
|
+
instance.verify
|
|
709
|
+
|
|
710
|
+
logger_io.string.
|
|
711
|
+
must_match regex_for("Finished verifying #{instance.to_str}")
|
|
712
|
+
end
|
|
713
|
+
end
|
|
714
|
+
|
|
715
|
+
describe "with last of create" do
|
|
716
|
+
|
|
717
|
+
before { state_file.write(:last_action => "create") }
|
|
718
|
+
|
|
719
|
+
it "calls converge, and verify with state hash" do
|
|
720
|
+
provisioner.expects(:call).
|
|
721
|
+
with { |state| state[:last_action] == "create" }
|
|
722
|
+
driver.expects(:setup).
|
|
723
|
+
with { |state| state[:last_action] == "converge" }.
|
|
724
|
+
never
|
|
725
|
+
verifier.expects(:call).
|
|
726
|
+
with { |state| state[:last_action] == "setup" }
|
|
727
|
+
|
|
728
|
+
instance.verify
|
|
729
|
+
end
|
|
730
|
+
|
|
731
|
+
it "writes the state file with last_action" do
|
|
732
|
+
instance.verify
|
|
733
|
+
|
|
734
|
+
state_file.read[:last_action].must_equal "verify"
|
|
735
|
+
end
|
|
736
|
+
end
|
|
737
|
+
|
|
738
|
+
describe "with last of converge" do
|
|
739
|
+
|
|
740
|
+
before { state_file.write(:last_action => "converge") }
|
|
741
|
+
|
|
742
|
+
it "calls Verifier#call with state hash" do
|
|
743
|
+
driver.expects(:setup).
|
|
744
|
+
with { |state| state[:last_action] == "converge" }.
|
|
745
|
+
never
|
|
746
|
+
verifier.expects(:call).
|
|
747
|
+
with { |state| state[:last_action] == "setup" }
|
|
748
|
+
|
|
749
|
+
instance.verify
|
|
750
|
+
end
|
|
751
|
+
|
|
752
|
+
it "writes the state file with last_action" do
|
|
753
|
+
instance.verify
|
|
754
|
+
|
|
755
|
+
state_file.read[:last_action].must_equal "verify"
|
|
756
|
+
end
|
|
757
|
+
end
|
|
758
|
+
|
|
759
|
+
describe "with last of setup" do
|
|
760
|
+
|
|
761
|
+
before { state_file.write(:last_action => "setup") }
|
|
762
|
+
|
|
763
|
+
it "calls Verifier#call with state hash" do
|
|
764
|
+
verifier.expects(:call).
|
|
765
|
+
with { |state| state[:last_action] == "setup" }
|
|
766
|
+
|
|
767
|
+
instance.verify
|
|
768
|
+
end
|
|
769
|
+
|
|
770
|
+
it "writes the state file with last_action" do
|
|
771
|
+
instance.verify
|
|
772
|
+
|
|
773
|
+
state_file.read[:last_action].must_equal "verify"
|
|
774
|
+
end
|
|
775
|
+
end
|
|
776
|
+
|
|
777
|
+
describe "with last of verify" do
|
|
778
|
+
|
|
779
|
+
before { state_file.write(:last_action => "verify") }
|
|
780
|
+
|
|
781
|
+
it "calls Verifier#call with state hash" do
|
|
782
|
+
verifier.expects(:call).
|
|
783
|
+
with { |state| state[:last_action] == "verify" }
|
|
784
|
+
|
|
785
|
+
instance.verify
|
|
786
|
+
end
|
|
787
|
+
|
|
788
|
+
it "writes the state file with last_action" do
|
|
789
|
+
instance.verify
|
|
790
|
+
|
|
791
|
+
state_file.read[:last_action].must_equal "verify"
|
|
792
|
+
end
|
|
793
|
+
end
|
|
794
|
+
end
|
|
795
|
+
|
|
796
|
+
describe "#destroy" do
|
|
797
|
+
|
|
798
|
+
describe "with no state" do
|
|
799
|
+
|
|
800
|
+
it "calls Driver#destroy with empty state hash" do
|
|
801
|
+
driver.expects(:destroy).with(Hash.new)
|
|
802
|
+
|
|
803
|
+
instance.destroy
|
|
804
|
+
end
|
|
805
|
+
|
|
806
|
+
it "destroys the state file" do
|
|
807
|
+
state_file.expects(:destroy)
|
|
808
|
+
|
|
809
|
+
instance.destroy
|
|
810
|
+
end
|
|
811
|
+
|
|
812
|
+
it "logs the action start" do
|
|
813
|
+
instance.destroy
|
|
814
|
+
|
|
815
|
+
logger_io.string.
|
|
816
|
+
must_match regex_for("Destroying #{instance.to_str}")
|
|
817
|
+
end
|
|
818
|
+
|
|
819
|
+
it "logs the create finish" do
|
|
820
|
+
instance.destroy
|
|
821
|
+
|
|
822
|
+
logger_io.string.
|
|
823
|
+
must_match regex_for("Finished destroying #{instance.to_str}")
|
|
824
|
+
end
|
|
825
|
+
end
|
|
826
|
+
|
|
827
|
+
[:create, :converge, :setup, :verify].each do |action|
|
|
828
|
+
|
|
829
|
+
describe "with last_action of #{action}" do
|
|
830
|
+
|
|
831
|
+
before { state_file.write(:last_action => action) }
|
|
832
|
+
|
|
833
|
+
it "calls Driver#create with state hash" do
|
|
834
|
+
driver.expects(:destroy).
|
|
835
|
+
with { |state| state[:last_action] == action }
|
|
836
|
+
|
|
837
|
+
instance.destroy
|
|
838
|
+
end
|
|
839
|
+
|
|
840
|
+
it "destroys the state file" do
|
|
841
|
+
state_file.expects(:destroy)
|
|
842
|
+
|
|
843
|
+
instance.destroy
|
|
844
|
+
end
|
|
845
|
+
end
|
|
846
|
+
end
|
|
847
|
+
end
|
|
848
|
+
|
|
849
|
+
describe "#test" do
|
|
850
|
+
|
|
851
|
+
describe "with no state" do
|
|
852
|
+
|
|
853
|
+
it "calls destroy, create, converge, setup, verify, destroy" do
|
|
854
|
+
driver.expects(:destroy)
|
|
855
|
+
driver.expects(:create)
|
|
856
|
+
provisioner.expects(:call)
|
|
857
|
+
verifier.expects(:call)
|
|
858
|
+
driver.expects(:destroy)
|
|
859
|
+
|
|
860
|
+
instance.test
|
|
861
|
+
end
|
|
862
|
+
|
|
863
|
+
it "logs the action start" do
|
|
864
|
+
instance.test
|
|
865
|
+
|
|
866
|
+
logger_io.string.must_match regex_for("Testing #{instance.to_str}")
|
|
867
|
+
end
|
|
868
|
+
|
|
869
|
+
it "logs the action finish" do
|
|
870
|
+
instance.test
|
|
871
|
+
|
|
872
|
+
logger_io.string.
|
|
873
|
+
must_match regex_for("Finished testing #{instance.to_str}")
|
|
874
|
+
end
|
|
875
|
+
end
|
|
876
|
+
|
|
877
|
+
[:create, :converge, :setup, :verify].each do |action|
|
|
878
|
+
|
|
879
|
+
describe "with last action of #{action}" do
|
|
880
|
+
|
|
881
|
+
before { state_file.write(:last_action => action) }
|
|
882
|
+
|
|
883
|
+
it "calls destroy, create, converge, setup, verify, destroy" do
|
|
884
|
+
driver.expects(:destroy)
|
|
885
|
+
driver.expects(:create)
|
|
886
|
+
provisioner.expects(:call)
|
|
887
|
+
verifier.expects(:call)
|
|
888
|
+
driver.expects(:destroy)
|
|
889
|
+
|
|
890
|
+
instance.test
|
|
891
|
+
end
|
|
892
|
+
end
|
|
893
|
+
end
|
|
894
|
+
|
|
895
|
+
describe "with destroy mode of never" do
|
|
896
|
+
|
|
897
|
+
it "calls destroy, create, converge, setup, verify" do
|
|
898
|
+
driver.expects(:destroy).once
|
|
899
|
+
driver.expects(:create)
|
|
900
|
+
provisioner.expects(:call)
|
|
901
|
+
verifier.expects(:call)
|
|
902
|
+
|
|
903
|
+
instance.test(:never)
|
|
904
|
+
end
|
|
905
|
+
end
|
|
906
|
+
|
|
907
|
+
describe "with destroy mode of always" do
|
|
908
|
+
|
|
909
|
+
it "calls destroy at even when action fails" do
|
|
910
|
+
driver.expects(:destroy)
|
|
911
|
+
driver.expects(:create)
|
|
912
|
+
provisioner.expects(:call).raises(Kitchen::ActionFailed)
|
|
913
|
+
driver.expects(:destroy)
|
|
914
|
+
|
|
915
|
+
begin
|
|
916
|
+
instance.test(:always)
|
|
917
|
+
rescue # rubocop:disable Lint/HandleExceptions
|
|
918
|
+
end
|
|
919
|
+
end
|
|
920
|
+
end
|
|
921
|
+
|
|
922
|
+
describe "with destroy mode of passing" do
|
|
923
|
+
|
|
924
|
+
it "doesn't call Driver#destroy at when action fails" do
|
|
925
|
+
driver.stubs(:create).raises(Kitchen::ActionFailed)
|
|
926
|
+
|
|
927
|
+
driver.expects(:destroy).once
|
|
928
|
+
|
|
929
|
+
begin
|
|
930
|
+
instance.test(:passing)
|
|
931
|
+
rescue # rubocop:disable Lint/HandleExceptions
|
|
932
|
+
end
|
|
933
|
+
end
|
|
934
|
+
end
|
|
935
|
+
end
|
|
936
|
+
|
|
937
|
+
describe "#remote_exec" do
|
|
938
|
+
|
|
939
|
+
before { state_file.write(:last_action => "create") }
|
|
940
|
+
|
|
941
|
+
it "calls Transport#execute with command" do
|
|
942
|
+
connection = mock("connection")
|
|
943
|
+
connection.expects(:execute).with("uptime")
|
|
944
|
+
transport.stubs(:connection).yields(connection)
|
|
945
|
+
|
|
946
|
+
instance.remote_exec("uptime")
|
|
947
|
+
end
|
|
948
|
+
end
|
|
949
|
+
|
|
950
|
+
[:create, :converge, :setup, :verify, :test].each do |action|
|
|
951
|
+
|
|
952
|
+
describe "#{action} on driver crash with ActionFailed" do
|
|
953
|
+
|
|
954
|
+
before do
|
|
955
|
+
driver.stubs(:create).raises(Kitchen::ActionFailed, "death")
|
|
956
|
+
end
|
|
957
|
+
|
|
958
|
+
it "write the state file with last action" do
|
|
959
|
+
begin
|
|
960
|
+
instance.public_send(action)
|
|
961
|
+
rescue Kitchen::Error
|
|
962
|
+
true # no need to act here
|
|
963
|
+
end
|
|
964
|
+
|
|
965
|
+
state_file.read[:last_action].must_be_nil
|
|
966
|
+
end
|
|
967
|
+
|
|
968
|
+
it "raises an InstanceFailure" do
|
|
969
|
+
proc { instance.public_send(action) }.
|
|
970
|
+
must_raise Kitchen::InstanceFailure
|
|
971
|
+
end
|
|
972
|
+
|
|
973
|
+
it "populates the InstanceFailure message" do
|
|
974
|
+
begin
|
|
975
|
+
instance.public_send(action)
|
|
976
|
+
rescue Kitchen::Error => e
|
|
977
|
+
e.message.must_match regex_for(
|
|
978
|
+
"Create failed on instance #{instance.to_str}")
|
|
979
|
+
end
|
|
980
|
+
end
|
|
981
|
+
|
|
982
|
+
it "logs the failure" do
|
|
983
|
+
begin
|
|
984
|
+
instance.public_send(action)
|
|
985
|
+
rescue Kitchen::Error
|
|
986
|
+
true # no need to act here
|
|
987
|
+
end
|
|
988
|
+
|
|
989
|
+
logger_io.string.must_match regex_for(
|
|
990
|
+
"Create failed on instance #{instance.to_str}")
|
|
991
|
+
end
|
|
992
|
+
end
|
|
993
|
+
|
|
994
|
+
describe "on driver crash with unexpected exception class" do
|
|
995
|
+
|
|
996
|
+
before do
|
|
997
|
+
driver.stubs(:create).raises(RuntimeError, "watwat")
|
|
998
|
+
end
|
|
999
|
+
|
|
1000
|
+
it "write the state file with last action" do
|
|
1001
|
+
begin
|
|
1002
|
+
instance.public_send(action)
|
|
1003
|
+
rescue Kitchen::Error
|
|
1004
|
+
true # no need to act here
|
|
1005
|
+
end
|
|
1006
|
+
|
|
1007
|
+
state_file.read[:last_action].must_be_nil
|
|
1008
|
+
end
|
|
1009
|
+
|
|
1010
|
+
it "raises an ActionFailed" do
|
|
1011
|
+
proc { instance.public_send(action) }.
|
|
1012
|
+
must_raise Kitchen::ActionFailed
|
|
1013
|
+
end
|
|
1014
|
+
|
|
1015
|
+
it "populates the ActionFailed message" do
|
|
1016
|
+
begin
|
|
1017
|
+
instance.public_send(action)
|
|
1018
|
+
rescue Kitchen::Error => e
|
|
1019
|
+
e.message.must_match regex_for(
|
|
1020
|
+
"Failed to complete #create action: [watwat]")
|
|
1021
|
+
end
|
|
1022
|
+
end
|
|
1023
|
+
|
|
1024
|
+
it "logs the failure" do
|
|
1025
|
+
begin
|
|
1026
|
+
instance.public_send(action)
|
|
1027
|
+
rescue Kitchen::Error
|
|
1028
|
+
true # no need to act here
|
|
1029
|
+
end
|
|
1030
|
+
|
|
1031
|
+
logger_io.string.must_match regex_for(
|
|
1032
|
+
"Create failed on instance #{instance.to_str}")
|
|
1033
|
+
end
|
|
1034
|
+
end
|
|
1035
|
+
end
|
|
1036
|
+
|
|
1037
|
+
describe "crashes preserve last action for desired verify action" do
|
|
1038
|
+
|
|
1039
|
+
before do
|
|
1040
|
+
verifier.stubs(:call).raises(Kitchen::ActionFailed, "death")
|
|
1041
|
+
end
|
|
1042
|
+
|
|
1043
|
+
[:create, :converge, :setup].each do |action|
|
|
1044
|
+
|
|
1045
|
+
it "for last state #{action}" do
|
|
1046
|
+
state_file.write(:last_action => action.to_s)
|
|
1047
|
+
begin
|
|
1048
|
+
instance.verify
|
|
1049
|
+
rescue Kitchen::Error
|
|
1050
|
+
true # no need to act here
|
|
1051
|
+
end
|
|
1052
|
+
|
|
1053
|
+
state_file.read[:last_action].must_equal "setup"
|
|
1054
|
+
end
|
|
1055
|
+
end
|
|
1056
|
+
|
|
1057
|
+
it "for last state verify" do
|
|
1058
|
+
state_file.write(:last_action => "verify")
|
|
1059
|
+
begin
|
|
1060
|
+
instance.verify
|
|
1061
|
+
rescue Kitchen::Error
|
|
1062
|
+
true # no need to act here
|
|
1063
|
+
end
|
|
1064
|
+
|
|
1065
|
+
state_file.read[:last_action].must_equal "verify"
|
|
1066
|
+
end
|
|
1067
|
+
end
|
|
1068
|
+
|
|
1069
|
+
describe "on drivers with serial actions" do
|
|
1070
|
+
|
|
1071
|
+
let(:driver) { SerialDummyDriver.new({}) }
|
|
1072
|
+
|
|
1073
|
+
it "runs in a synchronized block for serial actions" do
|
|
1074
|
+
instance.test
|
|
1075
|
+
|
|
1076
|
+
driver.action_in_mutex[:create].must_equal true
|
|
1077
|
+
driver.action_in_mutex[:destroy].must_equal true
|
|
1078
|
+
end
|
|
1079
|
+
end
|
|
1080
|
+
|
|
1081
|
+
describe "with legacy Driver::SSHBase subclasses" do
|
|
1082
|
+
|
|
1083
|
+
let(:driver) { LegacyDriver.new({}) }
|
|
1084
|
+
|
|
1085
|
+
describe "#converge" do
|
|
1086
|
+
|
|
1087
|
+
describe "with no state" do
|
|
1088
|
+
|
|
1089
|
+
it "calls Driver#create and Driver#converge with empty state hash" do
|
|
1090
|
+
driver.expects(:create).with(Hash.new)
|
|
1091
|
+
driver.expects(:converge).
|
|
1092
|
+
with { |state| state[:last_action] == "create" }
|
|
1093
|
+
|
|
1094
|
+
instance.converge
|
|
1095
|
+
end
|
|
1096
|
+
end
|
|
1097
|
+
|
|
1098
|
+
describe "with last action of create" do
|
|
1099
|
+
|
|
1100
|
+
before { state_file.write(:last_action => "create") }
|
|
1101
|
+
|
|
1102
|
+
it "calls Driver#converge with state hash" do
|
|
1103
|
+
driver.expects(:converge).
|
|
1104
|
+
with { |state| state[:last_action] == "create" }
|
|
1105
|
+
|
|
1106
|
+
instance.converge
|
|
1107
|
+
end
|
|
1108
|
+
end
|
|
1109
|
+
|
|
1110
|
+
describe "with last action of converge" do
|
|
1111
|
+
|
|
1112
|
+
before { state_file.write(:last_action => "converge") }
|
|
1113
|
+
|
|
1114
|
+
it "calls Driver#converge with state hash" do
|
|
1115
|
+
driver.expects(:converge).
|
|
1116
|
+
with { |state| state[:last_action] == "converge" }
|
|
1117
|
+
|
|
1118
|
+
instance.converge
|
|
1119
|
+
end
|
|
1120
|
+
end
|
|
1121
|
+
end
|
|
1122
|
+
|
|
1123
|
+
describe "#setup" do
|
|
1124
|
+
|
|
1125
|
+
describe "with no state" do
|
|
1126
|
+
|
|
1127
|
+
it "calls create, converge, and setup with empty state hash" do
|
|
1128
|
+
driver.expects(:create).with(Hash.new)
|
|
1129
|
+
driver.expects(:converge).
|
|
1130
|
+
with { |state| state[:last_action] == "create" }
|
|
1131
|
+
driver.expects(:setup).
|
|
1132
|
+
with { |state| state[:last_action] == "converge" }
|
|
1133
|
+
|
|
1134
|
+
instance.setup
|
|
1135
|
+
end
|
|
1136
|
+
end
|
|
1137
|
+
|
|
1138
|
+
describe "with last action of create" do
|
|
1139
|
+
|
|
1140
|
+
before { state_file.write(:last_action => "create") }
|
|
1141
|
+
|
|
1142
|
+
it "calls Provisioner#call and setup with state hash" do
|
|
1143
|
+
driver.expects(:converge).
|
|
1144
|
+
with { |state| state[:last_action] == "create" }
|
|
1145
|
+
driver.expects(:setup).
|
|
1146
|
+
with { |state| state[:last_action] == "converge" }
|
|
1147
|
+
|
|
1148
|
+
instance.setup
|
|
1149
|
+
end
|
|
1150
|
+
end
|
|
1151
|
+
|
|
1152
|
+
describe "with last action of converge" do
|
|
1153
|
+
|
|
1154
|
+
before { state_file.write(:last_action => "converge") }
|
|
1155
|
+
|
|
1156
|
+
it "calls Driver#setup with state hash" do
|
|
1157
|
+
driver.expects(:setup).
|
|
1158
|
+
with { |state| state[:last_action] == "converge" }
|
|
1159
|
+
|
|
1160
|
+
instance.setup
|
|
1161
|
+
end
|
|
1162
|
+
end
|
|
1163
|
+
|
|
1164
|
+
describe "with last action of setup" do
|
|
1165
|
+
|
|
1166
|
+
before { state_file.write(:last_action => "setup") }
|
|
1167
|
+
|
|
1168
|
+
it "calls Driver#setup with state hash" do
|
|
1169
|
+
driver.expects(:setup).
|
|
1170
|
+
with { |state| state[:last_action] == "setup" }
|
|
1171
|
+
|
|
1172
|
+
instance.setup
|
|
1173
|
+
end
|
|
1174
|
+
end
|
|
1175
|
+
end
|
|
1176
|
+
|
|
1177
|
+
describe "#verify" do
|
|
1178
|
+
|
|
1179
|
+
describe "with no state" do
|
|
1180
|
+
|
|
1181
|
+
it "calls create, converge, setup, and verify with empty state hash" do
|
|
1182
|
+
driver.expects(:create).with(Hash.new)
|
|
1183
|
+
driver.expects(:converge).
|
|
1184
|
+
with { |state| state[:last_action] == "create" }
|
|
1185
|
+
driver.expects(:setup).
|
|
1186
|
+
with { |state| state[:last_action] == "converge" }
|
|
1187
|
+
driver.expects(:verify).
|
|
1188
|
+
with { |state| state[:last_action] == "setup" }
|
|
1189
|
+
|
|
1190
|
+
instance.verify
|
|
1191
|
+
end
|
|
1192
|
+
end
|
|
1193
|
+
|
|
1194
|
+
describe "with last of create" do
|
|
1195
|
+
|
|
1196
|
+
before { state_file.write(:last_action => "create") }
|
|
1197
|
+
|
|
1198
|
+
it "calls converge, setup, and verify with state hash" do
|
|
1199
|
+
driver.expects(:converge).
|
|
1200
|
+
with { |state| state[:last_action] == "create" }
|
|
1201
|
+
driver.expects(:setup).
|
|
1202
|
+
with { |state| state[:last_action] == "converge" }
|
|
1203
|
+
driver.expects(:verify).
|
|
1204
|
+
with { |state| state[:last_action] == "setup" }
|
|
1205
|
+
|
|
1206
|
+
instance.verify
|
|
1207
|
+
end
|
|
1208
|
+
end
|
|
1209
|
+
|
|
1210
|
+
describe "with last of converge" do
|
|
1211
|
+
|
|
1212
|
+
before { state_file.write(:last_action => "converge") }
|
|
1213
|
+
|
|
1214
|
+
it "calls Driver#setup, and verify with state hash" do
|
|
1215
|
+
driver.expects(:setup).
|
|
1216
|
+
with { |state| state[:last_action] == "converge" }
|
|
1217
|
+
driver.expects(:verify).
|
|
1218
|
+
with { |state| state[:last_action] == "setup" }
|
|
1219
|
+
|
|
1220
|
+
instance.verify
|
|
1221
|
+
end
|
|
1222
|
+
end
|
|
1223
|
+
|
|
1224
|
+
describe "with last of setup" do
|
|
1225
|
+
|
|
1226
|
+
before { state_file.write(:last_action => "setup") }
|
|
1227
|
+
|
|
1228
|
+
it "calls Driver#verify with state hash" do
|
|
1229
|
+
driver.expects(:verify).
|
|
1230
|
+
with { |state| state[:last_action] == "setup" }
|
|
1231
|
+
|
|
1232
|
+
instance.verify
|
|
1233
|
+
end
|
|
1234
|
+
end
|
|
1235
|
+
|
|
1236
|
+
describe "with last of verify" do
|
|
1237
|
+
|
|
1238
|
+
before { state_file.write(:last_action => "verify") }
|
|
1239
|
+
|
|
1240
|
+
it "calls Driver#verify with state hash" do
|
|
1241
|
+
driver.expects(:verify).
|
|
1242
|
+
with { |state| state[:last_action] == "verify" }
|
|
1243
|
+
|
|
1244
|
+
instance.verify
|
|
1245
|
+
end
|
|
1246
|
+
end
|
|
1247
|
+
end
|
|
1248
|
+
|
|
1249
|
+
describe "#test" do
|
|
1250
|
+
|
|
1251
|
+
describe "with no state" do
|
|
1252
|
+
|
|
1253
|
+
it "calls destroy, create, converge, setup, verify, destroy" do
|
|
1254
|
+
driver.expects(:destroy)
|
|
1255
|
+
driver.expects(:create)
|
|
1256
|
+
driver.expects(:converge)
|
|
1257
|
+
driver.expects(:setup)
|
|
1258
|
+
driver.expects(:verify)
|
|
1259
|
+
driver.expects(:destroy)
|
|
1260
|
+
|
|
1261
|
+
instance.test
|
|
1262
|
+
end
|
|
1263
|
+
end
|
|
1264
|
+
|
|
1265
|
+
[:create, :converge, :setup, :verify].each do |action|
|
|
1266
|
+
|
|
1267
|
+
describe "with last action of #{action}" do
|
|
1268
|
+
|
|
1269
|
+
before { state_file.write(:last_action => action) }
|
|
1270
|
+
|
|
1271
|
+
it "calls destroy, create, converge, setup, verify, destroy" do
|
|
1272
|
+
driver.expects(:destroy)
|
|
1273
|
+
driver.expects(:create)
|
|
1274
|
+
driver.expects(:converge)
|
|
1275
|
+
driver.expects(:setup)
|
|
1276
|
+
driver.expects(:verify)
|
|
1277
|
+
driver.expects(:destroy)
|
|
1278
|
+
|
|
1279
|
+
instance.test
|
|
1280
|
+
end
|
|
1281
|
+
end
|
|
1282
|
+
end
|
|
1283
|
+
|
|
1284
|
+
describe "with destroy mode of never" do
|
|
1285
|
+
|
|
1286
|
+
it "calls destroy, create, converge, setup, verify" do
|
|
1287
|
+
driver.expects(:destroy).once
|
|
1288
|
+
driver.expects(:create)
|
|
1289
|
+
driver.expects(:converge)
|
|
1290
|
+
driver.expects(:setup)
|
|
1291
|
+
driver.expects(:verify)
|
|
1292
|
+
|
|
1293
|
+
instance.test(:never)
|
|
1294
|
+
end
|
|
1295
|
+
end
|
|
1296
|
+
|
|
1297
|
+
describe "with destroy mode of always" do
|
|
1298
|
+
|
|
1299
|
+
it "calls destroy at even when action fails" do
|
|
1300
|
+
driver.expects(:destroy)
|
|
1301
|
+
driver.expects(:create)
|
|
1302
|
+
driver.expects(:converge).raises(Kitchen::ActionFailed)
|
|
1303
|
+
driver.expects(:destroy)
|
|
1304
|
+
|
|
1305
|
+
begin
|
|
1306
|
+
instance.test(:always)
|
|
1307
|
+
rescue # rubocop:disable Lint/HandleExceptions
|
|
1308
|
+
end
|
|
1309
|
+
end
|
|
1310
|
+
end
|
|
1311
|
+
end
|
|
1312
|
+
|
|
1313
|
+
it "#login executes the driver's login_command" do
|
|
1314
|
+
state_file.write(:last_action => "create")
|
|
1315
|
+
driver.stubs(:login_command).with(:last_action => "create").
|
|
1316
|
+
returns(Kitchen::LoginCommand.new("echo", ["hello"], :purple => true))
|
|
1317
|
+
Kernel.expects(:exec).with("echo", "hello", :purple => true)
|
|
1318
|
+
|
|
1319
|
+
instance.login
|
|
1320
|
+
end
|
|
1321
|
+
end
|
|
1322
|
+
end
|
|
1323
|
+
|
|
1324
|
+
describe Kitchen::Instance::FSM do
|
|
1325
|
+
|
|
1326
|
+
let(:fsm) { Kitchen::Instance::FSM }
|
|
1327
|
+
|
|
1328
|
+
describe ".actions" do
|
|
1329
|
+
|
|
1330
|
+
it "passing nils returns destroy" do
|
|
1331
|
+
fsm.actions(nil, nil).must_equal [:destroy]
|
|
1332
|
+
end
|
|
1333
|
+
|
|
1334
|
+
it "accepts a string for desired argument" do
|
|
1335
|
+
fsm.actions(nil, "create").must_equal [:create]
|
|
1336
|
+
end
|
|
1337
|
+
|
|
1338
|
+
it "accepts a symbol for desired argument" do
|
|
1339
|
+
fsm.actions(nil, :create).must_equal [:create]
|
|
1340
|
+
end
|
|
1341
|
+
|
|
1342
|
+
it "starting from no state to create returns create" do
|
|
1343
|
+
fsm.actions(nil, :create).must_equal [:create]
|
|
1344
|
+
end
|
|
1345
|
+
|
|
1346
|
+
it "starting from :create to create returns create" do
|
|
1347
|
+
fsm.actions(:create, :create).must_equal [:create]
|
|
1348
|
+
end
|
|
1349
|
+
|
|
1350
|
+
it "starting from no state to converge returns create, converge" do
|
|
1351
|
+
fsm.actions(nil, :converge).must_equal [:create, :converge]
|
|
1352
|
+
end
|
|
1353
|
+
|
|
1354
|
+
it "starting from create to converge returns converge" do
|
|
1355
|
+
fsm.actions(:create, :converge).must_equal [:converge]
|
|
1356
|
+
end
|
|
1357
|
+
|
|
1358
|
+
it "starting from converge to converge returns converge" do
|
|
1359
|
+
fsm.actions(:converge, :converge).must_equal [:converge]
|
|
1360
|
+
end
|
|
1361
|
+
|
|
1362
|
+
it "starting from no state to setup returns create, converge, setup" do
|
|
1363
|
+
fsm.actions(nil, :setup).must_equal [:create, :converge, :setup]
|
|
1364
|
+
end
|
|
1365
|
+
|
|
1366
|
+
it "starting from create to setup returns converge, setup" do
|
|
1367
|
+
fsm.actions(:create, :setup).must_equal [:converge, :setup]
|
|
1368
|
+
end
|
|
1369
|
+
|
|
1370
|
+
it "starting from converge to setup returns setup" do
|
|
1371
|
+
fsm.actions(:converge, :setup).must_equal [:setup]
|
|
1372
|
+
end
|
|
1373
|
+
|
|
1374
|
+
it "starting from setup to setup return setup" do
|
|
1375
|
+
fsm.actions(:setup, :setup).must_equal [:setup]
|
|
1376
|
+
end
|
|
1377
|
+
|
|
1378
|
+
it "starting from no state to verify returns create, converge, setup, verify" do
|
|
1379
|
+
fsm.actions(nil, :verify).must_equal [:create, :converge, :setup, :verify]
|
|
1380
|
+
end
|
|
1381
|
+
|
|
1382
|
+
it "starting from create to verify returns converge, setup, verify" do
|
|
1383
|
+
fsm.actions(:create, :verify).must_equal [:converge, :setup, :verify]
|
|
1384
|
+
end
|
|
1385
|
+
|
|
1386
|
+
it "starting from converge to verify returns setup, verify" do
|
|
1387
|
+
fsm.actions(:converge, :verify).must_equal [:setup, :verify]
|
|
1388
|
+
end
|
|
1389
|
+
|
|
1390
|
+
it "starting from setup to verify returns verify" do
|
|
1391
|
+
fsm.actions(:setup, :verify).must_equal [:verify]
|
|
1392
|
+
end
|
|
1393
|
+
|
|
1394
|
+
it "starting from verify to verify returns verify" do
|
|
1395
|
+
fsm.actions(:verify, :verify).must_equal [:verify]
|
|
1396
|
+
end
|
|
1397
|
+
|
|
1398
|
+
[:verify, :setup, :converge].each do |s|
|
|
1399
|
+
it "starting from #{s} to create returns create" do
|
|
1400
|
+
fsm.actions(s, :create).must_equal [:create]
|
|
1401
|
+
end
|
|
1402
|
+
end
|
|
1403
|
+
|
|
1404
|
+
[:verify, :setup].each do |s|
|
|
1405
|
+
it "starting from #{s} to converge returns converge" do
|
|
1406
|
+
fsm.actions(s, :converge).must_equal [:converge]
|
|
1407
|
+
end
|
|
1408
|
+
end
|
|
1409
|
+
|
|
1410
|
+
it "starting from verify to setup returns setup" do
|
|
1411
|
+
fsm.actions(:verify, :setup).must_equal [:setup]
|
|
1412
|
+
end
|
|
1413
|
+
end
|
|
1414
|
+
end
|
|
1415
|
+
|
|
1416
|
+
def regex_for(string)
|
|
1417
|
+
Regexp.new(Regexp.escape(string))
|
|
1418
|
+
end
|
|
1419
|
+
end
|