beaker 2.3.0 → 2.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (45) hide show
  1. checksums.yaml +8 -8
  2. data/HISTORY.md +366 -2
  3. data/ext/completion/beaker-completion.bash +1 -1
  4. data/lib/beaker.rb +1 -1
  5. data/lib/beaker/answers.rb +3 -1
  6. data/lib/beaker/answers/version40.rb +42 -0
  7. data/lib/beaker/cli.rb +0 -2
  8. data/lib/beaker/command.rb +10 -2
  9. data/lib/beaker/dsl/ezbake_utils.rb +195 -157
  10. data/lib/beaker/dsl/helpers.rb +9 -6
  11. data/lib/beaker/dsl/install_utils.rb +22 -8
  12. data/lib/beaker/dsl/structure.rb +67 -0
  13. data/lib/beaker/host.rb +14 -4
  14. data/lib/beaker/host/mac.rb +4 -0
  15. data/lib/beaker/host/pswindows.rb +79 -0
  16. data/lib/beaker/host/pswindows/exec.rb +29 -0
  17. data/lib/beaker/host/pswindows/file.rb +15 -0
  18. data/lib/beaker/host/pswindows/group.rb +36 -0
  19. data/lib/beaker/host/pswindows/pkg.rb +47 -0
  20. data/lib/beaker/host/pswindows/user.rb +32 -0
  21. data/lib/beaker/host/unix.rb +16 -6
  22. data/lib/beaker/host/windows.rb +6 -2
  23. data/lib/beaker/host_prebuilt_steps.rb +2 -0
  24. data/lib/beaker/hypervisor.rb +3 -1
  25. data/lib/beaker/hypervisor/aws_sdk.rb +6 -1
  26. data/lib/beaker/hypervisor/docker.rb +6 -1
  27. data/lib/beaker/hypervisor/vagrant.rb +1 -1
  28. data/lib/beaker/hypervisor/vagrant_parallels.rb +18 -0
  29. data/lib/beaker/logger.rb +8 -1
  30. data/lib/beaker/logger_junit.rb +157 -0
  31. data/lib/beaker/network_manager.rb +28 -0
  32. data/lib/beaker/options/presets.rb +6 -0
  33. data/lib/beaker/test_suite.rb +65 -136
  34. data/lib/beaker/version.rb +1 -1
  35. data/spec/beaker/answers_spec.rb +74 -0
  36. data/spec/beaker/dsl/ezbake_utils_spec.rb +167 -126
  37. data/spec/beaker/dsl/install_utils_spec.rb +5 -4
  38. data/spec/beaker/dsl/structure_spec.rb +28 -1
  39. data/spec/beaker/host_prebuilt_steps_spec.rb +2 -1
  40. data/spec/beaker/host_spec.rb +1 -7
  41. data/spec/beaker/hypervisor/docker_spec.rb +19 -1
  42. data/spec/beaker/hypervisor/vagrant_parallels_spec.rb +44 -0
  43. data/spec/beaker/logger_junit_spec.rb +93 -0
  44. data/spec/beaker/network_manager_spec.rb +52 -0
  45. metadata +14 -2
@@ -547,14 +547,15 @@ describe ClassMixedWithDSLInstallUtils do
547
547
  let(:platform) { "windows-2008r2-i386" }
548
548
  it 'installs specific version of puppet when passed :version' do
549
549
  allow(subject).to receive(:link_exists?).and_return( true )
550
- expect(subject).to receive(:on).with(hosts[0], 'curl -O http://downloads.puppetlabs.com/windows/puppet-3000.msi')
551
- expect(subject).to receive(:on).with(hosts[0], 'msiexec /qn /i puppet-3000.msi')
550
+ expect(subject).to receive(:on).with(hosts[0], 'curl -O /cygdrive/c/Windows/Temp/puppet-3000.msi http://downloads.puppetlabs.com/windows/puppet-3000.msi')
551
+ expect(subject).to receive(:on).with(hosts[0], " echo 'export PATH=$PATH:\"/cygdrive/c/Program Files (x86)/Puppet Labs/Puppet/bin\":\"/cygdrive/c/Program Files/Puppet Labs/Puppet/bin\"' > /etc/bash.bashrc ")
552
+ expect(subject).to receive(:on).with(hosts[0], 'msiexec /qn /i /cygdrive/c/Windows/Temp/puppet-3000.msi')
552
553
  subject.install_puppet(:version => '3000')
553
554
  end
554
555
  it 'installs from custom url when passed :win_download_url' do
555
556
  allow(subject).to receive(:link_exists?).and_return( true )
556
- expect(subject).to receive(:on).with(hosts[0], 'curl -O http://nightlies.puppetlabs.com/puppet-latest/repos/windows/puppet-3000.msi')
557
- expect(subject).to receive(:on).with(hosts[0], 'msiexec /qn /i puppet-3000.msi')
557
+ expect(subject).to receive(:on).with(hosts[0], 'curl -O /cygdrive/c/Windows/Temp/puppet-3000.msi http://nightlies.puppetlabs.com/puppet-latest/repos/windows/puppet-3000.msi')
558
+ expect(subject).to receive(:on).with(hosts[0], 'msiexec /qn /i /cygdrive/c/Windows/Temp/puppet-3000.msi')
558
559
  subject.install_puppet( :version => '3000', :win_download_url => 'http://nightlies.puppetlabs.com/puppet-latest/repos/windows' )
559
560
  end
560
561
  end
@@ -5,7 +5,8 @@ class ClassMixedWithDSLStructure
5
5
  end
6
6
 
7
7
  describe ClassMixedWithDSLStructure do
8
- let(:logger) { Object.new }
8
+ include Beaker::DSL::Assertions
9
+ let(:logger) { double }
9
10
  describe '#step' do
10
11
  it 'requires a name' do
11
12
  expect { subject.step do; end }.to raise_error ArgumentError
@@ -57,4 +58,30 @@ describe ClassMixedWithDSLStructure do
57
58
  subject.teardown &block
58
59
  end
59
60
  end
61
+
62
+ describe '#expect_failure' do
63
+ it 'passes when a MiniTest assertion is raised' do
64
+ expect( subject ).to receive( :logger ).and_return( logger )
65
+ expect( logger ).to receive( :notify )
66
+ block = lambda { assert_equal('1', '2', '1 should not equal 2') }
67
+ expect{ subject.expect_failure 'this is an expected failure', &block }.to_not raise_error
68
+ end
69
+
70
+ it 'passes when a Beaker assertion is raised' do
71
+ expect( subject ).to receive( :logger ).and_return( logger )
72
+ expect( logger ).to receive( :notify )
73
+ block = lambda { assert_no_match('1', '1', '1 and 1 should not match') }
74
+ expect{ subject.expect_failure 'this is an expected failure', &block }.to_not raise_error
75
+ end
76
+
77
+ it 'fails when a non-Beaker, non-MiniTest assertion is raised' do
78
+ block = lambda { raise 'not a Beaker or MiniTest error' }
79
+ expect{ subject.expect_failure 'this has a non-Beaker, non-MiniTest exception', &block }.to raise_error(RuntimeError, /not a Beaker or MiniTest error/)
80
+ end
81
+
82
+ it 'fails when no assertion is raised' do
83
+ block = lambda { assert_equal('1', '1', '1 should equal 1') }
84
+ expect{ subject.expect_failure 'this has no failure', &block }.to raise_error(RuntimeError, /An assertion was expected to fail, but passed/)
85
+ end
86
+ end
60
87
  end
@@ -513,13 +513,14 @@ describe Beaker do
513
513
  expect( Beaker::Command ).to receive( :new ).with( "mkdir -p #{Pathname.new(host[:ssh_env_file]).dirname}" ).once
514
514
  expect( Beaker::Command ).to receive( :new ).with( "chmod 0600 #{Pathname.new(host[:ssh_env_file]).dirname}" ).once
515
515
  expect( Beaker::Command ).to receive( :new ).with( "touch #{host[:ssh_env_file]}" ).once
516
+ expect( Beaker::Command ).to receive( :new ).with( "cat #{host[:ssh_env_file]}" ).once
516
517
  expect( host ).to receive( :add_env_var ).with( 'RUBYLIB', '$RUBYLIB' ).once
517
518
  expect( host ).to receive( :add_env_var ).with( 'PATH', '$PATH' ).once
518
519
  opts.each_pair do |key, value|
519
520
  expect( host ).to receive( :add_env_var ).with( key, value ).once
520
521
  end
521
522
  expect( host ).to receive( :add_env_var ).with( 'CYGWIN', 'nodosfilewarning' ).once if platform_name =~ /windows/
522
- expect( host ).to receive( :exec ).exactly( host_specific_commands_array.length + 3 ).times
523
+ expect( host ).to receive( :exec ).exactly( host_specific_commands_array.length + 4 ).times
523
524
 
524
525
  subject.set_env(host, options.merge( opts ))
525
526
  end
@@ -64,16 +64,10 @@ module Beaker
64
64
  expect(host.is_using_passenger?).to be_falsy
65
65
  end
66
66
 
67
- it 'sets the paths correctly for an AIO agent host' do
67
+ it 'sets the paths correctly for an AIO host' do
68
68
  options['type'] = 'aio'
69
69
  expect(host['puppetvardir']).to be === Unix::Host::aio_defaults[:puppetvardir]
70
70
  end
71
-
72
- it 'sets the paths correctly for an AIO non-agent host' do
73
- options['type'] = 'aio'
74
- options['roles'] = ['master']
75
- expect(host['puppetvardir']).to be === Unix::Host::foss_defaults[:puppetvardir]
76
- end
77
71
  end
78
72
 
79
73
  describe "uses_passenger!" do
@@ -67,13 +67,26 @@ module Beaker
67
67
  allow( ::Docker ).to receive(:options).and_return(docker_options)
68
68
  allow( ::Docker ).to receive(:options=)
69
69
  allow( ::Docker ).to receive(:logger=)
70
- allow( ::Docker ).to receive(:validate_version!)
71
70
  allow( ::Docker::Image ).to receive(:build).and_return(image)
72
71
  allow( ::Docker::Container ).to receive(:create).and_return(container)
73
72
  allow_any_instance_of( ::Docker::Container ).to receive(:start)
74
73
  end
75
74
 
75
+ describe '#initialize, failure to validate' do
76
+ before :each do
77
+ require 'excon'
78
+ allow( ::Docker ).to receive(:validate_version!).and_raise(Excon::Errors::SocketError.new( StandardError.new('oops') ))
79
+ end
80
+ it 'should fail when docker not present' do
81
+ expect { docker }.to raise_error(RuntimeError, /Docker instance not found/)
82
+ end
83
+ end
84
+
76
85
  describe '#initialize' do
86
+ before :each do
87
+ allow( ::Docker ).to receive(:validate_version!)
88
+ end
89
+
77
90
  it 'should require the docker gem' do
78
91
  expect_any_instance_of( ::Beaker::Docker ).to receive(:require).with('docker').once
79
92
 
@@ -116,6 +129,7 @@ module Beaker
116
129
 
117
130
  describe '#provision' do
118
131
  before :each do
132
+ allow( ::Docker ).to receive(:validate_version!)
119
133
  allow( docker ).to receive(:dockerfile_for)
120
134
  end
121
135
 
@@ -195,6 +209,7 @@ module Beaker
195
209
  describe '#cleanup' do
196
210
  before :each do
197
211
  # get into a state where there's something to clean
212
+ allow( ::Docker ).to receive(:validate_version!)
198
213
  allow( docker ).to receive(:dockerfile_for)
199
214
  docker.provision
200
215
  end
@@ -238,6 +253,9 @@ module Beaker
238
253
  end
239
254
 
240
255
  describe '#dockerfile_for' do
256
+ before :each do
257
+ allow( ::Docker ).to receive(:validate_version!)
258
+ end
241
259
  it 'should raise on an unsupported platform' do
242
260
  expect { docker.send(:dockerfile_for, {'platform' => 'a_sidewalk' }) }.to raise_error(/platform a_sidewalk not yet supported on docker/)
243
261
  end
@@ -0,0 +1,44 @@
1
+ require 'spec_helper'
2
+
3
+ describe Beaker::VagrantParallels do
4
+ let( :options ) { make_opts.merge({ :hosts_file => 'sample.cfg', 'logger' => double().as_null_object }) }
5
+ let( :vagrant ) { Beaker::VagrantParallels.new( @hosts, options ) }
6
+
7
+ before :each do
8
+ @hosts = make_hosts()
9
+ end
10
+
11
+ it "uses the parallels provider for provisioning" do
12
+ @hosts.each do |host|
13
+ host_prev_name = host['user']
14
+ expect( vagrant ).to receive( :set_ssh_config ).with( host, 'vagrant' ).once
15
+ expect( vagrant ).to receive( :copy_ssh_to_root ).with( host, options ).once
16
+ expect( vagrant ).to receive( :set_ssh_config ).with( host, host_prev_name ).once
17
+ end
18
+ expect( vagrant ).to receive( :hack_etc_hosts ).with( @hosts, options ).once
19
+ expect( vagrant ).to receive( :vagrant_cmd ).with( "up --provider parallels" ).once
20
+ vagrant.provision
21
+ end
22
+
23
+ it "can make a Vagranfile for a set of hosts" do
24
+ path = vagrant.instance_variable_get( :@vagrant_path )
25
+ allow( vagrant ).to receive( :randmac ).and_return( "0123456789" )
26
+
27
+ vagrant.make_vfile( @hosts )
28
+
29
+ vagrantfile = File.read( File.expand_path( File.join( path, 'Vagrantfile' )))
30
+ expect( vagrantfile ).to include( %Q{ v.vm.provider :parallels do |prl|\n prl.optimize_power_consumption = false\n prl.memory = '1024'\n end})
31
+ end
32
+
33
+ it "can disable the auto-update functionality of the Parallels Guest Tools" do
34
+ options.merge!({ :prl_update_guest_tools => 'disable' })
35
+
36
+ vfile_section = vagrant.class.provider_vfile_section( @hosts.first, options )
37
+
38
+ match = vfile_section.match(/prl.update_guest_tools = false/)
39
+
40
+ expect( match ).to_not be nil
41
+
42
+ end
43
+
44
+ end
@@ -0,0 +1,93 @@
1
+ # encoding: UTF-8
2
+ require 'spec_helper'
3
+
4
+ module Beaker
5
+ describe LoggerJunit do
6
+ let( :xml_file ) { '/fake/file/location1' }
7
+ let( :stylesheet ) { '/fake/file/location2' }
8
+
9
+ describe '#is_valid_xml' do
10
+
11
+ it 'rejects all invalid values' do
12
+ invalid_values = [0x8, 0x10, 0xB, 0x0019, 0xD800, 0xDFFF, 0xFFFE, 0x99999, 0x110000]
13
+ invalid_values.each do |value|
14
+ expect( LoggerJunit.is_valid_xml(value) ).to be === false
15
+ end
16
+ end
17
+
18
+ it 'accepts valid values' do
19
+ valid_values = [0x9, 0xA, 0x0020, 0xD7FF, 0xE000, 0xFFFD, 0x100000, 0x10FFFF]
20
+ valid_values.each do |value|
21
+ expect( LoggerJunit.is_valid_xml(value) ).to be === true
22
+ end
23
+ end
24
+
25
+ end
26
+
27
+ describe '#escape_invalid_xml_chars' do
28
+
29
+ it 'escapes invalid xml characters correctly' do
30
+ testing_string = 'pants'
31
+ testing_string << 0x8
32
+ expect( LoggerJunit.escape_invalid_xml_chars(testing_string) ).to be === 'pants\8'
33
+ end
34
+
35
+ it 'leaves a string of all valid xml characters alone' do
36
+ testing_string = 'pants man, pants!'
37
+ expect( LoggerJunit.escape_invalid_xml_chars(testing_string) ).to be === testing_string
38
+ end
39
+
40
+ end
41
+
42
+ describe '#copy_stylesheet_into_xml_dir' do
43
+
44
+ it 'copies the stylesheet into the correct location' do
45
+ allow( File ).to receive( :file? ) { false }
46
+ correct_location = File.join(File.dirname(xml_file), File.basename(stylesheet))
47
+ expect( FileUtils ).to receive( :copy ).with( stylesheet, correct_location )
48
+ LoggerJunit.copy_stylesheet_into_xml_dir(stylesheet, xml_file)
49
+ end
50
+
51
+ it 'skips action if the file doesn\'t exist' do
52
+ allow( File ).to receive( :file? ) { true }
53
+ expect( FileUtils ).not_to receive( :copy )
54
+ LoggerJunit.copy_stylesheet_into_xml_dir(stylesheet, xml_file)
55
+ end
56
+
57
+ end
58
+
59
+ describe '#finish' do
60
+
61
+ it 'opens the given file for writing, and writes the doc to it' do
62
+ mock_doc = Object.new
63
+ doc_xml = 'flibbity-floo'
64
+ allow( mock_doc ).to receive( :to_xml ) { doc_xml }
65
+ mock_file_handle = Object.new
66
+ expect( mock_file_handle ).to receive( :write ).with( doc_xml )
67
+ expect( File ).to receive( :open ).with( xml_file, 'w' ).and_yield( mock_file_handle )
68
+ LoggerJunit.finish(mock_doc, xml_file)
69
+ end
70
+
71
+ end
72
+
73
+ describe '#write_xml' do
74
+
75
+ it 'throws an error with 1-arity in the given block' do
76
+ allow( LoggerJunit ).to receive( :get_xml_contents )
77
+ expect{ LoggerJunit.write_xml(xml_file, stylesheet) do |hey| end }.to raise_error(ArgumentError)
78
+ end
79
+
80
+ it 'doesn\'t throw an error with 2-arity in the given block' do
81
+ allow( LoggerJunit ).to receive( :get_xml_contents )
82
+ allow( LoggerJunit ).to receive( :finish )
83
+ expect{ LoggerJunit.write_xml(xml_file, stylesheet) do |hey1, hey2| end }.not_to raise_error
84
+ end
85
+
86
+ it 'throws an error with 3-arity in the given block' do
87
+ allow( LoggerJunit ).to receive( :get_xml_contents )
88
+ expect{ LoggerJunit.write_xml(xml_file, stylesheet) do |hey1, hey2, hey3| end }.to raise_error(ArgumentError)
89
+ end
90
+
91
+ end
92
+ end
93
+ end
@@ -0,0 +1,52 @@
1
+ # encoding: UTF-8
2
+ require 'spec_helper'
3
+
4
+ module Beaker
5
+ describe NetworkManager do
6
+ let( :mock_provisioning_logger ) {
7
+ mock_provisioning_logger = Object.new
8
+ allow( mock_provisioning_logger ).to receive( :notify )
9
+ mock_provisioning_logger }
10
+ let( :options ) { make_opts.merge({ 'logger' => double().as_null_object, :logger_sut => mock_provisioning_logger }) }
11
+ let( :network_manager ) { NetworkManager.new(options, options[:logger]) }
12
+ let( :hosts ) { make_hosts }
13
+ let( :host ) { hosts[0] }
14
+
15
+ describe '#log_sut_event' do
16
+
17
+ it 'creates the correct content for an event' do
18
+ log_line = network_manager.log_sut_event host, true
19
+ pieces = log_line.split("\t")
20
+ hypervisor_value = host['hypervisor'] ? host['hypervisor'] : ''
21
+ platform_value = host['platform'] ? host['platform'] : ''
22
+ expect( pieces[1] ).to be === '[+]'
23
+ expect( pieces[2] ).to be === hypervisor_value
24
+ expect( pieces[3] ).to be === platform_value
25
+ expect( pieces[4] ).to be === host.name
26
+ end
27
+
28
+ it 'follows the create parameter correctly' do
29
+ log_line = network_manager.log_sut_event host, true
30
+ pieces = log_line.split("\t")
31
+ expect( pieces[1] ).to be === '[+]'
32
+
33
+ log_line = network_manager.log_sut_event host, false
34
+ pieces = log_line.split("\t")
35
+ expect( pieces[1] ).to be === '[-]'
36
+ end
37
+
38
+ it 'sends the log line to the provisioning logger' do
39
+ nm = network_manager
40
+ options[:logger_sut] = mock_provisioning_logger
41
+ expect( mock_provisioning_logger ).to receive( :notify ).once
42
+ nm.log_sut_event host, true
43
+ end
44
+
45
+ it 'throws an error if the provisioning logger hasn\'t been created yet' do
46
+ nm = network_manager
47
+ options.delete(:logger_sut)
48
+ expect{ nm.log_sut_event(host, true) }.to raise_error(ArgumentError)
49
+ end
50
+ end
51
+ end
52
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: beaker
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.3.0
4
+ version: 2.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Puppetlabs
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-01-29 00:00:00.000000000 Z
11
+ date: 2015-02-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rspec
@@ -362,6 +362,7 @@ files:
362
362
  - lib/beaker/answers/version30.rb
363
363
  - lib/beaker/answers/version32.rb
364
364
  - lib/beaker/answers/version34.rb
365
+ - lib/beaker/answers/version40.rb
365
366
  - lib/beaker/cli.rb
366
367
  - lib/beaker/command.rb
367
368
  - lib/beaker/command_factory.rb
@@ -384,6 +385,12 @@ files:
384
385
  - lib/beaker/host/mac.rb
385
386
  - lib/beaker/host/mac/group.rb
386
387
  - lib/beaker/host/mac/user.rb
388
+ - lib/beaker/host/pswindows.rb
389
+ - lib/beaker/host/pswindows/exec.rb
390
+ - lib/beaker/host/pswindows/file.rb
391
+ - lib/beaker/host/pswindows/group.rb
392
+ - lib/beaker/host/pswindows/pkg.rb
393
+ - lib/beaker/host/pswindows/user.rb
387
394
  - lib/beaker/host/unix.rb
388
395
  - lib/beaker/host/unix/exec.rb
389
396
  - lib/beaker/host/unix/file.rb
@@ -410,6 +417,7 @@ files:
410
417
  - lib/beaker/hypervisor/vagrant.rb
411
418
  - lib/beaker/hypervisor/vagrant_fusion.rb
412
419
  - lib/beaker/hypervisor/vagrant_libvirt.rb
420
+ - lib/beaker/hypervisor/vagrant_parallels.rb
413
421
  - lib/beaker/hypervisor/vagrant_virtualbox.rb
414
422
  - lib/beaker/hypervisor/vagrant_workstation.rb
415
423
  - lib/beaker/hypervisor/vcloud.rb
@@ -418,6 +426,7 @@ files:
418
426
  - lib/beaker/hypervisor/vsphere_helper.rb
419
427
  - lib/beaker/junit.xsl
420
428
  - lib/beaker/logger.rb
429
+ - lib/beaker/logger_junit.rb
421
430
  - lib/beaker/network_manager.rb
422
431
  - lib/beaker/options.rb
423
432
  - lib/beaker/options/command_line_parser.rb
@@ -468,6 +477,7 @@ files:
468
477
  - spec/beaker/hypervisor/solaris_spec.rb
469
478
  - spec/beaker/hypervisor/vagrant_fusion_spec.rb
470
479
  - spec/beaker/hypervisor/vagrant_libvirt_spec.rb
480
+ - spec/beaker/hypervisor/vagrant_parallels_spec.rb
471
481
  - spec/beaker/hypervisor/vagrant_spec.rb
472
482
  - spec/beaker/hypervisor/vagrant_virtualbox_spec.rb
473
483
  - spec/beaker/hypervisor/vagrant_workstation_spec.rb
@@ -475,7 +485,9 @@ files:
475
485
  - spec/beaker/hypervisor/vcloud_spec.rb
476
486
  - spec/beaker/hypervisor/vsphere_helper_spec.rb
477
487
  - spec/beaker/hypervisor/vsphere_spec.rb
488
+ - spec/beaker/logger_junit_spec.rb
478
489
  - spec/beaker/logger_spec.rb
490
+ - spec/beaker/network_manager_spec.rb
479
491
  - spec/beaker/options/command_line_parser_spec.rb
480
492
  - spec/beaker/options/data/badyaml.cfg
481
493
  - spec/beaker/options/data/hosts.cfg