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.
Files changed (98) hide show
  1. checksums.yaml +8 -8
  2. data/.travis.yml +8 -0
  3. data/README.md +6 -6
  4. data/beaker.gemspec +6 -2
  5. data/lib/beaker.rb +1 -1
  6. data/lib/beaker/answers.rb +34 -7
  7. data/lib/beaker/answers/version20.rb +124 -0
  8. data/lib/beaker/answers/version28.rb +21 -0
  9. data/lib/beaker/answers/version30.rb +24 -5
  10. data/lib/beaker/cli.rb +55 -41
  11. data/lib/beaker/command.rb +2 -2
  12. data/lib/beaker/dsl/helpers.rb +320 -106
  13. data/lib/beaker/dsl/install_utils.rb +202 -81
  14. data/lib/beaker/dsl/roles.rb +40 -0
  15. data/lib/beaker/host.rb +28 -20
  16. data/lib/beaker/host/unix.rb +7 -4
  17. data/lib/beaker/host/unix/pkg.rb +42 -12
  18. data/lib/beaker/host/windows.rb +9 -5
  19. data/lib/beaker/host/windows/group.rb +1 -1
  20. data/lib/beaker/host/windows/pkg.rb +41 -8
  21. data/lib/beaker/hypervisor.rb +23 -10
  22. data/lib/beaker/hypervisor/aixer.rb +15 -19
  23. data/lib/beaker/hypervisor/blimper.rb +71 -72
  24. data/lib/beaker/hypervisor/fusion.rb +11 -10
  25. data/lib/beaker/hypervisor/solaris.rb +17 -23
  26. data/lib/beaker/hypervisor/vagrant.rb +27 -12
  27. data/lib/beaker/hypervisor/vcloud.rb +154 -138
  28. data/lib/beaker/hypervisor/vcloud_pooled.rb +97 -0
  29. data/lib/beaker/hypervisor/vsphere.rb +8 -5
  30. data/lib/beaker/hypervisor/vsphere_helper.rb +43 -33
  31. data/lib/beaker/network_manager.rb +16 -12
  32. data/lib/beaker/options/command_line_parser.rb +199 -0
  33. data/lib/beaker/options/hosts_file_parser.rb +39 -0
  34. data/lib/beaker/options/options_file_parser.rb +45 -0
  35. data/lib/beaker/options/options_hash.rb +294 -0
  36. data/lib/beaker/options/parser.rb +288 -0
  37. data/lib/beaker/options/pe_version_scraper.rb +35 -0
  38. data/lib/beaker/options/presets.rb +70 -0
  39. data/lib/beaker/shared.rb +2 -1
  40. data/lib/beaker/shared/host_handler.rb +7 -2
  41. data/lib/beaker/shared/repetition.rb +1 -0
  42. data/lib/beaker/shared/timed.rb +14 -0
  43. data/lib/beaker/test_case.rb +2 -38
  44. data/lib/beaker/test_suite.rb +11 -25
  45. data/lib/beaker/utils/repo_control.rb +6 -8
  46. data/lib/beaker/utils/setup_helper.rb +9 -20
  47. data/spec/beaker/answers_spec.rb +109 -0
  48. data/spec/beaker/command_spec.rb +2 -2
  49. data/spec/beaker/dsl/assertions_spec.rb +1 -3
  50. data/spec/beaker/dsl/helpers_spec.rb +519 -84
  51. data/spec/beaker/dsl/install_utils_spec.rb +265 -16
  52. data/spec/beaker/dsl/roles_spec.rb +31 -10
  53. data/spec/beaker/host/windows/group_spec.rb +55 -0
  54. data/spec/beaker/host_spec.rb +130 -40
  55. data/spec/beaker/hypervisor/aixer_spec.rb +34 -0
  56. data/spec/beaker/hypervisor/blimper_spec.rb +77 -0
  57. data/spec/beaker/hypervisor/fusion_spec.rb +26 -0
  58. data/spec/beaker/hypervisor/hypervisor_spec.rb +66 -0
  59. data/spec/beaker/hypervisor/solaris_spec.rb +39 -0
  60. data/spec/beaker/hypervisor/vagrant_spec.rb +105 -0
  61. data/spec/beaker/hypervisor/vcloud_pooled_spec.rb +60 -0
  62. data/spec/beaker/hypervisor/vcloud_spec.rb +70 -0
  63. data/spec/beaker/hypervisor/vsphere_helper_spec.rb +162 -0
  64. data/spec/beaker/hypervisor/vsphere_spec.rb +76 -0
  65. data/spec/beaker/options/command_line_parser_spec.rb +25 -0
  66. data/spec/beaker/options/data/LATEST +1 -0
  67. data/spec/beaker/options/data/badyaml.cfg +21 -0
  68. data/spec/beaker/options/data/hosts.cfg +21 -0
  69. data/spec/beaker/options/data/opts.txt +6 -0
  70. data/spec/beaker/options/hosts_file_parser_spec.rb +30 -0
  71. data/spec/beaker/options/options_file_parser_spec.rb +23 -0
  72. data/spec/beaker/options/options_hash_spec.rb +111 -0
  73. data/spec/beaker/options/parser_spec.rb +172 -0
  74. data/spec/beaker/options/pe_version_scaper_spec.rb +15 -0
  75. data/spec/beaker/options/presets_spec.rb +24 -0
  76. data/spec/beaker/puppet_command_spec.rb +54 -21
  77. data/spec/beaker/shared/error_handler_spec.rb +40 -0
  78. data/spec/beaker/shared/host_handler_spec.rb +104 -0
  79. data/spec/beaker/shared/repetition_spec.rb +72 -0
  80. data/spec/beaker/test_suite_spec.rb +3 -16
  81. data/spec/beaker/utils/ntp_control_spec.rb +42 -0
  82. data/spec/beaker/utils/repo_control_spec.rb +168 -0
  83. data/spec/beaker/utils/setup_helper_spec.rb +82 -0
  84. data/spec/beaker/utils/validator_spec.rb +58 -0
  85. data/spec/helpers.rb +97 -0
  86. data/spec/matchers.rb +39 -0
  87. data/spec/mock_blimpy.rb +48 -0
  88. data/spec/mock_fission.rb +60 -0
  89. data/spec/mock_vsphere.rb +310 -0
  90. data/spec/mock_vsphere_helper.rb +183 -0
  91. data/spec/mocks.rb +83 -0
  92. data/spec/spec_helper.rb +8 -1
  93. metadata +106 -13
  94. data/beaker.rb +0 -10
  95. data/lib/beaker/options_parsing.rb +0 -323
  96. data/lib/beaker/test_config.rb +0 -148
  97. data/spec/beaker/options_parsing_spec.rb +0 -37
  98. data/spec/mocks_and_helpers.rb +0 -34
@@ -91,7 +91,7 @@ module Beaker
91
91
  "#{env_string} #{cmd} #{options_string} #{args_string}"
92
92
  end
93
93
 
94
- # @param [Hash] options These are the options that the command takes
94
+ # @param [Hash] opts These are the options that the command takes
95
95
  #
96
96
  # @return [String] String of the options and flags for command.
97
97
  #
@@ -150,7 +150,7 @@ module Beaker
150
150
  # knowledge contained here. Really the relationship should be
151
151
  # reversed where a host is asked for an appropriate Command when
152
152
  # given a generic Command.
153
- def environment_string_for host, env
153
+ def environment_string_for host, env
154
154
  return '' if env.empty?
155
155
 
156
156
  env_array = parse_env_hash_for( host, env ).compact
@@ -1,4 +1,6 @@
1
1
  require 'resolv'
2
+ require 'inifile'
3
+ require 'timeout'
2
4
  require 'beaker/dsl/outcomes'
3
5
 
4
6
  module Beaker
@@ -13,6 +15,9 @@ module Beaker
13
15
  # {Beaker::Host}'s interface to act upon.
14
16
  # * a method *logger* that yields a logger implementing
15
17
  # {Beaker::Logger}'s interface.
18
+ # * the module {Beaker::DSL::Roles} that provides access to the various hosts implementing
19
+ # {Beaker::Host}'s interface to act upon
20
+ # * the module {Beaker::DSL::Wrappers} the provides convenience methods for {Beaker::DSL::Command} creation
16
21
  #
17
22
  #
18
23
  # @api dsl
@@ -31,7 +36,8 @@ module Beaker
31
36
 
32
37
  # The primary method for executing commands *on* some set of hosts.
33
38
  #
34
- # @param [Host, Array<Host>] host One or more hosts to act upon.
39
+ # @param [Host, Array<Host>, String, Symbol] host One or more hosts to act upon,
40
+ # or a role (String or Symbol) that identifies one or more hosts.
35
41
  # @param [String, Command] command The command to execute on *host*.
36
42
  # @param [Proc] block Additional actions or assertions.
37
43
  # @!macro common_opts
@@ -54,6 +60,12 @@ module Beaker
54
60
  # end
55
61
  # end
56
62
  #
63
+ # @example Using a role (defined in a String) to identify the host
64
+ # on "master", "echo hello"
65
+ #
66
+ # @example Using a role (defined in a Symbol) to identify the host
67
+ # on :dashboard, "echo hello"
68
+ #
57
69
  # @return [Result] An object representing the outcome of *command*.
58
70
  # @raise [FailTest] Raises an exception if *command* obviously fails.
59
71
  def on(host, command, opts = {}, &block)
@@ -61,6 +73,9 @@ module Beaker
61
73
  cmd_opts = opts[:environment] ? { 'ENV' => opts.delete(:environment) } : Hash.new
62
74
  command = Command.new(command.to_s, [], cmd_opts)
63
75
  end
76
+ if host.is_a? String or host.is_a? Symbol
77
+ host = hosts_as(host) #check by role
78
+ end
64
79
  if host.is_a? Array
65
80
  host.map { |h| on h, command, opts, &block }
66
81
  else
@@ -73,6 +88,66 @@ module Beaker
73
88
  end
74
89
  end
75
90
 
91
+ # The method for executing commands on the default host
92
+ #
93
+ # @param [String, Command] command The command to execute on *host*.
94
+ # @param [Proc] block Additional actions or assertions.
95
+ # @!macro common_opts
96
+ #
97
+ # @example Most basic usage
98
+ # shell 'ls /tmp'
99
+ #
100
+ # @example Allowing additional exit codes to pass
101
+ # shell 'puppet agent -t', :acceptable_exit_codes => [0,2]
102
+ #
103
+ # @example Using the returned result for any kind of checking
104
+ # if shell('ls -la ~').stdout =~ /\.bin/
105
+ # ...do some action...
106
+ # end
107
+ #
108
+ # @example Using TestCase helpers from within a test.
109
+ # agents.each do |agent|
110
+ # shell('cat /etc/puppet/puppet.conf') do |result|
111
+ # assert_match result.stdout, /server = #{master}/, 'WTF Mate'
112
+ # end
113
+ # end
114
+ #
115
+ # @return [Result] An object representing the outcome of *command*.
116
+ # @raise [FailTest] Raises an exception if *command* obviously fails.
117
+ def shell(command, opts = {}, &block)
118
+ on(default, command, opts, &block)
119
+ end
120
+
121
+ # @deprecated
122
+ # An proxy for the last {Beaker::Result#stdout} returned by
123
+ # a method that makes remote calls. Use the {Beaker::Result}
124
+ # object returned by the method directly instead. For Usage see
125
+ # {Beaker::Result}.
126
+ def stdout
127
+ return nil if @result.nil?
128
+ @result.stdout
129
+ end
130
+
131
+ # @deprecated
132
+ # An proxy for the last {Beaker::Result#stderr} returned by
133
+ # a method that makes remote calls. Use the {Beaker::Result}
134
+ # object returned by the method directly instead. For Usage see
135
+ # {Beaker::Result}.
136
+ def stderr
137
+ return nil if @result.nil?
138
+ @result.stderr
139
+ end
140
+
141
+ # @deprecated
142
+ # An proxy for the last {Beaker::Result#exit_code} returned by
143
+ # a method that makes remote calls. Use the {Beaker::Result}
144
+ # object returned by the method directly instead. For Usage see
145
+ # {Beaker::Result}.
146
+ def exit_code
147
+ return nil if @result.nil?
148
+ @result.exit_code
149
+ end
150
+
76
151
  # Move a file from a remote to a local path
77
152
  # @note If using {Beaker::Host} for the hosts *scp* is not
78
153
  # required on the system as it uses Ruby's net/scp library. The
@@ -119,17 +194,17 @@ module Beaker
119
194
 
120
195
  # Check to see if a package is installed on a remote host
121
196
  #
122
- # @param [Host] host A host object
197
+ # @param [Host] host A host object
123
198
  # @param [String] package_name Name of the package to check for.
124
199
  #
125
- # @return [Boolean] true/false if the package is found
200
+ # @return [Boolean] true/false if the package is found
126
201
  def check_for_package host, package_name
127
202
  host.check_for_package package_name
128
203
  end
129
204
 
130
205
  # Install a package on a host
131
206
  #
132
- # @param [Host] host A host object
207
+ # @param [Host] host A host object
133
208
  # @param [String] package_name Name of the package to install
134
209
  #
135
210
  # @return [Result] An object representing the outcome of *install command*.
@@ -180,6 +255,12 @@ module Beaker
180
255
  on host, remote_path, opts, &block
181
256
  end
182
257
 
258
+ # Move a local script to default host and execute it
259
+ # @see #run_script_on
260
+ def run_script(script, opts = {}, &block)
261
+ run_script_on(default, script, opts, &block)
262
+ end
263
+
183
264
  # Limit the hosts a test case is run against
184
265
  # @note This will modify the {Beaker::TestCase#hosts} member
185
266
  # in place unless an array of hosts is passed into it and
@@ -198,7 +279,7 @@ module Beaker
198
279
  # considered for inclusion or exclusion. The key is any attribute
199
280
  # of the host that will be yielded by {Beaker::Host#[]}.
200
281
  # The value can be any string/regex or array of strings/regexp.
201
- # The values are compared using {Enumerable#any?} so that if one
282
+ # The values are compared using [Enumerable#any?] so that if one
202
283
  # value of an array matches the host is considered a match for that
203
284
  # criteria.
204
285
  # @param [Array<Host>] host_array This creatively named parameter is
@@ -259,6 +340,23 @@ module Beaker
259
340
  hosts_to_modify
260
341
  end
261
342
 
343
+ # Ensures that host restrictions as specifid by type, criteria and
344
+ # host_array are confined to activity within the passed block.
345
+ # TestCase#hosts is reset after block has executed.
346
+ #
347
+ # @see #confine
348
+ def confine_block(type, criteria, host_array = nil, &block)
349
+ begin
350
+ original_hosts = self.hosts.dup
351
+ confine(type, criteria, host_array)
352
+
353
+ yield
354
+
355
+ ensure
356
+ self.hosts = original_hosts
357
+ end
358
+ end
359
+
262
360
  # @!visibility private
263
361
  def inspect_host(host, property, one_or_more_values)
264
362
  values = Array(one_or_more_values)
@@ -285,14 +383,25 @@ module Beaker
285
383
  # 6. Revert Puppet to the pre-test state
286
384
  # 7. Testing artifacts are saved in a folder named for the test
287
385
  #
288
- # @param [Host] hosts One object that act like Host
386
+ # @param [Host] host One object that act like Host
289
387
  #
290
- # @param [Hash{Symbol=>String}]
291
- # config_opts Represent puppet settings.
388
+ # @param [Hash{Symbol=>String}] conf_opts Represents puppet settings.
292
389
  # Sections of the puppet.conf may be
293
390
  # specified, if no section is specified the
294
391
  # a puppet.conf file will be written with the
295
- # options put in a section named after [mode].
392
+ # options put in a section named after [mode]
393
+ #
394
+ # There is a special setting for command_line
395
+ # arguments such as --debug or --logdest, which
396
+ # cannot be set in puppet.conf. For example:
397
+ #
398
+ # :__commandline_args__ => '--logdest /tmp/a.log'
399
+ #
400
+ # These will only be applied when starting a FOSS
401
+ # master, as a pe master is just bounced.
402
+ #
403
+ # @param [File] testdir The temporary directory which will hold backup
404
+ # configuration, and other test artifacts.
296
405
  #
297
406
  # @param [Block] block The point of this method, yields so
298
407
  # tests may be ran. After the block is finished
@@ -314,71 +423,127 @@ module Beaker
314
423
  #
315
424
  # @api dsl
316
425
  def with_puppet_running_on host, conf_opts, testdir = host.tmpdir(File.basename(@path)), &block
426
+ raise(ArgumentError, "with_puppet_running_on's conf_opts must be a Hash. You provided a #{conf_opts.class}: '#{conf_opts}'") if !conf_opts.kind_of?(Hash)
427
+ cmdline_args = conf_opts.delete(:__commandline_args__)
428
+
317
429
  begin
318
- backup_file host, host['puppetpath'], testdir, 'puppet.conf'
430
+ backup_file = backup_the_file(host, host['puppetpath'], testdir, 'puppet.conf')
319
431
  lay_down_new_puppet_conf host, conf_opts, testdir
320
432
 
321
433
  if host.is_pe?
322
- bounce_service( 'pe-httpd' )
323
-
434
+ bounce_service( host, 'pe-httpd' )
324
435
  else
325
- start_puppet_from_source_on!( host )
436
+ puppet_master_started = start_puppet_from_source_on!( host, cmdline_args )
326
437
  end
327
438
 
328
439
  yield self if block_given?
440
+
441
+ rescue Exception => early_exception
442
+ original_exception = RuntimeError.new("PuppetAcceptance::DSL::Helpers.with_puppet_running_on failed (check backtrace for location) because: #{early_exception}\n#{early_exception.backtrace.join("\n")}\n")
443
+ raise(original_exception)
444
+
329
445
  ensure
330
- restore_puppet_conf_from_backup( host )
446
+ begin
447
+ restore_puppet_conf_from_backup( host, backup_file )
331
448
 
332
- if host.is_pe?
333
- bounce_service( 'pe-httpd' )
449
+ if host.is_pe?
450
+ bounce_service( host, 'pe-httpd' )
451
+ else
452
+ stop_puppet_from_source_on( host ) if puppet_master_started
453
+ end
334
454
 
335
- else
336
- stop_puppet_from_source_on( host )
455
+ rescue Exception => teardown_exception
456
+ if original_exception
457
+ logger.error("Raised during attempt to teardown with_puppet_running_on: #{teardown_exception}\n---\n")
458
+ raise original_exception
459
+ else
460
+ raise teardown_exception
461
+ end
337
462
  end
338
463
  end
339
464
  end
340
465
 
466
+ # Test Puppet running in a certain run mode with specific options,
467
+ # on the default host
468
+ # @api dsl
469
+ # @see #with_puppet_running_on
470
+ def with_puppet_running conf_opts, testdir = host.tmpdir(File.basename(@path)), &block
471
+ with_puppet_running_on(default, conf_opts, testdir, &block)
472
+ end
473
+
341
474
  # @!visibility private
342
- def restore_puppet_conf_from_backup( host )
475
+ def restore_puppet_conf_from_backup( host, backup_file )
343
476
  puppetpath = host['puppetpath']
344
477
 
345
- host.exec( Command.new( "if [ -f #{puppetpath}/puppet.conf.bak ]; then " +
346
- "cat #{puppetpath}/puppet.conf.bak > " +
347
- "#{puppetpath}/puppet.conf; " +
348
- "rm -rf #{puppetpath}/puppet.conf.bak; " +
478
+ host.exec( Command.new( "if [ -f '#{backup_file}' ]; then " +
479
+ "cat '#{backup_file}' > " +
480
+ "'#{puppetpath}/puppet.conf'; " +
481
+ "rm -f '#{backup_file}'; " +
349
482
  "fi" ) )
350
483
  end
351
484
 
352
485
  # @!visibility private
353
- def backup_file host, current_dir, new_dir, filename = 'puppet.conf'
486
+ def backup_the_file host, current_dir, new_dir, filename = 'puppet.conf'
354
487
  old_location = current_dir + '/' + filename
355
- new_location = new_dir + '/' + filename
488
+ new_location = new_dir + '/' + filename + '.bak'
356
489
 
357
490
  host.exec( Command.new( "cp #{old_location} #{new_location}" ) )
491
+
492
+ return new_location
358
493
  end
359
494
 
360
495
  # @!visibility private
361
- def start_puppet_from_source_on! host
362
- host.exec( Command.new( puppet( 'master' ) ) )
496
+ def start_puppet_from_source_on! host, args = ''
497
+ host.exec( puppet( 'master', args ) )
363
498
 
364
499
  logger.debug 'Waiting for the puppet master to start'
365
500
  unless port_open_within?( host, 8140, 10 )
501
+ dump_puppet_log(host)
366
502
  raise Beaker::DSL::FailTest, 'Puppet master did not start in a timely fashion'
367
503
  end
368
504
  logger.debug 'The puppet master has started'
505
+ return true
369
506
  end
370
507
 
371
508
  # @!visibility private
372
509
  def stop_puppet_from_source_on( host )
373
- host.exec( Command.new( 'kill $(cat `puppet master --configprint pidfile`)' ) )
510
+ pid = host.exec( Command.new('cat `puppet master --configprint pidfile`') ).stdout.chomp
511
+ host.exec( Command.new( "kill #{pid}" ) )
512
+ Timeout.timeout(10) do
513
+ while host.exec( Command.new( "kill -0 #{pid}"), :acceptable_exit_codes => [0,1] ).exit_code == 0 do
514
+ # until kill -0 finds no process and we know that puppet has finished cleaning up
515
+ sleep 1
516
+ end
517
+ end
518
+ rescue RuntimeError => e
519
+ dump_puppet_log host
520
+ raise e
521
+ end
522
+
523
+ # @!visibility private
524
+ def dump_puppet_log(host)
525
+ syslogfile = case host['platform']
526
+ when /fedora|centos|el/ then '/var/log/messages'
527
+ when /ubuntu|debian/ then '/var/log/syslog'
528
+ else return
529
+ end
530
+
531
+ logger.notify "\n*************************"
532
+ logger.notify "* Dumping master log *"
533
+ logger.notify "*************************"
534
+ host.exec( Command.new( "tail -n 100 #{syslogfile}" ), :acceptable_exit_codes => [0,1])
535
+ logger.notify "*************************\n"
374
536
  end
375
537
 
376
538
  # @!visibility private
377
539
  def lay_down_new_puppet_conf( host, configuration_options, testdir )
378
- new_conf = puppet_conf_for( host )
540
+ new_conf = puppet_conf_for( host, configuration_options )
379
541
  create_remote_file host, "#{testdir}/puppet.conf", new_conf.to_s
380
542
 
381
- host.exec( Command.new( "cat #{testdir}/puppet.conf > #{host['puppetpath']}/puppet.conf", :silent => true ) )
543
+ host.exec(
544
+ Command.new( "cat #{testdir}/puppet.conf > #{host['puppetpath']}/puppet.conf" ),
545
+ :silent => true
546
+ )
382
547
  host.exec( Command.new( "cat #{host['puppetpath']}/puppet.conf" ) )
383
548
  end
384
549
 
@@ -467,6 +632,12 @@ module Beaker
467
632
  on host, puppet( 'apply', *args), on_options, &block
468
633
  end
469
634
 
635
+ # Runs 'puppet apply' on default host, piping manifest through stdin
636
+ # @see #apply_manifest_on
637
+ def apply_manifest(manifest, opts = {}, &block)
638
+ apply_manifest_on(default, manifest, opts, &block)
639
+ end
640
+
470
641
  # @deprecated
471
642
  def run_agent_on(host, arg='--no-daemonize --verbose --onetime --test',
472
643
  options={}, &block)
@@ -517,7 +688,7 @@ module Beaker
517
688
  # removed always.
518
689
  #
519
690
  # @param machine [String] the host to execute this stub
520
- # @param hosts [Hash{String=>String}] a hash containing the host to ip
691
+ # @param ip_spec [Hash{String=>String}] a hash containing the host to ip
521
692
  # mappings
522
693
  # @example Stub puppetlabs.com on the master to 127.0.0.1
523
694
  # stub_hosts_on(master, 'puppetlabs.com' => '127.0.0.1')
@@ -537,6 +708,16 @@ module Beaker
537
708
  end
538
709
  end
539
710
 
711
+ # This method accepts a block and using the puppet resource 'host' will
712
+ # setup host aliases before and after that block on the default host
713
+ #
714
+ # @example Stub puppetlabs.com on the default host to 127.0.0.1
715
+ # stub_hosts('puppetlabs.com' => '127.0.0.1')
716
+ # @see #stub_hosts_on
717
+ def stub_hosts(ip_spec)
718
+ stub_hosts_on(default, ip_spec)
719
+ end
720
+
540
721
  # This wraps the method `stub_hosts_on` and makes the stub specific to
541
722
  # the forge alias.
542
723
  #
@@ -545,81 +726,114 @@ module Beaker
545
726
  @forge_ip ||= Resolv.getaddress(forge)
546
727
  stub_hosts_on(machine, 'forge.puppetlabs.com' => @forge_ip)
547
728
  end
548
- def sleep_until_puppetdb_started(host)
549
- curl_with_retries("start puppetdb", host, "http://localhost:8080", 0, 120)
550
- curl_with_retries("start puppetdb (ssl)",
551
- host, "https://#{host.node_name}:8081", [35, 60])
552
- end
553
-
554
- def curl_with_retries(desc, host, url, desired_exit_codes, max_retries = 60, retry_interval = 1)
555
- retry_command(desc, host, "curl #{url}", desired_exit_codes, max_retries, retry_interval)
556
- end
557
-
558
- def retry_command(desc, host, command, desired_exit_codes = 0, max_retries = 60, retry_interval = 1)
559
- desired_exit_codes = [desired_exit_codes].flatten
560
- result = on host, command, :acceptable_exit_codes => (0...127)
561
- num_retries = 0
562
- until desired_exit_codes.include?(result.exit_code)
563
- sleep retry_interval
564
- result = on host, command, :acceptable_exit_codes => (0...127)
565
- num_retries += 1
566
- if (num_retries > max_retries)
567
- fail("Unable to #{desc}")
568
- end
569
- end
570
- end
571
-
572
- #stops the puppet agent running on the host
573
- def stop_agent(agent)
574
- vardir = agent.puppet['vardir']
575
- agent_running = true
576
- while agent_running
577
- result = on agent, "[ -e '#{vardir}/state/agent_catalog_run.lock' ]", :acceptable_exit_codes => [0,1]
578
- agent_running = (result.exit_code == 0)
579
- sleep 2 unless agent_running
580
- end
581
-
582
- if agent['platform'].include?('solaris')
583
- on(agent, '/usr/sbin/svcadm disable -s svc:/network/pe-puppet:default')
584
- elsif agent['platform'].include?('aix')
585
- on(agent, '/usr/bin/stopsrc -s pe-puppet')
586
- elsif agent['platform'].include?('windows')
587
- on(agent, 'net stop pe-puppet', :acceptable_exit_codes => [0,2])
588
- else
589
- # For the sake of not passing the PE version into this method,
590
- # we just query the system to find out which service we want to
591
- # stop
592
- result = on agent, "[ -e /etc/init.d/pe-puppet-agent ]", :acceptable_exit_codes => [0,1]
593
- service = (result.exit_code == 0) ? 'pe-puppet-agent' : 'pe-puppet'
594
- on(agent, "/etc/init.d/#{service} stop")
595
- end
596
- end
597
-
598
-
599
- #wait for a given host to appear in the dashboard
600
- def wait_for_host_in_dashboard(host)
601
- hostname = host.node_name
602
- retry_command("Wait for #{hostname} to be in the console", dashboard, "! curl --sslv3 -k -I https://#{dashboard}/nodes/#{hostname} | grep '404 Not Found'")
603
- end
604
-
605
-
606
- #prompt the master to sign certs then check to confirm the cert for this host is signed
607
- def sign_certificate(host)
608
- return if [master, dashboard, database].include? host
609
-
610
- hostname = Regexp.escape host.node_name
611
-
612
- last_sleep = 0
613
- next_sleep = 1
614
- (0..10).each do |i|
615
- fail_test("Failed to sign cert for #{hostname}") if i == 10
616
-
617
- on master, puppet("cert --sign --all"), :acceptable_exit_codes => [0,24]
618
- break if on(master, puppet("cert --list --all")).stdout =~ /\+ "?#{hostname}"?/
619
- sleep next_sleep
620
- (last_sleep, next_sleep) = next_sleep, last_sleep+next_sleep
621
- end
622
- end
729
+
730
+ # This wraps the method `stub_hosts` and makes the stub specific to
731
+ # the forge alias.
732
+ #
733
+ # @see #stub_forge_on
734
+ def stub_forge
735
+ stub_forge_on(default)
736
+ end
737
+
738
+ def sleep_until_puppetdb_started(host)
739
+ curl_with_retries("start puppetdb", host, "http://localhost:8080", 0, 120)
740
+ curl_with_retries("start puppetdb (ssl)",
741
+ host, "https://#{host.node_name}:8081", [35, 60])
742
+ end
743
+
744
+ def curl_with_retries(desc, host, url, desired_exit_codes, max_retries = 60, retry_interval = 1)
745
+ retry_command(desc, host, "curl #{url}", desired_exit_codes, max_retries, retry_interval)
746
+ end
747
+
748
+ def retry_command(desc, host, command, desired_exit_codes = 0, max_retries = 60, retry_interval = 1)
749
+ desired_exit_codes = [desired_exit_codes].flatten
750
+ result = on host, command, :acceptable_exit_codes => (0...127)
751
+ num_retries = 0
752
+ until desired_exit_codes.include?(result.exit_code)
753
+ sleep retry_interval
754
+ result = on host, command, :acceptable_exit_codes => (0...127)
755
+ num_retries += 1
756
+ if (num_retries > max_retries)
757
+ fail("Unable to #{desc}")
758
+ end
759
+ end
760
+ end
761
+
762
+ #stops the puppet agent running on the host
763
+ def stop_agent_on(agent)
764
+ vardir = agent.puppet['vardir']
765
+ agent_running = true
766
+ while agent_running
767
+ result = on agent, "[ -e '#{vardir}/state/agent_catalog_run.lock' ]", :acceptable_exit_codes => [0,1]
768
+ agent_running = (result.exit_code == 0)
769
+ sleep 2 unless agent_running
770
+ end
771
+
772
+ if agent['platform'].include?('solaris')
773
+ on(agent, '/usr/sbin/svcadm disable -s svc:/network/pe-puppet:default')
774
+ elsif agent['platform'].include?('aix')
775
+ on(agent, '/usr/bin/stopsrc -s pe-puppet')
776
+ elsif agent['platform'].include?('windows')
777
+ on(agent, 'net stop pe-puppet', :acceptable_exit_codes => [0,2])
778
+ else
779
+ # For the sake of not passing the PE version into this method,
780
+ # we just query the system to find out which service we want to
781
+ # stop
782
+ result = on agent, "[ -e /etc/init.d/pe-puppet-agent ]", :acceptable_exit_codes => [0,1]
783
+ service = (result.exit_code == 0) ? 'pe-puppet-agent' : 'pe-puppet'
784
+ on(agent, "/etc/init.d/#{service} stop")
785
+ end
786
+ end
787
+
788
+ #stops the puppet agent running on the default host
789
+ # @see #stop_agent_on
790
+ def stop_agent
791
+ stop_agent_on(default)
792
+ end
793
+
794
+
795
+ #wait for a given host to appear in the dashboard
796
+ def wait_for_host_in_dashboard(host)
797
+ hostname = host.node_name
798
+ retry_command("Wait for #{hostname} to be in the console", dashboard, "! curl --sslv3 -k -I https://#{dashboard}/nodes/#{hostname} | grep '404 Not Found'")
799
+ end
800
+
801
+ # Ensure the host has requested a cert, then sign it
802
+ #
803
+ # @param [Host] host The host to sign for
804
+ #
805
+ # @returns nil
806
+ # @raise [FailTest] if process times out
807
+ def sign_certificate_for(host)
808
+ if [master, dashboard, database].include? host
809
+
810
+ on host, puppet( 'agent -t' ), :acceptable_exit_codes => [0,1,2]
811
+ on master, puppet( "cert --allow-dns-alt-names sign #{host}" ), :acceptable_exit_codes => [0,24]
812
+
813
+ else
814
+
815
+ hostname = Regexp.escape host.node_name
816
+
817
+ last_sleep = 0
818
+ next_sleep = 1
819
+ (0..10).each do |i|
820
+ fail_test("Failed to sign cert for #{hostname}") if i == 10
821
+
822
+ on master, puppet("cert --sign --all"), :acceptable_exit_codes => [0,24]
823
+ break if on(master, puppet("cert --list --all")).stdout =~ /\+ "?#{hostname}"?/
824
+ sleep next_sleep
825
+ (last_sleep, next_sleep) = next_sleep, last_sleep+next_sleep
826
+ end
827
+
828
+ end
829
+ end
830
+
831
+ #prompt the master to sign certs then check to confirm the cert for the default host is signed
832
+ #@see #sign_certificate_for
833
+ def sign_certificate
834
+ sign_certificate_for(default)
835
+ end
836
+
623
837
  end
624
838
  end
625
839
  end