beaker 0.0.0 → 1.0.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.
- checksums.yaml +8 -8
- data/.travis.yml +8 -0
- data/README.md +6 -6
- data/beaker.gemspec +6 -2
- data/lib/beaker.rb +1 -1
- data/lib/beaker/answers.rb +34 -7
- data/lib/beaker/answers/version20.rb +124 -0
- data/lib/beaker/answers/version28.rb +21 -0
- data/lib/beaker/answers/version30.rb +24 -5
- data/lib/beaker/cli.rb +55 -41
- data/lib/beaker/command.rb +2 -2
- data/lib/beaker/dsl/helpers.rb +320 -106
- data/lib/beaker/dsl/install_utils.rb +202 -81
- data/lib/beaker/dsl/roles.rb +40 -0
- data/lib/beaker/host.rb +28 -20
- data/lib/beaker/host/unix.rb +7 -4
- data/lib/beaker/host/unix/pkg.rb +42 -12
- data/lib/beaker/host/windows.rb +9 -5
- data/lib/beaker/host/windows/group.rb +1 -1
- data/lib/beaker/host/windows/pkg.rb +41 -8
- data/lib/beaker/hypervisor.rb +23 -10
- data/lib/beaker/hypervisor/aixer.rb +15 -19
- data/lib/beaker/hypervisor/blimper.rb +71 -72
- data/lib/beaker/hypervisor/fusion.rb +11 -10
- data/lib/beaker/hypervisor/solaris.rb +17 -23
- data/lib/beaker/hypervisor/vagrant.rb +27 -12
- data/lib/beaker/hypervisor/vcloud.rb +154 -138
- data/lib/beaker/hypervisor/vcloud_pooled.rb +97 -0
- data/lib/beaker/hypervisor/vsphere.rb +8 -5
- data/lib/beaker/hypervisor/vsphere_helper.rb +43 -33
- data/lib/beaker/network_manager.rb +16 -12
- data/lib/beaker/options/command_line_parser.rb +199 -0
- data/lib/beaker/options/hosts_file_parser.rb +39 -0
- data/lib/beaker/options/options_file_parser.rb +45 -0
- data/lib/beaker/options/options_hash.rb +294 -0
- data/lib/beaker/options/parser.rb +288 -0
- data/lib/beaker/options/pe_version_scraper.rb +35 -0
- data/lib/beaker/options/presets.rb +70 -0
- data/lib/beaker/shared.rb +2 -1
- data/lib/beaker/shared/host_handler.rb +7 -2
- data/lib/beaker/shared/repetition.rb +1 -0
- data/lib/beaker/shared/timed.rb +14 -0
- data/lib/beaker/test_case.rb +2 -38
- data/lib/beaker/test_suite.rb +11 -25
- data/lib/beaker/utils/repo_control.rb +6 -8
- data/lib/beaker/utils/setup_helper.rb +9 -20
- data/spec/beaker/answers_spec.rb +109 -0
- data/spec/beaker/command_spec.rb +2 -2
- data/spec/beaker/dsl/assertions_spec.rb +1 -3
- data/spec/beaker/dsl/helpers_spec.rb +519 -84
- data/spec/beaker/dsl/install_utils_spec.rb +265 -16
- data/spec/beaker/dsl/roles_spec.rb +31 -10
- data/spec/beaker/host/windows/group_spec.rb +55 -0
- data/spec/beaker/host_spec.rb +130 -40
- data/spec/beaker/hypervisor/aixer_spec.rb +34 -0
- data/spec/beaker/hypervisor/blimper_spec.rb +77 -0
- data/spec/beaker/hypervisor/fusion_spec.rb +26 -0
- data/spec/beaker/hypervisor/hypervisor_spec.rb +66 -0
- data/spec/beaker/hypervisor/solaris_spec.rb +39 -0
- data/spec/beaker/hypervisor/vagrant_spec.rb +105 -0
- data/spec/beaker/hypervisor/vcloud_pooled_spec.rb +60 -0
- data/spec/beaker/hypervisor/vcloud_spec.rb +70 -0
- data/spec/beaker/hypervisor/vsphere_helper_spec.rb +162 -0
- data/spec/beaker/hypervisor/vsphere_spec.rb +76 -0
- data/spec/beaker/options/command_line_parser_spec.rb +25 -0
- data/spec/beaker/options/data/LATEST +1 -0
- data/spec/beaker/options/data/badyaml.cfg +21 -0
- data/spec/beaker/options/data/hosts.cfg +21 -0
- data/spec/beaker/options/data/opts.txt +6 -0
- data/spec/beaker/options/hosts_file_parser_spec.rb +30 -0
- data/spec/beaker/options/options_file_parser_spec.rb +23 -0
- data/spec/beaker/options/options_hash_spec.rb +111 -0
- data/spec/beaker/options/parser_spec.rb +172 -0
- data/spec/beaker/options/pe_version_scaper_spec.rb +15 -0
- data/spec/beaker/options/presets_spec.rb +24 -0
- data/spec/beaker/puppet_command_spec.rb +54 -21
- data/spec/beaker/shared/error_handler_spec.rb +40 -0
- data/spec/beaker/shared/host_handler_spec.rb +104 -0
- data/spec/beaker/shared/repetition_spec.rb +72 -0
- data/spec/beaker/test_suite_spec.rb +3 -16
- data/spec/beaker/utils/ntp_control_spec.rb +42 -0
- data/spec/beaker/utils/repo_control_spec.rb +168 -0
- data/spec/beaker/utils/setup_helper_spec.rb +82 -0
- data/spec/beaker/utils/validator_spec.rb +58 -0
- data/spec/helpers.rb +97 -0
- data/spec/matchers.rb +39 -0
- data/spec/mock_blimpy.rb +48 -0
- data/spec/mock_fission.rb +60 -0
- data/spec/mock_vsphere.rb +310 -0
- data/spec/mock_vsphere_helper.rb +183 -0
- data/spec/mocks.rb +83 -0
- data/spec/spec_helper.rb +8 -1
- metadata +106 -13
- data/beaker.rb +0 -10
- data/lib/beaker/options_parsing.rb +0 -323
- data/lib/beaker/test_config.rb +0 -148
- data/spec/beaker/options_parsing_spec.rb +0 -37
- data/spec/mocks_and_helpers.rb +0 -34
data/spec/beaker/command_spec.rb
CHANGED
|
@@ -19,7 +19,7 @@ module Beaker
|
|
|
19
19
|
|
|
20
20
|
expect( cmd.args_string ).to be == 'to the baz'
|
|
21
21
|
expect( cmd.options_string ).to be == '--foo=bar'
|
|
22
|
-
expect( cmd.environment_string_for(host) ).to be == ''
|
|
22
|
+
expect( cmd.environment_string_for(host, cmd.environment) ).to be == ''
|
|
23
23
|
|
|
24
24
|
end
|
|
25
25
|
|
|
@@ -43,7 +43,7 @@ module Beaker
|
|
|
43
43
|
|
|
44
44
|
describe '#environment_string_for' do
|
|
45
45
|
it 'returns a blank string if theres no env' do
|
|
46
|
-
expect( subject.environment_string_for({}) ).to be == ''
|
|
46
|
+
expect( subject.environment_string_for({}, {}) ).to be == ''
|
|
47
47
|
end
|
|
48
48
|
|
|
49
49
|
it 'takes an env hash with var_name/value pairs' do
|
|
@@ -93,9 +93,7 @@ EXPECT
|
|
|
93
93
|
|
|
94
94
|
result = double
|
|
95
95
|
result.should_receive( :nil? ).at_least( :once ).and_return( false )
|
|
96
|
-
result.should_receive( :
|
|
97
|
-
result.should_receive( :output ).any_number_of_times.and_return( output )
|
|
98
|
-
result.should_receive( :stderr ).any_number_of_times.and_return( stderr )
|
|
96
|
+
result.should_receive( :output ).and_return( output )
|
|
99
97
|
|
|
100
98
|
subject.should_receive( :result ).at_least( :once ).and_return( result )
|
|
101
99
|
expect { subject.assert_output expectation }.to raise_error( exception )
|
|
@@ -2,12 +2,35 @@ require 'spec_helper'
|
|
|
2
2
|
|
|
3
3
|
class ClassMixedWithDSLHelpers
|
|
4
4
|
include Beaker::DSL::Helpers
|
|
5
|
+
include Beaker::DSL::Wrappers
|
|
6
|
+
include Beaker::DSL::Roles
|
|
7
|
+
|
|
8
|
+
def logger
|
|
9
|
+
@logger ||= RSpec::Mocks::Mock.new('logger').as_null_object
|
|
10
|
+
end
|
|
5
11
|
end
|
|
6
12
|
|
|
7
13
|
describe ClassMixedWithDSLHelpers do
|
|
14
|
+
let( :command ) { 'ls' }
|
|
15
|
+
let( :host ) { double.as_null_object }
|
|
16
|
+
let( :result ) { Beaker::Result.new( host, command ) }
|
|
17
|
+
|
|
18
|
+
let( :master ) { make_host( 'master', :roles => %w( master agent ) ) }
|
|
19
|
+
let( :agent ) { make_host( 'agent', :roles => %w( agent ) ) }
|
|
20
|
+
let( :custom ) { make_host( 'custom', :roles => %w( custom agent ) ) }
|
|
21
|
+
let( :dash ) { make_host( 'console', :roles => %w( dashboard agent ) ) }
|
|
22
|
+
let( :db ) { make_host( 'db', :roles => %w( database agent ) ) }
|
|
23
|
+
let( :hosts ) { [ master, agent, dash, db, custom ] }
|
|
24
|
+
|
|
8
25
|
describe '#on' do
|
|
26
|
+
|
|
27
|
+
before :each do
|
|
28
|
+
result.stdout = 'stdout'
|
|
29
|
+
result.stderr = 'stderr'
|
|
30
|
+
result.exit_code = 0
|
|
31
|
+
end
|
|
32
|
+
|
|
9
33
|
it 'allows the environment the command is run within to be specified' do
|
|
10
|
-
host = double.as_null_object
|
|
11
34
|
|
|
12
35
|
Beaker::Command.should_receive( :new ).
|
|
13
36
|
with( 'ls ~/.bin', [], {'ENV' => { :HOME => '/tmp/test_home' }} )
|
|
@@ -15,42 +38,137 @@ describe ClassMixedWithDSLHelpers do
|
|
|
15
38
|
subject.on( host, 'ls ~/.bin', :environment => {:HOME => '/tmp/test_home' } )
|
|
16
39
|
end
|
|
17
40
|
|
|
18
|
-
it '
|
|
19
|
-
hosts
|
|
41
|
+
it 'if the host is a String Object, finds the matching hosts with that String as role' do
|
|
42
|
+
subject.stub( :hosts ).and_return( hosts )
|
|
43
|
+
|
|
44
|
+
master.should_receive( :exec ).once
|
|
45
|
+
|
|
46
|
+
subject.on( 'master', 'echo hello')
|
|
47
|
+
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
it 'if the host is a Symbol Object, finds the matching hsots with that Symbol as role' do
|
|
51
|
+
subject.stub( :hosts ).and_return( hosts )
|
|
20
52
|
|
|
53
|
+
master.should_receive( :exec ).once
|
|
54
|
+
|
|
55
|
+
subject.on( :master, 'echo hello')
|
|
56
|
+
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
it 'delegates to itself for each host passed' do
|
|
60
|
+
expected = []
|
|
21
61
|
hosts.each_with_index do |host, i|
|
|
62
|
+
expected << i
|
|
22
63
|
host.should_receive( :exec ).and_return( i )
|
|
23
64
|
end
|
|
24
65
|
|
|
25
|
-
results = subject.on( hosts,
|
|
26
|
-
expect( results ).to be ==
|
|
66
|
+
results = subject.on( hosts, command )
|
|
67
|
+
expect( results ).to be == expected
|
|
27
68
|
end
|
|
28
69
|
|
|
29
|
-
|
|
30
|
-
|
|
70
|
+
context 'upon command completion' do
|
|
71
|
+
before :each do
|
|
72
|
+
host.should_receive( :exec ).and_return( result )
|
|
73
|
+
@res = subject.on( host, command )
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
it 'returns the result of the action' do
|
|
77
|
+
expect( @res ).to be == result
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
it 'provides access to stdout' do
|
|
81
|
+
expect( @res.stdout ).to be == 'stdout'
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
it 'provides access to stderr' do
|
|
85
|
+
expect( @res.stderr ).to be == 'stderr'
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
it 'provides access to exit_code' do
|
|
89
|
+
expect( @res.exit_code ).to be == 0
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
context 'when passed a block with arity of 1' do
|
|
94
|
+
before :each do
|
|
95
|
+
host.should_receive( :exec ).and_return( result )
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
it 'yields self' do
|
|
99
|
+
subject.on host, command do |containing_class|
|
|
100
|
+
expect( containing_class ).
|
|
101
|
+
to be_an_instance_of( ClassMixedWithDSLHelpers )
|
|
102
|
+
end
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
it 'provides access to stdout' do
|
|
106
|
+
subject.on host, command do |containing_class|
|
|
107
|
+
expect( containing_class.stdout ).to be == 'stdout'
|
|
108
|
+
end
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
it 'provides access to stderr' do
|
|
112
|
+
subject.on host, command do |containing_class|
|
|
113
|
+
expect( containing_class.stderr ).to be == 'stderr'
|
|
114
|
+
end
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
it 'provides access to exit_code' do
|
|
118
|
+
subject.on host, command do |containing_class|
|
|
119
|
+
expect( containing_class.exit_code ).to be == 0
|
|
120
|
+
end
|
|
121
|
+
end
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
context 'when passed a block with arity of 0' do
|
|
125
|
+
before :each do
|
|
126
|
+
host.should_receive( :exec ).and_return( result )
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
it 'yields self' do
|
|
130
|
+
subject.on host, command do
|
|
131
|
+
expect( subject ).
|
|
132
|
+
to be_an_instance_of( ClassMixedWithDSLHelpers )
|
|
133
|
+
end
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
it 'provides access to stdout' do
|
|
137
|
+
subject.on host, command do
|
|
138
|
+
expect( subject.stdout ).to be == 'stdout'
|
|
139
|
+
end
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
it 'provides access to stderr' do
|
|
143
|
+
subject.on host, command do
|
|
144
|
+
expect( subject.stderr ).to be == 'stderr'
|
|
145
|
+
end
|
|
146
|
+
end
|
|
31
147
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
to
|
|
148
|
+
it 'provides access to exit_code' do
|
|
149
|
+
subject.on host, command do
|
|
150
|
+
expect( subject.exit_code ).to be == 0
|
|
151
|
+
end
|
|
35
152
|
end
|
|
36
153
|
end
|
|
37
154
|
|
|
38
|
-
|
|
39
|
-
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
describe "shell" do
|
|
158
|
+
it 'delegates to #on with the default host' do
|
|
159
|
+
subject.stub( :hosts ).and_return( hosts )
|
|
40
160
|
|
|
41
|
-
|
|
161
|
+
subject.should_receive( :on ).with( master, "echo hello", {}).once
|
|
42
162
|
|
|
43
|
-
|
|
163
|
+
subject.shell( "echo hello" )
|
|
44
164
|
end
|
|
45
165
|
end
|
|
46
166
|
|
|
47
167
|
describe '#scp_from' do
|
|
48
168
|
it 'delegates to the host' do
|
|
49
|
-
|
|
50
|
-
result
|
|
169
|
+
subject.should_receive( :logger ).exactly( hosts.length ).times
|
|
170
|
+
result.should_receive( :log ).exactly( hosts.length ).times
|
|
51
171
|
|
|
52
|
-
subject.should_receive( :logger ).exactly( 3 ).times
|
|
53
|
-
result.should_receive( :log ).exactly( 3 ).times
|
|
54
172
|
hosts.each do |host|
|
|
55
173
|
host.should_receive( :do_scp_from ).and_return( result )
|
|
56
174
|
end
|
|
@@ -61,11 +179,9 @@ describe ClassMixedWithDSLHelpers do
|
|
|
61
179
|
|
|
62
180
|
describe '#scp_to' do
|
|
63
181
|
it 'delegates to the host' do
|
|
64
|
-
|
|
65
|
-
result
|
|
182
|
+
subject.should_receive( :logger ).exactly( hosts.length ).times
|
|
183
|
+
result.should_receive( :log ).exactly( hosts.length ).times
|
|
66
184
|
|
|
67
|
-
subject.should_receive( :logger ).exactly( 3 ).times
|
|
68
|
-
result.should_receive( :log ).exactly( 3 ).times
|
|
69
185
|
hosts.each do |host|
|
|
70
186
|
host.should_receive( :do_scp_to ).and_return( result )
|
|
71
187
|
end
|
|
@@ -76,14 +192,16 @@ describe ClassMixedWithDSLHelpers do
|
|
|
76
192
|
|
|
77
193
|
describe '#create_remote_file' do
|
|
78
194
|
it 'scps the contents passed in to the hosts' do
|
|
79
|
-
hosts = [ 'uno.example.org', 'dos.example.org' ]
|
|
80
195
|
my_opts = { :silent => true }
|
|
81
196
|
tmpfile = double
|
|
82
197
|
|
|
83
198
|
tmpfile.should_receive( :path ).exactly( 2 ).times.
|
|
84
199
|
and_return( '/local/path/to/blah' )
|
|
200
|
+
|
|
85
201
|
Tempfile.should_receive( :open ).and_yield( tmpfile )
|
|
202
|
+
|
|
86
203
|
File.should_receive( :open )
|
|
204
|
+
|
|
87
205
|
subject.should_receive( :scp_to ).
|
|
88
206
|
with( hosts, '/local/path/to/blah', '/remote/path', my_opts )
|
|
89
207
|
|
|
@@ -99,83 +217,84 @@ describe ClassMixedWithDSLHelpers do
|
|
|
99
217
|
end
|
|
100
218
|
end
|
|
101
219
|
|
|
102
|
-
|
|
103
|
-
#
|
|
104
|
-
|
|
105
|
-
#let(:options_param) { Hash.new }
|
|
106
|
-
#let(:path_param) { '/file/path/string' }
|
|
107
|
-
#let(:test_case) do
|
|
108
|
-
# TestCase.new( host_param, logger_param, config_param, options_param, path_param )
|
|
109
|
-
#end
|
|
220
|
+
describe '#run_script' do
|
|
221
|
+
it 'delegates to #run_script_on with the default host' do
|
|
222
|
+
subject.stub( :hosts ).and_return( hosts )
|
|
110
223
|
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
224
|
+
subject.should_receive( :run_script_on ).with( master, "/tmp/test.sh", {}).once
|
|
225
|
+
|
|
226
|
+
subject.run_script( '/tmp/test.sh' )
|
|
227
|
+
end
|
|
228
|
+
end
|
|
116
229
|
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
with( 'No suitable hosts found' )
|
|
230
|
+
describe 'confine' do
|
|
231
|
+
let(:logger) { double.as_null_object }
|
|
232
|
+
before do
|
|
233
|
+
subject.stub( :logger ).and_return( logger )
|
|
234
|
+
end
|
|
123
235
|
|
|
124
|
-
|
|
125
|
-
|
|
236
|
+
it 'skips the test if there are no applicable hosts' do
|
|
237
|
+
subject.stub( :hosts ).and_return( [] )
|
|
238
|
+
subject.stub( :hosts= )
|
|
239
|
+
logger.should_receive( :warn )
|
|
240
|
+
subject.should_receive( :skip_test ).
|
|
241
|
+
with( 'No suitable hosts found' )
|
|
126
242
|
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
subject.should_receive( :hosts= ).any_number_of_times
|
|
243
|
+
subject.confine( :to, {} )
|
|
244
|
+
end
|
|
130
245
|
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
end
|
|
246
|
+
it 'raises when given mode is not :to or :except' do
|
|
247
|
+
subject.stub( :hosts )
|
|
248
|
+
subject.stub( :hosts= )
|
|
135
249
|
|
|
136
|
-
|
|
137
|
-
|
|
250
|
+
expect {
|
|
251
|
+
subject.confine( :regardless, {:thing => 'value'} )
|
|
252
|
+
}.to raise_error( 'Unknown option regardless' )
|
|
253
|
+
end
|
|
138
254
|
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
with( [ {'thing' => 'foo'} ] )
|
|
255
|
+
it 'rejects hosts that do not meet simple hash criteria' do
|
|
256
|
+
hosts = [ {'thing' => 'foo'}, {'thing' => 'bar'} ]
|
|
142
257
|
|
|
143
|
-
|
|
144
|
-
|
|
258
|
+
subject.should_receive( :hosts ).and_return( hosts )
|
|
259
|
+
subject.should_receive( :hosts= ).
|
|
260
|
+
with( [ {'thing' => 'foo'} ] )
|
|
145
261
|
|
|
146
|
-
|
|
147
|
-
|
|
262
|
+
subject.confine :to, :thing => 'foo'
|
|
263
|
+
end
|
|
148
264
|
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
with( [ {'thing' => 'bar'} ] )
|
|
265
|
+
it 'rejects hosts that match a list of criteria' do
|
|
266
|
+
hosts = [ {'thing' => 'foo'}, {'thing' => 'bar'}, {'thing' => 'baz'} ]
|
|
152
267
|
|
|
153
|
-
|
|
154
|
-
|
|
268
|
+
subject.should_receive( :hosts ).and_return( hosts )
|
|
269
|
+
subject.should_receive( :hosts= ).
|
|
270
|
+
with( [ {'thing' => 'bar'} ] )
|
|
155
271
|
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
host2 = {'platform' => 'solaris'}
|
|
159
|
-
host3 = {'platform' => 'windows'}
|
|
160
|
-
ret1 = (Struct.new('Result1', :stdout)).new(':global')
|
|
161
|
-
ret2 = (Struct.new('Result2', :stdout)).new('a_zone')
|
|
162
|
-
hosts = [ host1, host2, host3 ]
|
|
272
|
+
subject.confine :except, :thing => ['foo', 'baz']
|
|
273
|
+
end
|
|
163
274
|
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
275
|
+
it 'rejects hosts when a passed block returns true' do
|
|
276
|
+
host1 = {'platform' => 'solaris'}
|
|
277
|
+
host2 = {'platform' => 'solaris'}
|
|
278
|
+
host3 = {'platform' => 'windows'}
|
|
279
|
+
ret1 = (Struct.new('Result1', :stdout)).new(':global')
|
|
280
|
+
ret2 = (Struct.new('Result2', :stdout)).new('a_zone')
|
|
281
|
+
hosts = [ host1, host2, host3 ]
|
|
171
282
|
|
|
172
|
-
|
|
283
|
+
subject.should_receive( :hosts ).and_return( hosts )
|
|
284
|
+
subject.should_receive( :on ).
|
|
285
|
+
with( host1, '/sbin/zonename' ).
|
|
286
|
+
and_return( ret1 )
|
|
287
|
+
subject.should_receive( :on ).
|
|
288
|
+
with( host1, '/sbin/zonename' ).
|
|
289
|
+
and_return( ret2 )
|
|
173
290
|
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
291
|
+
subject.should_receive( :hosts= ).with( [ host1 ] )
|
|
292
|
+
|
|
293
|
+
subject.confine :to, :platform => 'solaris' do |host|
|
|
294
|
+
subject.on( host, '/sbin/zonename' ).stdout =~ /:global/
|
|
177
295
|
end
|
|
178
296
|
end
|
|
297
|
+
end
|
|
179
298
|
|
|
180
299
|
describe '#apply_manifest_on' do
|
|
181
300
|
it 'allows acceptable exit codes through :catch_failures' do
|
|
@@ -196,11 +315,22 @@ describe ClassMixedWithDSLHelpers do
|
|
|
196
315
|
end
|
|
197
316
|
end
|
|
198
317
|
|
|
318
|
+
describe "#apply_manifest" do
|
|
319
|
+
it "delegates to #apply_manifest_on with the default host" do
|
|
320
|
+
subject.stub( :hosts ).and_return( hosts )
|
|
321
|
+
|
|
322
|
+
subject.should_receive( :apply_manifest_on ).with( master, 'manifest', {:opt => 'value'}).once
|
|
323
|
+
|
|
324
|
+
subject.apply_manifest( 'manifest', {:opt => 'value'} )
|
|
325
|
+
|
|
326
|
+
end
|
|
327
|
+
end
|
|
328
|
+
|
|
199
329
|
describe '#stub_hosts_on' do
|
|
200
330
|
it 'executes puppet on the host passed and ensures it is reverted' do
|
|
201
331
|
logger = double.as_null_object
|
|
202
332
|
|
|
203
|
-
subject.
|
|
333
|
+
subject.stub( :logger ).and_return( logger )
|
|
204
334
|
subject.should_receive( :on ).twice
|
|
205
335
|
subject.should_receive( :teardown ).and_yield
|
|
206
336
|
subject.should_receive( :puppet ).once.
|
|
@@ -216,6 +346,17 @@ describe ClassMixedWithDSLHelpers do
|
|
|
216
346
|
end
|
|
217
347
|
end
|
|
218
348
|
|
|
349
|
+
describe "#stub_hosts" do
|
|
350
|
+
it "delegates to #stub_hosts_on with the default host" do
|
|
351
|
+
subject.stub( :hosts ).and_return( hosts )
|
|
352
|
+
|
|
353
|
+
subject.should_receive( :stub_hosts_on ).with( master, 'ipspec' ).once
|
|
354
|
+
|
|
355
|
+
subject.stub_hosts( 'ipspec' )
|
|
356
|
+
|
|
357
|
+
end
|
|
358
|
+
end
|
|
359
|
+
|
|
219
360
|
describe '#stub_forge_on' do
|
|
220
361
|
it 'stubs forge.puppetlabs.com with the value of `forge`' do
|
|
221
362
|
subject.should_receive( :forge ).and_return( 'my_forge.example.com' )
|
|
@@ -227,4 +368,298 @@ describe ClassMixedWithDSLHelpers do
|
|
|
227
368
|
subject.stub_forge_on( 'my_host' )
|
|
228
369
|
end
|
|
229
370
|
end
|
|
371
|
+
|
|
372
|
+
describe "#stub_forge" do
|
|
373
|
+
it "delegates to #stub_forge_on with the default host" do
|
|
374
|
+
subject.stub( :hosts ).and_return( hosts )
|
|
375
|
+
|
|
376
|
+
subject.should_receive( :stub_forge_on ).with( master ).once
|
|
377
|
+
|
|
378
|
+
subject.stub_forge( )
|
|
379
|
+
|
|
380
|
+
end
|
|
381
|
+
end
|
|
382
|
+
|
|
383
|
+
describe "#stop_agent_on" do
|
|
384
|
+
let( :result_fail ) { Beaker::Result.new( [], "" ) }
|
|
385
|
+
let( :result_pass ) { Beaker::Result.new( [], "" ) }
|
|
386
|
+
before :each do
|
|
387
|
+
subject.stub( :sleep ).and_return( true )
|
|
388
|
+
result_fail.stdout = 'stdout'
|
|
389
|
+
result_fail.stderr = 'stderr'
|
|
390
|
+
result_fail.exit_code = 1
|
|
391
|
+
result_pass.stdout = 'stdout'
|
|
392
|
+
result_pass.stderr = 'stderr'
|
|
393
|
+
result_pass.exit_code = 0
|
|
394
|
+
end
|
|
395
|
+
|
|
396
|
+
it 'runs the correct command on solaris' do
|
|
397
|
+
vardir = '/var'
|
|
398
|
+
solaris_agent = make_host( 'solaris', :platform => 'solaris' )
|
|
399
|
+
solaris_agent.stub( :puppet ).and_return( { 'vardir' => vardir } )
|
|
400
|
+
|
|
401
|
+
subject.should_receive( :on ).with( solaris_agent, "[ -e '#{vardir}/state/agent_catalog_run.lock' ]", :acceptable_exit_codes => [0,1] ).once.and_return( result_fail )
|
|
402
|
+
subject.should_receive( :on ).with( solaris_agent, '/usr/sbin/svcadm disable -s svc:/network/pe-puppet:default' ).once
|
|
403
|
+
|
|
404
|
+
subject.stop_agent_on( solaris_agent )
|
|
405
|
+
|
|
406
|
+
end
|
|
407
|
+
|
|
408
|
+
it 'runs the correct command on aix' do
|
|
409
|
+
vardir = '/var'
|
|
410
|
+
aix_agent = make_host( 'aix', :platform => 'aix' )
|
|
411
|
+
aix_agent.stub( :puppet ).and_return( { 'vardir' => vardir } )
|
|
412
|
+
|
|
413
|
+
subject.should_receive( :on ).with( aix_agent, "[ -e '#{vardir}/state/agent_catalog_run.lock' ]", :acceptable_exit_codes => [0,1] ).once.and_return( result_fail )
|
|
414
|
+
subject.should_receive( :on ).with( aix_agent, '/usr/bin/stopsrc -s pe-puppet' ).once
|
|
415
|
+
|
|
416
|
+
subject.stop_agent_on( aix_agent )
|
|
417
|
+
|
|
418
|
+
end
|
|
419
|
+
|
|
420
|
+
it 'runs the correct command on windows' do
|
|
421
|
+
vardir = '/var'
|
|
422
|
+
win_agent = make_host( 'win', :platform => 'windows' )
|
|
423
|
+
win_agent.stub( :puppet ).and_return( { 'vardir' => vardir } )
|
|
424
|
+
|
|
425
|
+
subject.should_receive( :on ).with( win_agent, "[ -e '#{vardir}/state/agent_catalog_run.lock' ]", :acceptable_exit_codes => [0,1] ).once.and_return( result_fail )
|
|
426
|
+
subject.should_receive( :on ).with( win_agent, 'net stop pe-puppet', :acceptable_exit_codes => [0,2] ).once
|
|
427
|
+
|
|
428
|
+
subject.stop_agent_on( win_agent )
|
|
429
|
+
|
|
430
|
+
end
|
|
431
|
+
|
|
432
|
+
it 'runs the pe-puppet on a unix system without pe-puppet-agent' do
|
|
433
|
+
vardir = '/var'
|
|
434
|
+
deb_agent = make_host( 'deb', :platform => 'debian-7-amd64' )
|
|
435
|
+
deb_agent.stub( :puppet ).and_return( { 'vardir' => vardir } )
|
|
436
|
+
|
|
437
|
+
subject.should_receive( :on ).with( deb_agent, "[ -e '#{vardir}/state/agent_catalog_run.lock' ]", :acceptable_exit_codes => [0,1] ).once.and_return( result_fail )
|
|
438
|
+
subject.should_receive( :on ).with( deb_agent, "[ -e /etc/init.d/pe-puppet-agent ]", :acceptable_exit_codes => [0,1] ).once.and_return( result_fail )
|
|
439
|
+
subject.should_receive( :on ).with( deb_agent, "/etc/init.d/pe-puppet stop" ).once
|
|
440
|
+
|
|
441
|
+
subject.stop_agent_on( deb_agent )
|
|
442
|
+
|
|
443
|
+
end
|
|
444
|
+
|
|
445
|
+
it 'runs the pe-puppet-agent on a unix system with pe-puppet-agent' do
|
|
446
|
+
vardir = '/var'
|
|
447
|
+
el_agent = make_host( 'el', :platform => 'el-5-x86_64' )
|
|
448
|
+
el_agent.stub( :puppet ).and_return( { 'vardir' => vardir } )
|
|
449
|
+
|
|
450
|
+
subject.should_receive( :on ).with( el_agent, "[ -e '#{vardir}/state/agent_catalog_run.lock' ]", :acceptable_exit_codes => [0,1] ).once.and_return( result_fail )
|
|
451
|
+
subject.should_receive( :on ).with( el_agent, "[ -e /etc/init.d/pe-puppet-agent ]", :acceptable_exit_codes => [0,1] ).once.and_return( result_pass )
|
|
452
|
+
subject.should_receive( :on ).with( el_agent, "/etc/init.d/pe-puppet-agent stop" ).once
|
|
453
|
+
|
|
454
|
+
subject.stop_agent_on( el_agent )
|
|
455
|
+
end
|
|
456
|
+
|
|
457
|
+
end
|
|
458
|
+
|
|
459
|
+
describe "#stop_agent" do
|
|
460
|
+
it 'delegates to #stop_agent_on with default host' do
|
|
461
|
+
subject.stub( :hosts ).and_return( hosts )
|
|
462
|
+
|
|
463
|
+
subject.should_receive( :stop_agent_on ).with( master ).once
|
|
464
|
+
|
|
465
|
+
subject.stop_agent( )
|
|
466
|
+
|
|
467
|
+
end
|
|
468
|
+
end
|
|
469
|
+
|
|
470
|
+
describe "#sign_certificate_for" do
|
|
471
|
+
it 'signs certs' do
|
|
472
|
+
subject.stub( :sleep ).and_return( true )
|
|
473
|
+
|
|
474
|
+
result.stdout = "+ \"#{agent}\""
|
|
475
|
+
subject.stub( :hosts ).and_return( hosts )
|
|
476
|
+
|
|
477
|
+
subject.stub( :puppet ) do |arg|
|
|
478
|
+
arg
|
|
479
|
+
end
|
|
480
|
+
|
|
481
|
+
subject.should_receive( :on ).with( master, "cert --sign --all", :acceptable_exit_codes => [0,24]).once
|
|
482
|
+
subject.should_receive( :on ).with( master, "cert --list --all").once.and_return( result )
|
|
483
|
+
|
|
484
|
+
|
|
485
|
+
subject.sign_certificate_for( agent )
|
|
486
|
+
end
|
|
487
|
+
|
|
488
|
+
it 'retries 11 times before quitting' do
|
|
489
|
+
subject.stub( :sleep ).and_return( true )
|
|
490
|
+
|
|
491
|
+
result.stdout = " \"#{agent}\""
|
|
492
|
+
subject.stub( :hosts ).and_return( hosts )
|
|
493
|
+
|
|
494
|
+
subject.stub( :puppet ) do |arg|
|
|
495
|
+
arg
|
|
496
|
+
end
|
|
497
|
+
|
|
498
|
+
subject.should_receive( :on ).with( master, "cert --sign --all", :acceptable_exit_codes => [0,24]).exactly( 11 ).times
|
|
499
|
+
subject.should_receive( :on ).with( master, "cert --list --all").exactly( 11 ).times.and_return( result )
|
|
500
|
+
subject.should_receive( :fail_test ).once
|
|
501
|
+
|
|
502
|
+
subject.sign_certificate_for( agent )
|
|
503
|
+
end
|
|
504
|
+
|
|
505
|
+
end
|
|
506
|
+
|
|
507
|
+
describe "#sign_certificate" do
|
|
508
|
+
it 'delegates to #sign_certificate_for with the default host' do
|
|
509
|
+
subject.stub( :hosts ).and_return( hosts )
|
|
510
|
+
|
|
511
|
+
subject.should_receive( :sign_certificate_for ).with( master ).once
|
|
512
|
+
|
|
513
|
+
subject.sign_certificate( )
|
|
514
|
+
end
|
|
515
|
+
end
|
|
516
|
+
|
|
517
|
+
describe '#with_puppet_running_on' do
|
|
518
|
+
let(:is_pe) { false }
|
|
519
|
+
let(:host) { FakeHost.new(:pe => is_pe) }
|
|
520
|
+
let(:test_case_path) { 'testcase/path' }
|
|
521
|
+
let(:tmpdir_path) { '/tmp/tmpdir' }
|
|
522
|
+
let(:puppet_path) { '/puppet/path' }
|
|
523
|
+
|
|
524
|
+
def stub_host_and_subject_to_allow_the_default_testdir_argument_to_be_created
|
|
525
|
+
subject.instance_variable_set(:@path, test_case_path)
|
|
526
|
+
host.stub(:tmpdir).and_return(tmpdir_path)
|
|
527
|
+
end
|
|
528
|
+
|
|
529
|
+
before do
|
|
530
|
+
stub_host_and_subject_to_allow_the_default_testdir_argument_to_be_created
|
|
531
|
+
host.stub(:[]).and_return(puppet_path)
|
|
532
|
+
end
|
|
533
|
+
|
|
534
|
+
it "raises an ArgumentError if you try to submit a String instead of a Hash of options" do
|
|
535
|
+
expect { subject.with_puppet_running_on(host, '--foo --bar') }.to raise_error(ArgumentError, /conf_opts must be a Hash. You provided a String: '--foo --bar'/)
|
|
536
|
+
end
|
|
537
|
+
|
|
538
|
+
describe "with valid arguments" do
|
|
539
|
+
before do
|
|
540
|
+
Tempfile.should_receive(:open).with('beaker')
|
|
541
|
+
end
|
|
542
|
+
|
|
543
|
+
context 'as pe' do
|
|
544
|
+
let(:is_pe) { true }
|
|
545
|
+
|
|
546
|
+
it 'bounces puppet twice' do
|
|
547
|
+
subject.with_puppet_running_on(host, {})
|
|
548
|
+
expect(host).to execute_commands_matching(/pe-httpd restart/).exactly(2).times
|
|
549
|
+
end
|
|
550
|
+
|
|
551
|
+
it 'yield to a block after bouncing service' do
|
|
552
|
+
execution = 0
|
|
553
|
+
expect do
|
|
554
|
+
subject.with_puppet_running_on(host, {}) do
|
|
555
|
+
expect(host).to execute_commands_matching(/pe-httpd restart/).once
|
|
556
|
+
execution += 1
|
|
557
|
+
end
|
|
558
|
+
end.to change { execution }.by(1)
|
|
559
|
+
expect(host).to execute_commands_matching(/pe-httpd restart/).exactly(2).times
|
|
560
|
+
end
|
|
561
|
+
end
|
|
562
|
+
|
|
563
|
+
context 'running from source' do
|
|
564
|
+
|
|
565
|
+
it 'does not try to stop if not started' do
|
|
566
|
+
subject.should_receive(:start_puppet_from_source_on!).and_return false
|
|
567
|
+
subject.should_not_receive(:stop_puppet_from_source_on)
|
|
568
|
+
|
|
569
|
+
subject.with_puppet_running_on(host, {})
|
|
570
|
+
end
|
|
571
|
+
|
|
572
|
+
context 'successfully' do
|
|
573
|
+
before do
|
|
574
|
+
host.should_receive(:port_open?).with(8140).and_return(true)
|
|
575
|
+
end
|
|
576
|
+
|
|
577
|
+
it 'starts puppet from source' do
|
|
578
|
+
subject.with_puppet_running_on(host, {})
|
|
579
|
+
end
|
|
580
|
+
|
|
581
|
+
it 'stops puppet from source' do
|
|
582
|
+
subject.with_puppet_running_on(host, {})
|
|
583
|
+
expect(host).to execute_commands_matching(/^kill [^-]/).once
|
|
584
|
+
expect(host).to execute_commands_matching(/^kill -0/).once
|
|
585
|
+
end
|
|
586
|
+
|
|
587
|
+
it 'yields between starting and stopping' do
|
|
588
|
+
execution = 0
|
|
589
|
+
expect do
|
|
590
|
+
subject.with_puppet_running_on(host, {}) do
|
|
591
|
+
expect(host).to execute_commands_matching(/^puppet master/).once
|
|
592
|
+
execution += 1
|
|
593
|
+
end
|
|
594
|
+
end.to change { execution }.by(1)
|
|
595
|
+
expect(host).to execute_commands_matching(/^kill [^-]/).once
|
|
596
|
+
expect(host).to execute_commands_matching(/^kill -0/).once
|
|
597
|
+
end
|
|
598
|
+
|
|
599
|
+
it 'passes on commandline args' do
|
|
600
|
+
subject.with_puppet_running_on(host, {:__commandline_args__ => '--with arg'})
|
|
601
|
+
expect(host).to execute_commands_matching(/^puppet master --with arg/).once
|
|
602
|
+
end
|
|
603
|
+
end
|
|
604
|
+
end
|
|
605
|
+
|
|
606
|
+
describe 'backup and restore of puppet.conf' do
|
|
607
|
+
let(:original_location) { "#{puppet_path}/puppet.conf" }
|
|
608
|
+
let(:backup_location) { "#{tmpdir_path}/puppet.conf.bak" }
|
|
609
|
+
let(:new_location) { "#{tmpdir_path}/puppet.conf" }
|
|
610
|
+
|
|
611
|
+
before do
|
|
612
|
+
host.should_receive(:port_open?).with(8140).and_return(true)
|
|
613
|
+
end
|
|
614
|
+
|
|
615
|
+
it 'backs up puppet.conf' do
|
|
616
|
+
subject.with_puppet_running_on(host, {})
|
|
617
|
+
expect(host).to execute_commands_matching(/cp #{original_location} #{backup_location}/).once
|
|
618
|
+
expect(host).to execute_commands_matching(/cat #{new_location} > #{original_location}/).once
|
|
619
|
+
|
|
620
|
+
end
|
|
621
|
+
|
|
622
|
+
it 'restores puppet.conf' do
|
|
623
|
+
subject.with_puppet_running_on(host, {})
|
|
624
|
+
expect(host).to execute_commands_matching(/cat '#{backup_location}' > '#{original_location}'/).once
|
|
625
|
+
end
|
|
626
|
+
end
|
|
627
|
+
|
|
628
|
+
describe 'handling failures' do
|
|
629
|
+
before do
|
|
630
|
+
subject.should_receive(:stop_puppet_from_source_on).and_raise(RuntimeError.new('Also failed in teardown.'))
|
|
631
|
+
end
|
|
632
|
+
|
|
633
|
+
it 'does not swallow an exception raised from within test block if ensure block also fails' do
|
|
634
|
+
host.should_receive(:port_open?).with(8140).and_return(true)
|
|
635
|
+
|
|
636
|
+
subject.logger.should_receive(:error).with(/Raised during attempt to teardown.*Also failed in teardown/)
|
|
637
|
+
|
|
638
|
+
expect do
|
|
639
|
+
subject.with_puppet_running_on(host, {}) { raise 'Failed while yielding.' }
|
|
640
|
+
end.to raise_error(RuntimeError, /failed.*because.*Failed while yielding./)
|
|
641
|
+
end
|
|
642
|
+
|
|
643
|
+
it 'does not swallow a teardown exception if no earlier exception was raised' do
|
|
644
|
+
host.should_receive(:port_open?).with(8140).and_return(true)
|
|
645
|
+
subject.logger.should_not_receive(:error)
|
|
646
|
+
expect do
|
|
647
|
+
subject.with_puppet_running_on(host, {})
|
|
648
|
+
end.to raise_error(RuntimeError, 'Also failed in teardown.')
|
|
649
|
+
end
|
|
650
|
+
end
|
|
651
|
+
end
|
|
652
|
+
end
|
|
653
|
+
|
|
654
|
+
describe '#with_puppet_running' do
|
|
655
|
+
it 'delegates to #with_puppet_running_on with the default host' do
|
|
656
|
+
subject.stub( :hosts ).and_return( hosts )
|
|
657
|
+
|
|
658
|
+
subject.should_receive( :with_puppet_running_on ).with( master, {:opt => 'value'}, '/dir').once
|
|
659
|
+
|
|
660
|
+
subject.with_puppet_running( {:opt => 'value'}, '/dir' )
|
|
661
|
+
|
|
662
|
+
|
|
663
|
+
end
|
|
664
|
+
end
|
|
230
665
|
end
|