beaker 0.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 (88) hide show
  1. checksums.yaml +15 -0
  2. data/.gitignore +17 -0
  3. data/.rspec +2 -0
  4. data/.simplecov +14 -0
  5. data/DOCUMENTING.md +167 -0
  6. data/Gemfile +3 -0
  7. data/LICENSE +17 -0
  8. data/README.md +332 -0
  9. data/Rakefile +121 -0
  10. data/beaker.gemspec +42 -0
  11. data/beaker.rb +10 -0
  12. data/bin/beaker +9 -0
  13. data/lib/beaker.rb +36 -0
  14. data/lib/beaker/answers.rb +29 -0
  15. data/lib/beaker/answers/version28.rb +104 -0
  16. data/lib/beaker/answers/version30.rb +194 -0
  17. data/lib/beaker/cli.rb +113 -0
  18. data/lib/beaker/command.rb +241 -0
  19. data/lib/beaker/command_factory.rb +21 -0
  20. data/lib/beaker/dsl.rb +85 -0
  21. data/lib/beaker/dsl/assertions.rb +87 -0
  22. data/lib/beaker/dsl/helpers.rb +625 -0
  23. data/lib/beaker/dsl/install_utils.rb +299 -0
  24. data/lib/beaker/dsl/outcomes.rb +99 -0
  25. data/lib/beaker/dsl/roles.rb +97 -0
  26. data/lib/beaker/dsl/structure.rb +63 -0
  27. data/lib/beaker/dsl/wrappers.rb +100 -0
  28. data/lib/beaker/host.rb +193 -0
  29. data/lib/beaker/host/aix.rb +15 -0
  30. data/lib/beaker/host/aix/file.rb +16 -0
  31. data/lib/beaker/host/aix/group.rb +35 -0
  32. data/lib/beaker/host/aix/user.rb +32 -0
  33. data/lib/beaker/host/unix.rb +54 -0
  34. data/lib/beaker/host/unix/exec.rb +15 -0
  35. data/lib/beaker/host/unix/file.rb +16 -0
  36. data/lib/beaker/host/unix/group.rb +40 -0
  37. data/lib/beaker/host/unix/pkg.rb +22 -0
  38. data/lib/beaker/host/unix/user.rb +32 -0
  39. data/lib/beaker/host/windows.rb +44 -0
  40. data/lib/beaker/host/windows/exec.rb +18 -0
  41. data/lib/beaker/host/windows/file.rb +15 -0
  42. data/lib/beaker/host/windows/group.rb +36 -0
  43. data/lib/beaker/host/windows/pkg.rb +26 -0
  44. data/lib/beaker/host/windows/user.rb +32 -0
  45. data/lib/beaker/hypervisor.rb +37 -0
  46. data/lib/beaker/hypervisor/aixer.rb +52 -0
  47. data/lib/beaker/hypervisor/blimper.rb +123 -0
  48. data/lib/beaker/hypervisor/fusion.rb +56 -0
  49. data/lib/beaker/hypervisor/solaris.rb +65 -0
  50. data/lib/beaker/hypervisor/vagrant.rb +118 -0
  51. data/lib/beaker/hypervisor/vcloud.rb +175 -0
  52. data/lib/beaker/hypervisor/vsphere.rb +80 -0
  53. data/lib/beaker/hypervisor/vsphere_helper.rb +200 -0
  54. data/lib/beaker/logger.rb +167 -0
  55. data/lib/beaker/network_manager.rb +73 -0
  56. data/lib/beaker/options_parsing.rb +323 -0
  57. data/lib/beaker/result.rb +55 -0
  58. data/lib/beaker/shared.rb +15 -0
  59. data/lib/beaker/shared/error_handler.rb +17 -0
  60. data/lib/beaker/shared/host_handler.rb +46 -0
  61. data/lib/beaker/shared/repetition.rb +28 -0
  62. data/lib/beaker/ssh_connection.rb +198 -0
  63. data/lib/beaker/test_case.rb +225 -0
  64. data/lib/beaker/test_config.rb +148 -0
  65. data/lib/beaker/test_suite.rb +288 -0
  66. data/lib/beaker/utils.rb +7 -0
  67. data/lib/beaker/utils/ntp_control.rb +42 -0
  68. data/lib/beaker/utils/repo_control.rb +92 -0
  69. data/lib/beaker/utils/setup_helper.rb +77 -0
  70. data/lib/beaker/utils/validator.rb +27 -0
  71. data/spec/beaker/command_spec.rb +94 -0
  72. data/spec/beaker/dsl/assertions_spec.rb +104 -0
  73. data/spec/beaker/dsl/helpers_spec.rb +230 -0
  74. data/spec/beaker/dsl/install_utils_spec.rb +70 -0
  75. data/spec/beaker/dsl/outcomes_spec.rb +43 -0
  76. data/spec/beaker/dsl/roles_spec.rb +86 -0
  77. data/spec/beaker/dsl/structure_spec.rb +60 -0
  78. data/spec/beaker/dsl/wrappers_spec.rb +52 -0
  79. data/spec/beaker/host_spec.rb +95 -0
  80. data/spec/beaker/logger_spec.rb +117 -0
  81. data/spec/beaker/options_parsing_spec.rb +37 -0
  82. data/spec/beaker/puppet_command_spec.rb +128 -0
  83. data/spec/beaker/ssh_connection_spec.rb +39 -0
  84. data/spec/beaker/test_case_spec.rb +6 -0
  85. data/spec/beaker/test_suite_spec.rb +44 -0
  86. data/spec/mocks_and_helpers.rb +34 -0
  87. data/spec/spec_helper.rb +15 -0
  88. metadata +359 -0
@@ -0,0 +1,54 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), '..', 'host'))
2
+ require File.expand_path(File.join(File.dirname(__FILE__), '..', 'command_factory'))
3
+ require File.expand_path(File.join(File.dirname(__FILE__), '..', 'command'))
4
+
5
+ module Unix
6
+ class Host < Beaker::Host
7
+ require File.expand_path(File.join(File.dirname(__FILE__), 'unix', 'user'))
8
+ require File.expand_path(File.join(File.dirname(__FILE__), 'unix', 'group'))
9
+ require File.expand_path(File.join(File.dirname(__FILE__), 'unix', 'exec'))
10
+ require File.expand_path(File.join(File.dirname(__FILE__), 'unix', 'pkg'))
11
+ require File.expand_path(File.join(File.dirname(__FILE__), 'unix', 'file'))
12
+
13
+ include Unix::User
14
+ include Unix::Group
15
+ include Unix::File
16
+ include Unix::Exec
17
+ include Unix::Pkg
18
+
19
+ def self.pe_defaults
20
+ {
21
+ 'user' => 'root',
22
+ 'group' => 'pe-puppet',
23
+ 'puppetpath' => '/etc/puppetlabs/puppet',
24
+ 'puppetbin' => '/opt/puppet/bin/puppet',
25
+ 'puppetbindir' => '/opt/puppet/bin',
26
+ 'puppetvardir' => '/var/opt/lib/pe-puppet',
27
+ 'hieradatadir' => '/var/lib/hiera',
28
+ 'hieraconf' => '/etc/puppetlabs/puppet/hiera.yaml',
29
+ 'distmoduledir' => '/etc/puppetlabs/puppet/modules',
30
+ 'sitemoduledir' => '/opt/puppet/share/puppet/modules',
31
+ 'pathseparator' => ':',
32
+ }
33
+ end
34
+
35
+ def self.foss_defaults
36
+ {
37
+ 'user' => 'root',
38
+ 'group' => 'puppet',
39
+ 'puppetpath' => '/etc/puppet',
40
+ 'puppetvardir' => '/var/lib/puppet',
41
+ 'puppetbin' => '/usr/bin/puppet',
42
+ 'puppetbindir' => '/usr/bin',
43
+ 'hieralibdir' => '/opt/puppet-git-repos/hiera/lib',
44
+ 'hierapuppetlibdir' => '/opt/puppet-git-repos/hiera-puppet/lib',
45
+ 'hierabindir' => '/opt/puppet-git-repos/hiera/bin',
46
+ 'hieradatadir' => '/etc/puppet/hieradata',
47
+ 'hieraconf' => '/etc/puppet/hiera.yaml',
48
+ 'distmoduledir' => '/etc/puppet/modules',
49
+ 'sitemoduledir' => '/usr/share/puppet/modules',
50
+ 'pathseparator' => ':',
51
+ }
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,15 @@
1
+ module Unix::Exec
2
+ include Beaker::CommandFactory
3
+
4
+ def echo(msg, abs=true)
5
+ (abs ? '/bin/echo' : 'echo') + " #{msg}"
6
+ end
7
+
8
+ def touch(file, abs=true)
9
+ (abs ? '/bin/touch' : 'touch') + " #{file}"
10
+ end
11
+
12
+ def path
13
+ '/bin:/usr/bin'
14
+ end
15
+ end
@@ -0,0 +1,16 @@
1
+ module Unix::File
2
+ include Beaker::CommandFactory
3
+
4
+ def tmpfile(name)
5
+ execute("mktemp -t #{name}.XXXXXX")
6
+ end
7
+
8
+ def tmpdir(name)
9
+ execute("mktemp -td #{name}.XXXXXX")
10
+ end
11
+
12
+ def path_split(paths)
13
+ paths.split(':')
14
+ end
15
+
16
+ end
@@ -0,0 +1,40 @@
1
+ module Unix::Group
2
+ include Beaker::CommandFactory
3
+
4
+ def group_list(&block)
5
+ execute("getent group") do |result|
6
+ groups = []
7
+ result.stdout.each_line do |line|
8
+ groups << (line.match(/^([^:]+)/) or next)[1]
9
+ end
10
+
11
+ yield result if block_given?
12
+
13
+ groups
14
+ end
15
+ end
16
+
17
+ def group_get(name, &block)
18
+ execute("getent group #{name}") do |result|
19
+ fail_test "failed to get group #{name}" unless result.stdout =~ /^#{name}:.*:[0-9]+:/
20
+
21
+ yield result if block_given?
22
+ end
23
+ end
24
+
25
+ def group_gid(name)
26
+ execute("getent group #{name}") do |result|
27
+ # Format is:
28
+ # wheel:x:10:root
29
+ result.stdout.split(':')[2]
30
+ end
31
+ end
32
+
33
+ def group_present(name, &block)
34
+ execute("if ! getent group #{name}; then groupadd #{name}; fi", {}, &block)
35
+ end
36
+
37
+ def group_absent(name, &block)
38
+ execute("if getent group #{name}; then groupdel #{name}; fi", {}, &block)
39
+ end
40
+ end
@@ -0,0 +1,22 @@
1
+ module Unix::Pkg
2
+ include Beaker::CommandFactory
3
+
4
+ def check_for_package name
5
+ result = exec(Beaker::Command.new("which #{name}"), :acceptable_exit_codes => (0...127))
6
+ result.exit_code == 0
7
+ end
8
+
9
+ def install_package name
10
+ if self['platform'] =~ /el-4/
11
+ @logger.debug("Package installation not supported on rhel4")
12
+ elsif self['platform'] =~ /(fedora)|(centos)|(el)/
13
+ execute("yum -y install #{name}")
14
+ elsif self['platform'] =~ /(ubuntu)|(debian)/
15
+ execute("apt-get update")
16
+ execute("apt-get install -y #{name}")
17
+ else
18
+ raise "Package #{name} cannot be installed on #{host}"
19
+ end
20
+ end
21
+
22
+ end
@@ -0,0 +1,32 @@
1
+ module Unix::User
2
+ include Beaker::CommandFactory
3
+
4
+ def user_list(&block)
5
+ execute("getent passwd") do |result|
6
+ users = []
7
+ result.stdout.each_line do |line|
8
+ users << (line.match( /^([^:]+)/) or next)[1]
9
+ end
10
+
11
+ yield result if block_given?
12
+
13
+ users
14
+ end
15
+ end
16
+
17
+ def user_get(name, &block)
18
+ execute("getent passwd #{name}") do |result|
19
+ fail_test "failed to get user #{name}" unless result.stdout =~ /^#{name}:/
20
+
21
+ yield result if block_given?
22
+ end
23
+ end
24
+
25
+ def user_present(name, &block)
26
+ execute("if ! getent passwd #{name}; then useradd #{name}; fi", {}, &block)
27
+ end
28
+
29
+ def user_absent(name, &block)
30
+ execute("if getent passwd #{name}; then userdel #{name}; fi", {}, &block)
31
+ end
32
+ end
@@ -0,0 +1,44 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), '..', 'host'))
2
+ require File.expand_path(File.join(File.dirname(__FILE__), '..', 'command_factory'))
3
+ require File.expand_path(File.join(File.dirname(__FILE__), '..', 'command'))
4
+
5
+ module Windows
6
+ class Host < Beaker::Host
7
+ require File.expand_path(File.join(File.dirname(__FILE__), 'windows', 'user'))
8
+ require File.expand_path(File.join(File.dirname(__FILE__), 'windows', 'group'))
9
+ require File.expand_path(File.join(File.dirname(__FILE__), 'windows', 'exec'))
10
+ require File.expand_path(File.join(File.dirname(__FILE__), 'windows', 'pkg'))
11
+ require File.expand_path(File.join(File.dirname(__FILE__), 'windows', 'file'))
12
+
13
+ include Windows::User
14
+ include Windows::Group
15
+ include Windows::File
16
+ include Windows::Exec
17
+ include Windows::Pkg
18
+
19
+ def self.pe_defaults
20
+ {
21
+ 'user' => 'Administrator',
22
+ 'group' => 'Administrators',
23
+ 'puppetpath' => '`cygpath -smF 35`/PuppetLabs/puppet/etc',
24
+ 'puppetvardir' => '`cygpath -smF 35`/PuppetLabs/puppet/var',
25
+ 'puppetbindir' => '`cygpath -F 38`/Puppet Labs/Puppet Enterprise/bin',
26
+ 'pathseparator' => ';',
27
+ }
28
+ end
29
+
30
+ def self.foss_defaults
31
+ {
32
+ 'user' => 'Administrator',
33
+ 'group' => 'Administrators',
34
+ 'puppetpath' => '`cygpath -smF 35`/PuppetLabs/puppet/etc',
35
+ 'puppetvardir' => '`cygpath -smF 35`/PuppetLabs/puppet/var',
36
+ 'hieralibdir' => '`cygpath -w /opt/puppet-git-repos/hiera/lib`',
37
+ 'hierapuppetlibdir' => '`cygpath -w /opt/puppet-git-repos/hiera-puppet/lib`',
38
+ # PATH related variables need to be Unix, which cygwin converts
39
+ 'hierabindir' => '/opt/puppet-git-repos/hiera/bin',
40
+ 'pathseparator' => ';',
41
+ }
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,18 @@
1
+ module Windows::Exec
2
+ include Beaker::CommandFactory
3
+
4
+ ABS_CMD = 'c:\\\\windows\\\\system32\\\\cmd.exe'
5
+ CMD = 'cmd.exe'
6
+
7
+ def echo(msg, abs=true)
8
+ (abs ? ABS_CMD : CMD) + " /c echo #{msg}"
9
+ end
10
+
11
+ def touch(file, abs=true)
12
+ (abs ? ABS_CMD : CMD) + " /c echo. 2> #{file}"
13
+ end
14
+
15
+ def path
16
+ 'c:/windows/system32;c:/windows'
17
+ end
18
+ end
@@ -0,0 +1,15 @@
1
+ module Windows::File
2
+ include Beaker::CommandFactory
3
+
4
+ def tmpfile(name)
5
+ execute("cygpath -m $(mktemp -t #{name}.XXXXXX)")
6
+ end
7
+
8
+ def tmpdir(name)
9
+ execute("cygpath -m $(mktemp -td #{name}.XXXXXX)")
10
+ end
11
+
12
+ def path_split(paths)
13
+ paths.split(';')
14
+ end
15
+ end
@@ -0,0 +1,36 @@
1
+ module Windows::Group
2
+ include Beaker::CommandFactory
3
+
4
+ def group_list(&block)
5
+ execute('cmd /c echo "" | wmic group where localaccount="true" get name /format:value') do |result|
6
+ groups = []
7
+ result.stdout.each_line do |line|
8
+ groups << (line.match(/^Name=([\w ]+)/) or next)[1]
9
+ end
10
+
11
+ yield result if block_given?
12
+
13
+ groups
14
+ end
15
+ end
16
+
17
+ def group_get(name, &block)
18
+ execute("net localgroup \"#{name}\"") do |result|
19
+ fail_test "failed to get group #{name}" unless result.stdout =~ /^Alias name\s+#{name}/
20
+
21
+ yield result if block_given?
22
+ end
23
+ end
24
+
25
+ def group_gid(name)
26
+ raise NotImplementedError, "Can't retrieve group gid on a Windows host"
27
+ end
28
+
29
+ def group_present(name, &block)
30
+ execute("net localgroup /add \"#{name}\"", {:acceptable_exit_codes => [0,2]}, &block)
31
+ end
32
+
33
+ def group_absent(name, &block)
34
+ execute("net localgroup /delete \"#{name}\"", {:acceptable_exit_codes => [0,2]}, &block)
35
+ end
36
+ end
@@ -0,0 +1,26 @@
1
+ module Windows::Pkg
2
+ include Beaker::CommandFactory
3
+
4
+ def check_for_package name
5
+ result = exec(Beaker::Command.new("which #{name}"), :acceptable_exit_codes => (0...127))
6
+ result.exit_code == 0
7
+ end
8
+
9
+ def install_package name
10
+ cygwin = ""
11
+ rootdir = ""
12
+ result = exec(Beaker::Command.new("wmic os get osarchitecture | grep 32"), :acceptable_exit_codes => (0...127))
13
+ if result.exit_code == 0 #32 bit version
14
+ rootdir = "c:\\\\cygwin"
15
+ cygwin = "setup-x86.exe"
16
+ else #64 bit version
17
+ rootdir = "c:\\\\cygwin64"
18
+ cygwin = "setup-x86_64.exe"
19
+ end
20
+ if not check_for_package(cygwin)
21
+ execute("curl --retry 5 http://cygwin.com/#{cygwin} -o /cygdrive/c/Windows/System32/#{cygwin}")
22
+ end
23
+ execute("#{cygwin} -q -n -N -d -R #{rootdir} -s http://cygwin.osuosl.org -P #{name}")
24
+ end
25
+
26
+ end
@@ -0,0 +1,32 @@
1
+ module Windows::User
2
+ include Beaker::CommandFactory
3
+
4
+ def user_list(&block)
5
+ execute('cmd /c echo "" | wmic useraccount where localaccount="true" get name /format:value') do |result|
6
+ users = []
7
+ result.stdout.each_line do |line|
8
+ users << (line.match(/^Name=([\w ]+)/) or next)[1]
9
+ end
10
+
11
+ yield result if block_given?
12
+
13
+ users
14
+ end
15
+ end
16
+
17
+ def user_get(name, &block)
18
+ execute("net user \"#{name}\"") do |result|
19
+ fail_test "failed to get user #{name}" unless result.stdout =~ /^User name\s+#{name}/
20
+
21
+ yield result if block_given?
22
+ end
23
+ end
24
+
25
+ def user_present(name, &block)
26
+ execute("net user /add \"#{name}\"", {:acceptable_exit_codes => [0,2]}, &block)
27
+ end
28
+
29
+ def user_absent(name, &block)
30
+ execute("net user /delete \"#{name}\"", {:acceptable_exit_codes => [0,2]}, &block)
31
+ end
32
+ end
@@ -0,0 +1,37 @@
1
+ module Beaker
2
+ class Hypervisor
3
+
4
+ def configure(hosts)
5
+ @logger.debug "No post-provisioning configuration necessary for #{self.class.name} boxes"
6
+ end
7
+
8
+ def self.create type, hosts_to_provision, options, config
9
+ @logger = options[:logger]
10
+ @logger.notify("Beaker::Hypervisor, found some #{type} boxes to create")
11
+ case type
12
+ when /aix/
13
+ Beaker::Aixer.new hosts_to_provision, options, config
14
+ when /solaris/
15
+ Beaker::Solaris.new hosts_to_provision, options, config
16
+ when /vsphere/
17
+ Beaker::Vsphere.new hosts_to_provision, options, config
18
+ when /fusion/
19
+ Beaker::Fusion.new hosts_to_provision, options, config
20
+ when /blimpy/
21
+ Beaker::Blimper.new hosts_to_provision, options, config
22
+ when /vcloud/
23
+ Beaker::Vcloud.new hosts_to_provision, options, config
24
+ when /vagrant/
25
+ Beaker::Vagrant.new hosts_to_provision, options, config
26
+ end
27
+ end
28
+ end
29
+ end
30
+
31
+ %w( vsphere_helper vagrant fusion blimper vsphere vcloud aixer solaris).each do |lib|
32
+ begin
33
+ require "hypervisor/#{lib}"
34
+ rescue LoadError
35
+ require File.expand_path(File.join(File.dirname(__FILE__), "hypervisor", lib))
36
+ end
37
+ end
@@ -0,0 +1,52 @@
1
+ module Beaker
2
+ class Aixer < Beaker::Hypervisor
3
+
4
+ def initialize(aix_hosts, options, config)
5
+ @options = options
6
+ @config = config['CONFIG'].dup
7
+ @logger = options[:logger]
8
+ @aix_hosts = aix_hosts
9
+ #aix machines are reverted to known state, not a snapshot
10
+ fog_file = nil
11
+ if File.exists?( File.join(ENV['HOME'], '.fog') )
12
+ fog_file = YAML.load_file( File.join(ENV['HOME'], '.fog') )
13
+ end
14
+ raise "Cant load ~/.fog config" unless fog_file
15
+
16
+ # Running the rake task on rpm-builder
17
+ hypername = fog_file[:default][:aix_hypervisor_server]
18
+ hyperconf = {
19
+ 'HOSTS' => {
20
+ hypername => { 'platform' => 'el-6-x86_64' }
21
+ },
22
+ 'CONFIG' => {
23
+ 'user' => fog_file[:default][:aix_hypervisor_username] || ENV['USER'],
24
+ 'ssh' => {
25
+ :keys => fog_file[:default][:aix_hypervisor_keyfile] || "#{ENV['HOME']}/.ssh/id_rsa"
26
+ }
27
+ }
28
+ }
29
+ hyperconfig = Beaker::TestConfig.new( hyperconf, @options )
30
+
31
+ @logger.notify "Connecting to hypervisor at #{hypername}"
32
+ hypervisor = Beaker::Host.create( hypername, @options, hyperconfig )
33
+
34
+ @aix_hosts.each do |host|
35
+ vm_name = host['vmname'] || host.name
36
+
37
+ @logger.notify "Reverting #{vm_name} to aix clean state"
38
+ start = Time.now
39
+ # Restore AIX image, ID'd by the hostname
40
+ hypervisor.exec(Command.new("cd pe-aix && rake restore:#{host.name}"))
41
+ time = Time.now - start
42
+ @logger.notify "Spent %.2f seconds reverting" % time
43
+ end
44
+ hypervisor.close
45
+ end
46
+
47
+ def cleanup
48
+ @logger.notify "No cleanup for aix boxes"
49
+ end
50
+
51
+ end
52
+ end