beaker 0.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +15 -0
- data/.gitignore +17 -0
- data/.rspec +2 -0
- data/.simplecov +14 -0
- data/DOCUMENTING.md +167 -0
- data/Gemfile +3 -0
- data/LICENSE +17 -0
- data/README.md +332 -0
- data/Rakefile +121 -0
- data/beaker.gemspec +42 -0
- data/beaker.rb +10 -0
- data/bin/beaker +9 -0
- data/lib/beaker.rb +36 -0
- data/lib/beaker/answers.rb +29 -0
- data/lib/beaker/answers/version28.rb +104 -0
- data/lib/beaker/answers/version30.rb +194 -0
- data/lib/beaker/cli.rb +113 -0
- data/lib/beaker/command.rb +241 -0
- data/lib/beaker/command_factory.rb +21 -0
- data/lib/beaker/dsl.rb +85 -0
- data/lib/beaker/dsl/assertions.rb +87 -0
- data/lib/beaker/dsl/helpers.rb +625 -0
- data/lib/beaker/dsl/install_utils.rb +299 -0
- data/lib/beaker/dsl/outcomes.rb +99 -0
- data/lib/beaker/dsl/roles.rb +97 -0
- data/lib/beaker/dsl/structure.rb +63 -0
- data/lib/beaker/dsl/wrappers.rb +100 -0
- data/lib/beaker/host.rb +193 -0
- data/lib/beaker/host/aix.rb +15 -0
- data/lib/beaker/host/aix/file.rb +16 -0
- data/lib/beaker/host/aix/group.rb +35 -0
- data/lib/beaker/host/aix/user.rb +32 -0
- data/lib/beaker/host/unix.rb +54 -0
- data/lib/beaker/host/unix/exec.rb +15 -0
- data/lib/beaker/host/unix/file.rb +16 -0
- data/lib/beaker/host/unix/group.rb +40 -0
- data/lib/beaker/host/unix/pkg.rb +22 -0
- data/lib/beaker/host/unix/user.rb +32 -0
- data/lib/beaker/host/windows.rb +44 -0
- data/lib/beaker/host/windows/exec.rb +18 -0
- data/lib/beaker/host/windows/file.rb +15 -0
- data/lib/beaker/host/windows/group.rb +36 -0
- data/lib/beaker/host/windows/pkg.rb +26 -0
- data/lib/beaker/host/windows/user.rb +32 -0
- data/lib/beaker/hypervisor.rb +37 -0
- data/lib/beaker/hypervisor/aixer.rb +52 -0
- data/lib/beaker/hypervisor/blimper.rb +123 -0
- data/lib/beaker/hypervisor/fusion.rb +56 -0
- data/lib/beaker/hypervisor/solaris.rb +65 -0
- data/lib/beaker/hypervisor/vagrant.rb +118 -0
- data/lib/beaker/hypervisor/vcloud.rb +175 -0
- data/lib/beaker/hypervisor/vsphere.rb +80 -0
- data/lib/beaker/hypervisor/vsphere_helper.rb +200 -0
- data/lib/beaker/logger.rb +167 -0
- data/lib/beaker/network_manager.rb +73 -0
- data/lib/beaker/options_parsing.rb +323 -0
- data/lib/beaker/result.rb +55 -0
- data/lib/beaker/shared.rb +15 -0
- data/lib/beaker/shared/error_handler.rb +17 -0
- data/lib/beaker/shared/host_handler.rb +46 -0
- data/lib/beaker/shared/repetition.rb +28 -0
- data/lib/beaker/ssh_connection.rb +198 -0
- data/lib/beaker/test_case.rb +225 -0
- data/lib/beaker/test_config.rb +148 -0
- data/lib/beaker/test_suite.rb +288 -0
- data/lib/beaker/utils.rb +7 -0
- data/lib/beaker/utils/ntp_control.rb +42 -0
- data/lib/beaker/utils/repo_control.rb +92 -0
- data/lib/beaker/utils/setup_helper.rb +77 -0
- data/lib/beaker/utils/validator.rb +27 -0
- data/spec/beaker/command_spec.rb +94 -0
- data/spec/beaker/dsl/assertions_spec.rb +104 -0
- data/spec/beaker/dsl/helpers_spec.rb +230 -0
- data/spec/beaker/dsl/install_utils_spec.rb +70 -0
- data/spec/beaker/dsl/outcomes_spec.rb +43 -0
- data/spec/beaker/dsl/roles_spec.rb +86 -0
- data/spec/beaker/dsl/structure_spec.rb +60 -0
- data/spec/beaker/dsl/wrappers_spec.rb +52 -0
- data/spec/beaker/host_spec.rb +95 -0
- data/spec/beaker/logger_spec.rb +117 -0
- data/spec/beaker/options_parsing_spec.rb +37 -0
- data/spec/beaker/puppet_command_spec.rb +128 -0
- data/spec/beaker/ssh_connection_spec.rb +39 -0
- data/spec/beaker/test_case_spec.rb +6 -0
- data/spec/beaker/test_suite_spec.rb +44 -0
- data/spec/mocks_and_helpers.rb +34 -0
- data/spec/spec_helper.rb +15 -0
- metadata +359 -0
@@ -0,0 +1,92 @@
|
|
1
|
+
module Beaker
|
2
|
+
module Utils
|
3
|
+
class RepoControl
|
4
|
+
|
5
|
+
APT_CFG = %q{ Acquire::http::Proxy "http://proxy.puppetlabs.net:3128/"; }
|
6
|
+
IPS_PKG_REPO="http://solaris-11-internal-repo.delivery.puppetlabs.net"
|
7
|
+
|
8
|
+
def initialize(options, hosts)
|
9
|
+
@options = options.dup
|
10
|
+
@hosts = hosts
|
11
|
+
@logger = options[:logger]
|
12
|
+
@debug_opt = options[:debug] ? 'vh' : ''
|
13
|
+
end
|
14
|
+
|
15
|
+
def epel_info_for! host
|
16
|
+
version = host['platform'].match(/el-(\d+)/)[1]
|
17
|
+
if version == '6'
|
18
|
+
pkg = 'epel-release-6-8.noarch.rpm'
|
19
|
+
url = "http://mirror.itc.virginia.edu/fedora-epel/6/i386/#{pkg}"
|
20
|
+
elsif version == '5'
|
21
|
+
pkg = 'epel-release-5-4.noarch.rpm'
|
22
|
+
url = "http://archive.linux.duke.edu/pub/epel/5/i386/#{pkg}"
|
23
|
+
else
|
24
|
+
raise "I don't understand your platform description!"
|
25
|
+
end
|
26
|
+
return url
|
27
|
+
end
|
28
|
+
|
29
|
+
def apt_get_update
|
30
|
+
@hosts.each do |host|
|
31
|
+
if host['platform'] =~ /ubuntu|debian/
|
32
|
+
host.exec(Command.new("apt-get -y -f -m update"))
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def copy_file_to_remote(host, file_path, file_content)
|
38
|
+
Tempfile.open 'beaker' do |tempfile|
|
39
|
+
File.open(tempfile.path, 'w') {|file| file.puts file_content }
|
40
|
+
|
41
|
+
host.do_scp_to(tempfile.path, file_path, @options)
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
45
|
+
|
46
|
+
def proxy_config
|
47
|
+
# repo_proxy
|
48
|
+
# supports ubuntu, debian and solaris platforms
|
49
|
+
@hosts.each do |host|
|
50
|
+
case
|
51
|
+
when host['platform'] =~ /ubuntu/
|
52
|
+
host.exec(Command.new("if test -f /etc/apt/apt.conf; then mv /etc/apt/apt.conf /etc/apt/apt.conf.bk; fi"))
|
53
|
+
copy_file_to_remote(host, '/etc/apt/apt.conf', APT_CFG)
|
54
|
+
apt_get_update
|
55
|
+
when host['platform'] =~ /debian/
|
56
|
+
host.exec(Command.new("if test -f /etc/apt/apt.conf; then mv /etc/apt/apt.conf /etc/apt/apt.conf.bk; fi"))
|
57
|
+
copy_file_to_remote(host, '/etc/apt/apt.conf', APT_CFG)
|
58
|
+
apt_get_update
|
59
|
+
when host['platform'] =~ /solaris-11/
|
60
|
+
host.exec(Command.new("/usr/bin/pkg unset-publisher solaris || :"))
|
61
|
+
host.exec(Command.new(host,"/usr/bin/pkg set-publisher -g %s solaris" % IPS_PKG_REPO))
|
62
|
+
else
|
63
|
+
@logger.debug "#{host}: repo proxy configuration not modified"
|
64
|
+
end
|
65
|
+
end
|
66
|
+
rescue => e
|
67
|
+
report_and_raise(@logger, e, "proxy_config")
|
68
|
+
end
|
69
|
+
|
70
|
+
def add_el_extras
|
71
|
+
#add_el_extras
|
72
|
+
#only supports el-* platforms
|
73
|
+
@hosts.each do |host|
|
74
|
+
case
|
75
|
+
when host['platform'] =~ /el-(5|6)/
|
76
|
+
result = host.exec(Command.new('rpm -qa | grep epel-release'), :acceptable_exit_codes => [0,1])
|
77
|
+
if result.exit_code == 1
|
78
|
+
url = epel_info_for! host
|
79
|
+
host.exec(Command.new("rpm -i#{@debug_opt} #{url}"))
|
80
|
+
host.exec(Command.new('yum clean all && yum makecache'))
|
81
|
+
end
|
82
|
+
else
|
83
|
+
@logger.debug "#{host}: package repo configuration not modified"
|
84
|
+
end
|
85
|
+
end
|
86
|
+
rescue => e
|
87
|
+
report_and_raise(@logger, e, "add_repos")
|
88
|
+
end
|
89
|
+
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
module Beaker
|
2
|
+
module Utils
|
3
|
+
class SetupHelper
|
4
|
+
|
5
|
+
def initialize(options, hosts)
|
6
|
+
@options = options.dup
|
7
|
+
@hosts = hosts
|
8
|
+
@logger = options[:logger]
|
9
|
+
end
|
10
|
+
|
11
|
+
def find_masters(hosts)
|
12
|
+
hosts.select do |host|
|
13
|
+
host['roles'].include?("master")
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def find_only_master(hosts)
|
18
|
+
m = find_masters(hosts)
|
19
|
+
raise "too many masters, expected one but found #{m.map {|h| h.to_s }}" unless m.length == 1
|
20
|
+
m.first
|
21
|
+
end
|
22
|
+
|
23
|
+
def add_master_entry
|
24
|
+
@logger.notify "Add Master entry to /etc/hosts"
|
25
|
+
master = find_only_master(@hosts)
|
26
|
+
if master["hypervisor"] and master["hypervisor"] =~ /vagrant/
|
27
|
+
@logger.debug "Don't update master entry on vagrant masters"
|
28
|
+
return
|
29
|
+
end
|
30
|
+
@logger.debug "Get ip address of Master #{master}"
|
31
|
+
if master['platform'].include? 'solaris'
|
32
|
+
stdout = master.exec(Command.new("ifconfig -a inet| awk '/broadcast/ {print $2}' | cut -d/ -f1 | head -1")).stdout
|
33
|
+
else
|
34
|
+
stdout = master.exec(Command.new("ip a|awk '/g/{print$2}' | cut -d/ -f1 | head -1")).stdout
|
35
|
+
end
|
36
|
+
ip=stdout.chomp
|
37
|
+
|
38
|
+
path = "/etc/hosts"
|
39
|
+
if master['platform'].include? 'solaris'
|
40
|
+
path = "/etc/inet/hosts"
|
41
|
+
end
|
42
|
+
|
43
|
+
@logger.debug "Update %s on #{master}" % path
|
44
|
+
# Preserve the mode the easy way...
|
45
|
+
master.exec(Command.new("cp %s %s.old" % [path, path]))
|
46
|
+
master.exec(Command.new("cp %s %s.new" % [path, path]))
|
47
|
+
master.exec(Command.new("grep -v '#{ip} #{master}' %s > %s.new" % [path, path]))
|
48
|
+
master.exec(Command.new("echo '#{ip} #{master}' >> %s.new" % path))
|
49
|
+
master.exec(Command.new("mv %s.new %s" % [path, path]))
|
50
|
+
rescue => e
|
51
|
+
report_and_raise(@logger, e, "add_master_entry")
|
52
|
+
end
|
53
|
+
|
54
|
+
def sync_root_keys
|
55
|
+
# JJM This step runs on every system under test right now. We're anticipating
|
56
|
+
# issues on Windows and maybe Solaris. We will likely need to filter this step
|
57
|
+
# but we're deliberately taking the approach of "assume it will work, fix it
|
58
|
+
# when reality dictates otherwise"
|
59
|
+
@logger.notify "Sync root authorized_keys from github"
|
60
|
+
script = "https://raw.github.com/puppetlabs/puppetlabs-sshkeys/master/templates/scripts/manage_root_authorized_keys"
|
61
|
+
setup_root_authorized_keys = "curl -k -o - #{script} | %s"
|
62
|
+
@logger.notify "Sync root authorized_keys from github"
|
63
|
+
@hosts.each do |host|
|
64
|
+
# Allow all exit code, as this operation is unlikely to cause problems if it fails.
|
65
|
+
if host['platform'].include? 'solaris'
|
66
|
+
host.exec(Command.new(setup_root_authorized_keys % "bash"), :acceptable_exit_codes => (0..255))
|
67
|
+
else
|
68
|
+
host.exec(Command.new(setup_root_authorized_keys % "env PATH=/usr/gnu/bin:$PATH bash"), :acceptable_exit_codes => (0..255))
|
69
|
+
end
|
70
|
+
end
|
71
|
+
rescue => e
|
72
|
+
report_and_raise(@logger, e, "sync_root_keys")
|
73
|
+
end
|
74
|
+
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module Beaker
|
2
|
+
module Utils
|
3
|
+
module Validator
|
4
|
+
PACKAGES = ['curl']
|
5
|
+
UNIX_PACKAGES = ['ntpdate']
|
6
|
+
|
7
|
+
def self.validate(hosts, logger)
|
8
|
+
hosts.each do |host|
|
9
|
+
PACKAGES.each do |pkg|
|
10
|
+
if not host.check_for_package pkg
|
11
|
+
host.install_package pkg
|
12
|
+
end
|
13
|
+
end
|
14
|
+
if host['platform'] !~ /(windows)|(aix)|(solaris)/
|
15
|
+
UNIX_PACKAGES.each do |pkg|
|
16
|
+
if not host.check_for_package pkg
|
17
|
+
host.install_package pkg
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
rescue => e
|
23
|
+
report_and_raise(logger, e, "validate")
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,94 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Beaker
|
4
|
+
describe Command do
|
5
|
+
let(:command) { @command || '/bin/ls' }
|
6
|
+
let(:args) { @args || Array.new }
|
7
|
+
let(:options) { @options || Hash.new }
|
8
|
+
subject(:cmd) { Command.new( command, args, options ) }
|
9
|
+
let(:host) { Hash.new }
|
10
|
+
|
11
|
+
it 'creates a new Command object' do
|
12
|
+
@command = '/usr/bin/blah'
|
13
|
+
@args = [ 'to', 'the', 'baz' ]
|
14
|
+
@options = { :foo => 'bar' }
|
15
|
+
|
16
|
+
expect( cmd.options ).to be == @options
|
17
|
+
expect( cmd.args ).to be == @args
|
18
|
+
expect( cmd.command ).to be == @command
|
19
|
+
|
20
|
+
expect( cmd.args_string ).to be == 'to the baz'
|
21
|
+
expect( cmd.options_string ).to be == '--foo=bar'
|
22
|
+
expect( cmd.environment_string_for(host) ).to be == ''
|
23
|
+
|
24
|
+
end
|
25
|
+
|
26
|
+
describe '#options_string' do
|
27
|
+
it 'parses things' do
|
28
|
+
subject.options = { :v => nil, :test => nil,
|
29
|
+
:server => 'master', :a => 'answers.txt' }
|
30
|
+
expect( subject.options_string ).to match /-v/
|
31
|
+
expect( subject.options_string ).to match /--test/
|
32
|
+
expect( subject.options_string ).to match /--server=master/
|
33
|
+
expect( subject.options_string ).to match /-a=answers\.txt/
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
describe '#args_string' do
|
38
|
+
it 'joins an array' do
|
39
|
+
subject.args = ['my/command and', nil, 'its args and opts']
|
40
|
+
expect( subject.args_string ).to be == 'my/command and its args and opts'
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
describe '#environment_string_for' do
|
45
|
+
it 'returns a blank string if theres no env' do
|
46
|
+
expect( subject.environment_string_for({}) ).to be == ''
|
47
|
+
end
|
48
|
+
|
49
|
+
it 'takes an env hash with var_name/value pairs' do
|
50
|
+
expect( subject.environment_string_for({}, {:HOME => '/'}) ).
|
51
|
+
to be == 'env HOME="/"'
|
52
|
+
end
|
53
|
+
|
54
|
+
it 'takes an env hash with var_name/value[Array] pairs' do
|
55
|
+
expect( subject.environment_string_for({}, {:LD_PATH => ['/', '/tmp']}) ).
|
56
|
+
to be == 'env LD_PATH="/:/tmp"'
|
57
|
+
end
|
58
|
+
|
59
|
+
it 'takes var_names where there is an array of default values' do
|
60
|
+
env = {:PATH => { :default => [ '/bin', '/usr/bin' ] } }
|
61
|
+
expect( subject.environment_string_for({}, env) ).
|
62
|
+
to be == 'env PATH="/bin:/usr/bin"'
|
63
|
+
|
64
|
+
end
|
65
|
+
|
66
|
+
it 'takes var_names where there is an array of host specific values' do
|
67
|
+
host = { 'pe_path' => '/opt/puppet/bin', 'foss_path' => '/usr/bin' }
|
68
|
+
env = {:PATH => { :host => [ 'pe_path', 'foss_path' ] } }
|
69
|
+
expect( subject.environment_string_for( host, env ) ).
|
70
|
+
to be == 'env PATH="/opt/puppet/bin:/usr/bin"'
|
71
|
+
|
72
|
+
end
|
73
|
+
it 'when using an array of values it allows to specify the separator' do
|
74
|
+
host = { 'whoosits_separator' => ' **sparkles** ' }
|
75
|
+
env = {
|
76
|
+
:WHOOSITS => {
|
77
|
+
:default => [ 'whatsits', 'wonkers' ],
|
78
|
+
:opts => {:separator => {:host => 'whoosits_separator' } }
|
79
|
+
}
|
80
|
+
}
|
81
|
+
expect( subject.environment_string_for( host, env ) ).
|
82
|
+
to be == 'env WHOOSITS="whatsits **sparkles** wonkers"'
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
describe '#parse_env_hash_for' do
|
87
|
+
it 'has too many responsiblities' do
|
88
|
+
env = { :PATH => { :default => [ '/bin', '/usr/bin' ] } }
|
89
|
+
var_array = cmd.parse_env_hash_for host, env
|
90
|
+
expect( var_array ).to be == [ 'PATH="/bin:/usr/bin"' ]
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
@@ -0,0 +1,104 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
class ClassMixedWithDSLAssertions
|
4
|
+
include Beaker::DSL::Assertions
|
5
|
+
end
|
6
|
+
|
7
|
+
describe ClassMixedWithDSLAssertions do
|
8
|
+
describe '#assert_output' do
|
9
|
+
it 'defaults to checking stdout' do
|
10
|
+
stdout = <<CONSOLE
|
11
|
+
This should not have space infront of it
|
12
|
+
While this should have two spaces infront of it
|
13
|
+
And this 3, all lines should be to stdout
|
14
|
+
CONSOLE
|
15
|
+
|
16
|
+
expectation = <<CONSOLE
|
17
|
+
This should not have space infront of it
|
18
|
+
While this should have two spaces infront of it
|
19
|
+
And this 3, all lines should be to stdout
|
20
|
+
CONSOLE
|
21
|
+
|
22
|
+
result = double
|
23
|
+
result.should_receive( :nil? ).at_least( :once ).and_return( false )
|
24
|
+
result.should_receive( :stdout ).and_return( stdout )
|
25
|
+
result.should_receive( :output ).and_return( stdout )
|
26
|
+
result.should_receive( :stderr ).and_return( '' )
|
27
|
+
|
28
|
+
subject.should_receive( :result ).at_least( :once ).and_return( result )
|
29
|
+
expect { subject.assert_output expectation }.to_not raise_error
|
30
|
+
end
|
31
|
+
|
32
|
+
it 'allows specifying stream markers' do
|
33
|
+
output = <<OUTPUT
|
34
|
+
This is on stdout
|
35
|
+
While this is on stderr
|
36
|
+
And THIS is again on stdout
|
37
|
+
OUTPUT
|
38
|
+
|
39
|
+
stdout = <<STDOUT
|
40
|
+
This is on stdout
|
41
|
+
And THIS is again on stdout
|
42
|
+
STDOUT
|
43
|
+
|
44
|
+
stderr = <<STDERR
|
45
|
+
While this is on stderr
|
46
|
+
STDERR
|
47
|
+
|
48
|
+
expectation = <<EXPECT
|
49
|
+
STDOUT> This is on stdout
|
50
|
+
STDERR> While this is on stderr
|
51
|
+
STDOUT> And THIS is again on stdout
|
52
|
+
EXPECT
|
53
|
+
|
54
|
+
result = double
|
55
|
+
result.should_receive( :nil? ).at_least( :once ).and_return( false )
|
56
|
+
result.should_receive( :stdout ).and_return( stdout )
|
57
|
+
result.should_receive( :output ).and_return( output )
|
58
|
+
result.should_receive( :stderr ).and_return( stderr )
|
59
|
+
|
60
|
+
subject.should_receive( :result ).at_least( :once ).and_return( result )
|
61
|
+
expect { subject.assert_output expectation }.to_not raise_error
|
62
|
+
end
|
63
|
+
|
64
|
+
it 'raises an approriate error when output does not match expectations' do
|
65
|
+
output = <<OUTPUT
|
66
|
+
This is on stdout
|
67
|
+
Holy Crap, what HAPPENED!?!?!?
|
68
|
+
And THIS is again on stdout
|
69
|
+
OUTPUT
|
70
|
+
|
71
|
+
stdout = <<STDOUT
|
72
|
+
This is on stdout
|
73
|
+
And THIS is again on stdout
|
74
|
+
STDOUT
|
75
|
+
|
76
|
+
stderr = <<STDERR
|
77
|
+
Holy Crap, what HAPPENED!?!?!?
|
78
|
+
STDERR
|
79
|
+
|
80
|
+
expectation = <<EXPECT
|
81
|
+
STDOUT> This is on stdout
|
82
|
+
STDERR> While this is on stderr
|
83
|
+
STDOUT> And THIS is again on stdout
|
84
|
+
EXPECT
|
85
|
+
|
86
|
+
require 'rbconfig'
|
87
|
+
ruby_conf = defined?(RbConfig) ? RbConfig::CONFIG : Config::CONFIG
|
88
|
+
if ruby_conf['MINOR'].to_i == 8
|
89
|
+
exception = Test::Unit::AssertionFailedError
|
90
|
+
else
|
91
|
+
exception = MiniTest::Assertion
|
92
|
+
end
|
93
|
+
|
94
|
+
result = double
|
95
|
+
result.should_receive( :nil? ).at_least( :once ).and_return( false )
|
96
|
+
result.should_receive( :stdout ).any_number_of_times.and_return( stdout )
|
97
|
+
result.should_receive( :output ).any_number_of_times.and_return( output )
|
98
|
+
result.should_receive( :stderr ).any_number_of_times.and_return( stderr )
|
99
|
+
|
100
|
+
subject.should_receive( :result ).at_least( :once ).and_return( result )
|
101
|
+
expect { subject.assert_output expectation }.to raise_error( exception )
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
@@ -0,0 +1,230 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
class ClassMixedWithDSLHelpers
|
4
|
+
include Beaker::DSL::Helpers
|
5
|
+
end
|
6
|
+
|
7
|
+
describe ClassMixedWithDSLHelpers do
|
8
|
+
describe '#on' do
|
9
|
+
it 'allows the environment the command is run within to be specified' do
|
10
|
+
host = double.as_null_object
|
11
|
+
|
12
|
+
Beaker::Command.should_receive( :new ).
|
13
|
+
with( 'ls ~/.bin', [], {'ENV' => { :HOME => '/tmp/test_home' }} )
|
14
|
+
|
15
|
+
subject.on( host, 'ls ~/.bin', :environment => {:HOME => '/tmp/test_home' } )
|
16
|
+
end
|
17
|
+
|
18
|
+
it 'delegates to itself for each host passed' do
|
19
|
+
hosts = [ double, double, double ]
|
20
|
+
|
21
|
+
hosts.each_with_index do |host, i|
|
22
|
+
host.should_receive( :exec ).and_return( i )
|
23
|
+
end
|
24
|
+
|
25
|
+
results = subject.on( hosts, 'ls' )
|
26
|
+
expect( results ).to be == [ 0, 1, 2 ]
|
27
|
+
end
|
28
|
+
|
29
|
+
it 'yields to a given block' do
|
30
|
+
host = double.as_null_object
|
31
|
+
|
32
|
+
subject.on host, 'ls' do |containing_class|
|
33
|
+
expect( containing_class ).
|
34
|
+
to be_an_instance_of( ClassMixedWithDSLHelpers )
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
it 'returns the result of the action' do
|
39
|
+
host = double.as_null_object
|
40
|
+
|
41
|
+
host.should_receive( :exec ).and_return( 'my_result' )
|
42
|
+
|
43
|
+
expect( subject.on( host, 'ls' ) ).to be == 'my_result'
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
describe '#scp_from' do
|
48
|
+
it 'delegates to the host' do
|
49
|
+
hosts = [ double, double, double ]
|
50
|
+
result = double
|
51
|
+
|
52
|
+
subject.should_receive( :logger ).exactly( 3 ).times
|
53
|
+
result.should_receive( :log ).exactly( 3 ).times
|
54
|
+
hosts.each do |host|
|
55
|
+
host.should_receive( :do_scp_from ).and_return( result )
|
56
|
+
end
|
57
|
+
|
58
|
+
subject.scp_from( hosts, '/var/log/my.log', 'log/my.log' )
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
describe '#scp_to' do
|
63
|
+
it 'delegates to the host' do
|
64
|
+
hosts = [ double, double, double ]
|
65
|
+
result = double
|
66
|
+
|
67
|
+
subject.should_receive( :logger ).exactly( 3 ).times
|
68
|
+
result.should_receive( :log ).exactly( 3 ).times
|
69
|
+
hosts.each do |host|
|
70
|
+
host.should_receive( :do_scp_to ).and_return( result )
|
71
|
+
end
|
72
|
+
|
73
|
+
subject.scp_to( hosts, '/var/log/my.log', 'log/my.log' )
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
describe '#create_remote_file' do
|
78
|
+
it 'scps the contents passed in to the hosts' do
|
79
|
+
hosts = [ 'uno.example.org', 'dos.example.org' ]
|
80
|
+
my_opts = { :silent => true }
|
81
|
+
tmpfile = double
|
82
|
+
|
83
|
+
tmpfile.should_receive( :path ).exactly( 2 ).times.
|
84
|
+
and_return( '/local/path/to/blah' )
|
85
|
+
Tempfile.should_receive( :open ).and_yield( tmpfile )
|
86
|
+
File.should_receive( :open )
|
87
|
+
subject.should_receive( :scp_to ).
|
88
|
+
with( hosts, '/local/path/to/blah', '/remote/path', my_opts )
|
89
|
+
|
90
|
+
subject.create_remote_file( hosts, '/remote/path', 'blah', my_opts )
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
describe '#run_script_on' do
|
95
|
+
it 'scps the script to a tmpdir and executes it on host(s)' do
|
96
|
+
subject.should_receive( :scp_to )
|
97
|
+
subject.should_receive( :on )
|
98
|
+
subject.run_script_on( 'host', '~/.bin/make-enterprisy' )
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
#let(:host_param) { @host_param || Array.new }
|
103
|
+
#let(:logger_param) { double('logger').as_null_object }
|
104
|
+
#let(:config_param) { Hash.new }
|
105
|
+
#let(:options_param) { Hash.new }
|
106
|
+
#let(:path_param) { '/file/path/string' }
|
107
|
+
#let(:test_case) do
|
108
|
+
# TestCase.new( host_param, logger_param, config_param, options_param, path_param )
|
109
|
+
#end
|
110
|
+
|
111
|
+
describe 'confine' do
|
112
|
+
let(:logger) { double.as_null_object }
|
113
|
+
before do
|
114
|
+
subject.should_receive( :logger ).any_number_of_times.and_return( logger )
|
115
|
+
end
|
116
|
+
|
117
|
+
it 'skips the test if there are no applicable hosts' do
|
118
|
+
subject.should_receive( :hosts ).any_number_of_times.and_return( [] )
|
119
|
+
subject.should_receive( :hosts= ).any_number_of_times
|
120
|
+
logger.should_receive( :warn )
|
121
|
+
subject.should_receive( :skip_test ).
|
122
|
+
with( 'No suitable hosts found' )
|
123
|
+
|
124
|
+
subject.confine( :to, {} )
|
125
|
+
end
|
126
|
+
|
127
|
+
it 'raises when given mode is not :to or :except' do
|
128
|
+
subject.should_receive( :hosts ).any_number_of_times
|
129
|
+
subject.should_receive( :hosts= ).any_number_of_times
|
130
|
+
|
131
|
+
expect {
|
132
|
+
subject.confine( :regardless, {:thing => 'value'} )
|
133
|
+
}.to raise_error( 'Unknown option regardless' )
|
134
|
+
end
|
135
|
+
|
136
|
+
it 'rejects hosts that do not meet simple hash criteria' do
|
137
|
+
hosts = [ {'thing' => 'foo'}, {'thing' => 'bar'} ]
|
138
|
+
|
139
|
+
subject.should_receive( :hosts ).and_return( hosts )
|
140
|
+
subject.should_receive( :hosts= ).
|
141
|
+
with( [ {'thing' => 'foo'} ] )
|
142
|
+
|
143
|
+
subject.confine :to, :thing => 'foo'
|
144
|
+
end
|
145
|
+
|
146
|
+
it 'rejects hosts that match a list of criteria' do
|
147
|
+
hosts = [ {'thing' => 'foo'}, {'thing' => 'bar'}, {'thing' => 'baz'} ]
|
148
|
+
|
149
|
+
subject.should_receive( :hosts ).and_return( hosts )
|
150
|
+
subject.should_receive( :hosts= ).
|
151
|
+
with( [ {'thing' => 'bar'} ] )
|
152
|
+
|
153
|
+
subject.confine :except, :thing => ['foo', 'baz']
|
154
|
+
end
|
155
|
+
|
156
|
+
it 'rejects hosts when a passed block returns true' do
|
157
|
+
host1 = {'platform' => 'solaris'}
|
158
|
+
host2 = {'platform' => 'solaris'}
|
159
|
+
host3 = {'platform' => 'windows'}
|
160
|
+
ret1 = (Struct.new('Result1', :stdout)).new(':global')
|
161
|
+
ret2 = (Struct.new('Result2', :stdout)).new('a_zone')
|
162
|
+
hosts = [ host1, host2, host3 ]
|
163
|
+
|
164
|
+
subject.should_receive( :hosts ).and_return( hosts )
|
165
|
+
subject.should_receive( :on ).
|
166
|
+
with( host1, '/sbin/zonename' ).
|
167
|
+
and_return( ret1 )
|
168
|
+
subject.should_receive( :on ).
|
169
|
+
with( host1, '/sbin/zonename' ).
|
170
|
+
and_return( ret2 )
|
171
|
+
|
172
|
+
subject.should_receive( :hosts= ).with( [ host1 ] )
|
173
|
+
|
174
|
+
subject.confine :to, :platform => 'solaris' do |host|
|
175
|
+
subject.on( host, '/sbin/zonename' ).stdout =~ /:global/
|
176
|
+
end
|
177
|
+
end
|
178
|
+
end
|
179
|
+
|
180
|
+
describe '#apply_manifest_on' do
|
181
|
+
it 'allows acceptable exit codes through :catch_failures' do
|
182
|
+
subject.should_receive( :puppet ).
|
183
|
+
with( 'apply', '--verbose', '--trace', '--detailed-exitcodes' ).
|
184
|
+
and_return( 'puppet_command' )
|
185
|
+
|
186
|
+
subject.should_receive( :on ).
|
187
|
+
with( 'my_host', 'puppet_command',
|
188
|
+
:acceptable_exit_codes => [4,0,2],
|
189
|
+
:stdin => "class { \"boo\": }\n" )
|
190
|
+
|
191
|
+
subject.apply_manifest_on( 'my_host',
|
192
|
+
'class { "boo": }',
|
193
|
+
:acceptable_exit_codes => [4],
|
194
|
+
:trace => true,
|
195
|
+
:catch_failures => true )
|
196
|
+
end
|
197
|
+
end
|
198
|
+
|
199
|
+
describe '#stub_hosts_on' do
|
200
|
+
it 'executes puppet on the host passed and ensures it is reverted' do
|
201
|
+
logger = double.as_null_object
|
202
|
+
|
203
|
+
subject.should_receive( :logger ).any_number_of_times.and_return( logger )
|
204
|
+
subject.should_receive( :on ).twice
|
205
|
+
subject.should_receive( :teardown ).and_yield
|
206
|
+
subject.should_receive( :puppet ).once.
|
207
|
+
with( 'resource', 'host',
|
208
|
+
'puppetlabs.com',
|
209
|
+
'ensure=present', 'ip=127.0.0.1' )
|
210
|
+
subject.should_receive( :puppet ).once.
|
211
|
+
with( 'resource', 'host',
|
212
|
+
'puppetlabs.com',
|
213
|
+
'ensure=absent' )
|
214
|
+
|
215
|
+
subject.stub_hosts_on( 'my_host', 'puppetlabs.com' => '127.0.0.1' )
|
216
|
+
end
|
217
|
+
end
|
218
|
+
|
219
|
+
describe '#stub_forge_on' do
|
220
|
+
it 'stubs forge.puppetlabs.com with the value of `forge`' do
|
221
|
+
subject.should_receive( :forge ).and_return( 'my_forge.example.com' )
|
222
|
+
Resolv.should_receive( :getaddress ).
|
223
|
+
with( 'my_forge.example.com' ).and_return( '127.0.0.1' )
|
224
|
+
subject.should_receive( :stub_hosts_on ).
|
225
|
+
with( 'my_host', 'forge.puppetlabs.com' => '127.0.0.1' )
|
226
|
+
|
227
|
+
subject.stub_forge_on( 'my_host' )
|
228
|
+
end
|
229
|
+
end
|
230
|
+
end
|