test-kitchen 1.5.0.rc.1 → 1.5.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +4 -33
- data/CHANGELOG.md +46 -1
- data/CONTRIBUTING.md +17 -0
- data/Gemfile.proxy_tests +1 -2
- data/MAINTAINERS.md +24 -0
- data/features/kitchen_init_command.feature +50 -4
- data/lib/kitchen/cli.rb +43 -5
- data/lib/kitchen/command.rb +1 -0
- data/lib/kitchen/config.rb +4 -0
- data/lib/kitchen/generator/init.rb +4 -4
- data/lib/kitchen/instance.rb +7 -0
- data/lib/kitchen/logger.rb +4 -7
- data/lib/kitchen/provisioner/chef_base.rb +2 -1
- data/lib/kitchen/provisioner/chef_solo.rb +1 -0
- data/lib/kitchen/provisioner/chef_zero.rb +5 -0
- data/lib/kitchen/ssh.rb +1 -1
- data/lib/kitchen/transport/base.rb +7 -0
- data/lib/kitchen/transport/ssh.rb +13 -6
- data/lib/kitchen/transport/winrm.rb +133 -49
- data/lib/kitchen/version.rb +1 -2
- data/spec/kitchen/collection_spec.rb +1 -1
- data/spec/kitchen/logger_spec.rb +10 -0
- data/spec/kitchen/provisioner/chef_base_spec.rb +2 -2
- data/spec/kitchen/provisioner/chef_solo_spec.rb +13 -0
- data/spec/kitchen/provisioner/chef_zero_spec.rb +13 -0
- data/spec/kitchen/ssh_spec.rb +1 -1
- data/spec/kitchen/transport/ssh_spec.rb +2 -1
- data/spec/kitchen/transport/winrm_spec.rb +178 -48
- data/support/chef_base_install_command.ps1 +19 -12
- data/templates/driver/README.md.erb +1 -1
- data/test-kitchen.gemspec +2 -1
- metadata +26 -10
data/lib/kitchen/version.rb
CHANGED
@@ -58,7 +58,7 @@ describe Kitchen::Collection do
|
|
58
58
|
result.get_all(/one/).size.must_equal 1
|
59
59
|
end
|
60
60
|
|
61
|
-
it "returns an empty Collection if
|
61
|
+
it "returns an empty Collection if no matches are found" do
|
62
62
|
result = collection.get_all(/noppa/)
|
63
63
|
result.must_equal []
|
64
64
|
result.get("nahuh").must_be_nil
|
data/spec/kitchen/logger_spec.rb
CHANGED
@@ -282,6 +282,16 @@ describe Kitchen::Logger do
|
|
282
282
|
)
|
283
283
|
end
|
284
284
|
|
285
|
+
it "logger that receives mixed first chunk will flush next message with newline" do
|
286
|
+
logger << "partially\no"
|
287
|
+
logger << "kay\n"
|
288
|
+
|
289
|
+
stdout.string.must_equal(
|
290
|
+
colorize(" partially", opts[:color]) + "\n" +
|
291
|
+
colorize(" okay", opts[:color]) + "\n"
|
292
|
+
)
|
293
|
+
end
|
294
|
+
|
285
295
|
it "logger chomps carriage return characters" do
|
286
296
|
logger << [
|
287
297
|
"-----> banner\r",
|
@@ -27,7 +27,7 @@ describe Kitchen::Provisioner::ChefBase do
|
|
27
27
|
let(:logger) { Logger.new(logged_output) }
|
28
28
|
let(:platform) { stub(:os_type => nil) }
|
29
29
|
let(:suite) { stub(:name => "fries") }
|
30
|
-
let(:default_version) { "" }
|
30
|
+
let(:default_version) { "true" }
|
31
31
|
|
32
32
|
let(:config) do
|
33
33
|
{ :test_base_path => "/basist", :kitchen_root => "/rooty" }
|
@@ -348,7 +348,7 @@ describe Kitchen::Provisioner::ChefBase do
|
|
348
348
|
|
349
349
|
it "sets the powershell flag for Mixlib::Install" do
|
350
350
|
Mixlib::Install.expects(:new).
|
351
|
-
with(
|
351
|
+
with("", true, install_opts).returns(installer)
|
352
352
|
cmd
|
353
353
|
end
|
354
354
|
end
|
@@ -424,6 +424,19 @@ describe Kitchen::Provisioner::ChefSolo do
|
|
424
424
|
|
425
425
|
cmd.must_match regexify(" --logfile /a/out.log", :partial_line)
|
426
426
|
end
|
427
|
+
|
428
|
+
it "sets profile-ruby flag when config element is set" do
|
429
|
+
config[:profile_ruby] = true
|
430
|
+
|
431
|
+
cmd.must_match regexify(
|
432
|
+
" --profile-ruby", :partial_line)
|
433
|
+
end
|
434
|
+
|
435
|
+
it "does not set profile-ruby flag when config element is falsey" do
|
436
|
+
config[:profile_ruby] = false
|
437
|
+
|
438
|
+
cmd.wont_match regexify(" --profile-ruby", :partial_line)
|
439
|
+
end
|
427
440
|
end
|
428
441
|
|
429
442
|
describe "for powershell shells on windows os types" do
|
@@ -686,6 +686,19 @@ describe Kitchen::Provisioner::ChefZero do
|
|
686
686
|
|
687
687
|
cmd.wont_match regexify(" --chef-zero-port ", :partial_line)
|
688
688
|
end
|
689
|
+
|
690
|
+
it "sets profile-ruby flag when config element is set" do
|
691
|
+
config[:profile_ruby] = true
|
692
|
+
|
693
|
+
cmd.must_match regexify(
|
694
|
+
" --profile-ruby", :partial_line)
|
695
|
+
end
|
696
|
+
|
697
|
+
it "does not set profile-ruby flag when config element is falsey" do
|
698
|
+
config[:profile_ruby] = false
|
699
|
+
|
700
|
+
cmd.wont_match regexify(" --profile-ruby", :partial_line)
|
701
|
+
end
|
689
702
|
end
|
690
703
|
# rubocop:enable Metrics/MethodLength, Metrics/AbcSize
|
691
704
|
|
data/spec/kitchen/ssh_spec.rb
CHANGED
@@ -138,7 +138,7 @@ describe Kitchen::SSH do
|
|
138
138
|
[
|
139
139
|
Errno::EACCES, Errno::EADDRINUSE, Errno::ECONNREFUSED,
|
140
140
|
Errno::ECONNRESET, Errno::ENETUNREACH, Errno::EHOSTUNREACH,
|
141
|
-
Net::SSH::Disconnect, Net::SSH::AuthenticationFailed
|
141
|
+
Net::SSH::Disconnect, Net::SSH::AuthenticationFailed, Net::SSH::ConnectionTimeout
|
142
142
|
].each do |klass|
|
143
143
|
describe "raising #{klass}" do
|
144
144
|
|
@@ -668,7 +668,8 @@ describe Kitchen::Transport::Ssh::Connection do
|
|
668
668
|
[
|
669
669
|
Errno::EACCES, Errno::EADDRINUSE, Errno::ECONNREFUSED, Errno::ETIMEDOUT,
|
670
670
|
Errno::ECONNRESET, Errno::ENETUNREACH, Errno::EHOSTUNREACH,
|
671
|
-
Net::SSH::Disconnect, Net::SSH::AuthenticationFailed,
|
671
|
+
Net::SSH::Disconnect, Net::SSH::AuthenticationFailed, Net::SSH::ConnectionTimeout,
|
672
|
+
Timeout::Error
|
672
673
|
].each do |klass|
|
673
674
|
describe "raising #{klass}" do
|
674
675
|
|
@@ -43,6 +43,10 @@ end
|
|
43
43
|
|
44
44
|
describe Kitchen::Transport::Winrm do
|
45
45
|
|
46
|
+
before do
|
47
|
+
RbConfig::CONFIG.stubs(:[]).with("host_os").returns("blah")
|
48
|
+
end
|
49
|
+
|
46
50
|
let(:logged_output) { StringIO.new }
|
47
51
|
let(:logger) { Logger.new(logged_output) }
|
48
52
|
let(:config) { Hash.new }
|
@@ -53,7 +57,11 @@ describe Kitchen::Transport::Winrm do
|
|
53
57
|
end
|
54
58
|
|
55
59
|
let(:transport) do
|
56
|
-
Kitchen::Transport::Winrm.new(config)
|
60
|
+
t = Kitchen::Transport::Winrm.new(config)
|
61
|
+
# :load_winrm_s! is not cross-platform safe
|
62
|
+
# and gets initialized too early in the pipeline
|
63
|
+
t.stubs(:load_winrm_s!)
|
64
|
+
t.finalize_config!(instance)
|
57
65
|
end
|
58
66
|
|
59
67
|
it "provisioner api_version is 1" do
|
@@ -98,6 +106,10 @@ describe Kitchen::Transport::Winrm do
|
|
98
106
|
it "sets :max_wait_until_ready to 600 by default" do
|
99
107
|
transport[:max_wait_until_ready].must_equal 600
|
100
108
|
end
|
109
|
+
|
110
|
+
it "sets :winrm_transport to :plaintext" do
|
111
|
+
transport[:winrm_transport].must_equal :plaintext
|
112
|
+
end
|
101
113
|
end
|
102
114
|
|
103
115
|
describe "#connection" do
|
@@ -165,9 +177,10 @@ describe Kitchen::Transport::Winrm do
|
|
165
177
|
it "sets :endpoint from data in config" do
|
166
178
|
config[:hostname] = "host_from_config"
|
167
179
|
config[:port] = "port_from_config"
|
180
|
+
config[:winrm_transport] = "ssl"
|
168
181
|
|
169
182
|
klass.expects(:new).with do |hash|
|
170
|
-
hash[:endpoint] == "
|
183
|
+
hash[:endpoint] == "https://host_from_config:port_from_config/wsman"
|
171
184
|
end
|
172
185
|
|
173
186
|
make_connection
|
@@ -178,9 +191,10 @@ describe Kitchen::Transport::Winrm do
|
|
178
191
|
config[:hostname] = "host_from_config"
|
179
192
|
state[:port] = "port_from_state"
|
180
193
|
config[:port] = "port_from_config"
|
194
|
+
config[:winrm_transport] = "ssl"
|
181
195
|
|
182
196
|
klass.expects(:new).with do |hash|
|
183
|
-
hash[:endpoint] == "
|
197
|
+
hash[:endpoint] == "https://host_from_state:port_from_state/wsman"
|
184
198
|
end
|
185
199
|
|
186
200
|
make_connection
|
@@ -312,6 +326,55 @@ describe Kitchen::Transport::Winrm do
|
|
312
326
|
make_connection
|
313
327
|
end
|
314
328
|
|
329
|
+
it "sets :winrm_transport from config data" do
|
330
|
+
config[:winrm_transport] = "ssl"
|
331
|
+
|
332
|
+
klass.expects(:new).with do |hash|
|
333
|
+
hash[:winrm_transport] == :ssl
|
334
|
+
end
|
335
|
+
|
336
|
+
make_connection
|
337
|
+
end
|
338
|
+
|
339
|
+
describe "when sspinegotiate is set in config" do
|
340
|
+
before do
|
341
|
+
config[:winrm_transport] = "sspinegotiate"
|
342
|
+
end
|
343
|
+
|
344
|
+
describe "for Windows workstations" do
|
345
|
+
before do
|
346
|
+
RbConfig::CONFIG.stubs(:[]).with("host_os").returns("mingw32")
|
347
|
+
end
|
348
|
+
|
349
|
+
it "sets :winrm_transport to sspinegotiate on Windows" do
|
350
|
+
|
351
|
+
klass.expects(:new).with do |hash|
|
352
|
+
hash[:winrm_transport] == :sspinegotiate &&
|
353
|
+
hash[:disable_sspi] == false &&
|
354
|
+
hash[:basic_auth_only] == false
|
355
|
+
end
|
356
|
+
|
357
|
+
make_connection
|
358
|
+
end
|
359
|
+
end
|
360
|
+
|
361
|
+
describe "for non-Windows workstations" do
|
362
|
+
before do
|
363
|
+
RbConfig::CONFIG.stubs(:[]).with("host_os").returns("darwin14")
|
364
|
+
end
|
365
|
+
|
366
|
+
it "sets :winrm_transport to plaintext" do
|
367
|
+
klass.expects(:new).with do |hash|
|
368
|
+
hash[:winrm_transport] == :plaintext &&
|
369
|
+
hash[:disable_sspi] == true &&
|
370
|
+
hash[:basic_auth_only] == true
|
371
|
+
end
|
372
|
+
|
373
|
+
make_connection
|
374
|
+
end
|
375
|
+
end
|
376
|
+
end
|
377
|
+
|
315
378
|
it "returns the same connection when called again with same state" do
|
316
379
|
first_connection = make_connection(state)
|
317
380
|
second_connection = make_connection(state)
|
@@ -375,66 +438,133 @@ describe Kitchen::Transport::Winrm do
|
|
375
438
|
end
|
376
439
|
|
377
440
|
describe "#load_needed_dependencies" do
|
441
|
+
describe "winrm-transport" do
|
442
|
+
before do
|
443
|
+
# force loading of winrm-transport to get the version constant
|
444
|
+
require "winrm/transport/version"
|
445
|
+
end
|
378
446
|
|
379
|
-
|
380
|
-
|
381
|
-
|
382
|
-
end
|
447
|
+
it "logs a message to debug that code will be loaded" do
|
448
|
+
transport.stubs(:require)
|
449
|
+
transport
|
383
450
|
|
384
|
-
|
385
|
-
|
451
|
+
logged_output.string.must_match debug_line_with(
|
452
|
+
"Winrm Transport requested, loading WinRM::Transport gem")
|
453
|
+
end
|
386
454
|
|
387
|
-
|
388
|
-
|
389
|
-
|
455
|
+
it "logs a message to debug when library is initially loaded" do
|
456
|
+
transport = Kitchen::Transport::Winrm.new(config)
|
457
|
+
transport.stubs(:require)
|
458
|
+
transport.stubs(:execute_block).returns(true)
|
390
459
|
|
391
|
-
|
392
|
-
transport = Kitchen::Transport::Winrm.new(config)
|
393
|
-
transport.stubs(:require)
|
394
|
-
transport.stubs(:require).with("winrm/transport/version").returns(true)
|
395
|
-
transport.finalize_config!(instance)
|
460
|
+
transport.finalize_config!(instance)
|
396
461
|
|
397
|
-
|
398
|
-
|
399
|
-
|
400
|
-
|
462
|
+
logged_output.string.must_match(
|
463
|
+
/WinRM::Transport library loaded/
|
464
|
+
)
|
465
|
+
end
|
401
466
|
|
402
|
-
|
403
|
-
|
404
|
-
|
405
|
-
|
406
|
-
transport.finalize_config!(instance)
|
467
|
+
it "logs a message to debug when library is previously loaded" do
|
468
|
+
transport = Kitchen::Transport::Winrm.new(config)
|
469
|
+
transport.stubs(:require)
|
470
|
+
transport.stubs(:execute_block).returns(false)
|
407
471
|
|
408
|
-
|
409
|
-
|
410
|
-
|
472
|
+
transport.finalize_config!(instance)
|
473
|
+
|
474
|
+
logged_output.string.must_match(
|
475
|
+
/WinRM::Transport previously loaded/
|
476
|
+
)
|
477
|
+
end
|
478
|
+
|
479
|
+
it "logs a message to fatal when libraries cannot be loaded" do
|
480
|
+
transport = Kitchen::Transport::Winrm.new(config)
|
481
|
+
transport.stubs(:require)
|
482
|
+
transport.stubs(:execute_block).raises(LoadError, "uh oh")
|
483
|
+
begin
|
484
|
+
transport.finalize_config!(instance)
|
485
|
+
rescue # rubocop:disable Lint/HandleExceptions
|
486
|
+
# we are interested in the log output, not this exception
|
487
|
+
end
|
488
|
+
|
489
|
+
logged_output.string.must_match fatal_line_with(
|
490
|
+
"The `winrm-transport` gem is missing and must be installed")
|
491
|
+
end
|
492
|
+
|
493
|
+
it "raises a UserError when libraries cannot be loaded" do
|
494
|
+
transport = Kitchen::Transport::Winrm.new(config)
|
495
|
+
transport.stubs(:require)
|
496
|
+
transport.stubs(:execute_block).raises(LoadError, "uh oh")
|
497
|
+
|
498
|
+
err = proc {
|
499
|
+
transport.finalize_config!(instance)
|
500
|
+
}.must_raise Kitchen::UserError
|
501
|
+
err.message.must_match(/^Could not load or activate winrm-transport\. /)
|
502
|
+
end
|
411
503
|
end
|
412
504
|
|
413
|
-
|
414
|
-
|
415
|
-
|
416
|
-
|
417
|
-
|
418
|
-
|
505
|
+
describe "winrm-s" do
|
506
|
+
before do
|
507
|
+
RbConfig::CONFIG.stubs(:[]).with("host_os").returns("mingw32")
|
508
|
+
end
|
509
|
+
|
510
|
+
it "logs a message to debug that code will be loaded" do
|
511
|
+
transport = Kitchen::Transport::Winrm.new(config)
|
512
|
+
transport.stubs(:load_winrm_transport!)
|
513
|
+
transport.stubs(:require)
|
419
514
|
transport.finalize_config!(instance)
|
420
|
-
|
421
|
-
|
515
|
+
|
516
|
+
logged_output.string.must_match debug_line_with(
|
517
|
+
"The winrm-s gem is being loaded")
|
422
518
|
end
|
423
519
|
|
424
|
-
|
425
|
-
|
426
|
-
|
520
|
+
it "logs a message to debug when library is initially loaded" do
|
521
|
+
transport = Kitchen::Transport::Winrm.new(config)
|
522
|
+
transport.stubs(:load_winrm_transport!)
|
523
|
+
transport.stubs(:execute_block).returns(true)
|
524
|
+
|
525
|
+
transport.finalize_config!(instance)
|
526
|
+
|
527
|
+
logged_output.string.must_match(
|
528
|
+
/winrm-s is loaded/
|
529
|
+
)
|
530
|
+
end
|
427
531
|
|
428
|
-
|
429
|
-
|
430
|
-
|
431
|
-
|
432
|
-
raises(LoadError, "uh oh")
|
532
|
+
it "logs a message to debug when library is previously loaded" do
|
533
|
+
transport = Kitchen::Transport::Winrm.new(config)
|
534
|
+
transport.stubs(:load_winrm_transport!)
|
535
|
+
transport.stubs(:execute_block).returns(false)
|
433
536
|
|
434
|
-
err = proc {
|
435
537
|
transport.finalize_config!(instance)
|
436
|
-
|
437
|
-
|
538
|
+
|
539
|
+
logged_output.string.must_match(
|
540
|
+
/winrm-s was already loaded/
|
541
|
+
)
|
542
|
+
end
|
543
|
+
|
544
|
+
it "logs a message to fatal when libraries cannot be loaded" do
|
545
|
+
transport = Kitchen::Transport::Winrm.new(config)
|
546
|
+
transport.stubs(:load_winrm_transport!)
|
547
|
+
transport.stubs(:execute_block).raises(LoadError, "uh oh")
|
548
|
+
begin
|
549
|
+
transport.finalize_config!(instance)
|
550
|
+
rescue # rubocop:disable Lint/HandleExceptions
|
551
|
+
# we are interested in the log output, not this exception
|
552
|
+
end
|
553
|
+
|
554
|
+
logged_output.string.must_match fatal_line_with(
|
555
|
+
"The `winrm-s` gem is missing and must be installed")
|
556
|
+
end
|
557
|
+
|
558
|
+
it "raises a UserError when libraries cannot be loaded" do
|
559
|
+
transport = Kitchen::Transport::Winrm.new(config)
|
560
|
+
transport.stubs(:load_winrm_transport!)
|
561
|
+
transport.stubs(:execute_block).raises(LoadError, "uh oh")
|
562
|
+
|
563
|
+
err = proc {
|
564
|
+
transport.finalize_config!(instance)
|
565
|
+
}.must_raise Kitchen::UserError
|
566
|
+
err.message.must_match(/^Could not load or activate winrm-s\. /)
|
567
|
+
end
|
438
568
|
end
|
439
569
|
end
|
440
570
|
|
@@ -1,14 +1,16 @@
|
|
1
|
+
$ErrorActionPreference = "stop"
|
2
|
+
|
1
3
|
Function Check-UpdateChef($root, $version) {
|
2
4
|
if (-Not (Test-Path $root)) { return $true }
|
3
5
|
elseif ("$version" -eq "true") { return $false }
|
4
6
|
elseif ("$version" -eq "latest") { return $true }
|
5
|
-
Try { $chef_version = Get-Content $root\version-manifest.txt | select-object -1}
|
7
|
+
Try { $chef_version = (Get-Content $root\version-manifest.txt | select-object -first 1) }
|
6
8
|
Catch {
|
7
|
-
Try { $chef_version = (& $root\bin\chef-solo.bat -v)
|
8
|
-
Catch { $chef_version = "" }
|
9
|
+
Try { $chef_version = (& $root\bin\chef-solo.bat -v) }
|
10
|
+
Catch { $chef_version = " " }
|
9
11
|
}
|
10
12
|
|
11
|
-
if ($chef_version.StartsWith($version)) { return $false }
|
13
|
+
if ($chef_version.split(" ", 2)[1].StartsWith($version)) { return $false }
|
12
14
|
else { return $true }
|
13
15
|
}
|
14
16
|
|
@@ -66,13 +68,18 @@ Function Unresolve-Path($p) {
|
|
66
68
|
else { return $ExecutionContext.SessionState.Path.GetUnresolvedProviderPathFromPSPath($p) }
|
67
69
|
}
|
68
70
|
|
69
|
-
|
70
|
-
$
|
71
|
+
Try {
|
72
|
+
$chef_omnibus_root = Unresolve-Path $chef_omnibus_root
|
73
|
+
$msi = Unresolve-Path $msi
|
71
74
|
|
72
|
-
if (Check-UpdateChef $chef_omnibus_root $version) {
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
} else {
|
77
|
-
|
75
|
+
if (Check-UpdateChef $chef_omnibus_root $version) {
|
76
|
+
Write-Host "-----> Installing Chef Omnibus ($pretty_version)`n"
|
77
|
+
Download-Chef "$chef_metadata_url" $msi
|
78
|
+
Install-Chef $msi
|
79
|
+
} else {
|
80
|
+
Write-Host "-----> Chef Omnibus installation detected ($pretty_version)`n"
|
81
|
+
}
|
82
|
+
Catch {
|
83
|
+
Write-Error ($_ | ft -Property * | out-string) -ErrorAction Continue
|
84
|
+
exit 1
|
78
85
|
}
|