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,1115 +1,1115 @@
|
|
|
1
|
-
# -*- encoding: utf-8 -*-
|
|
2
|
-
#
|
|
3
|
-
# Author:: Fletcher Nichol (<fnichol@nichol.ca>)
|
|
4
|
-
#
|
|
5
|
-
# Copyright (C) 2014, Fletcher Nichol
|
|
6
|
-
#
|
|
7
|
-
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
8
|
-
# you may not use this file except in compliance with the License.
|
|
9
|
-
# You may obtain a copy of the License at
|
|
10
|
-
#
|
|
11
|
-
# http://www.apache.org/licenses/LICENSE-2.0
|
|
12
|
-
#
|
|
13
|
-
# Unless required by applicable law or agreed to in writing, software
|
|
14
|
-
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
15
|
-
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
16
|
-
# See the License for the specific language governing permissions and
|
|
17
|
-
# limitations under the License.
|
|
18
|
-
|
|
19
|
-
require_relative "../../spec_helper"
|
|
20
|
-
|
|
21
|
-
require "kitchen"
|
|
22
|
-
require "kitchen/transport/ssh"
|
|
23
|
-
require "kitchen/verifier/busser"
|
|
24
|
-
|
|
25
|
-
module Kitchen
|
|
26
|
-
|
|
27
|
-
module Driver
|
|
28
|
-
|
|
29
|
-
class BackCompat < Kitchen::Driver::SSHBase
|
|
30
|
-
|
|
31
|
-
def use_run_remote(state, command)
|
|
32
|
-
connection = Kitchen::SSH.new(*build_ssh_args(state))
|
|
33
|
-
run_remote(command, connection)
|
|
34
|
-
end
|
|
35
|
-
|
|
36
|
-
def use_transfer_path(state, locals, remote)
|
|
37
|
-
connection = Kitchen::SSH.new(*build_ssh_args(state))
|
|
38
|
-
transfer_path(locals, remote, connection)
|
|
39
|
-
end
|
|
40
|
-
end
|
|
41
|
-
|
|
42
|
-
class SpeedyCompat < Kitchen::Driver::SSHBase
|
|
43
|
-
end
|
|
44
|
-
|
|
45
|
-
class DodgyCompat < Kitchen::Driver::SSHBase
|
|
46
|
-
|
|
47
|
-
no_parallel_for :converge
|
|
48
|
-
end
|
|
49
|
-
|
|
50
|
-
class SlowCompat < Kitchen::Driver::SSHBase
|
|
51
|
-
|
|
52
|
-
no_parallel_for :create, :destroy
|
|
53
|
-
no_parallel_for :verify
|
|
54
|
-
end
|
|
55
|
-
end
|
|
56
|
-
end
|
|
57
|
-
|
|
58
|
-
describe Kitchen::Driver::SSHBase do
|
|
59
|
-
|
|
60
|
-
let(:logged_output) { StringIO.new }
|
|
61
|
-
let(:logger) { Logger.new(logged_output) }
|
|
62
|
-
let(:config) { Hash.new }
|
|
63
|
-
let(:state) { Hash.new }
|
|
64
|
-
|
|
65
|
-
let(:verifier) do
|
|
66
|
-
v = mock("busser")
|
|
67
|
-
v.responds_like_instance_of(Kitchen::Verifier::Busser)
|
|
68
|
-
v.stubs(:install_command).returns("install")
|
|
69
|
-
v.stubs(:init_command).returns("init")
|
|
70
|
-
v.stubs(:prepare_command).returns("prepare")
|
|
71
|
-
v.stubs(:run_command).returns("run")
|
|
72
|
-
v.stubs(:create_sandbox).returns(true)
|
|
73
|
-
v.stubs(:cleanup_sandbox).returns(true)
|
|
74
|
-
v.stubs(:sandbox_path).returns("/tmp/sandbox")
|
|
75
|
-
v.stubs(:[]).with(:root_path).returns("/tmp/verifier")
|
|
76
|
-
v
|
|
77
|
-
end
|
|
78
|
-
|
|
79
|
-
let(:provisioner) do
|
|
80
|
-
stub(
|
|
81
|
-
:install_command => "install",
|
|
82
|
-
:init_command => "init",
|
|
83
|
-
:prepare_command => "prepare",
|
|
84
|
-
:run_command => "run",
|
|
85
|
-
:create_sandbox => true,
|
|
86
|
-
:cleanup_sandbox => true,
|
|
87
|
-
:sandbox_path => "/tmp/sandbox"
|
|
88
|
-
)
|
|
89
|
-
end
|
|
90
|
-
|
|
91
|
-
let(:transport) do
|
|
92
|
-
t = mock("transport")
|
|
93
|
-
t.responds_like_instance_of(Kitchen::Transport::Base)
|
|
94
|
-
t
|
|
95
|
-
end
|
|
96
|
-
|
|
97
|
-
let(:instance) do
|
|
98
|
-
stub(
|
|
99
|
-
:name => "coolbeans",
|
|
100
|
-
:logger => logger,
|
|
101
|
-
:verifier => verifier,
|
|
102
|
-
:provisioner => provisioner,
|
|
103
|
-
:transport => transport,
|
|
104
|
-
:to_str => "instance"
|
|
105
|
-
)
|
|
106
|
-
end
|
|
107
|
-
|
|
108
|
-
let(:driver) do
|
|
109
|
-
Kitchen::Driver::SSHBase.new(config).finalize_config!(instance)
|
|
110
|
-
end
|
|
111
|
-
|
|
112
|
-
it "plugin_version is not set" do
|
|
113
|
-
driver.diagnose_plugin[:version].must_equal nil
|
|
114
|
-
end
|
|
115
|
-
|
|
116
|
-
describe "configuration" do
|
|
117
|
-
|
|
118
|
-
it ":sudo defaults to true" do
|
|
119
|
-
driver[:sudo].must_equal true
|
|
120
|
-
end
|
|
121
|
-
|
|
122
|
-
it ":port defaults to 22" do
|
|
123
|
-
driver[:port].must_equal 22
|
|
124
|
-
end
|
|
125
|
-
end
|
|
126
|
-
|
|
127
|
-
it "#create raises a ClientError" do
|
|
128
|
-
proc { driver.create(state) }.must_raise Kitchen::ClientError
|
|
129
|
-
end
|
|
130
|
-
|
|
131
|
-
it "#destroy raises a ClientError" do
|
|
132
|
-
proc { driver.destroy(state) }.must_raise Kitchen::ClientError
|
|
133
|
-
end
|
|
134
|
-
|
|
135
|
-
# rubocop:disable Metrics/MethodLength, Metrics/AbcSize
|
|
136
|
-
def self.constructs_an_ssh_connection
|
|
137
|
-
describe "constructs an SSH connection" do
|
|
138
|
-
|
|
139
|
-
it "with hostname set from state" do
|
|
140
|
-
transport.expects(:connection).with { |state|
|
|
141
|
-
state[:hostname].must_equal "fizzy"
|
|
142
|
-
}.returns(stub(:login_command => stub))
|
|
143
|
-
|
|
144
|
-
cmd
|
|
145
|
-
end
|
|
146
|
-
|
|
147
|
-
it "with username set from state" do
|
|
148
|
-
transport.expects(:connection).with { |state|
|
|
149
|
-
state[:username].must_equal "bork"
|
|
150
|
-
}.returns(stub(:login_command => stub))
|
|
151
|
-
|
|
152
|
-
cmd
|
|
153
|
-
end
|
|
154
|
-
|
|
155
|
-
it "with :ssh_key option set from config" do
|
|
156
|
-
config[:ssh_key] = "wicked"
|
|
157
|
-
|
|
158
|
-
transport.expects(:connection).with { |state|
|
|
159
|
-
state[:ssh_key].must_equal "wicked"
|
|
160
|
-
}.returns(stub(:login_command => stub))
|
|
161
|
-
|
|
162
|
-
cmd
|
|
163
|
-
end
|
|
164
|
-
|
|
165
|
-
it "with :ssh_key option set from state" do
|
|
166
|
-
state[:ssh_key] = "wicked"
|
|
167
|
-
|
|
168
|
-
transport.expects(:connection).with { |state|
|
|
169
|
-
state[:ssh_key].must_equal "wicked"
|
|
170
|
-
}.returns(stub(:login_command => stub))
|
|
171
|
-
|
|
172
|
-
cmd
|
|
173
|
-
end
|
|
174
|
-
|
|
175
|
-
it "with :password option set to falsey by default" do
|
|
176
|
-
transport.expects(:connection).with { |state|
|
|
177
|
-
state[:password].nil?
|
|
178
|
-
}.returns(stub(:login_command => stub))
|
|
179
|
-
|
|
180
|
-
cmd
|
|
181
|
-
end
|
|
182
|
-
|
|
183
|
-
it "with :password option set if given in config" do
|
|
184
|
-
config[:password] = "psst"
|
|
185
|
-
|
|
186
|
-
transport.expects(:connection).with { |state|
|
|
187
|
-
state[:password].must_equal "psst"
|
|
188
|
-
}.returns(stub(:login_command => stub))
|
|
189
|
-
|
|
190
|
-
cmd
|
|
191
|
-
end
|
|
192
|
-
|
|
193
|
-
it "with :password option set if given in state" do
|
|
194
|
-
state[:password] = "psst"
|
|
195
|
-
|
|
196
|
-
transport.expects(:connection).with { |state|
|
|
197
|
-
state[:password].must_equal "psst"
|
|
198
|
-
}.returns(stub(:login_command => stub))
|
|
199
|
-
|
|
200
|
-
cmd
|
|
201
|
-
end
|
|
202
|
-
|
|
203
|
-
it "with :forward_agent option set to falsey by default" do
|
|
204
|
-
transport.expects(:connection).with { |state|
|
|
205
|
-
state[:forward_agent].nil?
|
|
206
|
-
}.returns(stub(:login_command => stub))
|
|
207
|
-
|
|
208
|
-
cmd
|
|
209
|
-
end
|
|
210
|
-
|
|
211
|
-
it "with :forward_agent option set if given in config" do
|
|
212
|
-
config[:forward_agent] = "yeah?"
|
|
213
|
-
|
|
214
|
-
transport.expects(:connection).with { |state|
|
|
215
|
-
state[:forward_agent].must_equal "yeah?"
|
|
216
|
-
}.returns(stub(:login_command => stub))
|
|
217
|
-
|
|
218
|
-
cmd
|
|
219
|
-
end
|
|
220
|
-
|
|
221
|
-
it "with :forward_agent option set if given in state" do
|
|
222
|
-
state[:forward_agent] = "yeah?"
|
|
223
|
-
|
|
224
|
-
transport.expects(:connection).with { |state|
|
|
225
|
-
state[:forward_agent].must_equal "yeah?"
|
|
226
|
-
}.returns(stub(:login_command => stub))
|
|
227
|
-
|
|
228
|
-
cmd
|
|
229
|
-
end
|
|
230
|
-
|
|
231
|
-
it "with :port option set to 22 by default" do
|
|
232
|
-
transport.expects(:connection).with { |state|
|
|
233
|
-
state[:port].must_equal 22
|
|
234
|
-
}.returns(stub(:login_command => stub))
|
|
235
|
-
|
|
236
|
-
cmd
|
|
237
|
-
end
|
|
238
|
-
|
|
239
|
-
it "with :port option set if customized in config" do
|
|
240
|
-
config[:port] = 1234
|
|
241
|
-
|
|
242
|
-
transport.expects(:connection).with { |state|
|
|
243
|
-
state[:port].must_equal 1234
|
|
244
|
-
}.returns(stub(:login_command => stub))
|
|
245
|
-
|
|
246
|
-
cmd
|
|
247
|
-
end
|
|
248
|
-
|
|
249
|
-
it "with :port option set if customized in state" do
|
|
250
|
-
state[:port] = 9999
|
|
251
|
-
|
|
252
|
-
transport.expects(:connection).with { |state|
|
|
253
|
-
state[:port].must_equal 9999
|
|
254
|
-
}.returns(stub(:login_command => stub))
|
|
255
|
-
|
|
256
|
-
cmd
|
|
257
|
-
end
|
|
258
|
-
end
|
|
259
|
-
end
|
|
260
|
-
# rubocop:enable Metrics/MethodLength, Metrics/AbcSize
|
|
261
|
-
|
|
262
|
-
describe "#login_command" do
|
|
263
|
-
|
|
264
|
-
let(:cmd) { driver.login_command(state) }
|
|
265
|
-
|
|
266
|
-
before do
|
|
267
|
-
state[:hostname] = "fizzy"
|
|
268
|
-
state[:username] = "bork"
|
|
269
|
-
end
|
|
270
|
-
|
|
271
|
-
it "returns a LoginCommand" do
|
|
272
|
-
transport.stubs(:connection).returns(stub(:login_command => "command"))
|
|
273
|
-
|
|
274
|
-
cmd.must_equal "command"
|
|
275
|
-
end
|
|
276
|
-
|
|
277
|
-
constructs_an_ssh_connection
|
|
278
|
-
end
|
|
279
|
-
|
|
280
|
-
describe "#converge" do
|
|
281
|
-
|
|
282
|
-
let(:cmd) { driver.converge(state) }
|
|
283
|
-
let(:connection) { stub(:execute => true, :upload => true) }
|
|
284
|
-
|
|
285
|
-
before do
|
|
286
|
-
state[:hostname] = "fizzy"
|
|
287
|
-
state[:username] = "bork"
|
|
288
|
-
provisioner.stubs(:[]).with(:root_path).returns("/rooty")
|
|
289
|
-
FakeFS.activate!
|
|
290
|
-
FileUtils.mkdir_p("/tmp")
|
|
291
|
-
@original_env = ENV.to_hash
|
|
292
|
-
ENV.replace("http_proxy" => nil, "HTTP_PROXY" => nil,
|
|
293
|
-
"https_proxy" => nil, "HTTPS_PROXY" => nil,
|
|
294
|
-
"ftp_proxy" => nil, "FTP_PROXY" => nil,
|
|
295
|
-
"no_proxy" => nil, "NO_PROXY" => nil)
|
|
296
|
-
end
|
|
297
|
-
|
|
298
|
-
after do
|
|
299
|
-
FakeFS.deactivate!
|
|
300
|
-
FakeFS::FileSystem.clear
|
|
301
|
-
ENV.clear
|
|
302
|
-
ENV.replace(@original_env)
|
|
303
|
-
end
|
|
304
|
-
|
|
305
|
-
constructs_an_ssh_connection
|
|
306
|
-
|
|
307
|
-
it "creates the sandbox" do
|
|
308
|
-
transport.stubs(:connection).yields(connection)
|
|
309
|
-
provisioner.expects(:create_sandbox)
|
|
310
|
-
|
|
311
|
-
cmd
|
|
312
|
-
end
|
|
313
|
-
|
|
314
|
-
it "ensures that the sandbox is cleaned up" do
|
|
315
|
-
transport.stubs(:connection).raises
|
|
316
|
-
provisioner.expects(:cleanup_sandbox)
|
|
317
|
-
|
|
318
|
-
begin
|
|
319
|
-
cmd
|
|
320
|
-
rescue # rubocop:disable Lint/HandleExceptions
|
|
321
|
-
end
|
|
322
|
-
end
|
|
323
|
-
|
|
324
|
-
it "invokes the provisioner commands over ssh" do
|
|
325
|
-
transport.stubs(:connection).yields(connection)
|
|
326
|
-
order = sequence("order")
|
|
327
|
-
connection.expects(:execute).with("install").in_sequence(order)
|
|
328
|
-
connection.expects(:execute).with("init").in_sequence(order)
|
|
329
|
-
connection.expects(:execute).with("prepare").in_sequence(order)
|
|
330
|
-
connection.expects(:execute).with("run").in_sequence(order)
|
|
331
|
-
|
|
332
|
-
cmd
|
|
333
|
-
end
|
|
334
|
-
|
|
335
|
-
it "invokes the #install_command with :http_proxy set in config" do
|
|
336
|
-
config[:http_proxy] = "http://proxy"
|
|
337
|
-
transport.stubs(:connection).yields(connection)
|
|
338
|
-
connection.expects(:execute).with("env http_proxy=http://proxy install")
|
|
339
|
-
|
|
340
|
-
cmd
|
|
341
|
-
end
|
|
342
|
-
|
|
343
|
-
it "invokes the #install_command with ENV[\"http_proxy\"] set" do
|
|
344
|
-
ENV["http_proxy"] = "http://proxy"
|
|
345
|
-
transport.stubs(:connection).yields(connection)
|
|
346
|
-
if running_tests_on_windows?
|
|
347
|
-
connection.expects(:execute).
|
|
348
|
-
with("env http_proxy=http://proxy HTTP_PROXY=http://proxy install")
|
|
349
|
-
else
|
|
350
|
-
connection.expects(:execute).with("env http_proxy=http://proxy install")
|
|
351
|
-
end
|
|
352
|
-
cmd
|
|
353
|
-
end
|
|
354
|
-
|
|
355
|
-
it "invokes the #install_command with ENV[\"http_proxy\"] and ENV[\"no_proxy\"] set" do
|
|
356
|
-
ENV["http_proxy"] = "http://proxy"
|
|
357
|
-
ENV["no_proxy"] = "http://no"
|
|
358
|
-
transport.stubs(:connection).yields(connection)
|
|
359
|
-
if running_tests_on_windows?
|
|
360
|
-
connection.expects(:execute).
|
|
361
|
-
with("env http_proxy=http://proxy HTTP_PROXY=http://proxy " \
|
|
362
|
-
"no_proxy=http://no NO_PROXY=http://no install")
|
|
363
|
-
else
|
|
364
|
-
connection.expects(:execute).with("env http_proxy=http://proxy " \
|
|
365
|
-
"no_proxy=http://no install")
|
|
366
|
-
end
|
|
367
|
-
cmd
|
|
368
|
-
end
|
|
369
|
-
|
|
370
|
-
it "invokes the #install_command with :https_proxy set in config" do
|
|
371
|
-
config[:https_proxy] = "https://proxy"
|
|
372
|
-
transport.stubs(:connection).yields(connection)
|
|
373
|
-
connection.expects(:execute).with("env https_proxy=https://proxy install")
|
|
374
|
-
|
|
375
|
-
cmd
|
|
376
|
-
end
|
|
377
|
-
|
|
378
|
-
it "invokes the #install_command with ENV[\"https_proxy\"] set" do
|
|
379
|
-
ENV["https_proxy"] = "https://proxy"
|
|
380
|
-
transport.stubs(:connection).yields(connection)
|
|
381
|
-
if running_tests_on_windows?
|
|
382
|
-
connection.expects(:execute).
|
|
383
|
-
with("env https_proxy=https://proxy HTTPS_PROXY=https://proxy install")
|
|
384
|
-
else
|
|
385
|
-
connection.expects(:execute).with("env https_proxy=https://proxy install")
|
|
386
|
-
end
|
|
387
|
-
cmd
|
|
388
|
-
end
|
|
389
|
-
|
|
390
|
-
it "invokes the #install_command with ENV[\"https_proxy\"] and ENV[\"no_proxy\"] set" do
|
|
391
|
-
ENV["https_proxy"] = "https://proxy"
|
|
392
|
-
ENV["no_proxy"] = "https://no"
|
|
393
|
-
transport.stubs(:connection).yields(connection)
|
|
394
|
-
if running_tests_on_windows?
|
|
395
|
-
connection.expects(:execute).
|
|
396
|
-
with("env https_proxy=https://proxy HTTPS_PROXY=https://proxy " \
|
|
397
|
-
"no_proxy=https://no NO_PROXY=https://no install")
|
|
398
|
-
else
|
|
399
|
-
connection.expects(:execute).with("env https_proxy=https://proxy " \
|
|
400
|
-
"no_proxy=https://no install")
|
|
401
|
-
end
|
|
402
|
-
cmd
|
|
403
|
-
end
|
|
404
|
-
|
|
405
|
-
it "invokes the #install_command with :ftp_proxy set in config" do
|
|
406
|
-
config[:ftp_proxy] = "ftp://proxy"
|
|
407
|
-
transport.stubs(:connection).yields(connection)
|
|
408
|
-
connection.expects(:execute).with("env ftp_proxy=ftp://proxy install")
|
|
409
|
-
|
|
410
|
-
cmd
|
|
411
|
-
end
|
|
412
|
-
|
|
413
|
-
it "invokes the #install_command with ENV[\"ftp_proxy\"] set" do
|
|
414
|
-
ENV["ftp_proxy"] = "ftp://proxy"
|
|
415
|
-
transport.stubs(:connection).yields(connection)
|
|
416
|
-
if running_tests_on_windows?
|
|
417
|
-
connection.expects(:execute).
|
|
418
|
-
with("env ftp_proxy=ftp://proxy FTP_PROXY=ftp://proxy install")
|
|
419
|
-
else
|
|
420
|
-
connection.expects(:execute).with("env ftp_proxy=ftp://proxy install")
|
|
421
|
-
end
|
|
422
|
-
cmd
|
|
423
|
-
end
|
|
424
|
-
|
|
425
|
-
it "invokes the #install_command with ENV[\"ftp_proxy\"] and ENV[\"no_proxy\"] set" do
|
|
426
|
-
ENV["ftp_proxy"] = "ftp://proxy"
|
|
427
|
-
ENV["no_proxy"] = "http://no"
|
|
428
|
-
transport.stubs(:connection).yields(connection)
|
|
429
|
-
if running_tests_on_windows?
|
|
430
|
-
connection.expects(:execute).
|
|
431
|
-
with("env ftp_proxy=ftp://proxy FTP_PROXY=http://proxy " \
|
|
432
|
-
"no_proxy=http://no NO_PROXY=http://no install")
|
|
433
|
-
else
|
|
434
|
-
connection.expects(:execute).with("env ftp_proxy=ftp://proxy " \
|
|
435
|
-
"no_proxy=http://no install")
|
|
436
|
-
end
|
|
437
|
-
cmd
|
|
438
|
-
end
|
|
439
|
-
|
|
440
|
-
it "invokes the #install_command with :http_proxy & :https_proxy & :ftp_proxy set" do
|
|
441
|
-
config[:http_proxy] = "http://proxy"
|
|
442
|
-
config[:https_proxy] = "https://proxy"
|
|
443
|
-
config[:ftp_proxy] = "ftp://proxy"
|
|
444
|
-
transport.stubs(:connection).yields(connection)
|
|
445
|
-
connection.expects(:execute).with(
|
|
446
|
-
"env http_proxy=http://proxy https_proxy=https://proxy ftp_proxy=ftp://proxy install")
|
|
447
|
-
|
|
448
|
-
cmd
|
|
449
|
-
end
|
|
450
|
-
|
|
451
|
-
describe "transferring files" do
|
|
452
|
-
|
|
453
|
-
before do
|
|
454
|
-
transport.stubs(:connection).yields(connection)
|
|
455
|
-
connection.stubs(:upload)
|
|
456
|
-
FileUtils.mkdir_p "/tmp/sandbox/stuff"
|
|
457
|
-
end
|
|
458
|
-
|
|
459
|
-
it "uploads files" do
|
|
460
|
-
connection.expects(:upload).with(["/tmp/sandbox/stuff"], "/rooty")
|
|
461
|
-
|
|
462
|
-
cmd
|
|
463
|
-
end
|
|
464
|
-
|
|
465
|
-
it "logs to info" do
|
|
466
|
-
cmd
|
|
467
|
-
|
|
468
|
-
logged_output.string.
|
|
469
|
-
must_match(/INFO -- : Transferring files to instance$/)
|
|
470
|
-
end
|
|
471
|
-
|
|
472
|
-
it "logs to debug" do
|
|
473
|
-
cmd
|
|
474
|
-
|
|
475
|
-
logged_output.string.must_match(/DEBUG -- : Transfer complete$/)
|
|
476
|
-
end
|
|
477
|
-
|
|
478
|
-
it "raises an ActionFailed on transfer when SshFailed is raised" do
|
|
479
|
-
connection.stubs(:upload).raises(Kitchen::Transport::SshFailed.new("dang"))
|
|
480
|
-
|
|
481
|
-
proc { cmd }.must_raise Kitchen::ActionFailed
|
|
482
|
-
end
|
|
483
|
-
end
|
|
484
|
-
|
|
485
|
-
it "raises an ActionFailed on execute when SshFailed is raised" do
|
|
486
|
-
transport.stubs(:connection).yields(connection)
|
|
487
|
-
connection.stubs(:execute).raises(Kitchen::Transport::SshFailed.new("dang"))
|
|
488
|
-
|
|
489
|
-
proc { cmd }.must_raise Kitchen::ActionFailed
|
|
490
|
-
end
|
|
491
|
-
end
|
|
492
|
-
|
|
493
|
-
describe "#setup" do
|
|
494
|
-
|
|
495
|
-
let(:cmd) { driver.setup(state) }
|
|
496
|
-
let(:connection) { mock }
|
|
497
|
-
|
|
498
|
-
before do
|
|
499
|
-
state[:hostname] = "fizzy"
|
|
500
|
-
state[:username] = "bork"
|
|
501
|
-
end
|
|
502
|
-
|
|
503
|
-
constructs_an_ssh_connection
|
|
504
|
-
|
|
505
|
-
it "invokes the Verifier#install_command over ssh" do
|
|
506
|
-
transport.stubs(:connection).yields(connection)
|
|
507
|
-
connection.expects(:execute).with("install")
|
|
508
|
-
|
|
509
|
-
cmd
|
|
510
|
-
end
|
|
511
|
-
|
|
512
|
-
it "invokes the Verifier#install_command with :http_proxy set in config" do
|
|
513
|
-
config[:http_proxy] = "http://proxy"
|
|
514
|
-
transport.stubs(:connection).yields(connection)
|
|
515
|
-
connection.expects(:execute).with("env http_proxy=http://proxy install")
|
|
516
|
-
|
|
517
|
-
cmd
|
|
518
|
-
end
|
|
519
|
-
|
|
520
|
-
it "invokes the Verifier#install_command with :https_proxy set in config" do
|
|
521
|
-
config[:https_proxy] = "https://proxy"
|
|
522
|
-
transport.stubs(:connection).yields(connection)
|
|
523
|
-
connection.expects(:execute).with("env https_proxy=https://proxy install")
|
|
524
|
-
|
|
525
|
-
cmd
|
|
526
|
-
end
|
|
527
|
-
|
|
528
|
-
it "invokes the Verifier#install_command with :ftp_proxy set in config" do
|
|
529
|
-
config[:ftp_proxy] = "ftp://proxy"
|
|
530
|
-
transport.stubs(:connection).yields(connection)
|
|
531
|
-
connection.expects(:execute).with("env ftp_proxy=ftp://proxy install")
|
|
532
|
-
|
|
533
|
-
cmd
|
|
534
|
-
end
|
|
535
|
-
|
|
536
|
-
it "invokes the Verifier#install_command with :http_proxy & :https_proxy & :ftp_proxy set" do
|
|
537
|
-
config[:http_proxy] = "http://proxy"
|
|
538
|
-
config[:https_proxy] = "https://proxy"
|
|
539
|
-
config[:ftp_proxy] = "ftp://proxy"
|
|
540
|
-
transport.stubs(:connection).yields(connection)
|
|
541
|
-
connection.expects(:execute).with(
|
|
542
|
-
"env http_proxy=http://proxy https_proxy=https://proxy ftp_proxy=ftp://proxy install")
|
|
543
|
-
|
|
544
|
-
cmd
|
|
545
|
-
end
|
|
546
|
-
|
|
547
|
-
it "raises an ActionFailed when SshFailed is raised" do
|
|
548
|
-
transport.stubs(:connection).yields(connection)
|
|
549
|
-
connection.stubs(:execute).raises(Kitchen::Transport::SshFailed.new("dang"))
|
|
550
|
-
|
|
551
|
-
proc { cmd }.must_raise Kitchen::ActionFailed
|
|
552
|
-
end
|
|
553
|
-
end
|
|
554
|
-
|
|
555
|
-
describe "#verify" do
|
|
556
|
-
|
|
557
|
-
let(:cmd) { driver.verify(state) }
|
|
558
|
-
let(:connection) { stub(:execute => true, :upload => true) }
|
|
559
|
-
|
|
560
|
-
before do
|
|
561
|
-
state[:hostname] = "fizzy"
|
|
562
|
-
state[:username] = "bork"
|
|
563
|
-
transport.stubs(:connection).yields(connection)
|
|
564
|
-
end
|
|
565
|
-
|
|
566
|
-
constructs_an_ssh_connection
|
|
567
|
-
|
|
568
|
-
it "creates the sandbox" do
|
|
569
|
-
verifier.expects(:create_sandbox)
|
|
570
|
-
|
|
571
|
-
cmd
|
|
572
|
-
end
|
|
573
|
-
|
|
574
|
-
it "ensures that the sandbox is cleanup up" do
|
|
575
|
-
transport.stubs(:connection).raises
|
|
576
|
-
verifier.expects(:cleanup_sandbox)
|
|
577
|
-
|
|
578
|
-
begin
|
|
579
|
-
cmd
|
|
580
|
-
rescue # rubocop:disable Lint/HandleExceptions
|
|
581
|
-
end
|
|
582
|
-
end
|
|
583
|
-
|
|
584
|
-
it "invokes the verifier commands over the transport" do
|
|
585
|
-
order = sequence("order")
|
|
586
|
-
connection.expects(:execute).with("init").in_sequence(order)
|
|
587
|
-
connection.expects(:execute).with("prepare").in_sequence(order)
|
|
588
|
-
connection.expects(:execute).with("run").in_sequence(order)
|
|
589
|
-
|
|
590
|
-
cmd
|
|
591
|
-
end
|
|
592
|
-
|
|
593
|
-
%W[init prepare run].each do |phase|
|
|
594
|
-
it "invokes Verifier##{phase}_command over ssh" do
|
|
595
|
-
connection.expects(:execute).with(phase)
|
|
596
|
-
|
|
597
|
-
cmd
|
|
598
|
-
end
|
|
599
|
-
|
|
600
|
-
it "invokes Verifier##{phase}_command with :http_proxy set in config" do
|
|
601
|
-
config[:http_proxy] = "http://proxy"
|
|
602
|
-
connection.expects(:execute).with("env http_proxy=http://proxy #{phase}")
|
|
603
|
-
|
|
604
|
-
cmd
|
|
605
|
-
end
|
|
606
|
-
|
|
607
|
-
it "invokes Verifier##{phase}_command with :https_proxy set in config" do
|
|
608
|
-
config[:https_proxy] = "https://proxy"
|
|
609
|
-
connection.expects(:execute).with("env https_proxy=https://proxy #{phase}")
|
|
610
|
-
|
|
611
|
-
cmd
|
|
612
|
-
end
|
|
613
|
-
|
|
614
|
-
it "invokes Verifier##{phase}_command with :ftp_proxy set in config" do
|
|
615
|
-
config[:ftp_proxy] = "ftp://proxy"
|
|
616
|
-
connection.expects(:execute).with("env ftp_proxy=ftp://proxy #{phase}")
|
|
617
|
-
|
|
618
|
-
cmd
|
|
619
|
-
end
|
|
620
|
-
|
|
621
|
-
it "invokes Verifier##{phase}_command with :http_proxy & :https_proxy & :ftp_proxy set" do
|
|
622
|
-
config[:http_proxy] = "http://proxy"
|
|
623
|
-
config[:https_proxy] = "https://proxy"
|
|
624
|
-
config[:ftp_proxy] = "ftp://proxy"
|
|
625
|
-
connection.expects(:execute).with(
|
|
626
|
-
"env http_proxy=http://proxy https_proxy=https://proxy ftp_proxy=ftp://proxy #{phase}")
|
|
627
|
-
|
|
628
|
-
cmd
|
|
629
|
-
end
|
|
630
|
-
end
|
|
631
|
-
|
|
632
|
-
it "logs to info" do
|
|
633
|
-
cmd
|
|
634
|
-
|
|
635
|
-
logged_output.string.
|
|
636
|
-
must_match(/INFO -- : Transferring files to instance$/)
|
|
637
|
-
end
|
|
638
|
-
|
|
639
|
-
it "uploads sandbox files" do
|
|
640
|
-
connection.expects(:upload).with([], "/tmp/verifier")
|
|
641
|
-
|
|
642
|
-
cmd
|
|
643
|
-
end
|
|
644
|
-
|
|
645
|
-
it "logs to debug" do
|
|
646
|
-
cmd
|
|
647
|
-
|
|
648
|
-
logged_output.string.must_match(/DEBUG -- : Transfer complete$/)
|
|
649
|
-
end
|
|
650
|
-
|
|
651
|
-
it "raises an ActionFailed on transfer when TransportFailed is raised" do
|
|
652
|
-
connection.stubs(:upload).
|
|
653
|
-
raises(Kitchen::Transport::TransportFailed.new("dang"))
|
|
654
|
-
|
|
655
|
-
proc { cmd }.must_raise Kitchen::ActionFailed
|
|
656
|
-
end
|
|
657
|
-
|
|
658
|
-
it "raises an ActionFailed when SSHFailed is raised" do
|
|
659
|
-
connection.stubs(:execute).raises(Kitchen::Transport::SshFailed.new("dang"))
|
|
660
|
-
|
|
661
|
-
proc { cmd }.must_raise Kitchen::ActionFailed
|
|
662
|
-
end
|
|
663
|
-
end
|
|
664
|
-
|
|
665
|
-
describe "#ssh" do
|
|
666
|
-
|
|
667
|
-
let(:cmd) { driver.ssh(["host", "user", { :one => "two" }], "go") }
|
|
668
|
-
let(:connection) { mock }
|
|
669
|
-
|
|
670
|
-
it "creates an SSH connection" do
|
|
671
|
-
connection.stubs(:execute)
|
|
672
|
-
transport.expects(:connection).with(
|
|
673
|
-
:hostname => "host",
|
|
674
|
-
:username => "user",
|
|
675
|
-
:port => 22,
|
|
676
|
-
:one => "two"
|
|
677
|
-
).yields(connection)
|
|
678
|
-
|
|
679
|
-
cmd
|
|
680
|
-
end
|
|
681
|
-
|
|
682
|
-
it "invokes the command over ssh" do
|
|
683
|
-
transport.expects(:connection).yields(connection)
|
|
684
|
-
connection.expects(:execute).with("go")
|
|
685
|
-
|
|
686
|
-
cmd
|
|
687
|
-
end
|
|
688
|
-
end
|
|
689
|
-
|
|
690
|
-
describe "#remote_command" do
|
|
691
|
-
|
|
692
|
-
let(:cmd) { driver.remote_command(state, "shipit") }
|
|
693
|
-
let(:connection) { mock }
|
|
694
|
-
|
|
695
|
-
before do
|
|
696
|
-
state[:hostname] = "fizzy"
|
|
697
|
-
state[:username] = "bork"
|
|
698
|
-
end
|
|
699
|
-
|
|
700
|
-
it "creates an SSH connection" do
|
|
701
|
-
transport.expects(:connection).with(
|
|
702
|
-
:hostname => "fizzy",
|
|
703
|
-
:username => "bork",
|
|
704
|
-
:port => 22
|
|
705
|
-
)
|
|
706
|
-
|
|
707
|
-
cmd
|
|
708
|
-
end
|
|
709
|
-
|
|
710
|
-
it "invokes the command over ssh" do
|
|
711
|
-
transport.expects(:connection).yields(connection)
|
|
712
|
-
connection.expects(:execute).with("shipit")
|
|
713
|
-
|
|
714
|
-
cmd
|
|
715
|
-
end
|
|
716
|
-
end
|
|
717
|
-
|
|
718
|
-
describe "#wait_for_sshd" do
|
|
719
|
-
|
|
720
|
-
let(:cmd) do
|
|
721
|
-
driver.send(:wait_for_sshd, "host", "user", :one => "two")
|
|
722
|
-
end
|
|
723
|
-
|
|
724
|
-
it "creates an SSH connection with merged options" do
|
|
725
|
-
transport.expects(:connection).with(
|
|
726
|
-
:hostname => "host",
|
|
727
|
-
:username => "user",
|
|
728
|
-
:port => 22,
|
|
729
|
-
:one => "two"
|
|
730
|
-
).returns(stub(:wait_until_ready => true))
|
|
731
|
-
|
|
732
|
-
cmd
|
|
733
|
-
end
|
|
734
|
-
|
|
735
|
-
it "calls wait on the SSH connection" do
|
|
736
|
-
connection = mock
|
|
737
|
-
transport.expects(:connection).returns(connection)
|
|
738
|
-
connection.expects(:wait_until_ready)
|
|
739
|
-
|
|
740
|
-
cmd
|
|
741
|
-
end
|
|
742
|
-
end
|
|
743
|
-
|
|
744
|
-
describe "to maintain backwards compatibility" do
|
|
745
|
-
|
|
746
|
-
let(:driver) do
|
|
747
|
-
Kitchen::Driver::BackCompat.new(config).finalize_config!(instance)
|
|
748
|
-
end
|
|
749
|
-
|
|
750
|
-
it "#instance returns its instance" do
|
|
751
|
-
driver.instance.must_equal instance
|
|
752
|
-
end
|
|
753
|
-
|
|
754
|
-
it "#name returns the name of the driver" do
|
|
755
|
-
driver.name.must_equal "BackCompat"
|
|
756
|
-
end
|
|
757
|
-
|
|
758
|
-
describe "#logger" do
|
|
759
|
-
|
|
760
|
-
before { @klog = Kitchen.logger }
|
|
761
|
-
after { Kitchen.logger = @klog }
|
|
762
|
-
|
|
763
|
-
it "returns the instance's logger if defined" do
|
|
764
|
-
driver.send(:logger).must_equal logger
|
|
765
|
-
end
|
|
766
|
-
|
|
767
|
-
it "returns the default logger if instance's logger is not set" do
|
|
768
|
-
driver = Kitchen::Driver::BackCompat.new(config)
|
|
769
|
-
Kitchen.logger = "yep"
|
|
770
|
-
|
|
771
|
-
driver.send(:logger).must_equal Kitchen.logger
|
|
772
|
-
end
|
|
773
|
-
end
|
|
774
|
-
|
|
775
|
-
it "#puts calls logger.info" do
|
|
776
|
-
driver.send(:puts, "yo")
|
|
777
|
-
|
|
778
|
-
logged_output.string.must_match(/I, /)
|
|
779
|
-
logged_output.string.must_match(/yo\n/)
|
|
780
|
-
end
|
|
781
|
-
|
|
782
|
-
it "#print calls logger.info" do
|
|
783
|
-
driver.send(:print, "yo")
|
|
784
|
-
|
|
785
|
-
logged_output.string.must_match(/I, /)
|
|
786
|
-
logged_output.string.must_match(/yo\n/)
|
|
787
|
-
end
|
|
788
|
-
|
|
789
|
-
it "has a default verify dependencies method" do
|
|
790
|
-
driver.verify_dependencies.must_be_nil
|
|
791
|
-
end
|
|
792
|
-
|
|
793
|
-
it "#busser returns the instance's verifier" do
|
|
794
|
-
driver.send(:busser).must_equal verifier
|
|
795
|
-
end
|
|
796
|
-
|
|
797
|
-
describe ".no_parallel_for" do
|
|
798
|
-
|
|
799
|
-
it "registers no serial actions when none are declared" do
|
|
800
|
-
Kitchen::Driver::SpeedyCompat.serial_actions.must_equal nil
|
|
801
|
-
end
|
|
802
|
-
|
|
803
|
-
it "registers a single serial action method" do
|
|
804
|
-
Kitchen::Driver::DodgyCompat.serial_actions.must_equal [:converge]
|
|
805
|
-
end
|
|
806
|
-
|
|
807
|
-
it "registers multiple serial action methods" do
|
|
808
|
-
actions = Kitchen::Driver::SlowCompat.serial_actions
|
|
809
|
-
|
|
810
|
-
actions.must_include :create
|
|
811
|
-
actions.must_include :verify
|
|
812
|
-
actions.must_include :destroy
|
|
813
|
-
end
|
|
814
|
-
|
|
815
|
-
it "raises a ClientError if value is not an action method" do
|
|
816
|
-
proc {
|
|
817
|
-
Class.new(Kitchen::Driver::BackCompat) {
|
|
818
|
-
no_parallel_for :telling_stories
|
|
819
|
-
}
|
|
820
|
-
}.must_raise Kitchen::ClientError
|
|
821
|
-
end
|
|
822
|
-
end
|
|
823
|
-
|
|
824
|
-
# rubocop:disable Metrics/MethodLength, Metrics/AbcSize
|
|
825
|
-
def self.constructs_an_ssh_object
|
|
826
|
-
it "with hostname set from state" do
|
|
827
|
-
Kitchen::SSH.expects(:new).with { |hostname, _username, _opts|
|
|
828
|
-
hostname.must_equal "fizzy"
|
|
829
|
-
}.returns(connection)
|
|
830
|
-
|
|
831
|
-
cmd
|
|
832
|
-
end
|
|
833
|
-
|
|
834
|
-
it "with username set from state" do
|
|
835
|
-
Kitchen::SSH.expects(:new).with { |_hostname, username, _opts|
|
|
836
|
-
username.must_equal "bork"
|
|
837
|
-
}.returns(connection)
|
|
838
|
-
|
|
839
|
-
cmd
|
|
840
|
-
end
|
|
841
|
-
|
|
842
|
-
it "with :user_known_hosts_file option set to /dev/null" do
|
|
843
|
-
Kitchen::SSH.expects(:new).with { |_hostname, _username, opts|
|
|
844
|
-
opts[:user_known_hosts_file].must_equal "/dev/null"
|
|
845
|
-
}.returns(connection)
|
|
846
|
-
|
|
847
|
-
cmd
|
|
848
|
-
end
|
|
849
|
-
|
|
850
|
-
it "with :paranoid option set to false" do
|
|
851
|
-
Kitchen::SSH.expects(:new).with { |_hostname, _username, opts|
|
|
852
|
-
opts[:paranoid].must_equal false
|
|
853
|
-
}.returns(connection)
|
|
854
|
-
|
|
855
|
-
cmd
|
|
856
|
-
end
|
|
857
|
-
|
|
858
|
-
it "with :keys_only option set to falsey by default" do
|
|
859
|
-
Kitchen::SSH.expects(:new).with { |_hostname, _username, opts|
|
|
860
|
-
opts[:keys_only].nil?
|
|
861
|
-
}.returns(connection)
|
|
862
|
-
|
|
863
|
-
cmd
|
|
864
|
-
end
|
|
865
|
-
|
|
866
|
-
it "with :keys_only option set to true if :ssh_key is set in config" do
|
|
867
|
-
config[:ssh_key] = "wicked"
|
|
868
|
-
|
|
869
|
-
Kitchen::SSH.expects(:new).with { |_hostname, _username, opts|
|
|
870
|
-
opts[:keys_only].must_equal true
|
|
871
|
-
}.returns(connection)
|
|
872
|
-
|
|
873
|
-
cmd
|
|
874
|
-
end
|
|
875
|
-
|
|
876
|
-
it "with :keys_only option set to true if :ssh_key is set in state" do
|
|
877
|
-
state[:ssh_key] = "wicked"
|
|
878
|
-
|
|
879
|
-
Kitchen::SSH.expects(:new).with { |_hostname, _username, opts|
|
|
880
|
-
opts[:keys_only].must_equal true
|
|
881
|
-
}.returns(connection)
|
|
882
|
-
|
|
883
|
-
cmd
|
|
884
|
-
end
|
|
885
|
-
|
|
886
|
-
it "with :keys option set to falsey by default" do
|
|
887
|
-
Kitchen::SSH.expects(:new).with { |_hostname, _username, opts|
|
|
888
|
-
opts[:keys].nil?
|
|
889
|
-
}.returns(connection)
|
|
890
|
-
|
|
891
|
-
cmd
|
|
892
|
-
end
|
|
893
|
-
|
|
894
|
-
it "with :keys option set to an array if :ssh_key is set in config" do
|
|
895
|
-
config[:ssh_key] = "wicked"
|
|
896
|
-
|
|
897
|
-
Kitchen::SSH.expects(:new).with { |_hostname, _username, opts|
|
|
898
|
-
opts[:keys].must_equal ["wicked"]
|
|
899
|
-
}.returns(connection)
|
|
900
|
-
|
|
901
|
-
cmd
|
|
902
|
-
end
|
|
903
|
-
|
|
904
|
-
it "with :keys option set to an array if :ssh_key is set in state" do
|
|
905
|
-
state[:ssh_key] = "wicked"
|
|
906
|
-
|
|
907
|
-
Kitchen::SSH.expects(:new).with { |_hostname, _username, opts|
|
|
908
|
-
opts[:keys].must_equal ["wicked"]
|
|
909
|
-
}.returns(connection)
|
|
910
|
-
|
|
911
|
-
cmd
|
|
912
|
-
end
|
|
913
|
-
|
|
914
|
-
it "with :password option set to falsey by default" do
|
|
915
|
-
Kitchen::SSH.expects(:new).with { |_hostname, _username, opts|
|
|
916
|
-
opts[:password].nil?
|
|
917
|
-
}.returns(connection)
|
|
918
|
-
|
|
919
|
-
cmd
|
|
920
|
-
end
|
|
921
|
-
|
|
922
|
-
it "with :password option set if given in config" do
|
|
923
|
-
config[:password] = "psst"
|
|
924
|
-
|
|
925
|
-
Kitchen::SSH.expects(:new).with { |_hostname, _username, opts|
|
|
926
|
-
opts[:password].must_equal "psst"
|
|
927
|
-
}.returns(connection)
|
|
928
|
-
|
|
929
|
-
cmd
|
|
930
|
-
end
|
|
931
|
-
|
|
932
|
-
it "with :password option set if given in state" do
|
|
933
|
-
state[:password] = "psst"
|
|
934
|
-
|
|
935
|
-
Kitchen::SSH.expects(:new).with { |_hostname, _username, opts|
|
|
936
|
-
opts[:password].must_equal "psst"
|
|
937
|
-
}.returns(connection)
|
|
938
|
-
|
|
939
|
-
cmd
|
|
940
|
-
end
|
|
941
|
-
|
|
942
|
-
it "with :forward_agent option set to falsey by default" do
|
|
943
|
-
Kitchen::SSH.expects(:new).with { |_hostname, _username, opts|
|
|
944
|
-
opts[:forward_agent].nil?
|
|
945
|
-
}.returns(connection)
|
|
946
|
-
|
|
947
|
-
cmd
|
|
948
|
-
end
|
|
949
|
-
|
|
950
|
-
it "with :forward_agent option set if given in config" do
|
|
951
|
-
config[:forward_agent] = "yeah?"
|
|
952
|
-
|
|
953
|
-
Kitchen::SSH.expects(:new).with { |_hostname, _username, opts|
|
|
954
|
-
opts[:forward_agent].must_equal "yeah?"
|
|
955
|
-
}.returns(connection)
|
|
956
|
-
|
|
957
|
-
cmd
|
|
958
|
-
end
|
|
959
|
-
|
|
960
|
-
it "with :forward_agent option set if given in state" do
|
|
961
|
-
state[:forward_agent] = "yeah?"
|
|
962
|
-
|
|
963
|
-
Kitchen::SSH.expects(:new).with { |_hostname, _username, opts|
|
|
964
|
-
opts[:forward_agent].must_equal "yeah?"
|
|
965
|
-
}.returns(connection)
|
|
966
|
-
|
|
967
|
-
cmd
|
|
968
|
-
end
|
|
969
|
-
|
|
970
|
-
it "with :port option set to 22 by default" do
|
|
971
|
-
Kitchen::SSH.expects(:new).with { |_hostname, _username, opts|
|
|
972
|
-
opts[:port].must_equal 22
|
|
973
|
-
}.returns(connection)
|
|
974
|
-
|
|
975
|
-
cmd
|
|
976
|
-
end
|
|
977
|
-
|
|
978
|
-
it "with :port option set if customized in config" do
|
|
979
|
-
config[:port] = 1234
|
|
980
|
-
|
|
981
|
-
Kitchen::SSH.expects(:new).with { |_hostname, _username, opts|
|
|
982
|
-
opts[:port].must_equal 1234
|
|
983
|
-
}.returns(connection)
|
|
984
|
-
|
|
985
|
-
cmd
|
|
986
|
-
end
|
|
987
|
-
|
|
988
|
-
it "with :port option set if customized in state" do
|
|
989
|
-
state[:port] = 9999
|
|
990
|
-
|
|
991
|
-
Kitchen::SSH.expects(:new).with { |_hostname, _username, opts|
|
|
992
|
-
opts[:port].must_equal 9999
|
|
993
|
-
}.returns(connection)
|
|
994
|
-
|
|
995
|
-
cmd
|
|
996
|
-
end
|
|
997
|
-
|
|
998
|
-
it "with :logger option set to driver's logger" do
|
|
999
|
-
Kitchen::SSH.expects(:new).with { |_hostname, _username, opts|
|
|
1000
|
-
opts[:logger].must_equal logger
|
|
1001
|
-
}.returns(connection)
|
|
1002
|
-
|
|
1003
|
-
cmd
|
|
1004
|
-
end
|
|
1005
|
-
end
|
|
1006
|
-
# rubocop:enable Metrics/MethodLength, Metrics/AbcSize
|
|
1007
|
-
|
|
1008
|
-
describe "#run_remote" do
|
|
1009
|
-
|
|
1010
|
-
let(:cmd) { driver.use_run_remote(state, "huh") }
|
|
1011
|
-
let(:connection) { stub(:exec => true) }
|
|
1012
|
-
|
|
1013
|
-
before do
|
|
1014
|
-
state[:hostname] = "fizzy"
|
|
1015
|
-
state[:username] = "bork"
|
|
1016
|
-
end
|
|
1017
|
-
|
|
1018
|
-
constructs_an_ssh_object
|
|
1019
|
-
|
|
1020
|
-
it "invokes the #install_command with :http_proxy set in config" do
|
|
1021
|
-
config[:http_proxy] = "http://proxy"
|
|
1022
|
-
Kitchen::SSH.stubs(:new).returns(connection)
|
|
1023
|
-
connection.expects(:exec).with("env http_proxy=http://proxy huh")
|
|
1024
|
-
|
|
1025
|
-
cmd
|
|
1026
|
-
end
|
|
1027
|
-
|
|
1028
|
-
it "invokes the #install_command with :https_proxy set in config" do
|
|
1029
|
-
config[:https_proxy] = "https://proxy"
|
|
1030
|
-
Kitchen::SSH.stubs(:new).returns(connection)
|
|
1031
|
-
connection.expects(:exec).with("env https_proxy=https://proxy huh")
|
|
1032
|
-
|
|
1033
|
-
cmd
|
|
1034
|
-
end
|
|
1035
|
-
|
|
1036
|
-
it "invokes the #install_command with :ftp_proxy set in config" do
|
|
1037
|
-
config[:ftp_proxy] = "ftp://proxy"
|
|
1038
|
-
Kitchen::SSH.stubs(:new).returns(connection)
|
|
1039
|
-
connection.expects(:exec).with("env ftp_proxy=ftp://proxy huh")
|
|
1040
|
-
|
|
1041
|
-
cmd
|
|
1042
|
-
end
|
|
1043
|
-
|
|
1044
|
-
it "invokes the #install_command with :http_proxy & :https_proxy & :ftp_proxy set" do
|
|
1045
|
-
config[:http_proxy] = "http://proxy"
|
|
1046
|
-
config[:https_proxy] = "https://proxy"
|
|
1047
|
-
config[:ftp_proxy] = "ftp://proxy"
|
|
1048
|
-
Kitchen::SSH.stubs(:new).returns(connection)
|
|
1049
|
-
connection.expects(:exec).with(
|
|
1050
|
-
"env http_proxy=http://proxy https_proxy=https://proxy ftp_proxy=ftp://proxy huh")
|
|
1051
|
-
|
|
1052
|
-
cmd
|
|
1053
|
-
end
|
|
1054
|
-
|
|
1055
|
-
it "doesn't invoke an ssh command if command is nil" do
|
|
1056
|
-
Kitchen::SSH.stubs(:new).returns(mock)
|
|
1057
|
-
|
|
1058
|
-
driver.use_run_remote(state, nil)
|
|
1059
|
-
end
|
|
1060
|
-
|
|
1061
|
-
it "raises an ActionFailed on transfer when SSHFailed is raised" do
|
|
1062
|
-
Kitchen::SSH.stubs(:new).returns(connection)
|
|
1063
|
-
connection.stubs(:exec).raises(Kitchen::SSHFailed.new("dang"))
|
|
1064
|
-
|
|
1065
|
-
proc { cmd }.must_raise Kitchen::ActionFailed
|
|
1066
|
-
end
|
|
1067
|
-
|
|
1068
|
-
it "raises an ActionFailed on exec when Net::SSH:Exception is raised" do
|
|
1069
|
-
Kitchen::SSH.stubs(:new).returns(connection)
|
|
1070
|
-
connection.stubs(:exec).raises(Net::SSH::Exception.new("dang"))
|
|
1071
|
-
|
|
1072
|
-
proc { cmd }.must_raise Kitchen::ActionFailed
|
|
1073
|
-
end
|
|
1074
|
-
end
|
|
1075
|
-
|
|
1076
|
-
describe "#transfer_path" do
|
|
1077
|
-
|
|
1078
|
-
let(:cmd) { driver.use_transfer_path(state, ["nope"], "nadda") }
|
|
1079
|
-
let(:connection) { stub(:upload_path! => true) }
|
|
1080
|
-
|
|
1081
|
-
before do
|
|
1082
|
-
state[:hostname] = "fizzy"
|
|
1083
|
-
state[:username] = "bork"
|
|
1084
|
-
end
|
|
1085
|
-
|
|
1086
|
-
constructs_an_ssh_object
|
|
1087
|
-
|
|
1088
|
-
it "doesn't invoke an scp command if locals is nil" do
|
|
1089
|
-
Kitchen::SSH.stubs(:new).returns(mock)
|
|
1090
|
-
|
|
1091
|
-
driver.use_transfer_path(state, nil, "nope")
|
|
1092
|
-
end
|
|
1093
|
-
|
|
1094
|
-
it "doesn't invoke an scp command if locals is an empty array" do
|
|
1095
|
-
Kitchen::SSH.stubs(:new).returns(mock)
|
|
1096
|
-
|
|
1097
|
-
driver.use_transfer_path(state, [], "nope")
|
|
1098
|
-
end
|
|
1099
|
-
|
|
1100
|
-
it "raises an ActionFailed on transfer when SSHFailed is raised" do
|
|
1101
|
-
Kitchen::SSH.stubs(:new).returns(connection)
|
|
1102
|
-
connection.stubs(:upload_path!).raises(Kitchen::SSHFailed.new("dang"))
|
|
1103
|
-
|
|
1104
|
-
proc { cmd }.must_raise Kitchen::ActionFailed
|
|
1105
|
-
end
|
|
1106
|
-
|
|
1107
|
-
it "raises an ActionFailed on exec when Net::SSH:Exception is raised" do
|
|
1108
|
-
Kitchen::SSH.stubs(:new).returns(connection)
|
|
1109
|
-
connection.stubs(:upload_path!).raises(Net::SSH::Exception.new("dang"))
|
|
1110
|
-
|
|
1111
|
-
proc { cmd }.must_raise Kitchen::ActionFailed
|
|
1112
|
-
end
|
|
1113
|
-
end
|
|
1114
|
-
end
|
|
1115
|
-
end
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
|
2
|
+
#
|
|
3
|
+
# Author:: Fletcher Nichol (<fnichol@nichol.ca>)
|
|
4
|
+
#
|
|
5
|
+
# Copyright (C) 2014, Fletcher Nichol
|
|
6
|
+
#
|
|
7
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
8
|
+
# you may not use this file except in compliance with the License.
|
|
9
|
+
# You may obtain a copy of the License at
|
|
10
|
+
#
|
|
11
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
12
|
+
#
|
|
13
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
14
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
15
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
16
|
+
# See the License for the specific language governing permissions and
|
|
17
|
+
# limitations under the License.
|
|
18
|
+
|
|
19
|
+
require_relative "../../spec_helper"
|
|
20
|
+
|
|
21
|
+
require "kitchen"
|
|
22
|
+
require "kitchen/transport/ssh"
|
|
23
|
+
require "kitchen/verifier/busser"
|
|
24
|
+
|
|
25
|
+
module Kitchen
|
|
26
|
+
|
|
27
|
+
module Driver
|
|
28
|
+
|
|
29
|
+
class BackCompat < Kitchen::Driver::SSHBase
|
|
30
|
+
|
|
31
|
+
def use_run_remote(state, command)
|
|
32
|
+
connection = Kitchen::SSH.new(*build_ssh_args(state))
|
|
33
|
+
run_remote(command, connection)
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def use_transfer_path(state, locals, remote)
|
|
37
|
+
connection = Kitchen::SSH.new(*build_ssh_args(state))
|
|
38
|
+
transfer_path(locals, remote, connection)
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
class SpeedyCompat < Kitchen::Driver::SSHBase
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
class DodgyCompat < Kitchen::Driver::SSHBase
|
|
46
|
+
|
|
47
|
+
no_parallel_for :converge
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
class SlowCompat < Kitchen::Driver::SSHBase
|
|
51
|
+
|
|
52
|
+
no_parallel_for :create, :destroy
|
|
53
|
+
no_parallel_for :verify
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
describe Kitchen::Driver::SSHBase do
|
|
59
|
+
|
|
60
|
+
let(:logged_output) { StringIO.new }
|
|
61
|
+
let(:logger) { Logger.new(logged_output) }
|
|
62
|
+
let(:config) { Hash.new }
|
|
63
|
+
let(:state) { Hash.new }
|
|
64
|
+
|
|
65
|
+
let(:verifier) do
|
|
66
|
+
v = mock("busser")
|
|
67
|
+
v.responds_like_instance_of(Kitchen::Verifier::Busser)
|
|
68
|
+
v.stubs(:install_command).returns("install")
|
|
69
|
+
v.stubs(:init_command).returns("init")
|
|
70
|
+
v.stubs(:prepare_command).returns("prepare")
|
|
71
|
+
v.stubs(:run_command).returns("run")
|
|
72
|
+
v.stubs(:create_sandbox).returns(true)
|
|
73
|
+
v.stubs(:cleanup_sandbox).returns(true)
|
|
74
|
+
v.stubs(:sandbox_path).returns("/tmp/sandbox")
|
|
75
|
+
v.stubs(:[]).with(:root_path).returns("/tmp/verifier")
|
|
76
|
+
v
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
let(:provisioner) do
|
|
80
|
+
stub(
|
|
81
|
+
:install_command => "install",
|
|
82
|
+
:init_command => "init",
|
|
83
|
+
:prepare_command => "prepare",
|
|
84
|
+
:run_command => "run",
|
|
85
|
+
:create_sandbox => true,
|
|
86
|
+
:cleanup_sandbox => true,
|
|
87
|
+
:sandbox_path => "/tmp/sandbox"
|
|
88
|
+
)
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
let(:transport) do
|
|
92
|
+
t = mock("transport")
|
|
93
|
+
t.responds_like_instance_of(Kitchen::Transport::Base)
|
|
94
|
+
t
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
let(:instance) do
|
|
98
|
+
stub(
|
|
99
|
+
:name => "coolbeans",
|
|
100
|
+
:logger => logger,
|
|
101
|
+
:verifier => verifier,
|
|
102
|
+
:provisioner => provisioner,
|
|
103
|
+
:transport => transport,
|
|
104
|
+
:to_str => "instance"
|
|
105
|
+
)
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
let(:driver) do
|
|
109
|
+
Kitchen::Driver::SSHBase.new(config).finalize_config!(instance)
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
it "plugin_version is not set" do
|
|
113
|
+
driver.diagnose_plugin[:version].must_equal nil
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
describe "configuration" do
|
|
117
|
+
|
|
118
|
+
it ":sudo defaults to true" do
|
|
119
|
+
driver[:sudo].must_equal true
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
it ":port defaults to 22" do
|
|
123
|
+
driver[:port].must_equal 22
|
|
124
|
+
end
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
it "#create raises a ClientError" do
|
|
128
|
+
proc { driver.create(state) }.must_raise Kitchen::ClientError
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
it "#destroy raises a ClientError" do
|
|
132
|
+
proc { driver.destroy(state) }.must_raise Kitchen::ClientError
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
# rubocop:disable Metrics/MethodLength, Metrics/AbcSize
|
|
136
|
+
def self.constructs_an_ssh_connection
|
|
137
|
+
describe "constructs an SSH connection" do
|
|
138
|
+
|
|
139
|
+
it "with hostname set from state" do
|
|
140
|
+
transport.expects(:connection).with { |state|
|
|
141
|
+
state[:hostname].must_equal "fizzy"
|
|
142
|
+
}.returns(stub(:login_command => stub))
|
|
143
|
+
|
|
144
|
+
cmd
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
it "with username set from state" do
|
|
148
|
+
transport.expects(:connection).with { |state|
|
|
149
|
+
state[:username].must_equal "bork"
|
|
150
|
+
}.returns(stub(:login_command => stub))
|
|
151
|
+
|
|
152
|
+
cmd
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
it "with :ssh_key option set from config" do
|
|
156
|
+
config[:ssh_key] = "wicked"
|
|
157
|
+
|
|
158
|
+
transport.expects(:connection).with { |state|
|
|
159
|
+
state[:ssh_key].must_equal "wicked"
|
|
160
|
+
}.returns(stub(:login_command => stub))
|
|
161
|
+
|
|
162
|
+
cmd
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
it "with :ssh_key option set from state" do
|
|
166
|
+
state[:ssh_key] = "wicked"
|
|
167
|
+
|
|
168
|
+
transport.expects(:connection).with { |state|
|
|
169
|
+
state[:ssh_key].must_equal "wicked"
|
|
170
|
+
}.returns(stub(:login_command => stub))
|
|
171
|
+
|
|
172
|
+
cmd
|
|
173
|
+
end
|
|
174
|
+
|
|
175
|
+
it "with :password option set to falsey by default" do
|
|
176
|
+
transport.expects(:connection).with { |state|
|
|
177
|
+
state[:password].nil?
|
|
178
|
+
}.returns(stub(:login_command => stub))
|
|
179
|
+
|
|
180
|
+
cmd
|
|
181
|
+
end
|
|
182
|
+
|
|
183
|
+
it "with :password option set if given in config" do
|
|
184
|
+
config[:password] = "psst"
|
|
185
|
+
|
|
186
|
+
transport.expects(:connection).with { |state|
|
|
187
|
+
state[:password].must_equal "psst"
|
|
188
|
+
}.returns(stub(:login_command => stub))
|
|
189
|
+
|
|
190
|
+
cmd
|
|
191
|
+
end
|
|
192
|
+
|
|
193
|
+
it "with :password option set if given in state" do
|
|
194
|
+
state[:password] = "psst"
|
|
195
|
+
|
|
196
|
+
transport.expects(:connection).with { |state|
|
|
197
|
+
state[:password].must_equal "psst"
|
|
198
|
+
}.returns(stub(:login_command => stub))
|
|
199
|
+
|
|
200
|
+
cmd
|
|
201
|
+
end
|
|
202
|
+
|
|
203
|
+
it "with :forward_agent option set to falsey by default" do
|
|
204
|
+
transport.expects(:connection).with { |state|
|
|
205
|
+
state[:forward_agent].nil?
|
|
206
|
+
}.returns(stub(:login_command => stub))
|
|
207
|
+
|
|
208
|
+
cmd
|
|
209
|
+
end
|
|
210
|
+
|
|
211
|
+
it "with :forward_agent option set if given in config" do
|
|
212
|
+
config[:forward_agent] = "yeah?"
|
|
213
|
+
|
|
214
|
+
transport.expects(:connection).with { |state|
|
|
215
|
+
state[:forward_agent].must_equal "yeah?"
|
|
216
|
+
}.returns(stub(:login_command => stub))
|
|
217
|
+
|
|
218
|
+
cmd
|
|
219
|
+
end
|
|
220
|
+
|
|
221
|
+
it "with :forward_agent option set if given in state" do
|
|
222
|
+
state[:forward_agent] = "yeah?"
|
|
223
|
+
|
|
224
|
+
transport.expects(:connection).with { |state|
|
|
225
|
+
state[:forward_agent].must_equal "yeah?"
|
|
226
|
+
}.returns(stub(:login_command => stub))
|
|
227
|
+
|
|
228
|
+
cmd
|
|
229
|
+
end
|
|
230
|
+
|
|
231
|
+
it "with :port option set to 22 by default" do
|
|
232
|
+
transport.expects(:connection).with { |state|
|
|
233
|
+
state[:port].must_equal 22
|
|
234
|
+
}.returns(stub(:login_command => stub))
|
|
235
|
+
|
|
236
|
+
cmd
|
|
237
|
+
end
|
|
238
|
+
|
|
239
|
+
it "with :port option set if customized in config" do
|
|
240
|
+
config[:port] = 1234
|
|
241
|
+
|
|
242
|
+
transport.expects(:connection).with { |state|
|
|
243
|
+
state[:port].must_equal 1234
|
|
244
|
+
}.returns(stub(:login_command => stub))
|
|
245
|
+
|
|
246
|
+
cmd
|
|
247
|
+
end
|
|
248
|
+
|
|
249
|
+
it "with :port option set if customized in state" do
|
|
250
|
+
state[:port] = 9999
|
|
251
|
+
|
|
252
|
+
transport.expects(:connection).with { |state|
|
|
253
|
+
state[:port].must_equal 9999
|
|
254
|
+
}.returns(stub(:login_command => stub))
|
|
255
|
+
|
|
256
|
+
cmd
|
|
257
|
+
end
|
|
258
|
+
end
|
|
259
|
+
end
|
|
260
|
+
# rubocop:enable Metrics/MethodLength, Metrics/AbcSize
|
|
261
|
+
|
|
262
|
+
describe "#login_command" do
|
|
263
|
+
|
|
264
|
+
let(:cmd) { driver.login_command(state) }
|
|
265
|
+
|
|
266
|
+
before do
|
|
267
|
+
state[:hostname] = "fizzy"
|
|
268
|
+
state[:username] = "bork"
|
|
269
|
+
end
|
|
270
|
+
|
|
271
|
+
it "returns a LoginCommand" do
|
|
272
|
+
transport.stubs(:connection).returns(stub(:login_command => "command"))
|
|
273
|
+
|
|
274
|
+
cmd.must_equal "command"
|
|
275
|
+
end
|
|
276
|
+
|
|
277
|
+
constructs_an_ssh_connection
|
|
278
|
+
end
|
|
279
|
+
|
|
280
|
+
describe "#converge" do
|
|
281
|
+
|
|
282
|
+
let(:cmd) { driver.converge(state) }
|
|
283
|
+
let(:connection) { stub(:execute => true, :upload => true) }
|
|
284
|
+
|
|
285
|
+
before do
|
|
286
|
+
state[:hostname] = "fizzy"
|
|
287
|
+
state[:username] = "bork"
|
|
288
|
+
provisioner.stubs(:[]).with(:root_path).returns("/rooty")
|
|
289
|
+
FakeFS.activate!
|
|
290
|
+
FileUtils.mkdir_p("/tmp")
|
|
291
|
+
@original_env = ENV.to_hash
|
|
292
|
+
ENV.replace("http_proxy" => nil, "HTTP_PROXY" => nil,
|
|
293
|
+
"https_proxy" => nil, "HTTPS_PROXY" => nil,
|
|
294
|
+
"ftp_proxy" => nil, "FTP_PROXY" => nil,
|
|
295
|
+
"no_proxy" => nil, "NO_PROXY" => nil)
|
|
296
|
+
end
|
|
297
|
+
|
|
298
|
+
after do
|
|
299
|
+
FakeFS.deactivate!
|
|
300
|
+
FakeFS::FileSystem.clear
|
|
301
|
+
ENV.clear
|
|
302
|
+
ENV.replace(@original_env)
|
|
303
|
+
end
|
|
304
|
+
|
|
305
|
+
constructs_an_ssh_connection
|
|
306
|
+
|
|
307
|
+
it "creates the sandbox" do
|
|
308
|
+
transport.stubs(:connection).yields(connection)
|
|
309
|
+
provisioner.expects(:create_sandbox)
|
|
310
|
+
|
|
311
|
+
cmd
|
|
312
|
+
end
|
|
313
|
+
|
|
314
|
+
it "ensures that the sandbox is cleaned up" do
|
|
315
|
+
transport.stubs(:connection).raises
|
|
316
|
+
provisioner.expects(:cleanup_sandbox)
|
|
317
|
+
|
|
318
|
+
begin
|
|
319
|
+
cmd
|
|
320
|
+
rescue # rubocop:disable Lint/HandleExceptions
|
|
321
|
+
end
|
|
322
|
+
end
|
|
323
|
+
|
|
324
|
+
it "invokes the provisioner commands over ssh" do
|
|
325
|
+
transport.stubs(:connection).yields(connection)
|
|
326
|
+
order = sequence("order")
|
|
327
|
+
connection.expects(:execute).with("install").in_sequence(order)
|
|
328
|
+
connection.expects(:execute).with("init").in_sequence(order)
|
|
329
|
+
connection.expects(:execute).with("prepare").in_sequence(order)
|
|
330
|
+
connection.expects(:execute).with("run").in_sequence(order)
|
|
331
|
+
|
|
332
|
+
cmd
|
|
333
|
+
end
|
|
334
|
+
|
|
335
|
+
it "invokes the #install_command with :http_proxy set in config" do
|
|
336
|
+
config[:http_proxy] = "http://proxy"
|
|
337
|
+
transport.stubs(:connection).yields(connection)
|
|
338
|
+
connection.expects(:execute).with("env http_proxy=http://proxy install")
|
|
339
|
+
|
|
340
|
+
cmd
|
|
341
|
+
end
|
|
342
|
+
|
|
343
|
+
it "invokes the #install_command with ENV[\"http_proxy\"] set" do
|
|
344
|
+
ENV["http_proxy"] = "http://proxy"
|
|
345
|
+
transport.stubs(:connection).yields(connection)
|
|
346
|
+
if running_tests_on_windows?
|
|
347
|
+
connection.expects(:execute).
|
|
348
|
+
with("env http_proxy=http://proxy HTTP_PROXY=http://proxy install")
|
|
349
|
+
else
|
|
350
|
+
connection.expects(:execute).with("env http_proxy=http://proxy install")
|
|
351
|
+
end
|
|
352
|
+
cmd
|
|
353
|
+
end
|
|
354
|
+
|
|
355
|
+
it "invokes the #install_command with ENV[\"http_proxy\"] and ENV[\"no_proxy\"] set" do
|
|
356
|
+
ENV["http_proxy"] = "http://proxy"
|
|
357
|
+
ENV["no_proxy"] = "http://no"
|
|
358
|
+
transport.stubs(:connection).yields(connection)
|
|
359
|
+
if running_tests_on_windows?
|
|
360
|
+
connection.expects(:execute).
|
|
361
|
+
with("env http_proxy=http://proxy HTTP_PROXY=http://proxy " \
|
|
362
|
+
"no_proxy=http://no NO_PROXY=http://no install")
|
|
363
|
+
else
|
|
364
|
+
connection.expects(:execute).with("env http_proxy=http://proxy " \
|
|
365
|
+
"no_proxy=http://no install")
|
|
366
|
+
end
|
|
367
|
+
cmd
|
|
368
|
+
end
|
|
369
|
+
|
|
370
|
+
it "invokes the #install_command with :https_proxy set in config" do
|
|
371
|
+
config[:https_proxy] = "https://proxy"
|
|
372
|
+
transport.stubs(:connection).yields(connection)
|
|
373
|
+
connection.expects(:execute).with("env https_proxy=https://proxy install")
|
|
374
|
+
|
|
375
|
+
cmd
|
|
376
|
+
end
|
|
377
|
+
|
|
378
|
+
it "invokes the #install_command with ENV[\"https_proxy\"] set" do
|
|
379
|
+
ENV["https_proxy"] = "https://proxy"
|
|
380
|
+
transport.stubs(:connection).yields(connection)
|
|
381
|
+
if running_tests_on_windows?
|
|
382
|
+
connection.expects(:execute).
|
|
383
|
+
with("env https_proxy=https://proxy HTTPS_PROXY=https://proxy install")
|
|
384
|
+
else
|
|
385
|
+
connection.expects(:execute).with("env https_proxy=https://proxy install")
|
|
386
|
+
end
|
|
387
|
+
cmd
|
|
388
|
+
end
|
|
389
|
+
|
|
390
|
+
it "invokes the #install_command with ENV[\"https_proxy\"] and ENV[\"no_proxy\"] set" do
|
|
391
|
+
ENV["https_proxy"] = "https://proxy"
|
|
392
|
+
ENV["no_proxy"] = "https://no"
|
|
393
|
+
transport.stubs(:connection).yields(connection)
|
|
394
|
+
if running_tests_on_windows?
|
|
395
|
+
connection.expects(:execute).
|
|
396
|
+
with("env https_proxy=https://proxy HTTPS_PROXY=https://proxy " \
|
|
397
|
+
"no_proxy=https://no NO_PROXY=https://no install")
|
|
398
|
+
else
|
|
399
|
+
connection.expects(:execute).with("env https_proxy=https://proxy " \
|
|
400
|
+
"no_proxy=https://no install")
|
|
401
|
+
end
|
|
402
|
+
cmd
|
|
403
|
+
end
|
|
404
|
+
|
|
405
|
+
it "invokes the #install_command with :ftp_proxy set in config" do
|
|
406
|
+
config[:ftp_proxy] = "ftp://proxy"
|
|
407
|
+
transport.stubs(:connection).yields(connection)
|
|
408
|
+
connection.expects(:execute).with("env ftp_proxy=ftp://proxy install")
|
|
409
|
+
|
|
410
|
+
cmd
|
|
411
|
+
end
|
|
412
|
+
|
|
413
|
+
it "invokes the #install_command with ENV[\"ftp_proxy\"] set" do
|
|
414
|
+
ENV["ftp_proxy"] = "ftp://proxy"
|
|
415
|
+
transport.stubs(:connection).yields(connection)
|
|
416
|
+
if running_tests_on_windows?
|
|
417
|
+
connection.expects(:execute).
|
|
418
|
+
with("env ftp_proxy=ftp://proxy FTP_PROXY=ftp://proxy install")
|
|
419
|
+
else
|
|
420
|
+
connection.expects(:execute).with("env ftp_proxy=ftp://proxy install")
|
|
421
|
+
end
|
|
422
|
+
cmd
|
|
423
|
+
end
|
|
424
|
+
|
|
425
|
+
it "invokes the #install_command with ENV[\"ftp_proxy\"] and ENV[\"no_proxy\"] set" do
|
|
426
|
+
ENV["ftp_proxy"] = "ftp://proxy"
|
|
427
|
+
ENV["no_proxy"] = "http://no"
|
|
428
|
+
transport.stubs(:connection).yields(connection)
|
|
429
|
+
if running_tests_on_windows?
|
|
430
|
+
connection.expects(:execute).
|
|
431
|
+
with("env ftp_proxy=ftp://proxy FTP_PROXY=http://proxy " \
|
|
432
|
+
"no_proxy=http://no NO_PROXY=http://no install")
|
|
433
|
+
else
|
|
434
|
+
connection.expects(:execute).with("env ftp_proxy=ftp://proxy " \
|
|
435
|
+
"no_proxy=http://no install")
|
|
436
|
+
end
|
|
437
|
+
cmd
|
|
438
|
+
end
|
|
439
|
+
|
|
440
|
+
it "invokes the #install_command with :http_proxy & :https_proxy & :ftp_proxy set" do
|
|
441
|
+
config[:http_proxy] = "http://proxy"
|
|
442
|
+
config[:https_proxy] = "https://proxy"
|
|
443
|
+
config[:ftp_proxy] = "ftp://proxy"
|
|
444
|
+
transport.stubs(:connection).yields(connection)
|
|
445
|
+
connection.expects(:execute).with(
|
|
446
|
+
"env http_proxy=http://proxy https_proxy=https://proxy ftp_proxy=ftp://proxy install")
|
|
447
|
+
|
|
448
|
+
cmd
|
|
449
|
+
end
|
|
450
|
+
|
|
451
|
+
describe "transferring files" do
|
|
452
|
+
|
|
453
|
+
before do
|
|
454
|
+
transport.stubs(:connection).yields(connection)
|
|
455
|
+
connection.stubs(:upload)
|
|
456
|
+
FileUtils.mkdir_p "/tmp/sandbox/stuff"
|
|
457
|
+
end
|
|
458
|
+
|
|
459
|
+
it "uploads files" do
|
|
460
|
+
connection.expects(:upload).with(["/tmp/sandbox/stuff"], "/rooty")
|
|
461
|
+
|
|
462
|
+
cmd
|
|
463
|
+
end
|
|
464
|
+
|
|
465
|
+
it "logs to info" do
|
|
466
|
+
cmd
|
|
467
|
+
|
|
468
|
+
logged_output.string.
|
|
469
|
+
must_match(/INFO -- : Transferring files to instance$/)
|
|
470
|
+
end
|
|
471
|
+
|
|
472
|
+
it "logs to debug" do
|
|
473
|
+
cmd
|
|
474
|
+
|
|
475
|
+
logged_output.string.must_match(/DEBUG -- : Transfer complete$/)
|
|
476
|
+
end
|
|
477
|
+
|
|
478
|
+
it "raises an ActionFailed on transfer when SshFailed is raised" do
|
|
479
|
+
connection.stubs(:upload).raises(Kitchen::Transport::SshFailed.new("dang"))
|
|
480
|
+
|
|
481
|
+
proc { cmd }.must_raise Kitchen::ActionFailed
|
|
482
|
+
end
|
|
483
|
+
end
|
|
484
|
+
|
|
485
|
+
it "raises an ActionFailed on execute when SshFailed is raised" do
|
|
486
|
+
transport.stubs(:connection).yields(connection)
|
|
487
|
+
connection.stubs(:execute).raises(Kitchen::Transport::SshFailed.new("dang"))
|
|
488
|
+
|
|
489
|
+
proc { cmd }.must_raise Kitchen::ActionFailed
|
|
490
|
+
end
|
|
491
|
+
end
|
|
492
|
+
|
|
493
|
+
describe "#setup" do
|
|
494
|
+
|
|
495
|
+
let(:cmd) { driver.setup(state) }
|
|
496
|
+
let(:connection) { mock }
|
|
497
|
+
|
|
498
|
+
before do
|
|
499
|
+
state[:hostname] = "fizzy"
|
|
500
|
+
state[:username] = "bork"
|
|
501
|
+
end
|
|
502
|
+
|
|
503
|
+
constructs_an_ssh_connection
|
|
504
|
+
|
|
505
|
+
it "invokes the Verifier#install_command over ssh" do
|
|
506
|
+
transport.stubs(:connection).yields(connection)
|
|
507
|
+
connection.expects(:execute).with("install")
|
|
508
|
+
|
|
509
|
+
cmd
|
|
510
|
+
end
|
|
511
|
+
|
|
512
|
+
it "invokes the Verifier#install_command with :http_proxy set in config" do
|
|
513
|
+
config[:http_proxy] = "http://proxy"
|
|
514
|
+
transport.stubs(:connection).yields(connection)
|
|
515
|
+
connection.expects(:execute).with("env http_proxy=http://proxy install")
|
|
516
|
+
|
|
517
|
+
cmd
|
|
518
|
+
end
|
|
519
|
+
|
|
520
|
+
it "invokes the Verifier#install_command with :https_proxy set in config" do
|
|
521
|
+
config[:https_proxy] = "https://proxy"
|
|
522
|
+
transport.stubs(:connection).yields(connection)
|
|
523
|
+
connection.expects(:execute).with("env https_proxy=https://proxy install")
|
|
524
|
+
|
|
525
|
+
cmd
|
|
526
|
+
end
|
|
527
|
+
|
|
528
|
+
it "invokes the Verifier#install_command with :ftp_proxy set in config" do
|
|
529
|
+
config[:ftp_proxy] = "ftp://proxy"
|
|
530
|
+
transport.stubs(:connection).yields(connection)
|
|
531
|
+
connection.expects(:execute).with("env ftp_proxy=ftp://proxy install")
|
|
532
|
+
|
|
533
|
+
cmd
|
|
534
|
+
end
|
|
535
|
+
|
|
536
|
+
it "invokes the Verifier#install_command with :http_proxy & :https_proxy & :ftp_proxy set" do
|
|
537
|
+
config[:http_proxy] = "http://proxy"
|
|
538
|
+
config[:https_proxy] = "https://proxy"
|
|
539
|
+
config[:ftp_proxy] = "ftp://proxy"
|
|
540
|
+
transport.stubs(:connection).yields(connection)
|
|
541
|
+
connection.expects(:execute).with(
|
|
542
|
+
"env http_proxy=http://proxy https_proxy=https://proxy ftp_proxy=ftp://proxy install")
|
|
543
|
+
|
|
544
|
+
cmd
|
|
545
|
+
end
|
|
546
|
+
|
|
547
|
+
it "raises an ActionFailed when SshFailed is raised" do
|
|
548
|
+
transport.stubs(:connection).yields(connection)
|
|
549
|
+
connection.stubs(:execute).raises(Kitchen::Transport::SshFailed.new("dang"))
|
|
550
|
+
|
|
551
|
+
proc { cmd }.must_raise Kitchen::ActionFailed
|
|
552
|
+
end
|
|
553
|
+
end
|
|
554
|
+
|
|
555
|
+
describe "#verify" do
|
|
556
|
+
|
|
557
|
+
let(:cmd) { driver.verify(state) }
|
|
558
|
+
let(:connection) { stub(:execute => true, :upload => true) }
|
|
559
|
+
|
|
560
|
+
before do
|
|
561
|
+
state[:hostname] = "fizzy"
|
|
562
|
+
state[:username] = "bork"
|
|
563
|
+
transport.stubs(:connection).yields(connection)
|
|
564
|
+
end
|
|
565
|
+
|
|
566
|
+
constructs_an_ssh_connection
|
|
567
|
+
|
|
568
|
+
it "creates the sandbox" do
|
|
569
|
+
verifier.expects(:create_sandbox)
|
|
570
|
+
|
|
571
|
+
cmd
|
|
572
|
+
end
|
|
573
|
+
|
|
574
|
+
it "ensures that the sandbox is cleanup up" do
|
|
575
|
+
transport.stubs(:connection).raises
|
|
576
|
+
verifier.expects(:cleanup_sandbox)
|
|
577
|
+
|
|
578
|
+
begin
|
|
579
|
+
cmd
|
|
580
|
+
rescue # rubocop:disable Lint/HandleExceptions
|
|
581
|
+
end
|
|
582
|
+
end
|
|
583
|
+
|
|
584
|
+
it "invokes the verifier commands over the transport" do
|
|
585
|
+
order = sequence("order")
|
|
586
|
+
connection.expects(:execute).with("init").in_sequence(order)
|
|
587
|
+
connection.expects(:execute).with("prepare").in_sequence(order)
|
|
588
|
+
connection.expects(:execute).with("run").in_sequence(order)
|
|
589
|
+
|
|
590
|
+
cmd
|
|
591
|
+
end
|
|
592
|
+
|
|
593
|
+
%W[init prepare run].each do |phase|
|
|
594
|
+
it "invokes Verifier##{phase}_command over ssh" do
|
|
595
|
+
connection.expects(:execute).with(phase)
|
|
596
|
+
|
|
597
|
+
cmd
|
|
598
|
+
end
|
|
599
|
+
|
|
600
|
+
it "invokes Verifier##{phase}_command with :http_proxy set in config" do
|
|
601
|
+
config[:http_proxy] = "http://proxy"
|
|
602
|
+
connection.expects(:execute).with("env http_proxy=http://proxy #{phase}")
|
|
603
|
+
|
|
604
|
+
cmd
|
|
605
|
+
end
|
|
606
|
+
|
|
607
|
+
it "invokes Verifier##{phase}_command with :https_proxy set in config" do
|
|
608
|
+
config[:https_proxy] = "https://proxy"
|
|
609
|
+
connection.expects(:execute).with("env https_proxy=https://proxy #{phase}")
|
|
610
|
+
|
|
611
|
+
cmd
|
|
612
|
+
end
|
|
613
|
+
|
|
614
|
+
it "invokes Verifier##{phase}_command with :ftp_proxy set in config" do
|
|
615
|
+
config[:ftp_proxy] = "ftp://proxy"
|
|
616
|
+
connection.expects(:execute).with("env ftp_proxy=ftp://proxy #{phase}")
|
|
617
|
+
|
|
618
|
+
cmd
|
|
619
|
+
end
|
|
620
|
+
|
|
621
|
+
it "invokes Verifier##{phase}_command with :http_proxy & :https_proxy & :ftp_proxy set" do
|
|
622
|
+
config[:http_proxy] = "http://proxy"
|
|
623
|
+
config[:https_proxy] = "https://proxy"
|
|
624
|
+
config[:ftp_proxy] = "ftp://proxy"
|
|
625
|
+
connection.expects(:execute).with(
|
|
626
|
+
"env http_proxy=http://proxy https_proxy=https://proxy ftp_proxy=ftp://proxy #{phase}")
|
|
627
|
+
|
|
628
|
+
cmd
|
|
629
|
+
end
|
|
630
|
+
end
|
|
631
|
+
|
|
632
|
+
it "logs to info" do
|
|
633
|
+
cmd
|
|
634
|
+
|
|
635
|
+
logged_output.string.
|
|
636
|
+
must_match(/INFO -- : Transferring files to instance$/)
|
|
637
|
+
end
|
|
638
|
+
|
|
639
|
+
it "uploads sandbox files" do
|
|
640
|
+
connection.expects(:upload).with([], "/tmp/verifier")
|
|
641
|
+
|
|
642
|
+
cmd
|
|
643
|
+
end
|
|
644
|
+
|
|
645
|
+
it "logs to debug" do
|
|
646
|
+
cmd
|
|
647
|
+
|
|
648
|
+
logged_output.string.must_match(/DEBUG -- : Transfer complete$/)
|
|
649
|
+
end
|
|
650
|
+
|
|
651
|
+
it "raises an ActionFailed on transfer when TransportFailed is raised" do
|
|
652
|
+
connection.stubs(:upload).
|
|
653
|
+
raises(Kitchen::Transport::TransportFailed.new("dang"))
|
|
654
|
+
|
|
655
|
+
proc { cmd }.must_raise Kitchen::ActionFailed
|
|
656
|
+
end
|
|
657
|
+
|
|
658
|
+
it "raises an ActionFailed when SSHFailed is raised" do
|
|
659
|
+
connection.stubs(:execute).raises(Kitchen::Transport::SshFailed.new("dang"))
|
|
660
|
+
|
|
661
|
+
proc { cmd }.must_raise Kitchen::ActionFailed
|
|
662
|
+
end
|
|
663
|
+
end
|
|
664
|
+
|
|
665
|
+
describe "#ssh" do
|
|
666
|
+
|
|
667
|
+
let(:cmd) { driver.ssh(["host", "user", { :one => "two" }], "go") }
|
|
668
|
+
let(:connection) { mock }
|
|
669
|
+
|
|
670
|
+
it "creates an SSH connection" do
|
|
671
|
+
connection.stubs(:execute)
|
|
672
|
+
transport.expects(:connection).with(
|
|
673
|
+
:hostname => "host",
|
|
674
|
+
:username => "user",
|
|
675
|
+
:port => 22,
|
|
676
|
+
:one => "two"
|
|
677
|
+
).yields(connection)
|
|
678
|
+
|
|
679
|
+
cmd
|
|
680
|
+
end
|
|
681
|
+
|
|
682
|
+
it "invokes the command over ssh" do
|
|
683
|
+
transport.expects(:connection).yields(connection)
|
|
684
|
+
connection.expects(:execute).with("go")
|
|
685
|
+
|
|
686
|
+
cmd
|
|
687
|
+
end
|
|
688
|
+
end
|
|
689
|
+
|
|
690
|
+
describe "#remote_command" do
|
|
691
|
+
|
|
692
|
+
let(:cmd) { driver.remote_command(state, "shipit") }
|
|
693
|
+
let(:connection) { mock }
|
|
694
|
+
|
|
695
|
+
before do
|
|
696
|
+
state[:hostname] = "fizzy"
|
|
697
|
+
state[:username] = "bork"
|
|
698
|
+
end
|
|
699
|
+
|
|
700
|
+
it "creates an SSH connection" do
|
|
701
|
+
transport.expects(:connection).with(
|
|
702
|
+
:hostname => "fizzy",
|
|
703
|
+
:username => "bork",
|
|
704
|
+
:port => 22
|
|
705
|
+
)
|
|
706
|
+
|
|
707
|
+
cmd
|
|
708
|
+
end
|
|
709
|
+
|
|
710
|
+
it "invokes the command over ssh" do
|
|
711
|
+
transport.expects(:connection).yields(connection)
|
|
712
|
+
connection.expects(:execute).with("shipit")
|
|
713
|
+
|
|
714
|
+
cmd
|
|
715
|
+
end
|
|
716
|
+
end
|
|
717
|
+
|
|
718
|
+
describe "#wait_for_sshd" do
|
|
719
|
+
|
|
720
|
+
let(:cmd) do
|
|
721
|
+
driver.send(:wait_for_sshd, "host", "user", :one => "two")
|
|
722
|
+
end
|
|
723
|
+
|
|
724
|
+
it "creates an SSH connection with merged options" do
|
|
725
|
+
transport.expects(:connection).with(
|
|
726
|
+
:hostname => "host",
|
|
727
|
+
:username => "user",
|
|
728
|
+
:port => 22,
|
|
729
|
+
:one => "two"
|
|
730
|
+
).returns(stub(:wait_until_ready => true))
|
|
731
|
+
|
|
732
|
+
cmd
|
|
733
|
+
end
|
|
734
|
+
|
|
735
|
+
it "calls wait on the SSH connection" do
|
|
736
|
+
connection = mock
|
|
737
|
+
transport.expects(:connection).returns(connection)
|
|
738
|
+
connection.expects(:wait_until_ready)
|
|
739
|
+
|
|
740
|
+
cmd
|
|
741
|
+
end
|
|
742
|
+
end
|
|
743
|
+
|
|
744
|
+
describe "to maintain backwards compatibility" do
|
|
745
|
+
|
|
746
|
+
let(:driver) do
|
|
747
|
+
Kitchen::Driver::BackCompat.new(config).finalize_config!(instance)
|
|
748
|
+
end
|
|
749
|
+
|
|
750
|
+
it "#instance returns its instance" do
|
|
751
|
+
driver.instance.must_equal instance
|
|
752
|
+
end
|
|
753
|
+
|
|
754
|
+
it "#name returns the name of the driver" do
|
|
755
|
+
driver.name.must_equal "BackCompat"
|
|
756
|
+
end
|
|
757
|
+
|
|
758
|
+
describe "#logger" do
|
|
759
|
+
|
|
760
|
+
before { @klog = Kitchen.logger }
|
|
761
|
+
after { Kitchen.logger = @klog }
|
|
762
|
+
|
|
763
|
+
it "returns the instance's logger if defined" do
|
|
764
|
+
driver.send(:logger).must_equal logger
|
|
765
|
+
end
|
|
766
|
+
|
|
767
|
+
it "returns the default logger if instance's logger is not set" do
|
|
768
|
+
driver = Kitchen::Driver::BackCompat.new(config)
|
|
769
|
+
Kitchen.logger = "yep"
|
|
770
|
+
|
|
771
|
+
driver.send(:logger).must_equal Kitchen.logger
|
|
772
|
+
end
|
|
773
|
+
end
|
|
774
|
+
|
|
775
|
+
it "#puts calls logger.info" do
|
|
776
|
+
driver.send(:puts, "yo")
|
|
777
|
+
|
|
778
|
+
logged_output.string.must_match(/I, /)
|
|
779
|
+
logged_output.string.must_match(/yo\n/)
|
|
780
|
+
end
|
|
781
|
+
|
|
782
|
+
it "#print calls logger.info" do
|
|
783
|
+
driver.send(:print, "yo")
|
|
784
|
+
|
|
785
|
+
logged_output.string.must_match(/I, /)
|
|
786
|
+
logged_output.string.must_match(/yo\n/)
|
|
787
|
+
end
|
|
788
|
+
|
|
789
|
+
it "has a default verify dependencies method" do
|
|
790
|
+
driver.verify_dependencies.must_be_nil
|
|
791
|
+
end
|
|
792
|
+
|
|
793
|
+
it "#busser returns the instance's verifier" do
|
|
794
|
+
driver.send(:busser).must_equal verifier
|
|
795
|
+
end
|
|
796
|
+
|
|
797
|
+
describe ".no_parallel_for" do
|
|
798
|
+
|
|
799
|
+
it "registers no serial actions when none are declared" do
|
|
800
|
+
Kitchen::Driver::SpeedyCompat.serial_actions.must_equal nil
|
|
801
|
+
end
|
|
802
|
+
|
|
803
|
+
it "registers a single serial action method" do
|
|
804
|
+
Kitchen::Driver::DodgyCompat.serial_actions.must_equal [:converge]
|
|
805
|
+
end
|
|
806
|
+
|
|
807
|
+
it "registers multiple serial action methods" do
|
|
808
|
+
actions = Kitchen::Driver::SlowCompat.serial_actions
|
|
809
|
+
|
|
810
|
+
actions.must_include :create
|
|
811
|
+
actions.must_include :verify
|
|
812
|
+
actions.must_include :destroy
|
|
813
|
+
end
|
|
814
|
+
|
|
815
|
+
it "raises a ClientError if value is not an action method" do
|
|
816
|
+
proc {
|
|
817
|
+
Class.new(Kitchen::Driver::BackCompat) {
|
|
818
|
+
no_parallel_for :telling_stories
|
|
819
|
+
}
|
|
820
|
+
}.must_raise Kitchen::ClientError
|
|
821
|
+
end
|
|
822
|
+
end
|
|
823
|
+
|
|
824
|
+
# rubocop:disable Metrics/MethodLength, Metrics/AbcSize
|
|
825
|
+
def self.constructs_an_ssh_object
|
|
826
|
+
it "with hostname set from state" do
|
|
827
|
+
Kitchen::SSH.expects(:new).with { |hostname, _username, _opts|
|
|
828
|
+
hostname.must_equal "fizzy"
|
|
829
|
+
}.returns(connection)
|
|
830
|
+
|
|
831
|
+
cmd
|
|
832
|
+
end
|
|
833
|
+
|
|
834
|
+
it "with username set from state" do
|
|
835
|
+
Kitchen::SSH.expects(:new).with { |_hostname, username, _opts|
|
|
836
|
+
username.must_equal "bork"
|
|
837
|
+
}.returns(connection)
|
|
838
|
+
|
|
839
|
+
cmd
|
|
840
|
+
end
|
|
841
|
+
|
|
842
|
+
it "with :user_known_hosts_file option set to /dev/null" do
|
|
843
|
+
Kitchen::SSH.expects(:new).with { |_hostname, _username, opts|
|
|
844
|
+
opts[:user_known_hosts_file].must_equal "/dev/null"
|
|
845
|
+
}.returns(connection)
|
|
846
|
+
|
|
847
|
+
cmd
|
|
848
|
+
end
|
|
849
|
+
|
|
850
|
+
it "with :paranoid option set to false" do
|
|
851
|
+
Kitchen::SSH.expects(:new).with { |_hostname, _username, opts|
|
|
852
|
+
opts[:paranoid].must_equal false
|
|
853
|
+
}.returns(connection)
|
|
854
|
+
|
|
855
|
+
cmd
|
|
856
|
+
end
|
|
857
|
+
|
|
858
|
+
it "with :keys_only option set to falsey by default" do
|
|
859
|
+
Kitchen::SSH.expects(:new).with { |_hostname, _username, opts|
|
|
860
|
+
opts[:keys_only].nil?
|
|
861
|
+
}.returns(connection)
|
|
862
|
+
|
|
863
|
+
cmd
|
|
864
|
+
end
|
|
865
|
+
|
|
866
|
+
it "with :keys_only option set to true if :ssh_key is set in config" do
|
|
867
|
+
config[:ssh_key] = "wicked"
|
|
868
|
+
|
|
869
|
+
Kitchen::SSH.expects(:new).with { |_hostname, _username, opts|
|
|
870
|
+
opts[:keys_only].must_equal true
|
|
871
|
+
}.returns(connection)
|
|
872
|
+
|
|
873
|
+
cmd
|
|
874
|
+
end
|
|
875
|
+
|
|
876
|
+
it "with :keys_only option set to true if :ssh_key is set in state" do
|
|
877
|
+
state[:ssh_key] = "wicked"
|
|
878
|
+
|
|
879
|
+
Kitchen::SSH.expects(:new).with { |_hostname, _username, opts|
|
|
880
|
+
opts[:keys_only].must_equal true
|
|
881
|
+
}.returns(connection)
|
|
882
|
+
|
|
883
|
+
cmd
|
|
884
|
+
end
|
|
885
|
+
|
|
886
|
+
it "with :keys option set to falsey by default" do
|
|
887
|
+
Kitchen::SSH.expects(:new).with { |_hostname, _username, opts|
|
|
888
|
+
opts[:keys].nil?
|
|
889
|
+
}.returns(connection)
|
|
890
|
+
|
|
891
|
+
cmd
|
|
892
|
+
end
|
|
893
|
+
|
|
894
|
+
it "with :keys option set to an array if :ssh_key is set in config" do
|
|
895
|
+
config[:ssh_key] = "wicked"
|
|
896
|
+
|
|
897
|
+
Kitchen::SSH.expects(:new).with { |_hostname, _username, opts|
|
|
898
|
+
opts[:keys].must_equal ["wicked"]
|
|
899
|
+
}.returns(connection)
|
|
900
|
+
|
|
901
|
+
cmd
|
|
902
|
+
end
|
|
903
|
+
|
|
904
|
+
it "with :keys option set to an array if :ssh_key is set in state" do
|
|
905
|
+
state[:ssh_key] = "wicked"
|
|
906
|
+
|
|
907
|
+
Kitchen::SSH.expects(:new).with { |_hostname, _username, opts|
|
|
908
|
+
opts[:keys].must_equal ["wicked"]
|
|
909
|
+
}.returns(connection)
|
|
910
|
+
|
|
911
|
+
cmd
|
|
912
|
+
end
|
|
913
|
+
|
|
914
|
+
it "with :password option set to falsey by default" do
|
|
915
|
+
Kitchen::SSH.expects(:new).with { |_hostname, _username, opts|
|
|
916
|
+
opts[:password].nil?
|
|
917
|
+
}.returns(connection)
|
|
918
|
+
|
|
919
|
+
cmd
|
|
920
|
+
end
|
|
921
|
+
|
|
922
|
+
it "with :password option set if given in config" do
|
|
923
|
+
config[:password] = "psst"
|
|
924
|
+
|
|
925
|
+
Kitchen::SSH.expects(:new).with { |_hostname, _username, opts|
|
|
926
|
+
opts[:password].must_equal "psst"
|
|
927
|
+
}.returns(connection)
|
|
928
|
+
|
|
929
|
+
cmd
|
|
930
|
+
end
|
|
931
|
+
|
|
932
|
+
it "with :password option set if given in state" do
|
|
933
|
+
state[:password] = "psst"
|
|
934
|
+
|
|
935
|
+
Kitchen::SSH.expects(:new).with { |_hostname, _username, opts|
|
|
936
|
+
opts[:password].must_equal "psst"
|
|
937
|
+
}.returns(connection)
|
|
938
|
+
|
|
939
|
+
cmd
|
|
940
|
+
end
|
|
941
|
+
|
|
942
|
+
it "with :forward_agent option set to falsey by default" do
|
|
943
|
+
Kitchen::SSH.expects(:new).with { |_hostname, _username, opts|
|
|
944
|
+
opts[:forward_agent].nil?
|
|
945
|
+
}.returns(connection)
|
|
946
|
+
|
|
947
|
+
cmd
|
|
948
|
+
end
|
|
949
|
+
|
|
950
|
+
it "with :forward_agent option set if given in config" do
|
|
951
|
+
config[:forward_agent] = "yeah?"
|
|
952
|
+
|
|
953
|
+
Kitchen::SSH.expects(:new).with { |_hostname, _username, opts|
|
|
954
|
+
opts[:forward_agent].must_equal "yeah?"
|
|
955
|
+
}.returns(connection)
|
|
956
|
+
|
|
957
|
+
cmd
|
|
958
|
+
end
|
|
959
|
+
|
|
960
|
+
it "with :forward_agent option set if given in state" do
|
|
961
|
+
state[:forward_agent] = "yeah?"
|
|
962
|
+
|
|
963
|
+
Kitchen::SSH.expects(:new).with { |_hostname, _username, opts|
|
|
964
|
+
opts[:forward_agent].must_equal "yeah?"
|
|
965
|
+
}.returns(connection)
|
|
966
|
+
|
|
967
|
+
cmd
|
|
968
|
+
end
|
|
969
|
+
|
|
970
|
+
it "with :port option set to 22 by default" do
|
|
971
|
+
Kitchen::SSH.expects(:new).with { |_hostname, _username, opts|
|
|
972
|
+
opts[:port].must_equal 22
|
|
973
|
+
}.returns(connection)
|
|
974
|
+
|
|
975
|
+
cmd
|
|
976
|
+
end
|
|
977
|
+
|
|
978
|
+
it "with :port option set if customized in config" do
|
|
979
|
+
config[:port] = 1234
|
|
980
|
+
|
|
981
|
+
Kitchen::SSH.expects(:new).with { |_hostname, _username, opts|
|
|
982
|
+
opts[:port].must_equal 1234
|
|
983
|
+
}.returns(connection)
|
|
984
|
+
|
|
985
|
+
cmd
|
|
986
|
+
end
|
|
987
|
+
|
|
988
|
+
it "with :port option set if customized in state" do
|
|
989
|
+
state[:port] = 9999
|
|
990
|
+
|
|
991
|
+
Kitchen::SSH.expects(:new).with { |_hostname, _username, opts|
|
|
992
|
+
opts[:port].must_equal 9999
|
|
993
|
+
}.returns(connection)
|
|
994
|
+
|
|
995
|
+
cmd
|
|
996
|
+
end
|
|
997
|
+
|
|
998
|
+
it "with :logger option set to driver's logger" do
|
|
999
|
+
Kitchen::SSH.expects(:new).with { |_hostname, _username, opts|
|
|
1000
|
+
opts[:logger].must_equal logger
|
|
1001
|
+
}.returns(connection)
|
|
1002
|
+
|
|
1003
|
+
cmd
|
|
1004
|
+
end
|
|
1005
|
+
end
|
|
1006
|
+
# rubocop:enable Metrics/MethodLength, Metrics/AbcSize
|
|
1007
|
+
|
|
1008
|
+
describe "#run_remote" do
|
|
1009
|
+
|
|
1010
|
+
let(:cmd) { driver.use_run_remote(state, "huh") }
|
|
1011
|
+
let(:connection) { stub(:exec => true) }
|
|
1012
|
+
|
|
1013
|
+
before do
|
|
1014
|
+
state[:hostname] = "fizzy"
|
|
1015
|
+
state[:username] = "bork"
|
|
1016
|
+
end
|
|
1017
|
+
|
|
1018
|
+
constructs_an_ssh_object
|
|
1019
|
+
|
|
1020
|
+
it "invokes the #install_command with :http_proxy set in config" do
|
|
1021
|
+
config[:http_proxy] = "http://proxy"
|
|
1022
|
+
Kitchen::SSH.stubs(:new).returns(connection)
|
|
1023
|
+
connection.expects(:exec).with("env http_proxy=http://proxy huh")
|
|
1024
|
+
|
|
1025
|
+
cmd
|
|
1026
|
+
end
|
|
1027
|
+
|
|
1028
|
+
it "invokes the #install_command with :https_proxy set in config" do
|
|
1029
|
+
config[:https_proxy] = "https://proxy"
|
|
1030
|
+
Kitchen::SSH.stubs(:new).returns(connection)
|
|
1031
|
+
connection.expects(:exec).with("env https_proxy=https://proxy huh")
|
|
1032
|
+
|
|
1033
|
+
cmd
|
|
1034
|
+
end
|
|
1035
|
+
|
|
1036
|
+
it "invokes the #install_command with :ftp_proxy set in config" do
|
|
1037
|
+
config[:ftp_proxy] = "ftp://proxy"
|
|
1038
|
+
Kitchen::SSH.stubs(:new).returns(connection)
|
|
1039
|
+
connection.expects(:exec).with("env ftp_proxy=ftp://proxy huh")
|
|
1040
|
+
|
|
1041
|
+
cmd
|
|
1042
|
+
end
|
|
1043
|
+
|
|
1044
|
+
it "invokes the #install_command with :http_proxy & :https_proxy & :ftp_proxy set" do
|
|
1045
|
+
config[:http_proxy] = "http://proxy"
|
|
1046
|
+
config[:https_proxy] = "https://proxy"
|
|
1047
|
+
config[:ftp_proxy] = "ftp://proxy"
|
|
1048
|
+
Kitchen::SSH.stubs(:new).returns(connection)
|
|
1049
|
+
connection.expects(:exec).with(
|
|
1050
|
+
"env http_proxy=http://proxy https_proxy=https://proxy ftp_proxy=ftp://proxy huh")
|
|
1051
|
+
|
|
1052
|
+
cmd
|
|
1053
|
+
end
|
|
1054
|
+
|
|
1055
|
+
it "doesn't invoke an ssh command if command is nil" do
|
|
1056
|
+
Kitchen::SSH.stubs(:new).returns(mock)
|
|
1057
|
+
|
|
1058
|
+
driver.use_run_remote(state, nil)
|
|
1059
|
+
end
|
|
1060
|
+
|
|
1061
|
+
it "raises an ActionFailed on transfer when SSHFailed is raised" do
|
|
1062
|
+
Kitchen::SSH.stubs(:new).returns(connection)
|
|
1063
|
+
connection.stubs(:exec).raises(Kitchen::SSHFailed.new("dang"))
|
|
1064
|
+
|
|
1065
|
+
proc { cmd }.must_raise Kitchen::ActionFailed
|
|
1066
|
+
end
|
|
1067
|
+
|
|
1068
|
+
it "raises an ActionFailed on exec when Net::SSH:Exception is raised" do
|
|
1069
|
+
Kitchen::SSH.stubs(:new).returns(connection)
|
|
1070
|
+
connection.stubs(:exec).raises(Net::SSH::Exception.new("dang"))
|
|
1071
|
+
|
|
1072
|
+
proc { cmd }.must_raise Kitchen::ActionFailed
|
|
1073
|
+
end
|
|
1074
|
+
end
|
|
1075
|
+
|
|
1076
|
+
describe "#transfer_path" do
|
|
1077
|
+
|
|
1078
|
+
let(:cmd) { driver.use_transfer_path(state, ["nope"], "nadda") }
|
|
1079
|
+
let(:connection) { stub(:upload_path! => true) }
|
|
1080
|
+
|
|
1081
|
+
before do
|
|
1082
|
+
state[:hostname] = "fizzy"
|
|
1083
|
+
state[:username] = "bork"
|
|
1084
|
+
end
|
|
1085
|
+
|
|
1086
|
+
constructs_an_ssh_object
|
|
1087
|
+
|
|
1088
|
+
it "doesn't invoke an scp command if locals is nil" do
|
|
1089
|
+
Kitchen::SSH.stubs(:new).returns(mock)
|
|
1090
|
+
|
|
1091
|
+
driver.use_transfer_path(state, nil, "nope")
|
|
1092
|
+
end
|
|
1093
|
+
|
|
1094
|
+
it "doesn't invoke an scp command if locals is an empty array" do
|
|
1095
|
+
Kitchen::SSH.stubs(:new).returns(mock)
|
|
1096
|
+
|
|
1097
|
+
driver.use_transfer_path(state, [], "nope")
|
|
1098
|
+
end
|
|
1099
|
+
|
|
1100
|
+
it "raises an ActionFailed on transfer when SSHFailed is raised" do
|
|
1101
|
+
Kitchen::SSH.stubs(:new).returns(connection)
|
|
1102
|
+
connection.stubs(:upload_path!).raises(Kitchen::SSHFailed.new("dang"))
|
|
1103
|
+
|
|
1104
|
+
proc { cmd }.must_raise Kitchen::ActionFailed
|
|
1105
|
+
end
|
|
1106
|
+
|
|
1107
|
+
it "raises an ActionFailed on exec when Net::SSH:Exception is raised" do
|
|
1108
|
+
Kitchen::SSH.stubs(:new).returns(connection)
|
|
1109
|
+
connection.stubs(:upload_path!).raises(Net::SSH::Exception.new("dang"))
|
|
1110
|
+
|
|
1111
|
+
proc { cmd }.must_raise Kitchen::ActionFailed
|
|
1112
|
+
end
|
|
1113
|
+
end
|
|
1114
|
+
end
|
|
1115
|
+
end
|