beaker 3.34.0 → 3.35.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +12 -1
- data/acceptance/tests/base/external_resources_test.rb +18 -3
- data/acceptance/tests/base/host/host_test.rb +1 -1
- data/docs/concepts/testing_beaker_itself.md +4 -4
- data/docs/concepts/ticket_process.md +12 -12
- data/docs/concepts/types_puppet_4_and_the_all_in_one_agent.md +1 -1
- data/docs/how_to/change_terminal_output_coloring.md +1 -1
- data/docs/how_to/confine.md +3 -3
- data/docs/how_to/debug_beaker_tests.md +19 -19
- data/docs/how_to/enabling_cross_sut_access.md +1 -1
- data/docs/how_to/hosts/README.md +1 -1
- data/docs/how_to/hosts/cisco.md +1 -1
- data/docs/how_to/hypervisors/README.md +1 -1
- data/docs/how_to/platform_specific_tag_confines.md +2 -2
- data/docs/how_to/preserve_hosts.md +2 -2
- data/docs/how_to/rake_tasks.md +3 -4
- data/docs/how_to/test_arbitrary_beaker_versions.md +3 -3
- data/docs/how_to/upgrade_from_2_to_3.md +4 -4
- data/docs/tutorials/README.md +1 -1
- data/docs/tutorials/test_suites.md +1 -1
- data/lib/beaker/cli.rb +1 -0
- data/lib/beaker/command.rb +2 -2
- data/lib/beaker/dsl/assertions.rb +1 -1
- data/lib/beaker/dsl/helpers/facter_helpers.rb +1 -1
- data/lib/beaker/dsl/install_utils/pe_defaults.rb +1 -1
- data/lib/beaker/dsl/roles.rb +1 -1
- data/lib/beaker/dsl/structure.rb +2 -2
- data/lib/beaker/host/cisco.rb +3 -3
- data/lib/beaker/host/mac/exec.rb +1 -1
- data/lib/beaker/host/windows/exec.rb +1 -1
- data/lib/beaker/host_prebuilt_steps.rb +3 -0
- data/lib/beaker/options/hosts_file_parser.rb +9 -2
- data/lib/beaker/options/parser.rb +1 -1
- data/lib/beaker/shared/options_resolver.rb +6 -6
- data/lib/beaker/subcommand.rb +13 -8
- data/lib/beaker/tasks/quick_start.rb +2 -2
- data/lib/beaker/version.rb +1 -1
- data/spec/beaker/host/unix/exec_spec.rb +1 -1
- data/spec/beaker/host_prebuilt_steps_spec.rb +1 -0
- data/spec/beaker/options/hosts_file_parser_spec.rb +15 -7
- data/spec/beaker/shared/error_handler_spec.rb +2 -2
- data/spec/beaker/shared/repetition_spec.rb +2 -2
- data/spec/beaker/subcommand_spec.rb +82 -30
- data/spec/helpers.rb +1 -1
- data/spec/mock_fission.rb +4 -4
- data/spec/mock_vsphere.rb +5 -5
- data/spec/mock_vsphere_helper.rb +1 -1
- metadata +2 -2
@@ -1,8 +1,8 @@
|
|
1
1
|
# How To Upgrade from 2.y to 3.0
|
2
2
|
|
3
3
|
This is a guide detailing all the issues to be aware of, and to help people make
|
4
|
-
any changes that you might need to move from beaker 2.y to 3.0. To test out
|
5
|
-
beaker 3.0.0, we recommend implementing the strategy outlined [here](test_arbitrary_beaker_versions.md)
|
4
|
+
any changes that you might need to move from beaker 2.y to 3.0. To test out
|
5
|
+
beaker 3.0.0, we recommend implementing the strategy outlined [here](test_arbitrary_beaker_versions.md)
|
6
6
|
to ensure this new major release does not break your existing testing.
|
7
7
|
|
8
8
|
## Ruby version 1.9.3 no longer supported
|
@@ -39,10 +39,10 @@ doc for info on how to do this.
|
|
39
39
|
|
40
40
|
## EPEL package update
|
41
41
|
|
42
|
-
In beaker < 3.0.0, the epel package names had hardcoded defaults listed in the
|
42
|
+
In beaker < 3.0.0, the epel package names had hardcoded defaults listed in the
|
43
43
|
presets default; in beaker >= 3.0.0, beaker utilizes the `release-latest` file
|
44
44
|
provided on epel mirrors for el versions 5, 6, and 7. Since only the latest epel
|
45
|
-
packages are available on epel mirrors, beaker only supports installation of
|
45
|
+
packages are available on epel mirrors, beaker only supports installation of
|
46
46
|
that latest version.
|
47
47
|
|
48
48
|
## Solaris and AIX Hypervisors removed
|
data/docs/tutorials/README.md
CHANGED
@@ -22,7 +22,7 @@ If you haven't installed beaker yet, your guide to doing
|
|
22
22
|
so can be found [here](installation.md).
|
23
23
|
|
24
24
|
## Quick Start
|
25
|
-
|
25
|
+
|
26
26
|
As a completely new beaker user, the
|
27
27
|
[quick start rake tasks doc](quick_start_rake_tasks.md)
|
28
28
|
will take you through getting beaker running for the
|
@@ -47,7 +47,7 @@ failure modes.
|
|
47
47
|
|
48
48
|
The pre-suite is for setting up the Systems Under Test (SUTs) for the testing
|
49
49
|
suite. No surprises here, usually these files are filled with the setup and
|
50
|
-
installation code needed to verify that the operating assumptions of the
|
50
|
+
installation code needed to verify that the operating assumptions of the
|
51
51
|
software being tested are true.
|
52
52
|
|
53
53
|
Pre-suites, since they’re supposed to contain just setup code, will fail-fast
|
data/lib/beaker/cli.rb
CHANGED
data/lib/beaker/command.rb
CHANGED
@@ -66,7 +66,7 @@ module Beaker
|
|
66
66
|
# interface.
|
67
67
|
# @param [String] cmd An command to call.
|
68
68
|
# @param [Hash] env An optional hash of environment variables to be used
|
69
|
-
# @param [String] pc An optional list of commands to prepend
|
69
|
+
# @param [String] pc An optional list of commands to prepend
|
70
70
|
#
|
71
71
|
# @return [String] This returns the fully formed command line invocation.
|
72
72
|
def cmd_line host, cmd = @command, env = @environment, pc = @prepend_cmds
|
@@ -78,7 +78,7 @@ module Beaker
|
|
78
78
|
end
|
79
79
|
|
80
80
|
# This will cause things like `puppet -t -v agent` which is maybe bad.
|
81
|
-
if host[:platform] =~ /cisco_ios_xr/
|
81
|
+
if host[:platform] =~ /cisco_ios_xr/
|
82
82
|
cmd_line_array = [prepend_commands, env_string, cmd, options_string, args_string]
|
83
83
|
else
|
84
84
|
cmd_line_array = [env_string, prepend_commands, cmd, options_string, args_string]
|
@@ -98,7 +98,7 @@ module Beaker
|
|
98
98
|
# Assert that the provided string does not match the provided regular expression, can pass optional message
|
99
99
|
# @deprecated This is placed her for backwards compatability for tests that used Test::Unit::Assertions,
|
100
100
|
# http://apidock.com/ruby/Test/Unit/Assertions/assert_no_match
|
101
|
-
#
|
101
|
+
#
|
102
102
|
def assert_no_match(regexp, string, msg=nil)
|
103
103
|
assert_instance_of(Regexp, regexp, "The first argument to assert_no_match should be a Regexp.")
|
104
104
|
msg = message(msg) { "<#{mu_pp(regexp)}> expected to not match\n<#{mu_pp(string)}>" }
|
@@ -13,7 +13,7 @@ module Beaker
|
|
13
13
|
# (or range) of integer exit codes that should be considered
|
14
14
|
# acceptable. An error will be thrown if the exit code does not
|
15
15
|
# match one of the values in this list.
|
16
|
-
# @option opts [Boolean] :accept_all_exit_codes (false) Consider all
|
16
|
+
# @option opts [Boolean] :accept_all_exit_codes (false) Consider all
|
17
17
|
# exit codes as passing.
|
18
18
|
# @option opts [Boolean] :dry_run (false) Do not actually execute any
|
19
19
|
# commands on the SUT
|
@@ -72,7 +72,7 @@ module Beaker
|
|
72
72
|
PE_DEFAULTS[platform].each_pair do |key, val|
|
73
73
|
host[key] = val
|
74
74
|
end
|
75
|
-
# add the type and group here for backwards compatability
|
75
|
+
# add the type and group here for backwards compatability
|
76
76
|
if host['platform'] =~ /windows/
|
77
77
|
host['group'] = 'Administrators'
|
78
78
|
else
|
data/lib/beaker/dsl/roles.rb
CHANGED
@@ -161,7 +161,7 @@ module Beaker
|
|
161
161
|
end
|
162
162
|
|
163
163
|
#Create a new role method for a given arbitrary role name. Makes it possible to be able to run
|
164
|
-
#commands without having to refer to role by String or Symbol. Will not add a new method
|
164
|
+
#commands without having to refer to role by String or Symbol. Will not add a new method
|
165
165
|
#definition if the name is already in use.
|
166
166
|
# @param [String, Symbol, Array[String,Symbol]] role The role that you wish to create a definition for, either a String
|
167
167
|
# Symbol or an Array of Strings or Symbols.
|
data/lib/beaker/dsl/structure.rb
CHANGED
@@ -68,7 +68,7 @@ module Beaker
|
|
68
68
|
|
69
69
|
set_current_step_name(step_name)
|
70
70
|
# Here we prompt the user to tell us if the step passed or failed
|
71
|
-
loop do
|
71
|
+
loop do
|
72
72
|
input = Readline.readline('Did this step pass, Y/n? ', true).squeeze(" ").strip.downcase
|
73
73
|
if %w(y yes).include?(input)
|
74
74
|
break
|
@@ -102,7 +102,7 @@ module Beaker
|
|
102
102
|
def manual_test manual_test_name, &block
|
103
103
|
if(@options.has_key?(:exec_manual_tests) && @options[:exec_manual_tests] == true)
|
104
104
|
# here the option is set so we run the test as normal
|
105
|
-
test_name manual_test_name, &block
|
105
|
+
test_name manual_test_name, &block
|
106
106
|
else
|
107
107
|
# here no option was set so we log the test name and skip it
|
108
108
|
test_name manual_test_name
|
data/lib/beaker/host/cisco.rb
CHANGED
@@ -119,15 +119,15 @@ module Cisco
|
|
119
119
|
# this will be raised with the appropriate message
|
120
120
|
def validate_setup
|
121
121
|
msg = nil
|
122
|
-
if self[:platform] =~ /cisco_nexus/
|
122
|
+
if self[:platform] =~ /cisco_nexus/
|
123
123
|
if !self[:vrf]
|
124
|
-
msg = 'Cisco Nexus hosts must be provided with a :vrf value.'
|
124
|
+
msg = 'Cisco Nexus hosts must be provided with a :vrf value.'
|
125
125
|
end
|
126
126
|
if !self[:user]
|
127
127
|
msg = 'Cisco hosts must be provided with a :user value'
|
128
128
|
end
|
129
129
|
end
|
130
|
-
if self[:platform] =~ /cisco_ios_xr/
|
130
|
+
if self[:platform] =~ /cisco_ios_xr/
|
131
131
|
if !self[:user]
|
132
132
|
msg = 'Cisco hosts must be provided with a :user value'
|
133
133
|
end
|
data/lib/beaker/host/mac/exec.rb
CHANGED
@@ -113,7 +113,7 @@ module Windows::Exec
|
|
113
113
|
#
|
114
114
|
# @return [Boolean]
|
115
115
|
def cygwin_installed?
|
116
|
-
output = exec(Beaker::Command.new('cygcheck --check-setup cygwin'), :accept_all_exit_codes => true).stdout
|
116
|
+
output = exec(Beaker::Command.new('cygcheck --check-setup cygwin'), :accept_all_exit_codes => true).stdout
|
117
117
|
return true if output.match(/cygwin/) && output.match(/OK/)
|
118
118
|
false
|
119
119
|
end
|
@@ -432,6 +432,9 @@ module Beaker
|
|
432
432
|
elsif host['platform'] =~ /solaris-11/
|
433
433
|
host.exec(Command.new("if grep \"root::::type=role\" /etc/user_attr; then sudo rolemod -K type=normal root; else echo \"root user already type=normal\"; fi"), {:pty => true} )
|
434
434
|
host.exec(Command.new("sudo gsed -i -e 's/PermitRootLogin no/PermitRootLogin yes/g' /etc/ssh/sshd_config"), {:pty => true} )
|
435
|
+
elsif host['platform'] =~ /f5/
|
436
|
+
#interacting with f5 should using tmsh
|
437
|
+
logger.warn("Attempting to enable root login non-supported platform: #{host.name}: #{host['platform']}")
|
435
438
|
elsif host.is_cygwin?
|
436
439
|
host.exec(Command.new("sed -ri 's/^#?PermitRootLogin /PermitRootLogin yes/' /etc/sshd_config"), {:pty => true})
|
437
440
|
elsif host.is_powershell?
|
@@ -14,12 +14,17 @@ module Beaker
|
|
14
14
|
# @raise [ArgumentError] Raises if hosts_file_path is not a valid YAML file
|
15
15
|
# @raise [Errno::ENOENT] File not found error: hosts_file doesn't exist
|
16
16
|
def self.parse_hosts_file(hosts_file_path = nil)
|
17
|
+
require 'erb'
|
18
|
+
|
17
19
|
host_options = new_host_options
|
18
20
|
return host_options unless hosts_file_path
|
19
21
|
error_message = "#{hosts_file_path} is not a valid YAML file\n\t"
|
20
22
|
host_options = self.merge_hosts_yaml( host_options, error_message ) {
|
21
23
|
hosts_file_path = File.expand_path( hosts_file_path )
|
22
|
-
|
24
|
+
|
25
|
+
raise "#{hosts_file_path} is not a valid path" unless File.exist?(hosts_file_path)
|
26
|
+
|
27
|
+
YAML.load(ERB.new(File.read(hosts_file_path), nil, '-').result(binding))
|
23
28
|
}
|
24
29
|
fix_roles_array( host_options )
|
25
30
|
end
|
@@ -31,11 +36,13 @@ module Beaker
|
|
31
36
|
# @return [OptionsHash] Contents of the hosts file as an OptionsHash
|
32
37
|
# @raise [ArgumentError] If hosts_def_yaml is not a valid YAML string
|
33
38
|
def self.parse_hosts_string(hosts_def_yaml = nil)
|
39
|
+
require 'erb'
|
40
|
+
|
34
41
|
host_options = new_host_options
|
35
42
|
return host_options unless hosts_def_yaml
|
36
43
|
error_message = "#{hosts_def_yaml}\nis not a valid YAML string\n\t"
|
37
44
|
host_options = self.merge_hosts_yaml( host_options, error_message ) {
|
38
|
-
YAML.load(
|
45
|
+
YAML.load(ERB.new(hosts_def_yaml, nil, '-').result(binding))
|
39
46
|
}
|
40
47
|
fix_roles_array( host_options )
|
41
48
|
end
|
@@ -171,7 +171,7 @@ module Beaker
|
|
171
171
|
|
172
172
|
# Update the @attribution hash with the source of each key in the options_hash
|
173
173
|
#
|
174
|
-
# @param [Hash] options_hash Options hash
|
174
|
+
# @param [Hash] options_hash Options hash
|
175
175
|
# @param [String] source Where the options were specified
|
176
176
|
# @return [Hash] hash Hash of sources for each key
|
177
177
|
def tag_sources(options_hash, source)
|
@@ -3,25 +3,25 @@ module Beaker
|
|
3
3
|
# Methods for parsing options.
|
4
4
|
module OptionsResolver
|
5
5
|
# parses local and global options to determine if a particular mode should
|
6
|
-
# be run in parallel. typically, local_options will specify a true/false
|
6
|
+
# be run in parallel. typically, local_options will specify a true/false
|
7
7
|
# value, while global_options will specify an array of mode names that should
|
8
8
|
# be run in parallel. the value specified in local_options will take precedence
|
9
|
-
# over the values specified in global_options.
|
9
|
+
# over the values specified in global_options.
|
10
10
|
# @param [Hash] local_options local options for running in parallel
|
11
11
|
# @option local_options [Boolean] :run_in_parallel flag for running in parallel
|
12
12
|
# @param [Hash] global_options global options for running in parallel
|
13
13
|
# @option global_options [Array<String>] :run_in_parallel list of modes to run in parallel
|
14
14
|
# @param [String] mode the mode we want to query global_options for
|
15
|
-
# @return [Boolean] true if the specified mode is in global_options and :run_in_parallel in local_options is not false,
|
15
|
+
# @return [Boolean] true if the specified mode is in global_options and :run_in_parallel in local_options is not false,
|
16
16
|
# or if :run_in_parallel in local_options is true, false otherwise
|
17
17
|
# @example
|
18
|
-
# run_in_parallel?({:run_in_parallel => true})
|
18
|
+
# run_in_parallel?({:run_in_parallel => true})
|
19
19
|
# -> will return true
|
20
20
|
#
|
21
|
-
# run_in_parallel?({:run_in_parallel => true}, {:run_in_parallel => ['install','configure']}, 'install')
|
21
|
+
# run_in_parallel?({:run_in_parallel => true}, {:run_in_parallel => ['install','configure']}, 'install')
|
22
22
|
# -> will return true
|
23
23
|
#
|
24
|
-
# run_in_parallel?({:run_in_parallel => false}, {:run_in_parallel => ['install','configure']}, 'install')
|
24
|
+
# run_in_parallel?({:run_in_parallel => false}, {:run_in_parallel => ['install','configure']}, 'install')
|
25
25
|
# -> will return false
|
26
26
|
def run_in_parallel?(local_options=nil, global_options=nil, mode=nil)
|
27
27
|
run_in_parallel = local_options[:run_in_parallel] unless local_options.nil?
|
data/lib/beaker/subcommand.rb
CHANGED
@@ -6,6 +6,7 @@ module Beaker
|
|
6
6
|
class Subcommand < Thor
|
7
7
|
SubcommandUtil = Beaker::Subcommands::SubcommandUtil
|
8
8
|
|
9
|
+
attr_reader :cli
|
9
10
|
|
10
11
|
def initialize(*args)
|
11
12
|
super
|
@@ -171,8 +172,9 @@ module Beaker
|
|
171
172
|
end
|
172
173
|
|
173
174
|
beaker_suites = [:pre_suite, :tests, :post_suite, :pre_cleanup]
|
174
|
-
|
175
|
-
|
175
|
+
resources = resource.split(',')
|
176
|
+
paths = resources.map { |r| Pathname(r) }
|
177
|
+
if paths.all?(&:exist?)
|
176
178
|
# If we determine the resource is a valid file resource, then we empty
|
177
179
|
# all the suites and run that file resource in the tests suite. In the
|
178
180
|
# future, when we have the ability to have custom suites, we should change
|
@@ -180,12 +182,14 @@ module Beaker
|
|
180
182
|
beaker_suites.each do |suite|
|
181
183
|
@cli.options[suite] = []
|
182
184
|
end
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
185
|
+
@cli.options[:tests] = paths.map do |path|
|
186
|
+
if path.directory?
|
187
|
+
Dir.glob("#{path}/**/*.rb")
|
188
|
+
else
|
189
|
+
path.to_s
|
190
|
+
end
|
191
|
+
end.flatten
|
192
|
+
elsif resources.all? { |r| r =~ /^(pre-suite|tests|post-suite|pre-cleanup)$/ }
|
189
193
|
# The regex match here is loose so that users can supply multiple suites,
|
190
194
|
# such as `beaker exec pre-suite,tests`.
|
191
195
|
beaker_suites.each do |suite|
|
@@ -194,6 +198,7 @@ module Beaker
|
|
194
198
|
else
|
195
199
|
raise ArgumentError, "Unable to parse #{resource} with beaker exec"
|
196
200
|
end
|
201
|
+
|
197
202
|
@cli.execute!
|
198
203
|
end
|
199
204
|
|
@@ -50,11 +50,11 @@ namespace :beaker_quickstart do
|
|
50
50
|
|
51
51
|
desc 'Generate Default Smoke Test'
|
52
52
|
task :gen_smoke_test do
|
53
|
-
smoke_test_file = "acceptance/
|
53
|
+
smoke_test_file = "acceptance/tests/default_smoke_test.rb"
|
54
54
|
FileUtils.mkdir_p('acceptance/tests') # -p ignores when dir already exists
|
55
55
|
if !File.exist?(smoke_test_file) then
|
56
56
|
puts "Writing default smoke test to file - #{smoke_test_file}"
|
57
|
-
File.open(
|
57
|
+
File.open(smoke_test_file, 'w') do |fh|
|
58
58
|
fh.print("test_name 'puppet install smoketest' do
|
59
59
|
step 'puppet install smoketest: verify \\'puppet help\\' can be successfully called on
|
60
60
|
all hosts' do
|
data/lib/beaker/version.rb
CHANGED
@@ -102,7 +102,7 @@ module Beaker
|
|
102
102
|
describe '#ssh_service_restart' do
|
103
103
|
PlatformHelpers::SYSTEMDPLATFORMS.each do |platform|
|
104
104
|
it "calls the correct command for #{platform}" do
|
105
|
-
opts['platform'] = platform
|
105
|
+
opts['platform'] = platform
|
106
106
|
expect(instance).to receive(:exec)
|
107
107
|
expect(Beaker::Command).to receive(:new).with("systemctl restart sshd.service")
|
108
108
|
expect{instance.ssh_service_restart}.to_not raise_error
|
@@ -28,14 +28,14 @@ module Beaker
|
|
28
28
|
|
29
29
|
it "raises an error on no file found" do
|
30
30
|
FakeFS.deactivate!
|
31
|
-
expect{parser.parse_hosts_file("not a valid path")}.to raise_error(
|
31
|
+
expect{parser.parse_hosts_file("not a valid path")}.to raise_error(/is not a valid path/)
|
32
32
|
end
|
33
33
|
|
34
34
|
it "raises an error on bad yaml file" do
|
35
35
|
FakeFS.deactivate!
|
36
|
-
|
37
|
-
|
38
|
-
expect { parser.parse_hosts_file("not a valid path") }.to raise_error(
|
36
|
+
expect( File ).to receive(:exist?).and_return(true)
|
37
|
+
|
38
|
+
expect { parser.parse_hosts_file("not a valid path") }.to raise_error(Errno::ENOENT)
|
39
39
|
end
|
40
40
|
|
41
41
|
it 'returns a #new_host_options hash if given no arguments' do
|
@@ -43,12 +43,20 @@ module Beaker
|
|
43
43
|
expect( host_options ).to be === parser.new_host_options
|
44
44
|
end
|
45
45
|
|
46
|
-
it 'passes a YAML.
|
46
|
+
it 'passes a YAML.load call through to #merge_hosts_yaml' do
|
47
47
|
yaml_string = 'not actually yaml, but that wont matter'
|
48
|
-
|
49
|
-
expect(
|
48
|
+
expect( File ).to receive( :exist?).and_return(true)
|
49
|
+
expect( File ).to receive( :read ).and_return(yaml_string)
|
50
50
|
parser.parse_hosts_file( yaml_string )
|
51
51
|
end
|
52
|
+
|
53
|
+
it 'processes ERB in the host YAML successfully' do
|
54
|
+
yaml_string = '1 plus 2: <%= 1 + 2 %>'
|
55
|
+
expect( File ).to receive( :exist?).and_return(true)
|
56
|
+
expect( File ).to receive( :read ).and_return(yaml_string)
|
57
|
+
beaker_options_hash = parser.parse_hosts_file( yaml_string )
|
58
|
+
expect(beaker_options_hash['1 plus 2']).to eq(3)
|
59
|
+
end
|
52
60
|
end
|
53
61
|
|
54
62
|
describe '#parse_hosts_string' do
|
@@ -19,14 +19,14 @@ module Beaker
|
|
19
19
|
ex = Exception.new("ArgumentError")
|
20
20
|
allow( ex ).to receive( :backtrace ).and_return(backtrace)
|
21
21
|
mesg = "I'm the extra message"
|
22
|
-
|
22
|
+
|
23
23
|
backtrace.each_line do |line|
|
24
24
|
expect( logger ).to receive( :error ).with(line)
|
25
25
|
end
|
26
26
|
|
27
27
|
expect( subject ).to receive( :raise ).once
|
28
28
|
|
29
|
-
subject.report_and_raise(logger, ex, mesg)
|
29
|
+
subject.report_and_raise(logger, ex, mesg)
|
30
30
|
|
31
31
|
end
|
32
32
|
|
@@ -10,7 +10,7 @@ module Beaker
|
|
10
10
|
|
11
11
|
block = double( 'block' )
|
12
12
|
expect( block ).to receive( :exec ).exactly( 5 ).times.and_return( false )
|
13
|
-
|
13
|
+
|
14
14
|
subject.repeat_for( 5 ) do
|
15
15
|
block.exec
|
16
16
|
end
|
@@ -21,7 +21,7 @@ module Beaker
|
|
21
21
|
|
22
22
|
block = double( 'block' )
|
23
23
|
expect( block ).to receive( :exec ).once.and_return( true )
|
24
|
-
|
24
|
+
|
25
25
|
subject.repeat_for( 5 ) do
|
26
26
|
block.exec
|
27
27
|
end
|
@@ -9,9 +9,9 @@ module Beaker
|
|
9
9
|
|
10
10
|
context '#initialize' do
|
11
11
|
it 'creates a cli object' do
|
12
|
-
expect(
|
13
|
-
subcommand
|
12
|
+
expect(subcommand.cli).to be
|
14
13
|
end
|
14
|
+
|
15
15
|
describe 'File operation initialization for subcommands' do
|
16
16
|
it 'checks to ensure subcommand file resources exist' do
|
17
17
|
expect(FileUtils).to receive(:mkdir_p).with(SubcommandUtil::CONFIG_DIR)
|
@@ -28,7 +28,6 @@ module Beaker
|
|
28
28
|
expect(FileUtils).to receive(:touch).with(SubcommandUtil::SUBCOMMAND_STATE)
|
29
29
|
subcommand
|
30
30
|
end
|
31
|
-
|
32
31
|
end
|
33
32
|
end
|
34
33
|
|
@@ -80,6 +79,9 @@ module Beaker
|
|
80
79
|
|
81
80
|
it 'should not error with valid beaker options' do
|
82
81
|
beaker_options_list.each do |option|
|
82
|
+
allow_any_instance_of(Beaker::CLI).to receive(:parse_options)
|
83
|
+
allow_any_instance_of(Beaker::CLI).to receive(:configured_options).and_return({})
|
84
|
+
|
83
85
|
allow(YAML::Store).to receive(:new).with(SubcommandUtil::SUBCOMMAND_STATE).and_return(yaml_store_mock)
|
84
86
|
allow(yaml_store_mock).to receive(:transaction).and_yield
|
85
87
|
allow(yaml_store_mock).to receive(:[]=).with('provisioned', false)
|
@@ -87,6 +89,7 @@ module Beaker
|
|
87
89
|
allow_any_instance_of(Beaker::Logger).to receive(:notify).twice
|
88
90
|
expect(SubcommandUtil::SUBCOMMAND_OPTIONS).to receive(:exist?).and_return(true)
|
89
91
|
expect(SubcommandUtil::SUBCOMMAND_STATE).to receive(:exist?).and_return(true)
|
92
|
+
|
90
93
|
expect {Beaker::Subcommand.start(['init', '--hosts', 'centos', "--#{option}"])}.to_not output(/ERROR/).to_stderr
|
91
94
|
end
|
92
95
|
end
|
@@ -103,13 +106,16 @@ module Beaker
|
|
103
106
|
end
|
104
107
|
|
105
108
|
context '#init' do
|
106
|
-
let( :cli ) { subcommand.
|
109
|
+
let( :cli ) { subcommand.cli }
|
107
110
|
let( :mock_options ) { {:timestamp => 'noon', :other_key => 'cordite'}}
|
108
111
|
let( :yaml_store_mock ) { double('yaml_store_mock') }
|
109
|
-
|
110
|
-
|
112
|
+
|
113
|
+
before :each do
|
114
|
+
allow(cli).to receive(:parse_options)
|
111
115
|
allow(cli).to receive(:configured_options).and_return(mock_options)
|
116
|
+
end
|
112
117
|
|
118
|
+
it 'calculates options and writes them to disk and deletes the' do
|
113
119
|
allow(File).to receive(:open)
|
114
120
|
allow(YAML::Store).to receive(:new).with(SubcommandUtil::SUBCOMMAND_STATE).and_return(yaml_store_mock)
|
115
121
|
allow(yaml_store_mock).to receive(:transaction).and_yield
|
@@ -117,13 +123,14 @@ module Beaker
|
|
117
123
|
subcommand.init
|
118
124
|
expect(mock_options).not_to have_key(:timestamp)
|
119
125
|
end
|
126
|
+
|
120
127
|
it 'requires hosts flag' do
|
121
128
|
expect{subcommand.init}.to raise_error(NotImplementedError)
|
122
129
|
end
|
123
130
|
end
|
124
131
|
|
125
132
|
context '#provision' do
|
126
|
-
let ( :cli ) { subcommand.
|
133
|
+
let ( :cli ) { subcommand.cli }
|
127
134
|
let( :yaml_store_mock ) { double('yaml_store_mock') }
|
128
135
|
let ( :host_hash ) { {'mynode.net' => {:name => 'mynode', :platform => Beaker::Platform.new('centos-6-x86_64')}}}
|
129
136
|
let ( :cleaned_hosts ) {double()}
|
@@ -133,6 +140,7 @@ module Beaker
|
|
133
140
|
let ( :hosts) {double('hosts')}
|
134
141
|
let ( :hypervisors) {double('hypervisors')}
|
135
142
|
let (:options) {double ('options')}
|
143
|
+
|
136
144
|
it 'provisions the host and saves the host info' do
|
137
145
|
expect(YAML::Store).to receive(:new).with(SubcommandUtil::SUBCOMMAND_STATE).and_return(yaml_store_mock)
|
138
146
|
allow(yaml_store_mock).to receive(:[]).and_return(false)
|
@@ -157,59 +165,103 @@ module Beaker
|
|
157
165
|
expect(yaml_store_mock).to receive(:[]=).with('provisioned', true)
|
158
166
|
subcommand.provision
|
159
167
|
end
|
168
|
+
|
160
169
|
it 'does not allow hosts to be passed' do
|
161
170
|
subcommand.options = {:hosts => "myhost"}
|
162
171
|
expect{subcommand.provision()}.to raise_error(NotImplementedError)
|
163
172
|
end
|
164
173
|
end
|
165
174
|
|
166
|
-
|
167
175
|
context 'exec' do
|
176
|
+
before :each do
|
177
|
+
allow(subcommand.cli).to receive(:parse_options)
|
178
|
+
allow(subcommand.cli).to receive(:initialize_network_manager)
|
179
|
+
end
|
180
|
+
|
168
181
|
it 'calls execute! when no resource is given' do
|
169
182
|
expect_any_instance_of(Pathname).to_not receive(:directory?)
|
170
183
|
expect_any_instance_of(Pathname).to_not receive(:exist?)
|
171
|
-
|
172
|
-
expect_any_instance_of(Beaker::CLI).to receive(:initialize_network_manager).once
|
173
|
-
expect_any_instance_of(Beaker::CLI).to receive(:execute!).once
|
184
|
+
expect(subcommand.cli).to receive(:execute!).once
|
174
185
|
expect{subcommand.exec}.to_not raise_error
|
175
186
|
end
|
176
187
|
|
177
|
-
it '
|
188
|
+
it 'allows hard coded suite names to be specified' do
|
189
|
+
subcommand.cli.options[:pre_suite] = %w[step1.rb]
|
190
|
+
subcommand.cli.options[:post_suite] = %w[step2.rb]
|
191
|
+
subcommand.cli.options[:tests] = %w[tests/1.rb]
|
192
|
+
|
193
|
+
subcommand.exec('pre-suite,tests')
|
194
|
+
|
195
|
+
expect(subcommand.cli.options[:pre_suite]).to eq(%w[step1.rb])
|
196
|
+
expect(subcommand.cli.options[:post_suite]).to eq([])
|
197
|
+
expect(subcommand.cli.options[:tests]).to eq(%w[tests/1.rb])
|
198
|
+
end
|
199
|
+
|
200
|
+
it 'errors when a resource is neither a valid file resource or suite name' do
|
201
|
+
allow_any_instance_of(Pathname).to receive(:exist?).and_return(false)
|
202
|
+
expect{subcommand.exec('blahblahblah')}.to raise_error(ArgumentError)
|
203
|
+
end
|
178
204
|
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
205
|
+
it 'accepts a tests directory, clearing all other suites' do
|
206
|
+
allow_any_instance_of(Pathname).to receive(:exist?).and_return(true)
|
207
|
+
allow_any_instance_of(Pathname).to receive(:directory?).and_return(true)
|
208
|
+
allow(Dir).to receive(:glob)
|
209
|
+
.with('tests/**/*.rb')
|
210
|
+
.and_return(%w[tests/a.rb tests/b/c.rb])
|
211
|
+
|
212
|
+
subcommand.exec('tests')
|
213
|
+
|
214
|
+
expect(subcommand.cli.options[:pre_suite]).to eq([])
|
215
|
+
expect(subcommand.cli.options[:post_suite]).to eq([])
|
216
|
+
expect(subcommand.cli.options[:pre_cleanup]).to eq([])
|
217
|
+
expect(subcommand.cli.options[:tests]).to eq(%w[tests/a.rb tests/b/c.rb])
|
183
218
|
end
|
184
219
|
|
185
|
-
it '
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
220
|
+
it 'accepts comma-separated list of tests, clearing all other suites' do
|
221
|
+
allow_any_instance_of(Pathname).to receive(:exist?).and_return(true)
|
222
|
+
allow_any_instance_of(Pathname).to receive(:file?).and_return(true)
|
223
|
+
|
224
|
+
subcommand.exec('tests/1.rb,tests/2.rb')
|
225
|
+
|
226
|
+
expect(subcommand.cli.options[:pre_suite]).to eq([])
|
227
|
+
expect(subcommand.cli.options[:post_suite]).to eq([])
|
228
|
+
expect(subcommand.cli.options[:pre_cleanup]).to eq([])
|
229
|
+
expect(subcommand.cli.options[:tests]).to eq(%w[tests/1.rb tests/2.rb])
|
191
230
|
end
|
192
231
|
|
193
|
-
it '
|
232
|
+
it 'accepts comma-separated list of directories, recursively scanning each' do
|
233
|
+
allow_any_instance_of(Pathname).to receive(:exist?).and_return(true)
|
234
|
+
allow_any_instance_of(Pathname).to receive(:directory?).and_return(true)
|
235
|
+
allow(Dir).to receive(:glob).with('tests/a/**/*.rb').and_return(%w[tests/a/x.rb])
|
236
|
+
allow(Dir).to receive(:glob).with('tests/b/**/*.rb').and_return(%w[tests/b/x/y.rb tests/b/x/z.rb])
|
194
237
|
|
195
|
-
|
196
|
-
|
197
|
-
expect
|
238
|
+
subcommand.exec('tests/a,tests/b')
|
239
|
+
|
240
|
+
expect(subcommand.cli.options[:tests]).to eq(%w[tests/a/x.rb tests/b/x/y.rb tests/b/x/z.rb])
|
198
241
|
end
|
199
242
|
|
200
|
-
it '
|
243
|
+
it 'rejects comma-separated file and suite name' do
|
201
244
|
allow_any_instance_of(Pathname).to receive(:exist?).and_return(false)
|
202
|
-
|
245
|
+
|
246
|
+
expect {
|
247
|
+
subcommand.exec('pre-suite,tests/whoops')
|
248
|
+
}.to raise_error(ArgumentError, %r{Unable to parse pre-suite,tests/whoops})
|
203
249
|
end
|
204
250
|
end
|
205
251
|
|
206
252
|
context 'destroy' do
|
207
|
-
let( :cli ) { subcommand.
|
253
|
+
let( :cli ) { subcommand.cli }
|
208
254
|
let( :mock_options ) { {:timestamp => 'noon', :other_key => 'cordite'}}
|
209
255
|
let( :yaml_store_mock ) { double('yaml_store_mock') }
|
256
|
+
let( :network_manager) {double('network_manager')}
|
257
|
+
|
210
258
|
it 'calls destroy and updates the yaml store' do
|
259
|
+
allow(cli).to receive(:parse_options)
|
260
|
+
allow(cli).to receive(:initialize_network_manager)
|
261
|
+
allow(cli).to receive(:network_manager).and_return(network_manager)
|
262
|
+
expect(network_manager).to receive(:cleanup)
|
263
|
+
|
211
264
|
expect(YAML::Store).to receive(:new).with(SubcommandUtil::SUBCOMMAND_STATE).and_return(yaml_store_mock)
|
212
|
-
allow(SubcommandUtil).to receive(:cleanup).with(cli).and_return(true)
|
213
265
|
allow(yaml_store_mock).to receive(:transaction).and_yield
|
214
266
|
allow(yaml_store_mock).to receive(:[]).with('provisioned').and_return(true)
|
215
267
|
allow(yaml_store_mock).to receive(:delete).with('provisioned').and_return(true)
|