beaker 1.16.0 → 1.17.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +8 -8
- data/CONTRIBUTING.md +90 -0
- data/HISTORY.md +654 -2
- data/beaker.gemspec +1 -0
- data/lib/beaker/answers/version34.rb +4 -0
- data/lib/beaker/cli.rb +49 -2
- data/lib/beaker/dsl/helpers.rb +356 -196
- data/lib/beaker/dsl/install_utils.rb +135 -16
- data/lib/beaker/dsl/patterns.rb +37 -0
- data/lib/beaker/dsl/roles.rb +29 -0
- data/lib/beaker/dsl.rb +2 -1
- data/lib/beaker/host/unix.rb +14 -10
- data/lib/beaker/host/windows.rb +2 -0
- data/lib/beaker/host.rb +96 -1
- data/lib/beaker/host_prebuilt_steps.rb +41 -51
- data/lib/beaker/hypervisor/aws_sdk.rb +80 -16
- data/lib/beaker/hypervisor/ec2_helper.rb +1 -1
- data/lib/beaker/logger.rb +17 -0
- data/lib/beaker/options/command_line_parser.rb +3 -0
- data/lib/beaker/options/hosts_file_parser.rb +7 -4
- data/lib/beaker/options/options_hash.rb +2 -2
- data/lib/beaker/options/parser.rb +1 -1
- data/lib/beaker/options/presets.rb +128 -83
- data/lib/beaker/perf.rb +58 -0
- data/lib/beaker/shared/host_manager.rb +81 -0
- data/lib/beaker/shared.rb +2 -2
- data/lib/beaker/ssh_connection.rb +14 -7
- data/lib/beaker/test_case.rb +13 -0
- data/lib/beaker/test_suite.rb +23 -5
- data/lib/beaker/version.rb +1 -1
- data/lib/beaker.rb +1 -1
- data/spec/beaker/answers_spec.rb +13 -8
- data/spec/beaker/dsl/ezbake_utils_spec.rb +8 -9
- data/spec/beaker/dsl/helpers_spec.rb +299 -51
- data/spec/beaker/dsl/install_utils_spec.rb +75 -10
- data/spec/beaker/dsl/roles_spec.rb +36 -1
- data/spec/beaker/host_prebuilt_steps_spec.rb +21 -5
- data/spec/beaker/host_spec.rb +187 -23
- data/spec/beaker/hypervisor/ec2_helper_spec.rb +4 -4
- data/spec/beaker/hypervisor/vagrant_spec.rb +1 -1
- data/spec/beaker/options/hosts_file_parser_spec.rb +5 -0
- data/spec/beaker/options/options_hash_spec.rb +2 -2
- data/spec/beaker/options/parser_spec.rb +6 -0
- data/spec/beaker/options/presets_spec.rb +18 -2
- data/spec/beaker/perf_spec.rb +87 -0
- data/spec/beaker/shared/{host_role_parser_spec.rb → host_manager_spec.rb} +36 -5
- data/spec/beaker/test_suite_spec.rb +4 -3
- data/spec/matchers.rb +31 -3
- data/spec/mocks.rb +31 -25
- metadata +24 -5
- data/lib/beaker/shared/host_role_parser.rb +0 -36
@@ -128,7 +128,7 @@ describe ClassMixedWithEZBakeUtils do
|
|
128
128
|
RSpec.shared_examples "installs-ezbake-dependencies" do
|
129
129
|
it "installs ezbake dependencies" do
|
130
130
|
expect(subject).to receive(:install_package).
|
131
|
-
with( kind_of(
|
131
|
+
with( kind_of(Beaker::Host), anything(), anything())
|
132
132
|
subject.install_ezbake_deps host
|
133
133
|
end
|
134
134
|
end
|
@@ -136,7 +136,7 @@ describe ClassMixedWithEZBakeUtils do
|
|
136
136
|
describe '#install_ezbake_deps' do
|
137
137
|
let( :platform ) { Beaker::Platform.new('redhat-7-i386') }
|
138
138
|
let(:host) do
|
139
|
-
FakeHost.
|
139
|
+
FakeHost.create('fakevm', platform.to_s)
|
140
140
|
end
|
141
141
|
|
142
142
|
before do
|
@@ -164,24 +164,23 @@ describe ClassMixedWithEZBakeUtils do
|
|
164
164
|
def install_from_ezbake_common_expects
|
165
165
|
expect(subject).to receive(:`).with(/rake package:tar/).ordered
|
166
166
|
expect(subject).to receive(:scp_to).
|
167
|
-
with( kind_of(
|
167
|
+
with( kind_of(Beaker::Host), anything(), anything()).ordered
|
168
168
|
expect(subject).to receive(:on).
|
169
|
-
with( kind_of(
|
169
|
+
with( kind_of(Beaker::Host), /tar -xzf/).ordered
|
170
170
|
expect(subject).to receive(:on).
|
171
|
-
with( kind_of(
|
171
|
+
with( kind_of(Beaker::Host), /make -e install-#{EZBAKE_CONFIG_EXAMPLE[:real_name]}/).ordered
|
172
172
|
end
|
173
173
|
|
174
174
|
describe '#install_from_ezbake' do
|
175
175
|
let( :platform ) { Beaker::Platform.new('redhat-7-i386') }
|
176
176
|
let(:host) do
|
177
|
-
FakeHost.
|
177
|
+
FakeHost.create('fakevm', platform.to_s)
|
178
178
|
end
|
179
179
|
|
180
180
|
before do
|
181
181
|
allow(subject).to receive(:ezbake_tools_available?) { true }
|
182
182
|
end
|
183
183
|
|
184
|
-
|
185
184
|
context "for non *nix-like platforms" do
|
186
185
|
let( :platform ) { Beaker::Platform.new('windows-7-i386') }
|
187
186
|
it "raises an exception" do
|
@@ -212,7 +211,7 @@ describe ClassMixedWithEZBakeUtils do
|
|
212
211
|
}.ordered
|
213
212
|
install_from_ezbake_common_expects
|
214
213
|
expect(subject).to receive(:on).
|
215
|
-
with( kind_of(
|
214
|
+
with( kind_of(Beaker::Host), /install-rpm-sysv-init/).ordered
|
216
215
|
subject.install_from_ezbake host, "blah", "blah"
|
217
216
|
end
|
218
217
|
|
@@ -228,7 +227,7 @@ describe ClassMixedWithEZBakeUtils do
|
|
228
227
|
it "skips ezbake_stage" do
|
229
228
|
install_from_ezbake_common_expects
|
230
229
|
expect(subject).to receive(:on).
|
231
|
-
with( kind_of(
|
230
|
+
with( kind_of(Beaker::Host), /install-rpm-sysv-init/).ordered
|
232
231
|
subject.install_from_ezbake host, "blah", "blah"
|
233
232
|
end
|
234
233
|
|
@@ -4,6 +4,7 @@ class ClassMixedWithDSLHelpers
|
|
4
4
|
include Beaker::DSL::Helpers
|
5
5
|
include Beaker::DSL::Wrappers
|
6
6
|
include Beaker::DSL::Roles
|
7
|
+
include Beaker::DSL::Patterns
|
7
8
|
|
8
9
|
def logger
|
9
10
|
@logger ||= RSpec::Mocks::Mock.new('logger').as_null_object
|
@@ -32,6 +33,7 @@ describe ClassMixedWithDSLHelpers do
|
|
32
33
|
end
|
33
34
|
|
34
35
|
it 'allows the environment the command is run within to be specified' do
|
36
|
+
subject.stub( :hosts ).and_return( hosts )
|
35
37
|
|
36
38
|
Beaker::Command.should_receive( :new ).
|
37
39
|
with( 'ls ~/.bin', [], {'ENV' => { :HOME => '/tmp/test_home' }} )
|
@@ -58,6 +60,7 @@ describe ClassMixedWithDSLHelpers do
|
|
58
60
|
end
|
59
61
|
|
60
62
|
it 'delegates to itself for each host passed' do
|
63
|
+
subject.stub( :hosts ).and_return( hosts )
|
61
64
|
expected = []
|
62
65
|
hosts.each_with_index do |host, i|
|
63
66
|
expected << i
|
@@ -70,6 +73,7 @@ describe ClassMixedWithDSLHelpers do
|
|
70
73
|
|
71
74
|
context 'upon command completion' do
|
72
75
|
before :each do
|
76
|
+
subject.stub( :hosts ).and_return( hosts )
|
73
77
|
host.should_receive( :exec ).and_return( result )
|
74
78
|
@res = subject.on( host, command )
|
75
79
|
end
|
@@ -93,6 +97,7 @@ describe ClassMixedWithDSLHelpers do
|
|
93
97
|
|
94
98
|
context 'when passed a block with arity of 1' do
|
95
99
|
before :each do
|
100
|
+
subject.stub( :hosts ).and_return( hosts )
|
96
101
|
host.should_receive( :exec ).and_return( result )
|
97
102
|
end
|
98
103
|
|
@@ -124,6 +129,7 @@ describe ClassMixedWithDSLHelpers do
|
|
124
129
|
|
125
130
|
context 'when passed a block with arity of 0' do
|
126
131
|
before :each do
|
132
|
+
subject.stub( :hosts ).and_return( hosts )
|
127
133
|
host.should_receive( :exec ).and_return( result )
|
128
134
|
end
|
129
135
|
|
@@ -167,6 +173,7 @@ describe ClassMixedWithDSLHelpers do
|
|
167
173
|
|
168
174
|
describe '#scp_from' do
|
169
175
|
it 'delegates to the host' do
|
176
|
+
subject.stub( :hosts ).and_return( hosts )
|
170
177
|
subject.should_receive( :logger ).exactly( hosts.length ).times
|
171
178
|
result.should_receive( :log ).exactly( hosts.length ).times
|
172
179
|
|
@@ -180,6 +187,7 @@ describe ClassMixedWithDSLHelpers do
|
|
180
187
|
|
181
188
|
describe '#scp_to' do
|
182
189
|
it 'delegates to the host' do
|
190
|
+
subject.stub( :hosts ).and_return( hosts )
|
183
191
|
subject.should_receive( :logger ).exactly( hosts.length ).times
|
184
192
|
result.should_receive( :log ).exactly( hosts.length ).times
|
185
193
|
|
@@ -384,8 +392,46 @@ describe ClassMixedWithDSLHelpers do
|
|
384
392
|
end
|
385
393
|
end
|
386
394
|
|
395
|
+
describe '#select_hosts' do
|
396
|
+
let(:logger) { double.as_null_object }
|
397
|
+
before do
|
398
|
+
subject.stub( :logger ).and_return( logger )
|
399
|
+
end
|
400
|
+
|
401
|
+
it 'it returns an empty array if there are no applicable hosts' do
|
402
|
+
hosts = [ {'thing' => 'foo'}, {'thing' => 'bar'} ]
|
403
|
+
|
404
|
+
expect(subject.select_hosts( {'thing' => 'nope'}, hosts )).to be == []
|
405
|
+
end
|
406
|
+
|
407
|
+
it 'selects hosts that match a list of criteria' do
|
408
|
+
hosts = [ {'thing' => 'foo'}, {'thing' => 'bar'}, {'thing' => 'baz'} ]
|
409
|
+
|
410
|
+
expect(subject.select_hosts( {:thing => ['foo', 'baz']}, hosts )).to be == [ {'thing' => 'foo'}, {'thing' => 'baz'} ]
|
411
|
+
end
|
412
|
+
|
413
|
+
it 'selects hosts when a passed block returns true' do
|
414
|
+
host1 = {'platform' => 'solaris1'}
|
415
|
+
host2 = {'platform' => 'solaris2'}
|
416
|
+
host3 = {'platform' => 'windows'}
|
417
|
+
ret1 = (Struct.new('Result1', :stdout)).new(':global')
|
418
|
+
ret2 = (Struct.new('Result2', :stdout)).new('a_zone')
|
419
|
+
hosts = [ host1, host2, host3 ]
|
420
|
+
subject.should_receive( :hosts ).and_return( hosts )
|
421
|
+
|
422
|
+
subject.should_receive( :on ).with( host1, '/sbin/zonename' ).once.and_return( ret1 )
|
423
|
+
subject.should_receive( :on ).with( host2, '/sbin/zonename' ).once.and_return( ret2 )
|
424
|
+
|
425
|
+
selected_hosts = subject.select_hosts 'platform' => 'solaris' do |host|
|
426
|
+
subject.on(host, '/sbin/zonename').stdout =~ /:global/
|
427
|
+
end
|
428
|
+
expect( selected_hosts ).to be == [ host1 ]
|
429
|
+
end
|
430
|
+
end
|
431
|
+
|
387
432
|
describe '#apply_manifest_on' do
|
388
433
|
it 'calls puppet' do
|
434
|
+
subject.stub( :hosts ).and_return( hosts )
|
389
435
|
subject.should_receive( :create_remote_file ).and_return( true )
|
390
436
|
subject.should_receive( :puppet ).
|
391
437
|
# with( 'apply', '--verbose', 'agent' ).
|
@@ -399,6 +445,7 @@ describe ClassMixedWithDSLHelpers do
|
|
399
445
|
end
|
400
446
|
|
401
447
|
it 'operates on an array of hosts' do
|
448
|
+
subject.stub( :hosts ).and_return( hosts )
|
402
449
|
the_hosts = [master, agent]
|
403
450
|
|
404
451
|
subject.should_receive( :create_remote_file ).twice.and_return( true )
|
@@ -415,6 +462,7 @@ describe ClassMixedWithDSLHelpers do
|
|
415
462
|
end
|
416
463
|
|
417
464
|
it 'adds acceptable exit codes with :catch_failures' do
|
465
|
+
subject.stub( :hosts ).and_return( hosts )
|
418
466
|
subject.should_receive( :create_remote_file ).and_return( true )
|
419
467
|
subject.should_receive( :puppet ).
|
420
468
|
and_return( 'puppet_command' )
|
@@ -428,6 +476,7 @@ describe ClassMixedWithDSLHelpers do
|
|
428
476
|
:catch_failures => true )
|
429
477
|
end
|
430
478
|
it 'allows acceptable exit codes through :catch_failures' do
|
479
|
+
subject.stub( :hosts ).and_return( hosts )
|
431
480
|
subject.should_receive( :create_remote_file ).and_return( true )
|
432
481
|
subject.should_receive( :puppet ).
|
433
482
|
and_return( 'puppet_command' )
|
@@ -442,6 +491,7 @@ describe ClassMixedWithDSLHelpers do
|
|
442
491
|
:catch_failures => true )
|
443
492
|
end
|
444
493
|
it 'enforces a 0 exit code through :catch_changes' do
|
494
|
+
subject.stub( :hosts ).and_return( hosts )
|
445
495
|
subject.should_receive( :create_remote_file ).and_return( true )
|
446
496
|
subject.should_receive( :puppet ).
|
447
497
|
and_return( 'puppet_command' )
|
@@ -459,6 +509,7 @@ describe ClassMixedWithDSLHelpers do
|
|
459
509
|
)
|
460
510
|
end
|
461
511
|
it 'enforces a 2 exit code through :expect_changes' do
|
512
|
+
subject.stub( :hosts ).and_return( hosts )
|
462
513
|
subject.should_receive( :create_remote_file ).and_return( true )
|
463
514
|
subject.should_receive( :puppet ).
|
464
515
|
and_return( 'puppet_command' )
|
@@ -476,6 +527,7 @@ describe ClassMixedWithDSLHelpers do
|
|
476
527
|
)
|
477
528
|
end
|
478
529
|
it 'enforces exit codes through :expect_failures' do
|
530
|
+
subject.stub( :hosts ).and_return( hosts )
|
479
531
|
subject.should_receive( :create_remote_file ).and_return( true )
|
480
532
|
subject.should_receive( :puppet ).
|
481
533
|
and_return( 'puppet_command' )
|
@@ -493,6 +545,7 @@ describe ClassMixedWithDSLHelpers do
|
|
493
545
|
)
|
494
546
|
end
|
495
547
|
it 'enforces exit codes through :expect_failures' do
|
548
|
+
subject.stub( :hosts ).and_return( hosts )
|
496
549
|
expect {
|
497
550
|
subject.apply_manifest_on(
|
498
551
|
agent,
|
@@ -503,6 +556,7 @@ describe ClassMixedWithDSLHelpers do
|
|
503
556
|
}.to raise_error ArgumentError, /catch_failures.+expect_failures/
|
504
557
|
end
|
505
558
|
it 'enforces added exit codes through :expect_failures' do
|
559
|
+
subject.stub( :hosts ).and_return( hosts )
|
506
560
|
subject.should_receive( :create_remote_file ).and_return( true )
|
507
561
|
subject.should_receive( :puppet ).
|
508
562
|
and_return( 'puppet_command' )
|
@@ -522,6 +576,7 @@ describe ClassMixedWithDSLHelpers do
|
|
522
576
|
end
|
523
577
|
|
524
578
|
it 'can set the --parser future flag' do
|
579
|
+
subject.stub( :hosts ).and_return( hosts )
|
525
580
|
subject.should_receive( :create_remote_file ).and_return( true )
|
526
581
|
|
527
582
|
expect( subject ).to receive( :on ).with {|h, command, opts|
|
@@ -543,6 +598,7 @@ describe ClassMixedWithDSLHelpers do
|
|
543
598
|
end
|
544
599
|
|
545
600
|
it 'can set the --noops flag' do
|
601
|
+
subject.stub( :hosts ).and_return( hosts )
|
546
602
|
subject.should_receive( :create_remote_file ).and_return( true )
|
547
603
|
expect( subject ).to receive( :on ).with {|h, command, opts|
|
548
604
|
cmdline = command.cmd_line( h )
|
@@ -575,6 +631,7 @@ describe ClassMixedWithDSLHelpers do
|
|
575
631
|
|
576
632
|
describe '#stub_hosts_on' do
|
577
633
|
it 'executes puppet on the host passed and ensures it is reverted' do
|
634
|
+
subject.stub( :hosts ).and_return( hosts )
|
578
635
|
logger = double.as_null_object
|
579
636
|
|
580
637
|
subject.stub( :logger ).and_return( logger )
|
@@ -589,7 +646,7 @@ describe ClassMixedWithDSLHelpers do
|
|
589
646
|
'puppetlabs.com',
|
590
647
|
'ensure=absent' )
|
591
648
|
|
592
|
-
subject.stub_hosts_on( 'my_host', 'puppetlabs.com' => '127.0.0.1' )
|
649
|
+
subject.stub_hosts_on( make_host('my_host', {}), 'puppetlabs.com' => '127.0.0.1' )
|
593
650
|
end
|
594
651
|
end
|
595
652
|
|
@@ -606,15 +663,16 @@ describe ClassMixedWithDSLHelpers do
|
|
606
663
|
|
607
664
|
describe '#stub_forge_on' do
|
608
665
|
it 'stubs forge.puppetlabs.com with the value of `forge`' do
|
609
|
-
subject.stub( :
|
666
|
+
subject.stub( :hosts ).and_return( hosts )
|
667
|
+
host = make_host('my_host', {})
|
610
668
|
Resolv.should_receive( :getaddress ).
|
611
669
|
with( 'my_forge.example.com' ).and_return( '127.0.0.1' )
|
612
670
|
subject.should_receive( :stub_hosts_on ).
|
613
|
-
with(
|
671
|
+
with( host, 'forge.puppetlabs.com' => '127.0.0.1' )
|
614
672
|
subject.should_receive( :stub_hosts_on ).
|
615
|
-
with(
|
673
|
+
with( host, 'forgeapi.puppetlabs.com' => '127.0.0.1' )
|
616
674
|
|
617
|
-
subject.stub_forge_on(
|
675
|
+
subject.stub_forge_on( host, 'my_forge.example.com' )
|
618
676
|
end
|
619
677
|
end
|
620
678
|
|
@@ -675,6 +733,7 @@ describe ClassMixedWithDSLHelpers do
|
|
675
733
|
deb_agent = make_host( 'deb', :platform => 'debian-7-amd64' )
|
676
734
|
deb_agent.stub( :puppet ).and_return( { 'vardir' => vardir } )
|
677
735
|
|
736
|
+
subject.stub( :hosts ).and_return( hosts )
|
678
737
|
subject.should_receive( :on ).with( deb_agent, "[ -e '#{vardir}/state/agent_catalog_run.lock' ]", :acceptable_exit_codes => [0,1] ).once.and_return( result_fail )
|
679
738
|
subject.should_receive( :on ).with( deb_agent, "[ -e /etc/init.d/pe-puppet-agent ]", :acceptable_exit_codes => [0,1] ).once.and_return( result_fail )
|
680
739
|
subject.should_receive( :puppet_resource ).with( "service", "pe-puppet", "ensure=stopped").once
|
@@ -689,6 +748,7 @@ describe ClassMixedWithDSLHelpers do
|
|
689
748
|
el_agent = make_host( 'el', :platform => 'el-5-x86_64' )
|
690
749
|
el_agent.stub( :puppet ).and_return( { 'vardir' => vardir } )
|
691
750
|
|
751
|
+
subject.stub( :hosts ).and_return( hosts )
|
692
752
|
subject.should_receive( :on ).with( el_agent, "[ -e '#{vardir}/state/agent_catalog_run.lock' ]", :acceptable_exit_codes => [0,1] ).once.and_return( result_fail )
|
693
753
|
subject.should_receive( :on ).with( el_agent, "[ -e /etc/init.d/pe-puppet-agent ]", :acceptable_exit_codes => [0,1] ).once.and_return( result_pass )
|
694
754
|
subject.should_receive( :puppet_resource ).with("service", "pe-puppet-agent", "ensure=stopped").once
|
@@ -760,16 +820,14 @@ describe ClassMixedWithDSLHelpers do
|
|
760
820
|
describe '#with_puppet_running_on' do
|
761
821
|
let(:test_case_path) { 'testcase/path' }
|
762
822
|
let(:tmpdir_path) { '/tmp/tmpdir' }
|
763
|
-
let(:puppet_path) { '/puppet/path' }
|
764
|
-
let(:puppetservice) { nil }
|
765
823
|
let(:is_pe) { false }
|
824
|
+
let(:use_service) { false }
|
825
|
+
let(:platform) { 'redhat' }
|
766
826
|
let(:host) do
|
767
|
-
FakeHost.
|
768
|
-
|
769
|
-
'
|
770
|
-
|
771
|
-
'platform' => 'el'
|
772
|
-
})
|
827
|
+
FakeHost.create('fakevm', "#{platform}-version-arch",
|
828
|
+
'type' => is_pe ? 'pe': 'git',
|
829
|
+
'use-service' => use_service
|
830
|
+
)
|
773
831
|
end
|
774
832
|
|
775
833
|
def stub_host_and_subject_to_allow_the_default_testdir_argument_to_be_created
|
@@ -781,6 +839,7 @@ describe ClassMixedWithDSLHelpers do
|
|
781
839
|
|
782
840
|
before do
|
783
841
|
stub_host_and_subject_to_allow_the_default_testdir_argument_to_be_created
|
842
|
+
subject.stub(:curl_with_retries)
|
784
843
|
end
|
785
844
|
|
786
845
|
it "raises an ArgumentError if you try to submit a String instead of a Hash of options" do
|
@@ -794,37 +853,150 @@ describe ClassMixedWithDSLHelpers do
|
|
794
853
|
}.to raise_error(RuntimeError, /puppet conf backup failed/)
|
795
854
|
end
|
796
855
|
|
856
|
+
describe 'with jvm puppet' do
|
857
|
+
let(:default_confdir) { "/etc/puppet" }
|
858
|
+
let(:default_vardir) { "/var/lib/puppet" }
|
859
|
+
|
860
|
+
let(:custom_confdir) { "/tmp/etc/puppet" }
|
861
|
+
let(:custom_vardir) { "/tmp/var/lib/puppet" }
|
862
|
+
|
863
|
+
let(:command_line_args) {"--vardir=#{custom_vardir} --confdir=#{custom_confdir}"}
|
864
|
+
let(:conf_opts) { {:__commandline_args__ => command_line_args,
|
865
|
+
:is_jvm_puppet => true}}
|
866
|
+
|
867
|
+
let(:default_jvm_puppet_opts) {{ "jruby-puppet" => {
|
868
|
+
"master-conf-dir" => default_confdir,
|
869
|
+
"master-var-dir" => default_vardir,
|
870
|
+
}}}
|
871
|
+
|
872
|
+
let(:custom_jvm_puppet_opts) {{ "jruby-puppet" => {
|
873
|
+
"master-conf-dir" => custom_confdir,
|
874
|
+
"master-var-dir" => custom_vardir,
|
875
|
+
}}}
|
876
|
+
|
877
|
+
let(:jvm_puppet_conf) { "/etc/jvm-puppet/conf.d/jvm-puppet.conf" }
|
878
|
+
let(:logger) { double }
|
879
|
+
|
880
|
+
def stub_post_setup
|
881
|
+
subject.stub( :restore_puppet_conf_from_backup)
|
882
|
+
subject.stub( :bounce_service)
|
883
|
+
subject.stub( :stop_puppet_from_source_on)
|
884
|
+
subject.stub( :dump_puppet_log)
|
885
|
+
subject.stub( :restore_puppet_conf_from_backup)
|
886
|
+
subject.stub( :puppet_master_started)
|
887
|
+
subject.stub( :start_puppet_from_source_on!)
|
888
|
+
subject.stub( :lay_down_new_puppet_conf)
|
889
|
+
subject.stub( :logger) .and_return( logger )
|
890
|
+
logger.stub( :error)
|
891
|
+
logger.stub( :debug)
|
892
|
+
end
|
893
|
+
|
894
|
+
before do
|
895
|
+
stub_post_setup
|
896
|
+
subject.stub( :options) .and_return( {:is_jvm_puppet => true})
|
897
|
+
subject.stub( :modify_tk_config)
|
898
|
+
host.stub(:puppet).with('master') .and_return({'confdir' => default_confdir,
|
899
|
+
'vardir' => default_vardir})
|
900
|
+
end
|
901
|
+
|
902
|
+
describe 'and command line args passed' do
|
903
|
+
it 'modifies SUT trapperkeeper configuration w/ command line args' do
|
904
|
+
subject.should_receive( :modify_tk_config).with(host, jvm_puppet_conf,
|
905
|
+
custom_jvm_puppet_opts)
|
906
|
+
subject.with_puppet_running_on(host, conf_opts)
|
907
|
+
end
|
908
|
+
end
|
909
|
+
|
910
|
+
describe 'and no command line args passed' do
|
911
|
+
let(:command_line_args) { nil }
|
912
|
+
it 'modifies SUT trapperkeeper configuration w/ puppet defaults' do
|
913
|
+
subject.should_receive( :modify_tk_config).with(host, jvm_puppet_conf,
|
914
|
+
default_jvm_puppet_opts)
|
915
|
+
subject.with_puppet_running_on(host, conf_opts)
|
916
|
+
end
|
917
|
+
end
|
918
|
+
end
|
919
|
+
|
797
920
|
describe "with valid arguments" do
|
798
921
|
before do
|
799
922
|
Tempfile.should_receive(:open).with('beaker')
|
800
923
|
end
|
801
924
|
|
802
|
-
context '
|
803
|
-
let(:
|
925
|
+
context 'for pe hosts' do
|
926
|
+
let(:is_pe) { true }
|
927
|
+
let(:service_restart) { true }
|
928
|
+
|
929
|
+
it 'bounces puppet twice' do
|
930
|
+
subject.with_puppet_running_on(host, {})
|
931
|
+
expect(host).to execute_commands_matching(/puppet resource service #{host['puppetservice']}.*ensure=running/).exactly(2).times
|
932
|
+
expect(host).to execute_commands_matching(/puppet resource service #{host['puppetservice']}.*ensure=stopped/).exactly(2).times
|
933
|
+
end
|
934
|
+
|
935
|
+
it 'yields to a block after bouncing service' do
|
936
|
+
execution = 0
|
937
|
+
subject.stub(:curl_with_retries)
|
938
|
+
expect do
|
939
|
+
subject.with_puppet_running_on(host, {}) do
|
940
|
+
expect(host).to execute_commands_matching(/puppet resource service #{host['puppetservice']}.*ensure=running/).exactly(1).times
|
941
|
+
expect(host).to execute_commands_matching(/puppet resource service #{host['puppetservice']}.*ensure=stopped/).exactly(1).times
|
942
|
+
execution += 1
|
943
|
+
end
|
944
|
+
end.to change { execution }.by(1)
|
945
|
+
expect(host).to execute_commands_matching(/puppet resource service #{host['puppetservice']}.*ensure=running/).exactly(2).times
|
946
|
+
expect(host).to execute_commands_matching(/puppet resource service #{host['puppetservice']}.*ensure=stopped/).exactly(2).times
|
947
|
+
end
|
948
|
+
end
|
949
|
+
|
950
|
+
context 'for foss packaged hosts using passenger' do
|
951
|
+
before(:each) do
|
952
|
+
host.uses_passenger!
|
953
|
+
end
|
804
954
|
|
805
955
|
it 'bounces puppet twice' do
|
806
956
|
subject.stub(:curl_with_retries)
|
807
957
|
subject.with_puppet_running_on(host, {})
|
808
|
-
expect(host).to execute_commands_matching(/
|
809
|
-
expect(host).to execute_commands_matching(/puppet resource service #{puppetservice} ensure=running/).exactly(2).times
|
958
|
+
expect(host).to execute_commands_matching(/apache2ctl graceful/).exactly(2).times
|
810
959
|
end
|
811
960
|
|
812
|
-
it '
|
961
|
+
it 'yields to a block after bouncing service' do
|
813
962
|
execution = 0
|
814
963
|
subject.stub(:curl_with_retries)
|
815
964
|
expect do
|
816
965
|
subject.with_puppet_running_on(host, {}) do
|
817
|
-
expect(host).to execute_commands_matching(/
|
818
|
-
expect(host).to execute_commands_matching(/puppet resource service #{puppetservice} ensure=running/).once
|
966
|
+
expect(host).to execute_commands_matching(/apache2ctl graceful/).once
|
819
967
|
execution += 1
|
820
968
|
end
|
821
969
|
end.to change { execution }.by(1)
|
822
|
-
expect(host).to execute_commands_matching(/
|
823
|
-
|
970
|
+
expect(host).to execute_commands_matching(/apache2ctl graceful/).exactly(2).times
|
971
|
+
end
|
972
|
+
end
|
973
|
+
|
974
|
+
context 'for foss packaged hosts using webrick' do
|
975
|
+
let(:use_service) { true }
|
976
|
+
|
977
|
+
it 'stops and starts master using service scripts' do
|
978
|
+
subject.stub(:curl_with_retries)
|
979
|
+
subject.with_puppet_running_on(host, {})
|
980
|
+
expect(host).to execute_commands_matching(/puppet resource service #{host['puppetservice']}.*ensure=running/).exactly(2).times
|
981
|
+
expect(host).to execute_commands_matching(/puppet resource service #{host['puppetservice']}.*ensure=stopped/).exactly(2).times
|
982
|
+
end
|
983
|
+
|
984
|
+
it 'yields to a block after stopping and starting service' do
|
985
|
+
execution = 0
|
986
|
+
expect do
|
987
|
+
subject.with_puppet_running_on(host, {}) do
|
988
|
+
expect(host).to execute_commands_matching(/puppet resource service #{host['puppetservice']}.*ensure=running/).once
|
989
|
+
expect(host).to execute_commands_matching(/puppet resource service #{host['puppetservice']}.*ensure=stopped/).once
|
990
|
+
execution += 1
|
991
|
+
end
|
992
|
+
end.to change { execution }.by(1)
|
993
|
+
expect(host).to execute_commands_matching(/puppet resource service #{host['puppetservice']}.*ensure=running/).exactly(2).times
|
994
|
+
expect(host).to execute_commands_matching(/puppet resource service #{host['puppetservice']}.*ensure=stopped/).exactly(2).times
|
824
995
|
end
|
825
996
|
end
|
826
997
|
|
827
998
|
context 'running from source' do
|
999
|
+
let('use-service') { false }
|
828
1000
|
|
829
1001
|
it 'does not try to stop if not started' do
|
830
1002
|
subject.should_receive(:start_puppet_from_source_on!).and_return false
|
@@ -868,30 +1040,49 @@ describe ClassMixedWithDSLHelpers do
|
|
868
1040
|
end
|
869
1041
|
|
870
1042
|
describe 'backup and restore of puppet.conf' do
|
871
|
-
let(:original_location) { "#{
|
1043
|
+
let(:original_location) { "#{host['puppetpath']}/puppet.conf" }
|
872
1044
|
let(:backup_location) { "#{tmpdir_path}/puppet.conf.bak" }
|
873
1045
|
let(:new_location) { "#{tmpdir_path}/puppet.conf" }
|
874
1046
|
|
875
|
-
|
876
|
-
|
877
|
-
end
|
1047
|
+
context 'when a puppetservice is used' do
|
1048
|
+
let(:use_service) { true }
|
878
1049
|
|
879
|
-
|
880
|
-
|
881
|
-
|
882
|
-
|
1050
|
+
it 'backs up puppet.conf' do
|
1051
|
+
subject.with_puppet_running_on(host, {})
|
1052
|
+
expect(host).to execute_commands_matching(/cp #{original_location} #{backup_location}/).once
|
1053
|
+
expect(host).to execute_commands_matching(/cat #{new_location} > #{original_location}/).once
|
1054
|
+
end
|
883
1055
|
|
1056
|
+
it 'restores puppet.conf before restarting' do
|
1057
|
+
subject.with_puppet_running_on(host, {})
|
1058
|
+
expect(host).to execute_commands_matching_in_order(/cat '#{backup_location}' > '#{original_location}'/,
|
1059
|
+
/ensure=stopped/,
|
1060
|
+
/ensure=running/)
|
1061
|
+
end
|
884
1062
|
end
|
885
1063
|
|
886
|
-
|
887
|
-
|
888
|
-
|
889
|
-
|
1064
|
+
context 'when a puppetservice is not used' do
|
1065
|
+
before do
|
1066
|
+
host.should_receive(:port_open?).with(8140).and_return(true)
|
1067
|
+
end
|
890
1068
|
|
891
|
-
|
892
|
-
|
893
|
-
|
894
|
-
|
1069
|
+
it 'backs up puppet.conf' do
|
1070
|
+
subject.with_puppet_running_on(host, {})
|
1071
|
+
expect(host).to execute_commands_matching(/cp #{original_location} #{backup_location}/).once
|
1072
|
+
expect(host).to execute_commands_matching(/cat #{new_location} > #{original_location}/).once
|
1073
|
+
end
|
1074
|
+
|
1075
|
+
it 'restores puppet.conf after restarting when a puppetservice is not used' do
|
1076
|
+
subject.with_puppet_running_on(host, {})
|
1077
|
+
expect(host).to execute_commands_matching_in_order(/kill [^-]/,
|
1078
|
+
/cat '#{backup_location}' > '#{original_location}'/m)
|
1079
|
+
end
|
1080
|
+
|
1081
|
+
it "doesn't restore a non-existent file" do
|
1082
|
+
subject.stub(:backup_the_file)
|
1083
|
+
subject.with_puppet_running_on(host, {})
|
1084
|
+
expect(host).to execute_commands_matching(/rm -f '#{original_location}'/)
|
1085
|
+
end
|
895
1086
|
end
|
896
1087
|
end
|
897
1088
|
|
@@ -954,11 +1145,24 @@ describe ClassMixedWithDSLHelpers do
|
|
954
1145
|
end
|
955
1146
|
|
956
1147
|
describe '#fact_on' do
|
957
|
-
it '
|
1148
|
+
it 'retrieves a fact on a single host' do
|
1149
|
+
result.stdout = "family\n"
|
958
1150
|
subject.should_receive(:facter).with('osfamily',{}).once
|
959
1151
|
subject.should_receive(:on).and_return(result)
|
960
1152
|
|
961
|
-
subject.fact_on('host','osfamily')
|
1153
|
+
expect( subject.fact_on('host','osfamily') ).to be === result.stdout.chomp
|
1154
|
+
end
|
1155
|
+
|
1156
|
+
it 'retrieves an array of facts from multiple hosts' do
|
1157
|
+
subject.stub( :hosts ).and_return( hosts )
|
1158
|
+
times = hosts.length
|
1159
|
+
result.stdout = "family\n"
|
1160
|
+
hosts.each do |host|
|
1161
|
+
host.should_receive(:exec).and_return(result)
|
1162
|
+
end
|
1163
|
+
|
1164
|
+
expect( subject.fact_on(hosts,'osfamily') ).to be === [result.stdout.chomp] * hosts.length
|
1165
|
+
|
962
1166
|
end
|
963
1167
|
end
|
964
1168
|
|
@@ -971,6 +1175,61 @@ describe ClassMixedWithDSLHelpers do
|
|
971
1175
|
end
|
972
1176
|
end
|
973
1177
|
|
1178
|
+
describe 'modify_tk_config' do
|
1179
|
+
let(:host) { double.as_null_object }
|
1180
|
+
let(:config_file_path) { 'existing-file-path'}
|
1181
|
+
let(:invalid_config_file_path) { 'nonexisting-file-path'}
|
1182
|
+
let(:options_hash) { {:key => 'value'} }
|
1183
|
+
let(:replace) { true }
|
1184
|
+
|
1185
|
+
shared_examples 'modify-tk-config-without-error' do
|
1186
|
+
it 'dumps to the SUT config file path' do
|
1187
|
+
JSON.stub(:dump)
|
1188
|
+
subject.stub(:create_remote_file).with(host, config_file_path, anything())
|
1189
|
+
subject.modify_tk_config(host, config_file_path, options_hash, replace)
|
1190
|
+
end
|
1191
|
+
end
|
1192
|
+
|
1193
|
+
before do
|
1194
|
+
host.stub(:file_exist?).with(invalid_config_file_path).and_return(false)
|
1195
|
+
host.stub(:file_exist?).with(config_file_path).and_return(true)
|
1196
|
+
end
|
1197
|
+
|
1198
|
+
describe 'if file does not exist on SUT' do
|
1199
|
+
it 'raises Runtime error' do
|
1200
|
+
expect do
|
1201
|
+
subject.modify_tk_config(host, invalid_config_file_path, options_hash)
|
1202
|
+
end.to raise_error(RuntimeError, /.* does not exist on .*/)
|
1203
|
+
end
|
1204
|
+
end
|
1205
|
+
|
1206
|
+
describe 'given an empty options hash' do
|
1207
|
+
it 'returns nil' do
|
1208
|
+
expect(subject.modify_tk_config(host, 'blahblah', {})).to eq(nil)
|
1209
|
+
end
|
1210
|
+
end
|
1211
|
+
|
1212
|
+
describe 'given a non-empty options hash' do
|
1213
|
+
|
1214
|
+
describe 'given a false value to its `replace` parameter' do
|
1215
|
+
let(:replace) { false }
|
1216
|
+
before do
|
1217
|
+
subject.should_receive(:read_tk_config_string).with(anything())
|
1218
|
+
end
|
1219
|
+
include_examples('modify-tk-config-without-error')
|
1220
|
+
end
|
1221
|
+
|
1222
|
+
describe 'given a true value to its `replace` parameter' do
|
1223
|
+
before do
|
1224
|
+
JSON.should_receive(:dump)
|
1225
|
+
subject.should_receive(:create_remote_file).with(host, config_file_path, anything())
|
1226
|
+
end
|
1227
|
+
include_examples('modify-tk-config-without-error')
|
1228
|
+
end
|
1229
|
+
|
1230
|
+
end
|
1231
|
+
|
1232
|
+
end
|
974
1233
|
|
975
1234
|
describe 'copy_module_to' do
|
976
1235
|
let(:ignore_list){%w(.git .idea .vagrant .vendor acceptance spec tests log . ..)}
|
@@ -1073,14 +1332,3 @@ describe ClassMixedWithDSLHelpers do
|
|
1073
1332
|
|
1074
1333
|
end
|
1075
1334
|
end
|
1076
|
-
|
1077
|
-
module FakeFS
|
1078
|
-
class File < StringIO
|
1079
|
-
def self.absolute_path(filepath)
|
1080
|
-
RealFile.absolute_path(filepath)
|
1081
|
-
end
|
1082
|
-
def self.expand_path(filepath)
|
1083
|
-
RealFile.expand_path(filepath)
|
1084
|
-
end
|
1085
|
-
end
|
1086
|
-
end
|