beaker-pe 0.1.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.
@@ -0,0 +1,35 @@
1
+ require 'open-uri'
2
+ module Beaker
3
+ module Options
4
+ #A set of functions to determine the PE version to use during testing
5
+ module PEVersionScraper
6
+ # Scrape the PE version (such as 3.0) from the file at dist_dir/version_file
7
+ #
8
+ # Version file is of the format
9
+ #
10
+ # 3.0.1-3-g57b669e
11
+ #
12
+ # @param [String] dist_dir The directory containing the version_file
13
+ # @param [String] version_file The file to scrape
14
+ #
15
+ # @return [String, nil] The PE version in the version_file or nil if not found
16
+ # @raise [ArgumentError] Raises if version_file does not exist or cannot be opened
17
+ def self.load_pe_version dist_dir, version_file
18
+ version = nil
19
+ begin
20
+ open("#{dist_dir}/#{version_file}") do |file|
21
+ while line = file.gets
22
+ if /(\w.*)/ =~ line then
23
+ version = $1.strip
24
+ end
25
+ end
26
+ end
27
+ rescue Errno::ENOENT, OpenURI::HTTPError => e
28
+ raise ArgumentError, "Failure to examine #{dist_dir}/#{version_file}\n\t\t#{e.to_s}"
29
+ end
30
+ return version
31
+ end
32
+
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,11 @@
1
+ module Beaker
2
+ module DSL
3
+ module PE
4
+
5
+ module Version
6
+ STRING = '0.1.0'
7
+ end
8
+
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,21 @@
1
+ require 'spec_helper'
2
+
3
+ class ClassMixedWithDSLHelpers
4
+ include Beaker::DSL::PE
5
+
6
+ def logger
7
+ RSpec::Mocks::Double.new('logger').as_null_object
8
+ end
9
+
10
+ end
11
+
12
+ describe ClassMixedWithDSLHelpers do
13
+
14
+ describe 'release conditions' do
15
+
16
+ it 'has updated the version number from the original template' do
17
+ expect( Beaker::DSL::PE::Version::STRING ).to_not be === '0.0.1rc0'
18
+ end
19
+
20
+ end
21
+ end
@@ -0,0 +1,916 @@
1
+ require 'spec_helper'
2
+ require 'beaker'
3
+
4
+ class ClassMixedWithDSLInstallUtils
5
+ include Beaker::DSL::InstallUtils
6
+ include Beaker::DSL::Wrappers
7
+ include Beaker::DSL::Helpers
8
+ include Beaker::DSL::Structure
9
+ include Beaker::DSL::Roles
10
+ include Beaker::DSL::Patterns
11
+ include Beaker::DSL::PE
12
+
13
+ attr_accessor :hosts
14
+
15
+ def logger
16
+ @logger ||= RSpec::Mocks::Double.new('logger').as_null_object
17
+ end
18
+ end
19
+
20
+ describe ClassMixedWithDSLInstallUtils do
21
+ let(:presets) { Beaker::Options::Presets.new }
22
+ let(:opts) { presets.presets.merge(presets.env_vars) }
23
+ let(:basic_hosts) { make_hosts( { :pe_ver => '3.0',
24
+ :platform => 'linux',
25
+ :roles => [ 'agent' ],
26
+ :type => 'pe'}, 4 ) }
27
+ let(:hosts) { basic_hosts[0][:roles] = ['master', 'database', 'dashboard']
28
+ basic_hosts[1][:platform] = 'windows'
29
+ basic_hosts[2][:platform] = 'osx-10.9-x86_64'
30
+ basic_hosts[3][:platform] = 'eos'
31
+ basic_hosts }
32
+ let(:hosts_sorted) { [ hosts[1], hosts[0], hosts[2], hosts[3] ] }
33
+ let(:winhost) { make_host( 'winhost', { :platform => 'windows',
34
+ :pe_ver => '3.0',
35
+ :type => 'pe',
36
+ :working_dir => '/tmp' } ) }
37
+ let(:machost) { make_host( 'machost', { :platform => 'osx-10.9-x86_64',
38
+ :pe_ver => '3.0',
39
+ :type => 'pe',
40
+ :working_dir => '/tmp' } ) }
41
+ let(:unixhost) { make_host( 'unixhost', { :platform => 'linux',
42
+ :pe_ver => '3.0',
43
+ :type => 'pe',
44
+ :working_dir => '/tmp',
45
+ :dist => 'puppet-enterprise-3.1.0-rc0-230-g36c9e5c-debian-7-i386' } ) }
46
+ let(:eoshost) { make_host( 'eoshost', { :platform => 'eos',
47
+ :pe_ver => '3.0',
48
+ :type => 'pe',
49
+ :working_dir => '/tmp',
50
+ :dist => 'puppet-enterprise-3.7.1-rc0-78-gffc958f-eos-4-i386' } ) }
51
+ context '#configure_pe_defaults_on' do
52
+ it 'uses aio paths for hosts of role aio' do
53
+ hosts.each do |host|
54
+ host[:pe_ver] = nil
55
+ host[:version] = nil
56
+ host[:roles] = host[:roles] | ['aio']
57
+ end
58
+ expect(subject).to receive(:add_pe_defaults_on).exactly(hosts.length).times
59
+ expect(subject).to receive(:add_aio_defaults_on).exactly(hosts.length).times
60
+ expect(subject).to receive(:add_puppet_paths_on).exactly(hosts.length).times
61
+
62
+ subject.configure_pe_defaults_on( hosts )
63
+ end
64
+
65
+ it 'uses pe paths for hosts of type pe' do
66
+ hosts.each do |host|
67
+ host[:type] = 'pe'
68
+ end
69
+ expect(subject).to receive(:add_pe_defaults_on).exactly(hosts.length).times
70
+ expect(subject).to receive(:add_aio_defaults_on).never
71
+ expect(subject).to receive(:add_puppet_paths_on).exactly(hosts.length).times
72
+
73
+ subject.configure_pe_defaults_on( hosts )
74
+ end
75
+
76
+ it 'uses aio paths for hosts of type aio' do
77
+ hosts.each do |host|
78
+ host[:pe_ver] = nil
79
+ host[:version] = nil
80
+ host[:type] = 'aio'
81
+ end
82
+ expect(subject).to receive(:add_aio_defaults_on).exactly(hosts.length).times
83
+ expect(subject).to receive(:add_puppet_paths_on).exactly(hosts.length).times
84
+
85
+ subject.configure_pe_defaults_on( hosts )
86
+ end
87
+
88
+ it 'uses no paths for hosts with no type' do
89
+ hosts.each do |host|
90
+ host[:type] = nil
91
+ end
92
+ expect(subject).to receive(:add_pe_defaults_on).never
93
+ expect(subject).to receive(:add_aio_defaults_on).never
94
+ expect(subject).to receive(:add_puppet_paths_on).never
95
+
96
+ subject.configure_pe_defaults_on( hosts )
97
+ end
98
+
99
+ it 'uses aio paths for hosts of version >= 4.0' do
100
+ hosts.each do |host|
101
+ host[:pe_ver] = '4.0'
102
+ end
103
+ expect(subject).to receive(:add_pe_defaults_on).exactly(hosts.length).times
104
+ expect(subject).to receive(:add_aio_defaults_on).exactly(hosts.length).times
105
+ expect(subject).to receive(:add_puppet_paths_on).exactly(hosts.length).times
106
+
107
+ subject.configure_pe_defaults_on( hosts )
108
+ end
109
+
110
+ it 'uses pe paths for hosts of version < 4.0' do
111
+ hosts.each do |host|
112
+ host[:pe_ver] = '3.8'
113
+ end
114
+ expect(subject).to receive(:add_pe_defaults_on).exactly(hosts.length).times
115
+ expect(subject).to receive(:add_aio_defaults_on).never
116
+ expect(subject).to receive(:add_puppet_paths_on).exactly(hosts.length).times
117
+
118
+ subject.configure_pe_defaults_on( hosts )
119
+ end
120
+
121
+ end
122
+
123
+ describe 'sorted_hosts' do
124
+ it 'can reorder so that the master comes first' do
125
+ allow( subject ).to receive( :hosts ).and_return( hosts_sorted )
126
+ expect( subject.sorted_hosts ).to be === hosts
127
+ end
128
+
129
+ it 'leaves correctly ordered hosts alone' do
130
+ allow( subject ).to receive( :hosts ).and_return( hosts )
131
+ expect( subject.sorted_hosts ).to be === hosts
132
+ end
133
+
134
+ it 'does not allow nil entries' do
135
+ allow( subject ).to receive( :options ).and_return( { :masterless => true } )
136
+ masterless_host = [basic_hosts[0]]
137
+ allow( subject ).to receive( :hosts ).and_return( masterless_host )
138
+ expect( subject.sorted_hosts ).to be === masterless_host
139
+ end
140
+ end
141
+
142
+ describe 'installer_cmd' do
143
+
144
+ it 'generates a unix PE install command for a unix host' do
145
+ the_host = unixhost.dup
146
+ the_host['pe_installer'] = 'puppet-enterprise-installer'
147
+ expect( subject.installer_cmd( the_host, {} ) ).to be === "cd /tmp/puppet-enterprise-3.1.0-rc0-230-g36c9e5c-debian-7-i386 && ./puppet-enterprise-installer -a /tmp/answers"
148
+ end
149
+
150
+ it 'generates a unix PE frictionless install command for a unix host with role "frictionless"' do
151
+ allow( subject ).to receive( :version_is_less ).and_return( false )
152
+ allow( subject ).to receive( :master ).and_return( 'testmaster' )
153
+ the_host = unixhost.dup
154
+ the_host['pe_installer'] = 'puppet-enterprise-installer'
155
+ the_host['roles'] = ['frictionless']
156
+ expect( subject.installer_cmd( the_host, {} ) ).to be === "cd /tmp && curl --tlsv1 -kO https://testmaster:8140/packages/3.0/install.bash && bash install.bash"
157
+ end
158
+
159
+ it 'generates a unix PE frictionless install command for a unix host with role "frictionless" and "frictionless_options"' do
160
+ allow( subject ).to receive( :version_is_less ).and_return( false )
161
+ allow( subject ).to receive( :master ).and_return( 'testmaster' )
162
+ the_host = unixhost.dup
163
+ the_host['pe_installer'] = 'puppet-enterprise-installer'
164
+ the_host['roles'] = ['frictionless']
165
+ the_host['frictionless_options'] = { 'main' => { 'dns_alt_names' => 'puppet' } }
166
+ expect( subject.installer_cmd( the_host, {} ) ).to be === "cd /tmp && curl --tlsv1 -kO https://testmaster:8140/packages/3.0/install.bash && bash install.bash main:dns_alt_names=puppet"
167
+ end
168
+
169
+ it 'generates a osx PE install command for a osx host' do
170
+ the_host = machost.dup
171
+ the_host['pe_installer'] = 'puppet-enterprise-installer'
172
+ expect( subject.installer_cmd( the_host, {} ) ).to be === "cd /tmp && hdiutil attach .dmg && installer -pkg /Volumes/puppet-enterprise-3.0/puppet-enterprise-installer-3.0.pkg -target /"
173
+ end
174
+
175
+ it 'calls the EOS PE install command for an EOS host' do
176
+ the_host = eoshost.dup
177
+ expect( the_host ).to receive( :install_from_file ).with( /swix$/ )
178
+ subject.installer_cmd( the_host, {} )
179
+ end
180
+
181
+ it 'generates a unix PE install command in verbose for a unix host when pe_debug is enabled' do
182
+ the_host = unixhost.dup
183
+ the_host['pe_installer'] = 'puppet-enterprise-installer'
184
+ the_host[:pe_debug] = true
185
+ expect( subject.installer_cmd( the_host, {} ) ).to be === "cd /tmp/puppet-enterprise-3.1.0-rc0-230-g36c9e5c-debian-7-i386 && ./puppet-enterprise-installer -D -a /tmp/answers"
186
+ end
187
+
188
+ it 'generates a osx PE install command in verbose for a osx host when pe_debug is enabled' do
189
+ the_host = machost.dup
190
+ the_host['pe_installer'] = 'puppet-enterprise-installer'
191
+ the_host[:pe_debug] = true
192
+ expect( subject.installer_cmd( the_host, {} ) ).to be === "cd /tmp && hdiutil attach .dmg && installer -verboseR -pkg /Volumes/puppet-enterprise-3.0/puppet-enterprise-installer-3.0.pkg -target /"
193
+ end
194
+
195
+ it 'generates a unix PE frictionless install command in verbose for a unix host with role "frictionless" and pe_debug is enabled' do
196
+ allow( subject ).to receive( :version_is_less ).and_return( false )
197
+ allow( subject ).to receive( :master ).and_return( 'testmaster' )
198
+ the_host = unixhost.dup
199
+ the_host['pe_installer'] = 'puppet-enterprise-installer'
200
+ the_host['roles'] = ['frictionless']
201
+ the_host[:pe_debug] = true
202
+ expect( subject.installer_cmd( the_host, {} ) ).to be === "cd /tmp && curl --tlsv1 -kO https://testmaster:8140/packages/3.0/install.bash && bash -x install.bash"
203
+ end
204
+
205
+ end
206
+
207
+
208
+ describe 'fetch_pe' do
209
+
210
+ it 'can push a local PE .tar.gz to a host and unpack it' do
211
+ allow( File ).to receive( :directory? ).and_return( true ) #is local
212
+ allow( File ).to receive( :exists? ).and_return( true ) #is a .tar.gz
213
+ unixhost['pe_dir'] = '/local/file/path'
214
+ allow( subject ).to receive( :scp_to ).and_return( true )
215
+
216
+ path = unixhost['pe_dir']
217
+ filename = "#{ unixhost['dist'] }"
218
+ extension = '.tar.gz'
219
+ expect( subject ).to receive( :scp_to ).with( unixhost, "#{ path }/#{ filename }#{ extension }", "#{ unixhost['working_dir'] }/#{ filename }#{ extension }" ).once
220
+ expect( subject ).to receive( :on ).with( unixhost, /gunzip/ ).once
221
+ expect( subject ).to receive( :on ).with( unixhost, /tar -xvf/ ).once
222
+ subject.fetch_pe( [unixhost], {} )
223
+ end
224
+
225
+ it 'can download a PE .tar from a URL to a host and unpack it' do
226
+ allow( File ).to receive( :directory? ).and_return( false ) #is not local
227
+ allow( subject ).to receive( :link_exists? ) do |arg|
228
+ if arg =~ /.tar.gz/ #there is no .tar.gz link, only a .tar
229
+ false
230
+ else
231
+ true
232
+ end
233
+ end
234
+ allow( subject ).to receive( :on ).and_return( true )
235
+
236
+ path = unixhost['pe_dir']
237
+ filename = "#{ unixhost['dist'] }"
238
+ extension = '.tar'
239
+ expect( subject ).to receive( :on ).with( unixhost, "cd #{ unixhost['working_dir'] }; curl #{ path }/#{ filename }#{ extension } | tar -xvf -" ).once
240
+ subject.fetch_pe( [unixhost], {} )
241
+ end
242
+
243
+ it 'can download a PE .tar from a URL to #fetch_and_push_pe' do
244
+ allow( File ).to receive( :directory? ).and_return( false ) #is not local
245
+ allow( subject ).to receive( :link_exists? ) do |arg|
246
+ if arg =~ /.tar.gz/ #there is no .tar.gz link, only a .tar
247
+ false
248
+ else
249
+ true
250
+ end
251
+ end
252
+ allow( subject ).to receive( :on ).and_return( true )
253
+
254
+ path = unixhost['pe_dir']
255
+ filename = "#{ unixhost['dist'] }"
256
+ extension = '.tar'
257
+ expect( subject ).to receive( :fetch_and_push_pe ).with( unixhost, anything, filename, extension ).once
258
+ expect( subject ).to receive( :on ).with( unixhost, "cd #{ unixhost['working_dir'] }; cat #{ filename }#{ extension } | tar -xvf -" ).once
259
+ subject.fetch_pe( [unixhost], {:fetch_local_then_push_to_host => true} )
260
+ end
261
+
262
+ it 'can download a PE .tar.gz from a URL to a host and unpack it' do
263
+ allow( File ).to receive( :directory? ).and_return( false ) #is not local
264
+ allow( subject ).to receive( :link_exists? ).and_return( true ) #is a tar.gz
265
+ allow( subject ).to receive( :on ).and_return( true )
266
+
267
+ path = unixhost['pe_dir']
268
+ filename = "#{ unixhost['dist'] }"
269
+ extension = '.tar.gz'
270
+ expect( subject ).to receive( :on ).with( unixhost, "cd #{ unixhost['working_dir'] }; curl #{ path }/#{ filename }#{ extension } | gunzip | tar -xvf -" ).once
271
+ subject.fetch_pe( [unixhost], {} )
272
+ end
273
+
274
+ it 'can download a PE .tar.gz from a URL to #fetch_and_push_pe' do
275
+ allow( File ).to receive( :directory? ).and_return( false ) #is not local
276
+ allow( subject ).to receive( :link_exists? ).and_return( true ) #is a tar.gz
277
+ allow( subject ).to receive( :on ).and_return( true )
278
+
279
+ path = unixhost['pe_dir']
280
+ filename = "#{ unixhost['dist'] }"
281
+ extension = '.tar.gz'
282
+ expect( subject ).to receive( :fetch_and_push_pe ).with( unixhost, anything, filename, extension ).once
283
+ expect( subject ).to receive( :on ).with( unixhost, "cd #{ unixhost['working_dir'] }; cat #{ filename }#{ extension } | gunzip | tar -xvf -" ).once
284
+ subject.fetch_pe( [unixhost], {:fetch_local_then_push_to_host => true} )
285
+ end
286
+
287
+ it 'calls the host method to get an EOS .swix file from a URL' do
288
+ allow( File ).to receive( :directory? ).and_return( false ) #is not local
289
+ allow( subject ).to receive( :link_exists? ).and_return( true ) #skip file check
290
+
291
+ expect( eoshost ).to receive( :get_remote_file ).with( /swix$/ ).once
292
+ subject.fetch_pe( [eoshost], {} )
293
+ end
294
+
295
+ it 'can push a local PE package to a windows host' do
296
+ allow( File ).to receive( :directory? ).and_return( true ) #is local
297
+ allow( File ).to receive( :exists? ).and_return( true ) #is present
298
+ winhost['dist'] = 'puppet-enterprise-3.0'
299
+ allow( subject ).to receive( :scp_to ).and_return( true )
300
+
301
+ path = winhost['pe_dir']
302
+ filename = "puppet-enterprise-#{ winhost['pe_ver'] }"
303
+ extension = '.msi'
304
+ expect( subject ).to receive( :scp_to ).with( winhost, "#{ path }/#{ filename }#{ extension }", "#{ winhost['working_dir'] }/#{ filename }#{ extension }" ).once
305
+ subject.fetch_pe( [winhost], {} )
306
+
307
+ end
308
+
309
+ it 'can download a PE dmg from a URL to a mac host' do
310
+ allow( File ).to receive( :directory? ).and_return( false ) #is not local
311
+ allow( subject ).to receive( :link_exists? ).and_return( true ) #is not local
312
+ allow( subject ).to receive( :on ).and_return( true )
313
+
314
+ path = machost['pe_dir']
315
+ filename = "#{ machost['dist'] }"
316
+ extension = '.dmg'
317
+ expect( subject ).to receive( :on ).with( machost, "cd #{ machost['working_dir'] }; curl -O #{ path }/#{ filename }#{ extension }" ).once
318
+ subject.fetch_pe( [machost], {} )
319
+ end
320
+
321
+ it 'can push a PE dmg to a mac host' do
322
+ allow( File ).to receive( :directory? ).and_return( true ) #is local
323
+ allow( File ).to receive( :exists? ).and_return( true ) #is present
324
+ allow( subject ).to receive( :scp_to ).and_return( true )
325
+
326
+ path = machost['pe_dir']
327
+ filename = "#{ machost['dist'] }"
328
+ extension = '.dmg'
329
+ expect( subject ).to receive( :scp_to ).with( machost, "#{ path }/#{ filename }#{ extension }", "#{ machost['working_dir'] }/#{ filename }#{ extension }" ).once
330
+ subject.fetch_pe( [machost], {} )
331
+ end
332
+
333
+ it "does nothing for a frictionless agent for PE >= 3.2.0" do
334
+ unixhost['roles'] << 'frictionless'
335
+ unixhost['pe_ver'] = '3.2.0'
336
+
337
+ expect( subject).to_not receive(:scp_to)
338
+ expect( subject).to_not receive(:on)
339
+ allow( subject ).to receive(:version_is_less).with('3.2.0', '3.2.0').and_return(false)
340
+ subject.fetch_pe( [unixhost], {} )
341
+ end
342
+ end
343
+
344
+ describe 'do_install' do
345
+ it 'can perform a simple installation' do
346
+ allow( subject ).to receive( :on ).and_return( Beaker::Result.new( {}, '' ) )
347
+ allow( subject ).to receive( :fetch_pe ).and_return( true )
348
+ allow( subject ).to receive( :create_remote_file ).and_return( true )
349
+ allow( subject ).to receive( :sign_certificate_for ).and_return( true )
350
+ allow( subject ).to receive( :stop_agent_on ).and_return( true )
351
+ allow( subject ).to receive( :sleep_until_puppetdb_started ).and_return( true )
352
+ allow( subject ).to receive( :max_version ).with(anything, '3.8').and_return('3.0')
353
+ allow( subject ).to receive( :version_is_less ).with('3.0', '4.0').and_return( true )
354
+ allow( subject ).to receive( :version_is_less ).with('3.0', '3.4').and_return( true )
355
+ allow( subject ).to receive( :version_is_less ).with('3.0', '3.0').and_return( false )
356
+ allow( subject ).to receive( :version_is_less ).with('3.0', '3.99').and_return( true )
357
+ allow( subject ).to receive( :version_is_less ).with('3.99', '3.0').and_return( false )
358
+ allow( subject ).to receive( :wait_for_host_in_dashboard ).and_return( true )
359
+ allow( subject ).to receive( :puppet_agent ) do |arg|
360
+ "puppet agent #{arg}"
361
+ end
362
+ allow( subject ).to receive( :puppet ) do |arg|
363
+ "puppet #{arg}"
364
+ end
365
+
366
+ allow( subject ).to receive( :hosts ).and_return( hosts )
367
+ #create answers file per-host, except windows
368
+ expect( subject ).to receive( :create_remote_file ).with( hosts[0], /answers/, /q/ ).once
369
+ #run installer on all hosts
370
+ expect( subject ).to receive( :on ).with( hosts[0], /puppet-enterprise-installer/ ).once
371
+ expect( subject ).to receive( :install_msi_on ).with ( any_args ) do | host, msi_path, msi_opts, opts |
372
+ expect( host ).to eq( hosts[1] )
373
+ end.once
374
+ 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
375
+ expect( hosts[3] ).to receive( :install_from_file ).with( /swix$/ ).once
376
+ #does extra mac/EOS specific commands
377
+ expect( subject ).to receive( :on ).with( hosts[2], /puppet config set server/ ).once
378
+ expect( subject ).to receive( :on ).with( hosts[3], /puppet config set server/ ).once
379
+ expect( subject ).to receive( :on ).with( hosts[2], /puppet config set certname/ ).once
380
+ expect( subject ).to receive( :on ).with( hosts[3], /puppet config set certname/ ).once
381
+ expect( subject ).to receive( :on ).with( hosts[2], /puppet agent -t/, :acceptable_exit_codes => [1] ).once
382
+ expect( subject ).to receive( :on ).with( hosts[3], /puppet agent -t/, :acceptable_exit_codes => [0, 1] ).once
383
+ #sign certificate per-host
384
+ expect( subject ).to receive( :sign_certificate_for ).with( hosts[0] ).once
385
+ expect( subject ).to receive( :sign_certificate_for ).with( hosts[1] ).once
386
+ expect( subject ).to receive( :sign_certificate_for ).with( hosts[2] ).once
387
+ expect( subject ).to receive( :sign_certificate_for ).with( hosts[3] ).once
388
+ #stop puppet agent on all hosts
389
+ expect( subject ).to receive( :stop_agent_on ).with( hosts[0] ).once
390
+ expect( subject ).to receive( :stop_agent_on ).with( hosts[1] ).once
391
+ expect( subject ).to receive( :stop_agent_on ).with( hosts[2] ).once
392
+ expect( subject ).to receive( :stop_agent_on ).with( hosts[3] ).once
393
+ #wait for puppetdb to start
394
+ expect( subject ).to receive( :sleep_until_puppetdb_started ).with( hosts[0] ).once
395
+ #run each puppet agent once
396
+ expect( subject ).to receive( :on ).with( hosts[0], /puppet agent -t/, :acceptable_exit_codes => [0,2] ).once
397
+ expect( subject ).to receive( :on ).with( hosts[1], /puppet agent -t/, :acceptable_exit_codes => [0,2] ).once
398
+ expect( subject ).to receive( :on ).with( hosts[2], /puppet agent -t/, :acceptable_exit_codes => [0,2] ).once
399
+ expect( subject ).to receive( :on ).with( hosts[3], /puppet agent -t/, :acceptable_exit_codes => [0,2] ).once
400
+ #run rake task on dashboard
401
+
402
+ expect( subject ).to receive( :on ).with( hosts[0], /\/opt\/puppet\/bin\/rake -sf \/opt\/puppet\/share\/puppet-dashboard\/Rakefile .* RAILS_ENV=production/ ).once
403
+ #wait for all hosts to appear in the dashboard
404
+ #run puppet agent now that installation is complete
405
+ expect( subject ).to receive( :on ).with( hosts, /puppet agent/, :acceptable_exit_codes => [0,2] ).once
406
+
407
+ hosts.each do |host|
408
+ allow( host ).to receive( :tmpdir )
409
+ allow( subject ).to receive( :configure_type_defaults_on ).with( host )
410
+ end
411
+
412
+ subject.do_install( hosts, opts )
413
+ end
414
+
415
+ it 'can perform a masterless installation' do
416
+ hosts = make_hosts({
417
+ :pe_ver => '3.0',
418
+ :roles => ['agent']
419
+ }, 1)
420
+ opts[:masterless] = true
421
+
422
+ allow( subject ).to receive( :hosts ).and_return( hosts )
423
+ allow( subject ).to receive( :on ).and_return( Beaker::Result.new( {}, '' ) )
424
+ allow( subject ).to receive( :fetch_pe ).and_return( true )
425
+ allow( subject ).to receive( :create_remote_file ).and_return( true )
426
+ allow( subject ).to receive( :stop_agent_on ).and_return( true )
427
+ allow( subject ).to receive( :max_version ).with(['3.0'], '3.8').and_return('3.0')
428
+ allow( subject ).to receive( :version_is_less ).with('3.99', '3.0').and_return( false )
429
+ allow( subject ).to receive( :version_is_less ).with(anything, '3.2.0').exactly(hosts.length + 1).times.and_return( false )
430
+ allow( subject ).to receive( :version_is_less ).with(anything, '4.0').exactly(hosts.length + 1).times.and_return( true )
431
+
432
+ expect( subject ).to receive( :on ).with( hosts[0], /puppet-enterprise-installer/ ).once
433
+ expect( subject ).to receive( :create_remote_file ).with( hosts[0], /answers/, /q/ ).once
434
+ expect( subject ).to_not receive( :sign_certificate_for )
435
+ expect( subject ).to receive( :stop_agent_on ).with( hosts[0] ).once
436
+ expect( subject ).to_not receive( :sleep_until_puppetdb_started )
437
+ expect( subject ).to_not receive( :wait_for_host_in_dashboard )
438
+ expect( subject ).to_not receive( :on ).with( hosts[0], /puppet agent -t/, :acceptable_exit_codes => [0,2] )
439
+
440
+ hosts.each do |host|
441
+ allow( host ).to receive( :tmpdir )
442
+ allow( subject ).to receive( :configure_type_defaults_on ).with( host )
443
+ end
444
+
445
+ subject.do_install( hosts, opts)
446
+ end
447
+
448
+ it 'can perform a 4+ installation using AIO agents' do
449
+ hosts = make_hosts({
450
+ :pe_ver => '4.0',
451
+ :roles => ['agent'],
452
+ }, 3)
453
+ hosts[0][:roles] = ['master', 'database', 'dashboard']
454
+ hosts[1][:platform] = 'windows'
455
+ hosts[2][:platform] = Beaker::Platform.new('el-6-x86_64')
456
+
457
+ allow( subject ).to receive( :hosts ).and_return( hosts )
458
+ allow( subject ).to receive( :options ).and_return(Beaker::Options::Presets.new.presets)
459
+ allow( subject ).to receive( :on ).and_return( Beaker::Result.new( {}, '' ) )
460
+ allow( subject ).to receive( :fetch_pe ).and_return( true )
461
+ allow( subject ).to receive( :create_remote_file ).and_return( true )
462
+ allow( subject ).to receive( :sign_certificate_for ).and_return( true )
463
+ allow( subject ).to receive( :stop_agent_on ).and_return( true )
464
+ allow( subject ).to receive( :sleep_until_puppetdb_started ).and_return( true )
465
+ allow( subject ).to receive( :max_version ).with(anything, '3.8').and_return('4.0')
466
+ allow( subject ).to receive( :version_is_less ).with('4.0', '4.0').and_return( false )
467
+ allow( subject ).to receive( :version_is_less ).with('4.0', '3.4').and_return( false )
468
+ allow( subject ).to receive( :version_is_less ).with('4.0', '3.0').and_return( false )
469
+ allow( subject ).to receive( :version_is_less ).with('3.99', '4.0').and_return( true )
470
+ # pe_ver is only set on the hosts for this test, not the opt
471
+ allow( subject ).to receive( :version_is_less ).with('4.0', '3.99').and_return( true )
472
+ allow( subject ).to receive( :wait_for_host_in_dashboard ).and_return( true )
473
+ allow( subject ).to receive( :puppet_agent ) do |arg|
474
+ "puppet agent #{arg}"
475
+ end
476
+ allow( subject ).to receive( :puppet ) do |arg|
477
+ "puppet #{arg}"
478
+ end
479
+
480
+ allow( subject ).to receive( :hosts ).and_return( hosts )
481
+ #create answers file per-host, except windows
482
+ expect( subject ).to receive( :create_remote_file ).with( hosts[0], /answers/, /q/ ).once
483
+ #run installer on all hosts
484
+ expect( subject ).to receive( :on ).with( hosts[0], /puppet-enterprise-installer/ ).once
485
+ expect( subject ).to receive( :install_puppet_agent_pe_promoted_repo_on ).with( hosts[1],
486
+ {:puppet_agent_version=>nil, :puppet_agent_sha=>nil, :pe_ver=>hosts[1][:pe_ver], :puppet_collection=>nil} ).once
487
+ expect( subject ).to receive( :install_puppet_agent_pe_promoted_repo_on ).with( hosts[2],
488
+ {:puppet_agent_version=>nil, :puppet_agent_sha=>nil, :pe_ver=>hosts[2][:pe_ver], :puppet_collection=>nil} ).once
489
+ hosts.each do |host|
490
+ expect( subject ).to receive( :configure_type_defaults_on ).with( host ).once
491
+ expect( subject ).to receive( :sign_certificate_for ).with( host ).once
492
+ expect( subject ).to receive( :stop_agent_on ).with( host ).once
493
+ expect( subject ).to receive( :on ).with( host, /puppet agent -t/, :acceptable_exit_codes => [0,2] ).once
494
+ end
495
+ #wait for puppetdb to start
496
+ expect( subject ).to receive( :sleep_until_puppetdb_started ).with( hosts[0] ).once#wait for all hosts to appear in the dashboard
497
+ #run puppet agent now that installation is complete
498
+ expect( subject ).to receive( :on ).with( hosts, /puppet agent/, :acceptable_exit_codes => [0,2] ).once
499
+
500
+ hosts.each do |host|
501
+ allow( host ).to receive( :tmpdir )
502
+ allow( subject ).to receive( :configure_type_defaults_on ).with( host )
503
+ end
504
+
505
+ subject.do_install( hosts, opts )
506
+ end
507
+
508
+ it 'can perform a 4/3 mixed installation with AIO and -non agents' do
509
+ hosts = make_hosts({
510
+ :pe_ver => '4.0',
511
+ :roles => ['agent'],
512
+ }, 3)
513
+ hosts[0][:roles] = ['master', 'database', 'dashboard']
514
+ hosts[1][:platform] = 'windows'
515
+ hosts[2][:platform] = Beaker::Platform.new('el-6-x86_64')
516
+ hosts[2][:pe_ver] = '3.8'
517
+
518
+ allow( subject ).to receive( :hosts ).and_return( hosts )
519
+ allow( subject ).to receive( :options ).and_return(Beaker::Options::Presets.new.presets)
520
+ allow( subject ).to receive( :on ).and_return( Beaker::Result.new( {}, '' ) )
521
+ allow( subject ).to receive( :fetch_pe ).and_return( true )
522
+ allow( subject ).to receive( :create_remote_file ).and_return( true )
523
+ allow( subject ).to receive( :sign_certificate_for ).and_return( true )
524
+ allow( subject ).to receive( :stop_agent_on ).and_return( true )
525
+ allow( subject ).to receive( :sleep_until_puppetdb_started ).and_return( true )
526
+ allow( subject ).to receive( :max_version ).with(anything, '3.8').and_return('4.0')
527
+ allow( subject ).to receive( :version_is_less ).with('4.0', '4.0').and_return( false )
528
+ allow( subject ).to receive( :version_is_less ).with('4.0', '3.4').and_return( false )
529
+ allow( subject ).to receive( :version_is_less ).with('4.0', '3.0').and_return( false )
530
+ allow( subject ).to receive( :version_is_less ).with('3.99', '4.0').and_return( true )
531
+ allow( subject ).to receive( :version_is_less ).with('3.8', '4.0').and_return( true )
532
+ # pe_ver is only set on the hosts for this test, not the opt
533
+ allow( subject ).to receive( :version_is_less ).with('4.0', '3.99').and_return( true )
534
+ allow( subject ).to receive( :wait_for_host_in_dashboard ).and_return( true )
535
+ allow( subject ).to receive( :puppet_agent ) do |arg|
536
+ "puppet agent #{arg}"
537
+ end
538
+ allow( subject ).to receive( :puppet ) do |arg|
539
+ "puppet #{arg}"
540
+ end
541
+
542
+ allow( subject ).to receive( :hosts ).and_return( hosts )
543
+ #create answers file per-host, except windows
544
+ expect( subject ).to receive( :create_remote_file ).with( hosts[0], /answers/, /q/ ).once
545
+ #run installer on all hosts
546
+ expect( subject ).to receive( :on ).with( hosts[0], /puppet-enterprise-installer/ ).once
547
+ expect( subject ).to receive( :install_puppet_agent_pe_promoted_repo_on ).with( hosts[1],
548
+ {:puppet_agent_version=>nil, :puppet_agent_sha=>nil, :pe_ver=>hosts[1][:pe_ver], :puppet_collection=>nil} ).once
549
+ expect( subject ).to receive( :on ).with( hosts[2], /puppet-enterprise-installer/ ).once
550
+ hosts.each do |host|
551
+ expect( subject ).to receive( :configure_type_defaults_on ).with( host ).once
552
+ expect( subject ).to receive( :sign_certificate_for ).with( host ).once
553
+ expect( subject ).to receive( :stop_agent_on ).with( host ).once
554
+ expect( subject ).to receive( :on ).with( host, /puppet agent -t/, :acceptable_exit_codes => [0,2] ).once
555
+ end
556
+ #wait for puppetdb to start
557
+ expect( subject ).to receive( :sleep_until_puppetdb_started ).with( hosts[0] ).once#wait for all hosts to appear in the dashboard
558
+ #run puppet agent now that installation is complete
559
+ expect( subject ).to receive( :on ).with( hosts, /puppet agent/, :acceptable_exit_codes => [0,2] ).once
560
+
561
+ hosts.each do |host|
562
+ allow( host ).to receive( :tmpdir )
563
+ allow( subject ).to receive( :configure_type_defaults_on ).with( host )
564
+ end
565
+
566
+ subject.do_install( hosts, opts )
567
+ end
568
+
569
+ it 'sets puppet-agent acceptable_exit_codes correctly for config helper on upgrade' do
570
+ hosts = make_hosts({
571
+ :pe_ver => '4.0',
572
+ :roles => ['agent'],
573
+ }, 2)
574
+ hosts[0][:roles] = ['master', 'database', 'dashboard']
575
+ hosts[1][:platform] = Beaker::Platform.new('el-6-x86_64')
576
+
577
+ allow( subject ).to receive( :hosts ).and_return( hosts )
578
+ allow( subject ).to receive( :options ).and_return(Beaker::Options::Presets.new.presets)
579
+ allow( subject ).to receive( :on ).and_return( Beaker::Result.new( {}, '' ) )
580
+ allow( subject ).to receive( :fetch_pe ).and_return( true )
581
+ allow( subject ).to receive( :create_remote_file ).and_return( true )
582
+ allow( subject ).to receive( :sign_certificate_for ).and_return( true )
583
+ allow( subject ).to receive( :stop_agent_on ).and_return( true )
584
+ allow( subject ).to receive( :sleep_until_puppetdb_started ).and_return( true )
585
+ allow( subject ).to receive( :max_version ).with(anything, '3.8').and_return('4.0')
586
+ allow( subject ).to receive( :version_is_less ).with('4.0', '4.0').and_return( false )
587
+ allow( subject ).to receive( :version_is_less ).with('4.0', '3.4').and_return( false )
588
+ allow( subject ).to receive( :version_is_less ).with('4.0', '3.0').and_return( false )
589
+ allow( subject ).to receive( :version_is_less ).with('3.99', '4.0').and_return( true )
590
+ allow( subject ).to receive( :version_is_less ).with('3.8', '4.0').and_return( true )
591
+ # pe_ver is only set on the hosts for this test, not the opt
592
+ allow( subject ).to receive( :version_is_less ).with('4.0', '3.99').and_return( true )
593
+ allow( subject ).to receive( :wait_for_host_in_dashboard ).and_return( true )
594
+ allow( subject ).to receive( :puppet_agent ) do |arg|
595
+ "puppet agent #{arg}"
596
+ end
597
+ allow( subject ).to receive( :puppet ) do |arg|
598
+ "puppet #{arg}"
599
+ end
600
+
601
+ allow( subject ).to receive( :hosts ).and_return( hosts )
602
+ #create answers file per-host, except windows
603
+ allow( subject ).to receive( :create_remote_file ).with( hosts[0], /answers/, /q/ )
604
+ #run installer on all hosts
605
+ allow( subject ).to receive( :on ).with( hosts[0], /puppet-enterprise-installer/ )
606
+ allow( subject ).to receive( :install_puppet_agent_pe_promoted_repo_on ).with( hosts[1],
607
+ {:puppet_agent_version=>nil, :puppet_agent_sha=>nil, :pe_ver=>hosts[1][:pe_ver], :puppet_collection=>nil} )
608
+ # expect( subject ).to receive( :on ).with( hosts[2], /puppet-enterprise-installer/ ).once
609
+ hosts.each do |host|
610
+ allow( subject ).to receive( :add_pe_defaults_on ).with( host ) unless subject.aio_version?(host)
611
+ allow( subject ).to receive( :sign_certificate_for ).with( host )
612
+ allow( subject ).to receive( :stop_agent_on ).with( host )
613
+ allow( subject ).to receive( :on ).with( host, /puppet agent -t/, :acceptable_exit_codes => [0,2] )
614
+ end
615
+ #wait for puppetdb to start
616
+ allow( subject ).to receive( :sleep_until_puppetdb_started ).with( hosts[0] ) #wait for all hosts to appear in the dashboard
617
+ #run puppet agent now that installation is complete
618
+ allow( subject ).to receive( :on ).with( hosts, /puppet agent/, :acceptable_exit_codes => [0,2] )
619
+
620
+ opts[:type] = :upgrade
621
+ expect( subject ).to receive( :setup_defaults_and_config_helper_on ).with( hosts[1], hosts[0], [0, 1, 2] )
622
+
623
+ hosts.each do |host|
624
+ allow( host ).to receive( :tmpdir )
625
+ allow( subject ).to receive( :configure_type_defaults_on ).with( host )
626
+ end
627
+
628
+ subject.do_install( hosts, opts )
629
+ end
630
+
631
+ end
632
+
633
+ describe 'do_higgs_install' do
634
+
635
+ before :each do
636
+ my_time = double( "time double" )
637
+ allow( my_time ).to receive( :strftime ).and_return( "2014-07-01_15.27.53" )
638
+ allow( Time ).to receive( :new ).and_return( my_time )
639
+
640
+ hosts[0]['working_dir'] = "tmp/2014-07-01_15.27.53"
641
+ hosts[0]['dist'] = 'dist'
642
+ hosts[0]['pe_installer'] = 'pe-installer'
643
+ allow( hosts[0] ).to receive( :tmpdir ).and_return( "/tmp/2014-07-01_15.27.53" )
644
+
645
+ @fail_result = Beaker::Result.new( {}, '' )
646
+ @fail_result.stdout = "No match here"
647
+ @success_result = Beaker::Result.new( {}, '' )
648
+ @success_result.stdout = "Please go to https://website in your browser to continue installation"
649
+ end
650
+
651
+ it 'can perform a simple installation' do
652
+ allow( subject ).to receive( :fetch_pe ).and_return( true )
653
+ allow( subject ).to receive( :sleep ).and_return( true )
654
+
655
+ allow( subject ).to receive( :hosts ).and_return( hosts )
656
+
657
+ #run higgs installer command
658
+ expect( subject ).to receive( :on ).with( hosts[0],
659
+ "cd /tmp/2014-07-01_15.27.53/puppet-enterprise-3.0-linux ; nohup ./pe-installer <<<Y > higgs_2014-07-01_15.27.53.log 2>&1 &",
660
+ opts ).once
661
+ #check to see if the higgs installation has proceeded correctly, works on second check
662
+ expect( subject ).to receive( :on ).with( hosts[0], /cat #{hosts[0]['higgs_file']}/, { :accept_all_exit_codes => true }).and_return( @fail_result, @success_result )
663
+ subject.do_higgs_install( hosts[0], opts )
664
+ end
665
+
666
+ it 'fails out after checking installation log 10 times' do
667
+ allow( subject ).to receive( :fetch_pe ).and_return( true )
668
+ allow( subject ).to receive( :sleep ).and_return( true )
669
+
670
+ allow( subject ).to receive( :hosts ).and_return( hosts )
671
+
672
+ #run higgs installer command
673
+ expect( subject ).to receive( :on ).with( hosts[0],
674
+ "cd /tmp/2014-07-01_15.27.53/puppet-enterprise-3.0-linux ; nohup ./pe-installer <<<Y > higgs_2014-07-01_15.27.53.log 2>&1 &",
675
+ opts ).once
676
+ #check to see if the higgs installation has proceeded correctly, works on second check
677
+ 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 )
678
+ expect{ subject.do_higgs_install( hosts[0], opts ) }.to raise_error RuntimeError, "Failed to kick off PE (Higgs) web installation"
679
+ end
680
+
681
+ end
682
+
683
+ describe 'install_pe' do
684
+
685
+ it 'calls do_install with sorted hosts' do
686
+ allow( subject ).to receive( :options ).and_return( {} )
687
+ allow( subject ).to receive( :hosts ).and_return( hosts_sorted )
688
+ allow( subject ).to receive( :do_install ).and_return( true )
689
+ expect( subject ).to receive( :do_install ).with( hosts, {} )
690
+ subject.install_pe
691
+ end
692
+
693
+ it 'fills in missing pe_ver' do
694
+ hosts.each do |h|
695
+ h['pe_ver'] = nil
696
+ end
697
+ allow( Beaker::Options::PEVersionScraper ).to receive( :load_pe_version ).and_return( '2.8' )
698
+ allow( subject ).to receive( :hosts ).and_return( hosts_sorted )
699
+ allow( subject ).to receive( :options ).and_return( {} )
700
+ allow( subject ).to receive( :do_install ).and_return( true )
701
+ expect( subject ).to receive( :do_install ).with( hosts, {} )
702
+ subject.install_pe
703
+ hosts.each do |h|
704
+ expect( h['pe_ver'] ).to be === '2.8'
705
+ end
706
+ end
707
+
708
+ it 'can act upon a single host' do
709
+ allow( subject ).to receive( :hosts ).and_return( hosts )
710
+ allow( subject ).to receive( :sorted_hosts ).and_return( [hosts[0]] )
711
+ expect( subject ).to receive( :do_install ).with( [hosts[0]], {} )
712
+ subject.install_pe_on(hosts[0], {})
713
+ end
714
+ end
715
+
716
+ describe 'install_higgs' do
717
+ it 'fills in missing pe_ver' do
718
+ hosts[0]['pe_ver'] = nil
719
+ allow( Beaker::Options::PEVersionScraper ).to receive( :load_pe_version ).and_return( '2.8' )
720
+ allow( subject ).to receive( :hosts ).and_return( [ hosts[1], hosts[0], hosts[2] ] )
721
+ allow( subject ).to receive( :options ).and_return( {} )
722
+ allow( subject ).to receive( :do_higgs_install ).and_return( true )
723
+ expect( subject ).to receive( :do_higgs_install ).with( hosts[0], {} )
724
+ subject.install_higgs
725
+ expect( hosts[0]['pe_ver'] ).to be === '2.8'
726
+ end
727
+
728
+ end
729
+
730
+ describe 'upgrade_pe' do
731
+
732
+ it 'calls puppet-enterprise-upgrader for pre 3.0 upgrades' do
733
+ allow( Beaker::Options::PEVersionScraper ).to receive( :load_pe_version ).and_return( '2.8' )
734
+ allow( Beaker::Options::PEVersionScraper ).to receive( :load_pe_version_win ).and_return( '2.8' )
735
+ the_hosts = [ hosts[0].dup, hosts[1].dup, hosts[2].dup ]
736
+ allow( subject ).to receive( :hosts ).and_return( the_hosts )
737
+ allow( subject ).to receive( :options ).and_return( {} )
738
+ allow( subject ).to receive( :version_is_less ).with('3.0', '3.4.0').and_return( true )
739
+ allow( subject ).to receive( :version_is_less ).with('2.8', '3.0').and_return( true )
740
+ version = version_win = '2.8'
741
+ path = "/path/to/upgradepkg"
742
+ expect( subject ).to receive( :do_install ).with( the_hosts, {:type=>:upgrade, :set_console_password=>true} )
743
+ subject.upgrade_pe( path )
744
+ the_hosts.each do |h|
745
+ expect( h['pe_installer'] ).to be === 'puppet-enterprise-upgrader'
746
+ end
747
+ end
748
+
749
+ it 'uses standard upgrader for post 3.0 upgrades' do
750
+ allow( Beaker::Options::PEVersionScraper ).to receive( :load_pe_version ).and_return( '3.1' )
751
+ allow( Beaker::Options::PEVersionScraper ).to receive( :load_pe_version_win ).and_return( '3.1' )
752
+ the_hosts = [ hosts[0].dup, hosts[1].dup, hosts[2].dup ]
753
+ allow( subject ).to receive( :hosts ).and_return( the_hosts )
754
+ allow( subject ).to receive( :options ).and_return( {} )
755
+ allow( subject ).to receive( :version_is_less ).with('3.0', '3.4.0').and_return( true )
756
+ allow( subject ).to receive( :version_is_less ).with('3.1', '3.0').and_return( false )
757
+ version = version_win = '3.1'
758
+ path = "/path/to/upgradepkg"
759
+ expect( subject ).to receive( :do_install ).with( the_hosts, {:type=>:upgrade, :set_console_password=>true} )
760
+ subject.upgrade_pe( path )
761
+ the_hosts.each do |h|
762
+ expect( h['pe_installer'] ).to be nil
763
+ end
764
+ end
765
+
766
+ it 'updates pe_ver post upgrade' do
767
+ allow( Beaker::Options::PEVersionScraper ).to receive( :load_pe_version ).and_return( '2.8' )
768
+ allow( Beaker::Options::PEVersionScraper ).to receive( :load_pe_version_win ).and_return( '2.8' )
769
+ the_hosts = [ hosts[0].dup, hosts[1].dup, hosts[2].dup ]
770
+ allow( subject ).to receive( :hosts ).and_return( the_hosts )
771
+ allow( subject ).to receive( :options ).and_return( {} )
772
+ allow( subject ).to receive( :version_is_less ).with('3.0', '3.4.0').and_return( true )
773
+ allow( subject ).to receive( :version_is_less ).with('2.8', '3.0').and_return( true )
774
+ version = version_win = '2.8'
775
+ path = "/path/to/upgradepkg"
776
+ expect( subject ).to receive( :do_install ).with( the_hosts, {:type=>:upgrade, :set_console_password=>true} )
777
+ subject.upgrade_pe( path )
778
+ the_hosts.each do |h|
779
+ expect( h['pe_ver'] ).to be === '2.8'
780
+ end
781
+ end
782
+
783
+ it 'can act upon a single host' do
784
+ allow( Beaker::Options::PEVersionScraper ).to receive( :load_pe_version ).and_return( '3.1' )
785
+ allow( Beaker::Options::PEVersionScraper ).to receive( :load_pe_version_win ).and_return( '3.1' )
786
+ allow( subject ).to receive( :hosts ).and_return( hosts )
787
+ allow( subject ).to receive( :version_is_less ).with('3.0', '3.4.0').and_return( true )
788
+ allow( subject ).to receive( :version_is_less ).with('3.1', '3.0').and_return( false )
789
+ allow( subject ).to receive( :sorted_hosts ).and_return( [hosts[0]] )
790
+ version = version_win = '3.1'
791
+ path = "/path/to/upgradepkg"
792
+ expect( subject ).to receive( :do_install ).with( [hosts[0]], {:type=>:upgrade, :set_console_password=>true} )
793
+ subject.upgrade_pe_on(hosts[0], {}, path)
794
+ end
795
+
796
+ end
797
+
798
+ describe 'fetch_and_push_pe' do
799
+
800
+ it 'fetches the file' do
801
+ allow( subject ).to receive( :scp_to )
802
+
803
+ path = 'abcde/fg/hij'
804
+ filename = 'pants'
805
+ extension = '.txt'
806
+ expect( subject ).to receive( :fetch_http_file ).with( path, "#{filename}#{extension}", 'tmp/pe' )
807
+ subject.fetch_and_push_pe(unixhost, path, filename, extension)
808
+ end
809
+
810
+ it 'allows you to set the local copy dir' do
811
+ allow( subject ).to receive( :scp_to )
812
+
813
+ path = 'defg/hi/j'
814
+ filename = 'pants'
815
+ extension = '.txt'
816
+ local_dir = '/root/domes'
817
+ expect( subject ).to receive( :fetch_http_file ).with( path, "#{filename}#{extension}", local_dir )
818
+ subject.fetch_and_push_pe(unixhost, path, filename, extension, local_dir)
819
+ end
820
+
821
+ it 'scp\'s to the host' do
822
+ allow( subject ).to receive( :fetch_http_file )
823
+
824
+ path = 'abcde/fg/hij'
825
+ filename = 'pants'
826
+ extension = '.txt'
827
+ expect( subject ).to receive( :scp_to ).with( unixhost, "tmp/pe/#{filename}#{extension}", unixhost['working_dir'] )
828
+ subject.fetch_and_push_pe(unixhost, path, filename, extension)
829
+ end
830
+
831
+ end
832
+
833
+ describe 'create_agent_specified_arrays' do
834
+ let(:master) { make_host( 'master', { :platform => 'linux',
835
+ :pe_ver => '4.0',
836
+ :roles => ['master', 'agent']})}
837
+ let(:db) { make_host( 'db', { :platform => 'linux',
838
+ :pe_ver => '4.0',
839
+ :roles => ['database', 'agent']})}
840
+ let(:console) { make_host( 'console', { :platform => 'linux',
841
+ :pe_ver => '4.0',
842
+ :roles => ['dashboard', 'agent']})}
843
+ let(:monolith) { make_host( 'monolith', { :platform => 'linux',
844
+ :pe_ver => '4.0',
845
+ :roles => %w(master dashboard database)})}
846
+ let(:frictionless) { make_host( 'frictionless', { :platform => 'linux',
847
+ :pe_ver => '4.0',
848
+ :roles => ['agent', 'frictionless']})}
849
+ let(:agent1) { make_host( 'agent1', { :platform => 'linux',
850
+ :pe_ver => '4.0',
851
+ :roles => ['agent']})}
852
+ let(:agent2) { make_host( 'agent2', { :platform => 'linux',
853
+ :pe_ver => '4.0',
854
+ :roles => ['agent']})}
855
+ let(:default_agent) { make_host( 'default', { :platform => 'linux',
856
+ :pe_ver => '4.0',
857
+ :roles => ['default', 'agent']})}
858
+ let(:masterless) { make_host( 'masterless', { :platform => 'linux',
859
+ :pe_ver => '4.0',
860
+ :roles => ['agent', 'masterless']})}
861
+ let(:compiler) { make_host( 'compiler', { :platform => 'linux',
862
+ :pe_ver => '4.0',
863
+ :roles => ['agent', 'compile_master']})}
864
+
865
+ it 'sorts hosts with common PE roles' do
866
+ these_hosts = [master, db, console, agent1, frictionless]
867
+ agent_only, non_agent = subject.create_agent_specified_arrays(these_hosts)
868
+ expect(agent_only.length).to be 1
869
+ expect(agent_only).to include(agent1)
870
+ expect(non_agent.length).to be 4
871
+ expect(non_agent).to include(master)
872
+ expect(non_agent).to include(db)
873
+ expect(non_agent).to include(console)
874
+ expect(non_agent).to include(frictionless)
875
+ end
876
+
877
+ # Possibly needed for NetDev and Scale testing
878
+ it 'defaults to classifying custom roles as "agent only"' do
879
+ these_hosts = [monolith, compiler, agent1, agent2]
880
+ agent_only, non_agent = subject.create_agent_specified_arrays(these_hosts)
881
+ expect(agent_only.length).to be 3
882
+ expect(agent_only).to include(agent1)
883
+ expect(agent_only).to include(agent2)
884
+ expect(agent_only).to include(compiler)
885
+ expect(non_agent.length).to be 1
886
+ expect(non_agent).to include(monolith)
887
+ end
888
+
889
+ # Most common form of module testing
890
+ it 'allows a puppet-agent host to be the default test target' do
891
+ these_hosts = [monolith, default_agent]
892
+ agent_only, non_agent = subject.create_agent_specified_arrays(these_hosts)
893
+ expect(agent_only.length).to be 1
894
+ expect(agent_only).to include(default_agent)
895
+ expect(non_agent.length).to be 1
896
+ expect(non_agent).to include(monolith)
897
+ end
898
+
899
+ # Preferred module on commit scenario
900
+ it 'handles masterless scenarios' do
901
+ these_hosts = [masterless]
902
+ agent_only, non_agent = subject.create_agent_specified_arrays(these_hosts)
903
+ expect(agent_only.length).to be 1
904
+ expect(non_agent).to be_empty
905
+ end
906
+
907
+ # IIRC, this is the basic PE integration smoke test
908
+ it 'handles agent-only-less scenarios' do
909
+ these_hosts = [monolith, frictionless]
910
+ agent_only, non_agent = subject.create_agent_specified_arrays(these_hosts)
911
+ expect(agent_only).to be_empty
912
+ expect(non_agent.length).to be 2
913
+ end
914
+ end
915
+
916
+ end