beaker 2.18.3 → 2.19.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 (63) hide show
  1. checksums.yaml +8 -8
  2. data/HISTORY.md +439 -2
  3. data/acceptance/lib/beaker/acceptance/install_utils.rb +58 -0
  4. data/acceptance/pre_suite/puppet_git/install.rb +6 -65
  5. data/acceptance/tests/foss_utils/clone_git_repo_on.rb +49 -0
  6. data/beaker.gemspec +2 -0
  7. data/lib/beaker/dsl/helpers/web_helpers.rb +2 -1
  8. data/lib/beaker/dsl/install_utils/aio_defaults.rb +0 -2
  9. data/lib/beaker/dsl/install_utils/foss_utils.rb +97 -60
  10. data/lib/beaker/dsl/install_utils/pe_utils.rb +30 -53
  11. data/lib/beaker/dsl/install_utils/puppet_utils.rb +43 -0
  12. data/lib/beaker/dsl/install_utils/windows_utils.rb +144 -0
  13. data/lib/beaker/dsl/roles.rb +20 -3
  14. data/lib/beaker/dsl/structure.rb +14 -3
  15. data/lib/beaker/host.rb +24 -3
  16. data/lib/beaker/host/unix/pkg.rb +9 -0
  17. data/lib/beaker/host/windows/exec.rb +3 -0
  18. data/lib/beaker/host_prebuilt_steps.rb +5 -9
  19. data/lib/beaker/hypervisor/aws_sdk.rb +22 -18
  20. data/lib/beaker/hypervisor/docker.rb +7 -0
  21. data/lib/beaker/hypervisor/vmpooler.rb +4 -0
  22. data/lib/beaker/logger.rb +12 -1
  23. data/lib/beaker/options/command_line_parser.rb +9 -0
  24. data/lib/beaker/options/options_hash.rb +3 -296
  25. data/lib/beaker/options/parser.rb +12 -0
  26. data/lib/beaker/options/presets.rb +0 -1
  27. data/lib/beaker/ssh_connection.rb +48 -23
  28. data/lib/beaker/test_case.rb +1 -1
  29. data/lib/beaker/version.rb +1 -1
  30. data/spec/beaker/dsl/helpers/web_helpers_spec.rb +10 -1
  31. data/spec/beaker/dsl/install_utils/foss_utils_spec.rb +194 -49
  32. data/spec/beaker/dsl/install_utils/pe_utils_spec.rb +112 -22
  33. data/spec/beaker/dsl/install_utils/puppet_utils_spec.rb +57 -0
  34. data/spec/beaker/dsl/install_utils/windows_utils_spec.rb +132 -0
  35. data/spec/beaker/dsl/roles_spec.rb +36 -5
  36. data/spec/beaker/dsl/structure_spec.rb +9 -2
  37. data/spec/beaker/host/unix/pkg_spec.rb +26 -6
  38. data/spec/beaker/host_prebuilt_steps_spec.rb +3 -2
  39. data/spec/beaker/host_spec.rb +18 -0
  40. data/spec/beaker/hypervisor/aixer_spec.rb +1 -1
  41. data/spec/beaker/hypervisor/aws_sdk_spec.rb +595 -58
  42. data/spec/beaker/hypervisor/docker_spec.rb +2 -1
  43. data/spec/beaker/hypervisor/solaris_spec.rb +1 -0
  44. data/spec/beaker/hypervisor/vagrant_spec.rb +2 -1
  45. data/spec/beaker/logger_spec.rb +39 -0
  46. data/spec/beaker/options/command_line_parser_spec.rb +2 -2
  47. data/spec/beaker/options/options_hash_spec.rb +1 -102
  48. data/spec/beaker/options/parser_spec.rb +19 -0
  49. data/spec/beaker/options/pe_version_scaper_spec.rb +11 -1
  50. data/spec/beaker/options/presets_spec.rb +8 -0
  51. data/spec/beaker/ssh_connection_spec.rb +39 -21
  52. data/spec/helpers.rb +9 -3
  53. data/spec/mocks.rb +2 -0
  54. metadata +34 -11
  55. data/lib/beaker/answers.rb +0 -143
  56. data/lib/beaker/answers/version20.rb +0 -120
  57. data/lib/beaker/answers/version28.rb +0 -121
  58. data/lib/beaker/answers/version30.rb +0 -227
  59. data/lib/beaker/answers/version32.rb +0 -44
  60. data/lib/beaker/answers/version34.rb +0 -51
  61. data/lib/beaker/answers/version38.rb +0 -29
  62. data/lib/beaker/answers/version40.rb +0 -44
  63. data/spec/beaker/answers_spec.rb +0 -547
@@ -19,8 +19,9 @@ describe ClassMixedWithDSLInstallUtils do
19
19
  let(:presets) { Beaker::Options::Presets.new }
20
20
  let(:opts) { presets.presets.merge(presets.env_vars) }
21
21
  let(:basic_hosts) { make_hosts( { :pe_ver => '3.0',
22
- :platform => 'linux',
23
- :roles => [ 'agent' ] }, 4 ) }
22
+ :platform => 'linux',
23
+ :roles => [ 'agent' ],
24
+ :type => 'pe'}, 4 ) }
24
25
  let(:hosts) { basic_hosts[0][:roles] = ['master', 'database', 'dashboard']
25
26
  basic_hosts[1][:platform] = 'windows'
26
27
  basic_hosts[2][:platform] = 'osx-10.9-x86_64'
@@ -29,23 +30,28 @@ describe ClassMixedWithDSLInstallUtils do
29
30
  let(:hosts_sorted) { [ hosts[1], hosts[0], hosts[2], hosts[3] ] }
30
31
  let(:winhost) { make_host( 'winhost', { :platform => 'windows',
31
32
  :pe_ver => '3.0',
33
+ :type => 'pe',
32
34
  :working_dir => '/tmp' } ) }
33
35
  let(:machost) { make_host( 'machost', { :platform => 'osx-10.9-x86_64',
34
36
  :pe_ver => '3.0',
37
+ :type => 'pe',
35
38
  :working_dir => '/tmp' } ) }
36
39
  let(:unixhost) { make_host( 'unixhost', { :platform => 'linux',
37
40
  :pe_ver => '3.0',
41
+ :type => 'pe',
38
42
  :working_dir => '/tmp',
39
43
  :dist => 'puppet-enterprise-3.1.0-rc0-230-g36c9e5c-debian-7-i386' } ) }
40
44
  let(:eoshost) { make_host( 'eoshost', { :platform => 'eos',
41
45
  :pe_ver => '3.0',
46
+ :type => 'pe',
42
47
  :working_dir => '/tmp',
43
48
  :dist => 'puppet-enterprise-3.7.1-rc0-78-gffc958f-eos-4-i386' } ) }
44
49
  context '#configure_pe_defaults_on' do
45
- it 'uses aio paths for hosts of type aio' do
50
+ it 'uses aio paths for hosts of role aio' do
46
51
  hosts.each do |host|
47
- host[:type] = 'aio'
52
+ host[:roles] = host[:roles] | ['aio']
48
53
  end
54
+ expect(subject).to receive(:add_pe_defaults_on).exactly(hosts.length).times
49
55
  expect(subject).to receive(:add_aio_defaults_on).exactly(hosts.length).times
50
56
  expect(subject).to receive(:add_puppet_paths_on).exactly(hosts.length).times
51
57
 
@@ -57,33 +63,50 @@ describe ClassMixedWithDSLInstallUtils do
57
63
  host[:type] = 'pe'
58
64
  end
59
65
  expect(subject).to receive(:add_pe_defaults_on).exactly(hosts.length).times
66
+ expect(subject).to receive(:add_aio_defaults_on).never
60
67
  expect(subject).to receive(:add_puppet_paths_on).exactly(hosts.length).times
61
68
 
62
69
  subject.configure_pe_defaults_on( hosts )
63
70
  end
64
71
 
65
- it 'uses foss paths for hosts with no type and version < 4.0' do
66
- expect(subject).to receive(:add_pe_defaults_on).exactly(hosts.length).times
72
+ it 'uses aio paths for hosts of type aio' do
73
+ hosts.each do |host|
74
+ host[:type] = 'aio'
75
+ end
76
+ expect(subject).to receive(:add_aio_defaults_on).exactly(hosts.length).times
67
77
  expect(subject).to receive(:add_puppet_paths_on).exactly(hosts.length).times
68
78
 
69
79
  subject.configure_pe_defaults_on( hosts )
70
80
  end
71
81
 
82
+ it 'uses no paths for hosts with no type' do
83
+ hosts.each do |host|
84
+ host[:type] = nil
85
+ end
86
+ expect(subject).to receive(:add_pe_defaults_on).never
87
+ expect(subject).to receive(:add_aio_defaults_on).never
88
+ expect(subject).to receive(:add_puppet_paths_on).never
89
+
90
+ subject.configure_pe_defaults_on( hosts )
91
+ end
92
+
72
93
  it 'uses aio paths for hosts of version >= 4.0' do
73
94
  hosts.each do |host|
74
95
  host[:pe_ver] = '4.0'
75
96
  end
97
+ expect(subject).to receive(:add_pe_defaults_on).exactly(hosts.length).times
76
98
  expect(subject).to receive(:add_aio_defaults_on).exactly(hosts.length).times
77
99
  expect(subject).to receive(:add_puppet_paths_on).exactly(hosts.length).times
78
100
 
79
101
  subject.configure_pe_defaults_on( hosts )
80
102
  end
81
103
 
82
- it 'uses foss paths for hosts of version < 4.0' do
104
+ it 'uses pe paths for hosts of version < 4.0' do
83
105
  hosts.each do |host|
84
106
  host[:pe_ver] = '3.8'
85
107
  end
86
108
  expect(subject).to receive(:add_pe_defaults_on).exactly(hosts.length).times
109
+ expect(subject).to receive(:add_aio_defaults_on).never
87
110
  expect(subject).to receive(:add_puppet_paths_on).exactly(hosts.length).times
88
111
 
89
112
  subject.configure_pe_defaults_on( hosts )
@@ -112,13 +135,6 @@ describe ClassMixedWithDSLInstallUtils do
112
135
 
113
136
  describe 'installer_cmd' do
114
137
 
115
- it 'generates a windows PE install command for a windows host' do
116
- winhost['dist'] = 'puppet-enterprise-3.0'
117
- allow( subject ).to receive( :hosts ).and_return( [ hosts[1], hosts[0], hosts[2], winhost ] )
118
- allow( winhost ).to receive( :is_cygwin?).and_return(true)
119
- expect( subject.installer_cmd( winhost, {} ) ).to be === "cd /tmp && cmd /C 'start /w msiexec.exe /qn /L*V tmp.log /i puppet-enterprise-3.0.msi PUPPET_MASTER_SERVER=vm1 PUPPET_AGENT_CERTNAME=winhost'"
120
- end
121
-
122
138
  it 'generates a unix PE install command for a unix host' do
123
139
  the_host = unixhost.dup
124
140
  the_host['pe_installer'] = 'puppet-enterprise-installer'
@@ -353,7 +369,9 @@ describe ClassMixedWithDSLInstallUtils do
353
369
  expect( subject ).to receive( :create_remote_file ).with( hosts[0], /answers/, /q/ ).once
354
370
  #run installer on all hosts
355
371
  expect( subject ).to receive( :on ).with( hosts[0], /puppet-enterprise-installer/ ).once
356
- expect( subject ).to receive( :on ).with( hosts[1], /msiexec.exe/ ).once
372
+ expect( subject ).to receive( :install_msi_on ).with ( any_args ) do | host, msi_path, msi_opts, opts |
373
+ expect( host ).to eq( hosts[1] )
374
+ end.once
357
375
  expect( subject ).to receive( :on ).with( hosts[2], / hdiutil attach puppet-enterprise-3.0-osx-10.9-x86_64.dmg && installer -pkg \/Volumes\/puppet-enterprise-3.0\/puppet-enterprise-installer-3.0.pkg -target \// ).once
358
376
  expect( subject ).to receive( :on ).with( hosts[3], /^Cli/ ).once
359
377
  #does extra mac/EOS specific commands
@@ -458,7 +476,7 @@ describe ClassMixedWithDSLInstallUtils do
458
476
  expect( subject ).to receive( :install_puppet_agent_pe_promoted_repo_on ).with( hosts[2],
459
477
  {:puppet_agent_version=>nil, :puppet_agent_sha=>nil, :pe_ver=>hosts[2][:pe_ver], :puppet_collection=>nil} ).once
460
478
  hosts.each do |host|
461
- expect( subject ).to receive( :add_aio_defaults_on ).with( host ).once
479
+ expect( subject ).to receive( :configure_type_defaults_on ).with( host ).once
462
480
  expect( subject ).to receive( :sign_certificate_for ).with( host ).once
463
481
  expect( subject ).to receive( :stop_agent_on ).with( host ).once
464
482
  expect( subject ).to receive( :on ).with( host, /puppet agent -t/, :acceptable_exit_codes => [0,2] ).once
@@ -513,11 +531,7 @@ describe ClassMixedWithDSLInstallUtils do
513
531
  {:puppet_agent_version=>nil, :puppet_agent_sha=>nil, :pe_ver=>hosts[1][:pe_ver], :puppet_collection=>nil} ).once
514
532
  expect( subject ).to receive( :on ).with( hosts[2], /puppet-enterprise-installer/ ).once
515
533
  hosts.each do |host|
516
- if subject.aio_version?(host)
517
- expect( subject ).to receive( :add_aio_defaults_on ).with( host ).once
518
- else
519
- expect( subject ).to receive( :add_pe_defaults_on ).with( host ).once
520
- end
534
+ expect( subject ).to receive( :configure_type_defaults_on ).with( host ).once
521
535
  expect( subject ).to receive( :sign_certificate_for ).with( host ).once
522
536
  expect( subject ).to receive( :stop_agent_on ).with( host ).once
523
537
  expect( subject ).to receive( :on ).with( host, /puppet agent -t/, :acceptable_exit_codes => [0,2] ).once
@@ -529,6 +543,62 @@ describe ClassMixedWithDSLInstallUtils do
529
543
  subject.do_install( hosts, opts )
530
544
  end
531
545
 
546
+ it 'sets puppet-agent acceptable_exit_codes correctly for config helper on upgrade' do
547
+ hosts = make_hosts({
548
+ :pe_ver => '4.0',
549
+ :roles => ['agent'],
550
+ }, 2)
551
+ hosts[0][:roles] = ['master', 'database', 'dashboard']
552
+ hosts[1][:platform] = Beaker::Platform.new('el-6-x86_64')
553
+
554
+ allow( subject ).to receive( :hosts ).and_return( hosts )
555
+ allow( subject ).to receive( :options ).and_return(Beaker::Options::Presets.new.presets)
556
+ allow( subject ).to receive( :on ).and_return( Beaker::Result.new( {}, '' ) )
557
+ allow( subject ).to receive( :fetch_pe ).and_return( true )
558
+ allow( subject ).to receive( :create_remote_file ).and_return( true )
559
+ allow( subject ).to receive( :sign_certificate_for ).and_return( true )
560
+ allow( subject ).to receive( :stop_agent_on ).and_return( true )
561
+ allow( subject ).to receive( :sleep_until_puppetdb_started ).and_return( true )
562
+ allow( subject ).to receive( :max_version ).with(anything, '3.8').and_return('4.0')
563
+ allow( subject ).to receive( :version_is_less ).with('4.0', '4.0').and_return( false )
564
+ allow( subject ).to receive( :version_is_less ).with('4.0', '3.4').and_return( false )
565
+ allow( subject ).to receive( :version_is_less ).with('4.0', '3.0').and_return( false )
566
+ allow( subject ).to receive( :version_is_less ).with('3.99', '4.0').and_return( true )
567
+ allow( subject ).to receive( :version_is_less ).with('3.8', '4.0').and_return( true )
568
+ # pe_ver is only set on the hosts for this test, not the opt
569
+ allow( subject ).to receive( :version_is_less ).with('4.0', '3.99').and_return( true )
570
+ allow( subject ).to receive( :wait_for_host_in_dashboard ).and_return( true )
571
+ allow( subject ).to receive( :puppet_agent ) do |arg|
572
+ "puppet agent #{arg}"
573
+ end
574
+ allow( subject ).to receive( :puppet ) do |arg|
575
+ "puppet #{arg}"
576
+ end
577
+
578
+ allow( subject ).to receive( :hosts ).and_return( hosts )
579
+ #create answers file per-host, except windows
580
+ allow( subject ).to receive( :create_remote_file ).with( hosts[0], /answers/, /q/ )
581
+ #run installer on all hosts
582
+ allow( subject ).to receive( :on ).with( hosts[0], /puppet-enterprise-installer/ )
583
+ allow( subject ).to receive( :install_puppet_agent_pe_promoted_repo_on ).with( hosts[1],
584
+ {:puppet_agent_version=>nil, :puppet_agent_sha=>nil, :pe_ver=>hosts[1][:pe_ver], :puppet_collection=>nil} )
585
+ # expect( subject ).to receive( :on ).with( hosts[2], /puppet-enterprise-installer/ ).once
586
+ hosts.each do |host|
587
+ allow( subject ).to receive( :add_pe_defaults_on ).with( host ) unless subject.aio_version?(host)
588
+ allow( subject ).to receive( :sign_certificate_for ).with( host )
589
+ allow( subject ).to receive( :stop_agent_on ).with( host )
590
+ allow( subject ).to receive( :on ).with( host, /puppet agent -t/, :acceptable_exit_codes => [0,2] )
591
+ end
592
+ #wait for puppetdb to start
593
+ allow( subject ).to receive( :sleep_until_puppetdb_started ).with( hosts[0] ) #wait for all hosts to appear in the dashboard
594
+ #run puppet agent now that installation is complete
595
+ allow( subject ).to receive( :on ).with( hosts, /puppet agent/, :acceptable_exit_codes => [0,2] )
596
+
597
+ opts[:type] = :upgrade
598
+ expect( subject ).to receive( :setup_defaults_and_config_helper_on ).with( hosts[1], hosts[0], [0, 1, 2] )
599
+ subject.do_install( hosts, opts )
600
+ end
601
+
532
602
  end
533
603
 
534
604
  describe 'do_higgs_install' do
@@ -576,7 +646,7 @@ describe ClassMixedWithDSLInstallUtils do
576
646
  opts ).once
577
647
  #check to see if the higgs installation has proceeded correctly, works on second check
578
648
  expect( subject ).to receive( :on ).with( hosts[0], /cat #{hosts[0]['higgs_file']}/, { :accept_all_exit_codes => true }).exactly(10).times.and_return( @fail_result )
579
- expect{ subject.do_higgs_install( hosts[0], opts ) }.to raise_error
649
+ expect{ subject.do_higgs_install( hosts[0], opts ) }.to raise_error RuntimeError, "Failed to kick off PE (Higgs) web installation"
580
650
  end
581
651
 
582
652
  end
@@ -605,6 +675,13 @@ describe ClassMixedWithDSLInstallUtils do
605
675
  expect( h['pe_ver'] ).to be === '2.8'
606
676
  end
607
677
  end
678
+
679
+ it 'can act upon a single host' do
680
+ allow( subject ).to receive( :hosts ).and_return( hosts )
681
+ allow( subject ).to receive( :sorted_hosts ).and_return( [hosts[0]] )
682
+ expect( subject ).to receive( :do_install ).with( [hosts[0]], {} )
683
+ subject.install_pe_on(hosts[0], {})
684
+ end
608
685
  end
609
686
 
610
687
  describe 'install_higgs' do
@@ -674,6 +751,19 @@ describe ClassMixedWithDSLInstallUtils do
674
751
  end
675
752
  end
676
753
 
754
+ it 'can act upon a single host' do
755
+ allow( Beaker::Options::PEVersionScraper ).to receive( :load_pe_version ).and_return( '3.1' )
756
+ allow( Beaker::Options::PEVersionScraper ).to receive( :load_pe_version_win ).and_return( '3.1' )
757
+ allow( subject ).to receive( :hosts ).and_return( hosts )
758
+ allow( subject ).to receive( :version_is_less ).with('3.0', '3.4.0').and_return( true )
759
+ allow( subject ).to receive( :version_is_less ).with('3.1', '3.0').and_return( false )
760
+ allow( subject ).to receive( :sorted_hosts ).and_return( [hosts[0]] )
761
+ version = version_win = '3.1'
762
+ path = "/path/to/upgradepkg"
763
+ expect( subject ).to receive( :do_install ).with( [hosts[0]], {:type=>:upgrade, :set_console_password=>true} )
764
+ subject.upgrade_pe_on(hosts[0], {}, path)
765
+ end
766
+
677
767
  end
678
768
 
679
769
  describe 'fetch_and_push_pe' do
@@ -70,4 +70,61 @@ describe ClassMixedWithDSLInstallUtils do
70
70
  subject.configure_defaults_on(hosts, 'foss')
71
71
  end
72
72
  end
73
+
74
+ describe "#configure_type_defaults_on" do
75
+
76
+ it "can set foss defaults for foss type" do
77
+ hosts.each do |host|
78
+ host['type'] = 'foss'
79
+ end
80
+ expect(subject).to receive(:add_foss_defaults_on).exactly(hosts.length).times
81
+ subject.configure_type_defaults_on(hosts)
82
+ end
83
+
84
+ it "adds aio defaults to foss hosts when they have an aio foss puppet version" do
85
+ hosts.each do |host|
86
+ host['type'] = 'foss'
87
+ host['version'] = '4.0'
88
+ end
89
+ expect(subject).to receive(:add_foss_defaults_on).exactly(hosts.length).times
90
+ expect(subject).to receive(:add_aio_defaults_on).exactly(hosts.length).times
91
+ subject.configure_type_defaults_on(hosts)
92
+ end
93
+
94
+ it "adds aio defaults to foss hosts when they have type foss-aio" do
95
+ hosts.each do |host|
96
+ host['type'] = 'foss-aio'
97
+ end
98
+ expect(subject).to receive(:add_foss_defaults_on).exactly(hosts.length).times
99
+ expect(subject).to receive(:add_aio_defaults_on).exactly(hosts.length).times
100
+ subject.configure_type_defaults_on(hosts)
101
+ end
102
+
103
+ it "can set aio defaults for aio type (backwards compatability)" do
104
+ hosts.each do |host|
105
+ host['type'] = 'aio'
106
+ end
107
+ expect(subject).to receive(:add_aio_defaults_on).exactly(hosts.length).times
108
+ subject.configure_type_defaults_on(hosts)
109
+ end
110
+
111
+ it "can set pe defaults for pe type" do
112
+ hosts.each do |host|
113
+ host['type'] = 'pe'
114
+ end
115
+ expect(subject).to receive(:add_pe_defaults_on).exactly(hosts.length).times
116
+ subject.configure_type_defaults_on(hosts)
117
+ end
118
+
119
+ it "adds aio defaults to pe hosts when they an aio pe version" do
120
+ hosts.each do |host|
121
+ host['type'] = 'pe'
122
+ host['pe_ver'] = '4.0'
123
+ end
124
+ expect(subject).to receive(:add_pe_defaults_on).exactly(hosts.length).times
125
+ expect(subject).to receive(:add_aio_defaults_on).exactly(hosts.length).times
126
+ subject.configure_type_defaults_on(hosts)
127
+ end
128
+
129
+ end
73
130
  end
@@ -0,0 +1,132 @@
1
+ require 'spec_helper'
2
+
3
+ class ClassMixedWithDSLInstallUtils
4
+ include Beaker::DSL::Helpers
5
+ include Beaker::DSL::Patterns
6
+ include Beaker::DSL::InstallUtils
7
+
8
+ def logger
9
+ @logger ||= RSpec::Mocks::Double.new('logger').as_null_object
10
+ end
11
+ end
12
+
13
+ describe ClassMixedWithDSLInstallUtils do
14
+ let(:windows_temp) { 'C:\\Windows\\Temp' }
15
+ let(:msi_path) { 'c:\\foo\\puppet.msi' }
16
+ let(:winhost) { make_host( 'winhost',
17
+ { :platform => 'windows',
18
+ :pe_ver => '3.0',
19
+ :working_dir => '/tmp',
20
+ :is_cygwin => true} ) }
21
+ let(:winhost_non_cygwin) { make_host( 'winhost_non_cygwin',
22
+ { :platform => 'windows',
23
+ :pe_ver => '3.0',
24
+ :working_dir => '/tmp',
25
+ :is_cygwin => 'false' } ) }
26
+ let(:hosts) { [ winhost, winhost_non_cygwin ] }
27
+
28
+ def expect_install_called(times = hosts.length)
29
+ result = expect( Beaker::Command ).to receive( :new )
30
+ .with( /^"#{Regexp.quote(windows_temp)}\\install-puppet-msi.*\.bat"$/, [], {:cmdexe => true})
31
+ .exactly( times ).times
32
+
33
+ yield result if block_given?
34
+ end
35
+
36
+ def expect_status_called(times = hosts.length)
37
+ expect( Beaker::Command ).to receive( :new )
38
+ .with( "sc query puppet || sc query pe-puppet", [], {:cmdexe => true} )
39
+ .exactly( times ).times
40
+ end
41
+
42
+ def expect_script_matches(hosts, contents)
43
+ hosts.each do |host|
44
+ expect( host )
45
+ .to receive( :do_scp_to ) do |local_path, remote_path|
46
+ expect(File.read(local_path)).to match(contents)
47
+ end
48
+ .and_return( true )
49
+ end
50
+ end
51
+
52
+ describe "#install_msi_on" do
53
+ before :each do
54
+ FakeFS::FileSystem.add(File.expand_path '/tmp')
55
+
56
+ allow( subject ).to receive( :on ).and_return( true )
57
+ allow( subject ).to receive( :get_temp_path ).and_return( windows_temp )
58
+ end
59
+
60
+ it "will specify a PUPPET_AGENT_STARTUP_MODE of Manual (disabling the service) by default" do
61
+ expect_install_called
62
+ expect_status_called
63
+ expected_cmd = /^start \/w msiexec\.exe \/i "c:\\foo\\puppet.msi" \/qn \/L\*V .*\.log PUPPET_AGENT_STARTUP_MODE=Manual$/
64
+ expect_script_matches(hosts, expected_cmd)
65
+ subject.install_msi_on(hosts, msi_path, {})
66
+ end
67
+
68
+ it "allows configuration of PUPPET_AGENT_STARTUP_MODE" do
69
+ expect_install_called
70
+ expect_status_called
71
+ expected_cmd = /^start \/w msiexec\.exe \/i "c:\\foo\\puppet.msi" \/qn \/L\*V .*\.log PUPPET_AGENT_STARTUP_MODE=Automatic$/
72
+ expect_script_matches(hosts, expected_cmd)
73
+ subject.install_msi_on(hosts, msi_path, {'PUPPET_AGENT_STARTUP_MODE' => 'Automatic'})
74
+ end
75
+
76
+ it "will generate an appropriate command with a MSI file path using non-Windows slashes" do
77
+ expect_install_called
78
+ expect_status_called
79
+ msi_path = 'c:/foo/puppet.msi'
80
+ expected_cmd = /^start \/w msiexec\.exe \/i "c:\\foo\\puppet.msi" \/qn \/L\*V .*\.log PUPPET_AGENT_STARTUP_MODE=Manual$/
81
+ expect_script_matches(hosts, expected_cmd)
82
+ subject.install_msi_on(hosts, msi_path)
83
+ end
84
+
85
+ it "will generate an appropriate command with a MSI http(s) url" do
86
+ expect_install_called
87
+ expect_status_called
88
+ msi_url = "https://downloads.puppetlabs.com/puppet.msi"
89
+ expected_cmd = /^start \/w msiexec\.exe \/i "https\:\/\/downloads\.puppetlabs\.com\/puppet\.msi" \/qn \/L\*V .*\.log PUPPET_AGENT_STARTUP_MODE=Manual$/
90
+ expect_script_matches(hosts, expected_cmd)
91
+ subject.install_msi_on(hosts, msi_url)
92
+ end
93
+
94
+ it "will generate an appropriate command with a MSI file url" do
95
+ expect_install_called
96
+ expect_status_called
97
+ msi_url = "file://c:\\foo\\puppet.msi"
98
+ expected_cmd = /^start \/w msiexec\.exe \/i "file\:\/\/c:\\foo\\puppet\.msi" \/qn \/L\*V .*\.log PUPPET_AGENT_STARTUP_MODE=Manual$/
99
+ expect_script_matches(hosts, expected_cmd)
100
+ subject.install_msi_on(hosts, msi_url)
101
+ end
102
+
103
+ it "will not generate a command to emit a log file without the :debug option set" do
104
+ expect_install_called
105
+ expect_status_called
106
+ hosts.each { |h| allow( h ).to receive( :do_scp_to ).and_return( true ) }
107
+ expect( Beaker::Command ).not_to receive( :new ).with( /^type .*\.log$/, [], {:cmdexe => true} )
108
+ subject.install_msi_on(hosts, msi_path)
109
+ end
110
+
111
+ it "will generate a command to emit a log file when the install script fails" do
112
+ # note a single failure aborts executing against remaining hosts
113
+ hosts_affected = 1
114
+
115
+ expect_install_called(hosts_affected) { |e| e.and_raise }
116
+ expect_status_called(0)
117
+ hosts.each { |h| allow( h ).to receive( :do_scp_to ).and_return( true ) }
118
+
119
+ expect( Beaker::Command ).to receive( :new ).with( /^type \".*\.log\"$/, [], {:cmdexe => true} ).exactly( hosts_affected ).times
120
+ expect { subject.install_msi_on(hosts, msi_path) }.to raise_error(RuntimeError)
121
+ end
122
+
123
+ it "will generate a command to emit a log file with the :debug option set" do
124
+ expect_install_called
125
+ expect_status_called
126
+ hosts.each { |h| allow( h ).to receive( :do_scp_to ).and_return( true ) }
127
+
128
+ expect( Beaker::Command ).to receive( :new ).with( /^type \".*\.log\"$/, [], {:cmdexe => true} ).exactly( hosts.length ).times
129
+ subject.install_msi_on(hosts, msi_path, {}, { :debug => true })
130
+ end
131
+ end
132
+ end
@@ -116,22 +116,53 @@ describe ClassMixedWithDSLRoles do
116
116
  end
117
117
  end
118
118
  describe '#aio_version?' do
119
- it 'returns true if the host doesn\'t have a :pe_ver' do
119
+ it 'returns false if the host doesn\'t have a :pe_ver or :version' do
120
120
  agent1[:pe_ver] = nil
121
- expect( subject.aio_version?(agent1) ).to be === true
121
+ agent1[:version] = nil
122
+ expect( subject.aio_version?(agent1) ).to be === false
123
+ end
124
+ it 'returns false if :version < 4.0 and pe_ver is nil, type foss' do
125
+ agent1[:pe_ver] = nil
126
+ agent1[:version] = '3.8'
127
+ agent1[:type] = 'foss'
128
+ expect( subject.aio_version?(agent1) ).to be === false
122
129
  end
123
130
  it 'returns false if the host :pe_ver is set < 4.0' do
124
131
  agent1[:pe_ver] = '3.8'
125
132
  expect( subject.aio_version?(agent1) ).to be === false
126
133
  end
134
+ it 'returns false if the host :version is set < 4.0' do
135
+ agent1[:version] = '3.8'
136
+ expect( subject.aio_version?(agent1) ).to be === false
137
+ end
127
138
  it 'returns true if the host :pe_ver is 4.0' do
128
139
  agent1[:pe_ver] = '4.0'
129
140
  expect( subject.aio_version?(agent1) ).to be === true
130
141
  end
142
+ it 'returns true if the host :version is 4.0' do
143
+ agent1[:version] = '4.0'
144
+ expect( subject.aio_version?(agent1) ).to be === true
145
+ end
131
146
  it 'returns true if the host :pe_ver is 2015.5' do
132
147
  agent1[:pe_ver] = '2015.5'
133
148
  expect( subject.aio_version?(agent1) ).to be === true
134
149
  end
150
+ it 'returns true if the host has role aio' do
151
+ agent1[:roles] = agent1[:roles] | ['aio']
152
+ expect( subject.aio_version?(agent1) ).to be === true
153
+ end
154
+ it 'returns true if the host is type aio' do
155
+ agent1[:type] = 'aio'
156
+ expect( subject.aio_version?(agent1) ).to be === true
157
+ end
158
+ it 'returns true if the host is type aio-foss' do
159
+ agent1[:type] = 'aio-foss'
160
+ expect( subject.aio_version?(agent1) ).to be === true
161
+ end
162
+ it 'returns true if the host is type foss-aio' do
163
+ agent1[:type] = 'aio-foss'
164
+ expect( subject.aio_version?(agent1) ).to be === true
165
+ end
135
166
  end
136
167
  describe '#aio_agent?' do
137
168
  it 'returns false if agent_only check doesn\'t pass' do
@@ -172,13 +203,13 @@ describe ClassMixedWithDSLRoles do
172
203
  end
173
204
  describe '#add_role_def' do
174
205
  it 'raises an error on unsupported role format "1role"' do
175
- expect { subject.add_role_def( "1role" ) }.to raise_error
206
+ expect { subject.add_role_def( "1role" ) }.to raise_error ArgumentError
176
207
  end
177
208
  it 'raises an error on unsupported role format "role_!a"' do
178
- expect { subject.add_role_def( "role_!a" ) }.to raise_error
209
+ expect { subject.add_role_def( "role_!a" ) }.to raise_error ArgumentError
179
210
  end
180
211
  it 'raises an error on unsupported role format "role=="' do
181
- expect { subject.add_role_def( "role==" ) }.to raise_error
212
+ expect { subject.add_role_def( "role==" ) }.to raise_error ArgumentError
182
213
  end
183
214
  it 'creates new method for role "role_correct!"' do
184
215
  test_role = "role_correct!"