beaker 2.3.0 → 2.4.0

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