beaker 3.12.0 → 3.13.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 +8 -8
- data/acceptance/tests/subcommands/init.rb +17 -15
- data/acceptance/tests/subcommands/provision.rb +45 -0
- data/beaker.gemspec +5 -9
- data/bin/beaker +1 -1
- data/docs/concepts/test_tagging.md +27 -14
- data/docs/how_to/archive_sut_files.md +19 -1
- data/docs/how_to/hypervisors/README.md +20 -3
- data/docs/how_to/hypervisors/ec2.md +4 -0
- data/docs/how_to/hypervisors/vmpooler.md +24 -0
- data/docs/how_to/hypervisors/vsphere.md +0 -3
- data/docs/tutorials/installation.md +22 -7
- data/lib/beaker/cli.rb +28 -12
- data/lib/beaker/dsl.rb +2 -1
- data/lib/beaker/dsl/helpers/puppet_helpers.rb +1 -1
- data/lib/beaker/dsl/helpers/tk_helpers.rb +1 -1
- data/lib/beaker/dsl/structure.rb +0 -130
- data/lib/beaker/dsl/test_tagging.rb +157 -0
- data/lib/beaker/host/unix/exec.rb +9 -1
- data/lib/beaker/host_prebuilt_steps.rb +1 -1
- data/lib/beaker/hypervisor/openstack.rb +8 -9
- data/lib/beaker/options/command_line_parser.rb +19 -4
- data/lib/beaker/options/parser.rb +18 -9
- data/lib/beaker/options/presets.rb +6 -4
- data/lib/beaker/options/validator.rb +11 -5
- data/lib/beaker/subcommand.rb +84 -6
- data/lib/beaker/subcommands/subcommand_util.rb +58 -7
- data/lib/beaker/version.rb +1 -1
- data/spec/beaker/cli_spec.rb +44 -1
- data/spec/beaker/dsl/structure_spec.rb +1 -214
- data/spec/beaker/dsl/test_tagging_spec.rb +274 -0
- data/spec/beaker/host/cisco_spec.rb +4 -4
- data/spec/beaker/host/unix/exec_spec.rb +2 -2
- data/spec/beaker/host_prebuilt_steps_spec.rb +1 -1
- data/spec/beaker/options/command_line_parser_spec.rb +2 -2
- data/spec/beaker/options/parser_spec.rb +33 -24
- data/spec/beaker/options/validator_spec.rb +18 -3
- data/spec/beaker/subcommand/subcommand_util_spec.rb +121 -10
- metadata +12 -8
@@ -245,12 +245,27 @@ module Beaker
|
|
245
245
|
@cmd_options[:type] = type
|
246
246
|
end
|
247
247
|
|
248
|
-
opts.on '--tag TAGS',
|
249
|
-
|
248
|
+
opts.on '--tag TAGS',
|
249
|
+
'DEPRECATED - use --test-tag-and instead' do |value|
|
250
|
+
@cmd_options[:test_tag_and] = value
|
251
|
+
end
|
252
|
+
opts.on '--test-tag-and TAGS',
|
253
|
+
'Run the set of tests matching ALL of the provided single or comma separated list of tags' do |value|
|
254
|
+
@cmd_options[:test_tag_and] = value
|
255
|
+
end
|
256
|
+
|
257
|
+
opts.on '--test-tag-or TAGS',
|
258
|
+
'Run the set of tests matching ANY of the provided single or comma separated list of tags' do |value|
|
259
|
+
@cmd_options[:test_tag_or] = value
|
250
260
|
end
|
251
261
|
|
252
|
-
opts.on '--exclude-tag TAGS',
|
253
|
-
|
262
|
+
opts.on '--exclude-tag TAGS',
|
263
|
+
'DEPRECATED - use --test-tag-exclude instead' do |value|
|
264
|
+
@cmd_options[:test_tag_exclude] = value
|
265
|
+
end
|
266
|
+
opts.on '--test-tag-exclude TAGS',
|
267
|
+
'Run the set of tests that do not contain ANY of the provided single or comma separated list of tags' do |value|
|
268
|
+
@cmd_options[:test_tag_exclude] = value
|
254
269
|
end
|
255
270
|
|
256
271
|
opts.on '--xml-time-order',
|
@@ -363,8 +363,12 @@ module Beaker
|
|
363
363
|
host[:host_tags] = @options[:host_tags].merge(host[:host_tags] || {})
|
364
364
|
end
|
365
365
|
|
366
|
-
|
367
|
-
@validator.
|
366
|
+
normalize_test_tags!
|
367
|
+
@validator.validate_test_tags(
|
368
|
+
@options[:test_tag_and],
|
369
|
+
@options[:test_tag_or],
|
370
|
+
@options[:test_tag_exclude]
|
371
|
+
)
|
368
372
|
resolve_symlinks!
|
369
373
|
|
370
374
|
#set the default role
|
@@ -411,13 +415,18 @@ module Beaker
|
|
411
415
|
|
412
416
|
# Normalize include and exclude tags. This modifies @options.
|
413
417
|
#
|
414
|
-
|
415
|
-
|
416
|
-
|
417
|
-
@options[:
|
418
|
-
@options[:
|
419
|
-
@options[:
|
420
|
-
@options[:
|
418
|
+
# @note refer to {Beaker::DSL::TestTagging} for test tagging implementation
|
419
|
+
#
|
420
|
+
def normalize_test_tags!
|
421
|
+
@options[:test_tag_and] ||= ''
|
422
|
+
@options[:test_tag_or] ||= ''
|
423
|
+
@options[:test_tag_exclude] ||= ''
|
424
|
+
@options[:test_tag_and] = @options[:test_tag_and].split(',') if @options[:test_tag_and].respond_to?(:split)
|
425
|
+
@options[:test_tag_or] = @options[:test_tag_or].split(',') if @options[:test_tag_or].respond_to?(:split)
|
426
|
+
@options[:test_tag_exclude] = @options[:test_tag_exclude].split(',') if @options[:test_tag_exclude].respond_to?(:split)
|
427
|
+
@options[:test_tag_and].map!(&:downcase)
|
428
|
+
@options[:test_tag_or].map!(&:downcase)
|
429
|
+
@options[:test_tag_exclude].map!(&:downcase)
|
421
430
|
end
|
422
431
|
|
423
432
|
private
|
@@ -34,8 +34,9 @@ module Beaker
|
|
34
34
|
:release_yum_repo_url => ['BEAKER_RELEASE_YUM_REPO', 'RELEASE_YUM_REPO'],
|
35
35
|
:dev_builds_url => ['BEAKER_DEV_BUILDS_URL', 'DEV_BUILDS_URL'],
|
36
36
|
:vbguest_plugin => ['BEAKER_VB_GUEST_PLUGIN', 'BEAKER_vb_guest_plugin'],
|
37
|
-
:
|
38
|
-
:
|
37
|
+
:test_tag_and => ['BEAKER_TAG', 'BEAKER_TEST_TAG_AND'],
|
38
|
+
:test_tag_or => ['BEAKER_TEST_TAG_OR'],
|
39
|
+
:test_tag_exclude => ['BEAKER_EXCLUDE_TAG', 'BEAKER_TEST_TAG_EXCLUDE'],
|
39
40
|
:run_in_parallel => ['BEAKER_RUN_IN_PARALLEL'],
|
40
41
|
}
|
41
42
|
|
@@ -157,8 +158,9 @@ module Beaker
|
|
157
158
|
:log_sut_event => 'sut.log',
|
158
159
|
:color => true,
|
159
160
|
:dry_run => false,
|
160
|
-
:
|
161
|
-
:
|
161
|
+
:test_tag_and => '',
|
162
|
+
:test_tag_or => '',
|
163
|
+
:test_tag_exclude => '',
|
162
164
|
:timeout => 900, # 15 minutes
|
163
165
|
:fail_mode => 'slow',
|
164
166
|
:accept_all_exit_codes => false,
|
@@ -81,14 +81,20 @@ module Beaker
|
|
81
81
|
|
82
82
|
# Raise an error if an item exists in both the include and exclude lists.
|
83
83
|
#
|
84
|
-
# @
|
85
|
-
#
|
84
|
+
# @note see test tagging logic at {Beaker::DSL::TestTagging} module
|
85
|
+
#
|
86
|
+
# @param [Array] tags_and included items
|
87
|
+
# @param [Array] tags_exclude excluded items
|
86
88
|
# @return [nil] Does not return anything
|
87
|
-
def
|
88
|
-
|
89
|
+
def validate_test_tags(tags_and, tags_or, tags_exclude)
|
90
|
+
if tags_and.length > 0 && tags_or.length > 0
|
91
|
+
validator_error "cannot have values for both test tagging operands (AND and OR)"
|
92
|
+
end
|
93
|
+
|
94
|
+
tags_and.each do |included_tag|
|
89
95
|
# select items from exclude set that match included_tag
|
90
96
|
# no match is an empty list/array/[]
|
91
|
-
if
|
97
|
+
if tags_exclude.select { |ex| ex == included_tag } != []
|
92
98
|
validator_error "tag '#{included_tag}' cannot be in both the included and excluded tag sets"
|
93
99
|
end
|
94
100
|
end
|
data/lib/beaker/subcommand.rb
CHANGED
@@ -6,20 +6,98 @@ module Beaker
|
|
6
6
|
class Subcommand < Thor
|
7
7
|
SubcommandUtil = Beaker::Subcommands::SubcommandUtil
|
8
8
|
|
9
|
-
|
10
|
-
|
9
|
+
def initialize(*args)
|
10
|
+
super
|
11
|
+
@@config = SubcommandUtil.init_config()
|
12
|
+
end
|
13
|
+
|
14
|
+
# Options listed in this group 'Beaker run' are options that can be set on subcommands
|
15
|
+
# but are not processed by the subcommand itself. They are passed through so that when
|
16
|
+
# a Beaker::CLI object executes, it can pick up these options. Notably excluded from this
|
17
|
+
# group are `help` and `version`. Please note that whenever the command_line_parser.rb is
|
18
|
+
# updated, this list should also be updated as well.
|
19
|
+
class_option :hosts, :aliases => '-h', :type => :string, :group => 'Beaker run'
|
20
|
+
class_option :'options-file', :aliases => '-o', :type => :string, :group => 'Beaker run'
|
21
|
+
class_option :helper, :type => :string, :group => 'Beaker run'
|
22
|
+
class_option :'load-path', :type => :string, :group => 'Beaker run'
|
23
|
+
class_option :tests, :aliases => '-t', :type => :string, :group => 'Beaker run'
|
24
|
+
class_option :'pre-suite', :type => :string, :group => 'Beaker run'
|
25
|
+
class_option :'post-suite', :type => :string, :group => 'Beaker run'
|
26
|
+
class_option :'pre-cleanup', :type => :string, :group => 'Beaker run'
|
27
|
+
class_option :'provision', :type => :boolean, :group => 'Beaker run'
|
28
|
+
class_option :'preserve-hosts', :type => :string, :group => 'Beaker run'
|
29
|
+
class_option :'root-keys', :type => :boolean, :group => 'Beaker run'
|
30
|
+
class_option :keyfile, :type => :string, :group => 'Beaker run'
|
31
|
+
class_option :timeout, :type => :string, :group => 'Beaker run'
|
32
|
+
class_option :install, :aliases => '-i', :type => :string, :group => 'Beaker run'
|
33
|
+
class_option :modules, :aliases => '-m', :type => :string, :group => 'Beaker run'
|
34
|
+
class_option :quiet, :aliases => '-q', :type => :boolean, :group => 'Beaker run'
|
35
|
+
class_option :color, :type => :boolean, :group => 'Beaker run'
|
36
|
+
class_option :'color-host-output', :type => :boolean, :group => 'Beaker run'
|
37
|
+
class_option :'log-level', :type => :string, :group => 'Beaker run'
|
38
|
+
class_option :'log-prefix', :type => :string, :group => 'Beaker run'
|
39
|
+
class_option :'dry-run', :type => :boolean, :group => 'Beaker run'
|
40
|
+
class_option :'fail-mode', :type => :string, :group => 'Beaker run'
|
41
|
+
class_option :ntp, :type => :boolean, :group => 'Beaker run'
|
42
|
+
class_option :'repo-proxy', :type => :boolean, :group => 'Beaker run'
|
43
|
+
class_option :'add-el-extras', :type => :boolean, :group => 'Beaker run'
|
44
|
+
class_option :'package-proxy', :type => :string, :group => 'Beaker run'
|
45
|
+
class_option :'validate', :type => :boolean, :group => 'Beaker run'
|
46
|
+
class_option :'collect-perf-data', :type => :boolean, :group => 'Beaker run'
|
47
|
+
class_option :'parse-only', :type => :boolean, :group => 'Beaker run'
|
48
|
+
class_option :tag, :type => :string, :group => 'Beaker run'
|
49
|
+
class_option :'exclude-tags', :type => :string, :group => 'Beaker run'
|
50
|
+
class_option :'xml-time-order', :type => :boolean, :group => 'Beaker run'
|
51
|
+
|
52
|
+
desc "init HYPERVISOR", "Initialises the beaker test environment configuration"
|
11
53
|
option :help, :type => :boolean, :hide => true
|
12
54
|
long_desc <<-LONGDESC
|
13
|
-
|
55
|
+
|
56
|
+
Initialises a test environment configuration for a specific hypervisor
|
57
|
+
|
58
|
+
Supported hypervisors are: vagrant (default), vmpooler
|
59
|
+
|
14
60
|
LONGDESC
|
15
|
-
def init()
|
61
|
+
def init(hypervisor='vagrant')
|
16
62
|
if options[:help]
|
17
63
|
invoke :help, [], ["init"]
|
18
64
|
return
|
19
65
|
end
|
66
|
+
SubcommandUtil.verify_init_args(hypervisor)
|
20
67
|
SubcommandUtil.require_tasks()
|
21
|
-
SubcommandUtil.init_hypervisor(
|
22
|
-
say "Writing host config to .beaker/acceptance/config/default_#{
|
68
|
+
SubcommandUtil.init_hypervisor(hypervisor)
|
69
|
+
say "Writing host config to .beaker/acceptance/config/default_#{hypervisor}_hosts.yaml"
|
70
|
+
SubcommandUtil.store_config({:hypervisor => hypervisor})
|
71
|
+
SubcommandUtil.delete_config([:provisioned])
|
72
|
+
end
|
73
|
+
|
74
|
+
desc "provision", "Provisions the beaker test configuration"
|
75
|
+
option :validate, :type => :boolean, :default => true
|
76
|
+
option :configure, :type => :boolean, :default => true
|
77
|
+
option :help, :type => :boolean, :hide => true
|
78
|
+
long_desc <<-LONGDESC
|
79
|
+
Provisions a beaker configuration
|
80
|
+
LONGDESC
|
81
|
+
def provision()
|
82
|
+
if options[:help]
|
83
|
+
invoke :help, [], ["provision"]
|
84
|
+
return
|
85
|
+
end
|
86
|
+
|
87
|
+
hypervisor = @@config.transaction { @@config[:hypervisor] }
|
88
|
+
|
89
|
+
unless hypervisor
|
90
|
+
SubcommandUtil.error_with("Please initialise a configuration")
|
91
|
+
end
|
92
|
+
|
93
|
+
provisioned = @@config.transaction { @@config[:provisioned] }
|
94
|
+
|
95
|
+
if !provisioned or options[:force]
|
96
|
+
SubcommandUtil.provision(hypervisor, options)
|
97
|
+
SubcommandUtil.store_config({:provisioned => true})
|
98
|
+
else
|
99
|
+
say "Hosts have already been provisioned"
|
100
|
+
end
|
23
101
|
end
|
24
102
|
end
|
25
103
|
end
|
@@ -1,5 +1,7 @@
|
|
1
1
|
require 'rake'
|
2
2
|
require 'stringio'
|
3
|
+
require 'yaml/store'
|
4
|
+
require 'fileutils'
|
3
5
|
|
4
6
|
module Beaker
|
5
7
|
module Subcommands
|
@@ -18,6 +20,8 @@ module Beaker
|
|
18
20
|
module SubcommandUtil
|
19
21
|
BEAKER_REQUIRE = "require 'beaker/tasks/quick_start'"
|
20
22
|
HYPERVISORS = ["vagrant", "vmpooler"]
|
23
|
+
CONFIG_DIR = ".beaker"
|
24
|
+
CONFIG_KEYS = [:hypervisor, :provisioned]
|
21
25
|
|
22
26
|
# Check if the first argument to the beaker execution is a subcommand
|
23
27
|
# @return [Boolean] true if argv[0] is "help" or a method defined in the Subcommands class, false otherwise
|
@@ -86,17 +90,20 @@ module Beaker
|
|
86
90
|
execute_rake_task("beaker_quickstart:gen_hosts[vmpooler]")
|
87
91
|
end
|
88
92
|
|
89
|
-
# Print a message to the console and exit with
|
90
|
-
# @param [String] msg the message to
|
91
|
-
|
93
|
+
# Print a message to the console and exit with specified exit code, defaults to 1
|
94
|
+
# @param [String] msg the message to output
|
95
|
+
# @param [Hash<Object>] options to specify exit code or output stack trace
|
96
|
+
def self.error_with(msg, options={})
|
92
97
|
puts msg
|
93
|
-
|
98
|
+
puts options[:stack_trace] if options[:stack_trace]
|
99
|
+
exit_code = options[:exit_code] ? options[:exit_code] : 1
|
100
|
+
exit(exit_code)
|
94
101
|
end
|
95
102
|
|
96
103
|
# Call the quick start task for the specified hypervisor
|
97
|
-
# @param [
|
98
|
-
def self.init_hypervisor(
|
99
|
-
case
|
104
|
+
# @param [String] hypervisor the hypervisor we want to query
|
105
|
+
def self.init_hypervisor(hypervisor)
|
106
|
+
case hypervisor
|
100
107
|
when "vagrant"
|
101
108
|
init_vagrant
|
102
109
|
when "vmpooler"
|
@@ -104,6 +111,14 @@ module Beaker
|
|
104
111
|
end
|
105
112
|
end
|
106
113
|
|
114
|
+
# Verify that a valid hypervisor has been specified
|
115
|
+
# @param [String] hypervisor the hypervisor we want to validate
|
116
|
+
def self.verify_init_args(hypervisor)
|
117
|
+
unless HYPERVISORS.include?(hypervisor)
|
118
|
+
error_with("Invalid hypervisor. Currently supported hypervisors are: #{HYPERVISORS.join(', ')}")
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
107
122
|
# Execute a task but capture stdout and stderr to a buffer
|
108
123
|
def self.with_captured_output
|
109
124
|
begin
|
@@ -117,6 +132,42 @@ module Beaker
|
|
117
132
|
$stderr = old_stderr
|
118
133
|
end
|
119
134
|
end
|
135
|
+
|
136
|
+
# Initialise the beaker config
|
137
|
+
def self.init_config()
|
138
|
+
FileUtils.mkdir_p CONFIG_DIR
|
139
|
+
@@store = YAML::Store.new("#{CONFIG_DIR}/config")
|
140
|
+
end
|
141
|
+
|
142
|
+
# Store values from a hash into the beaker config
|
143
|
+
# @param [Hash{Symbol=>String}] config values we want to store
|
144
|
+
def self.store_config(config)
|
145
|
+
@@store.transaction do
|
146
|
+
CONFIG_KEYS.each do |key|
|
147
|
+
@@store[key] = config[key] unless config[key].nil?
|
148
|
+
end
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
# Delete keys from the beaker configi
|
153
|
+
# @param [Array<Object>] keys the keys we want to delete from the config
|
154
|
+
def self.delete_config(keys)
|
155
|
+
@@store.transaction {
|
156
|
+
keys.each do |key|
|
157
|
+
@@store.delete(key)
|
158
|
+
end
|
159
|
+
}
|
160
|
+
end
|
161
|
+
|
162
|
+
# Reset args and provision nodes
|
163
|
+
# @param [String] hypervisor the hypervisor to use
|
164
|
+
# @param [Array<Object>] options the options to use when provisioning
|
165
|
+
def self.provision(hypervisor, options)
|
166
|
+
reset_argv(["--hosts", "#{CONFIG_DIR}/acceptance/config/default_#{hypervisor}_hosts.yaml", "--validate", options[:validate], "--configure", options[:configure]])
|
167
|
+
beaker = Beaker::CLI.new.parse_options
|
168
|
+
beaker.provision
|
169
|
+
beaker.preserve_hosts_file
|
170
|
+
end
|
120
171
|
end
|
121
172
|
end
|
122
173
|
end
|
data/lib/beaker/version.rb
CHANGED
data/spec/beaker/cli_spec.rb
CHANGED
@@ -2,9 +2,52 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
module Beaker
|
4
4
|
describe CLI do
|
5
|
+
|
6
|
+
context 'initializing and parsing' do
|
7
|
+
let( :cli ) {
|
8
|
+
Beaker::CLI.new
|
9
|
+
}
|
10
|
+
|
11
|
+
describe 'instance variable initialization' do
|
12
|
+
it 'creates a logger for use before parse is called' do
|
13
|
+
expect(Beaker::Logger).to receive(:new).once.and_call_original
|
14
|
+
expect(cli.logger).to be_instance_of(Beaker::Logger)
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'generates the timestamp' do
|
18
|
+
expect(Time).to receive(:now).once
|
19
|
+
cli
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
describe '#parse_options' do
|
24
|
+
it 'returns self' do
|
25
|
+
expect(cli.parse_options).to be_instance_of(Beaker::CLI)
|
26
|
+
end
|
27
|
+
|
28
|
+
it 'replaces the logger object with a new one' do
|
29
|
+
expect(Beaker::Logger).to receive(:new).with(no_args).once.and_call_original
|
30
|
+
expect(Beaker::Logger).to receive(:new).once.and_call_original
|
31
|
+
cli.parse_options
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
describe '#print_version_and_options' do
|
36
|
+
before do
|
37
|
+
options = Beaker::Options::OptionsHash.new
|
38
|
+
options[:beaker_version] = 'version_number'
|
39
|
+
cli.instance_variable_set('@options', options)
|
40
|
+
end
|
41
|
+
it 'prints the version and dumps the options' do
|
42
|
+
expect(cli.logger).to receive(:info).exactly(3).times
|
43
|
+
cli.print_version_and_options
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
5
48
|
let(:cli) {
|
6
49
|
allow(File).to receive(:exists?).and_return(true)
|
7
|
-
Beaker::CLI.new
|
50
|
+
Beaker::CLI.new.parse_options
|
8
51
|
}
|
9
52
|
|
10
53
|
context 'execute!' do
|
@@ -280,217 +280,4 @@ describe ClassMixedWithDSLStructure do
|
|
280
280
|
end
|
281
281
|
end
|
282
282
|
|
283
|
-
|
284
|
-
let ( :tag_includes ) { @tag_includes || [] }
|
285
|
-
let ( :tag_excludes ) { @tag_excludes || [] }
|
286
|
-
let ( :options ) {
|
287
|
-
opts = Beaker::Options::OptionsHash.new
|
288
|
-
opts[:tag_includes] = tag_includes
|
289
|
-
opts[:tag_excludes] = tag_excludes
|
290
|
-
opts
|
291
|
-
}
|
292
|
-
|
293
|
-
before :each do
|
294
|
-
allow( subject ).to receive( :platform_specific_tag_confines )
|
295
|
-
end
|
296
|
-
|
297
|
-
it 'sets tags on the TestCase\'s metadata object' do
|
298
|
-
subject.instance_variable_set(:@options, options)
|
299
|
-
tags = ['pants', 'jayjay', 'moguely']
|
300
|
-
subject.tag(*tags)
|
301
|
-
expect( metadata[:case][:tags] ).to be === tags
|
302
|
-
end
|
303
|
-
|
304
|
-
it 'lowercases the tags' do
|
305
|
-
subject.instance_variable_set(:@options, options)
|
306
|
-
tags_upper = ['pANTs', 'jAYJAy', 'moGUYly']
|
307
|
-
tags_lower = tags_upper.map(&:downcase)
|
308
|
-
subject.tag(*tags_upper)
|
309
|
-
expect( metadata[:case][:tags] ).to be === tags_lower
|
310
|
-
end
|
311
|
-
|
312
|
-
it 'skips the test if any of the requested tags isn\'t included in this test' do
|
313
|
-
test_tags = ['pants', 'jayjay', 'moguely']
|
314
|
-
@tag_includes = test_tags.compact.push('needed_tag_not_in_test')
|
315
|
-
subject.instance_variable_set(:@options, options)
|
316
|
-
|
317
|
-
allow( subject ).to receive( :path )
|
318
|
-
expect( subject ).to receive( :skip_test )
|
319
|
-
subject.tag(*test_tags)
|
320
|
-
end
|
321
|
-
|
322
|
-
it 'runs the test if all requested tags are included in this test' do
|
323
|
-
@tag_includes = ['pants_on_head', 'jayjay_jayjay', 'mo']
|
324
|
-
test_tags = @tag_includes.compact.push('extra_asdf')
|
325
|
-
subject.instance_variable_set(:@options, options)
|
326
|
-
|
327
|
-
allow( subject ).to receive( :path )
|
328
|
-
expect( subject ).to receive( :skip_test ).never
|
329
|
-
subject.tag(*test_tags)
|
330
|
-
end
|
331
|
-
|
332
|
-
it 'skips the test if any of the excluded tags are included in this test' do
|
333
|
-
test_tags = ['ports', 'jay_john_mary', 'mog_the_dog']
|
334
|
-
@tag_excludes = [test_tags[0]]
|
335
|
-
subject.instance_variable_set(:@options, options)
|
336
|
-
|
337
|
-
allow( subject ).to receive( :path )
|
338
|
-
expect( subject ).to receive( :skip_test )
|
339
|
-
subject.tag(*test_tags)
|
340
|
-
end
|
341
|
-
|
342
|
-
it 'runs the test if none of the excluded tags are included in this test' do
|
343
|
-
@tag_excludes = ['pants_on_head', 'jayjay_jayjay', 'mo']
|
344
|
-
test_tags = ['pants_at_head', 'jayj00_jayjay', 'motly_crew']
|
345
|
-
subject.instance_variable_set(:@options, options)
|
346
|
-
|
347
|
-
allow( subject ).to receive( :path )
|
348
|
-
expect( subject ).to receive( :skip_test ).never
|
349
|
-
subject.tag(*test_tags)
|
350
|
-
end
|
351
|
-
|
352
|
-
end
|
353
|
-
end
|
354
|
-
|
355
|
-
describe Beaker::DSL::Structure::PlatformTagConfiner do
|
356
|
-
let ( :confines_array ) { @confines_array || [] }
|
357
|
-
let ( :confiner ) {
|
358
|
-
Beaker::DSL::Structure::PlatformTagConfiner.new( confines_array )
|
359
|
-
}
|
360
|
-
|
361
|
-
describe '#initialize' do
|
362
|
-
it 'transforms one entry' do
|
363
|
-
platform_regex = /^ubuntu$/
|
364
|
-
tag_reason_hash = {
|
365
|
-
'tag1' => 'reason1',
|
366
|
-
'tag2' => 'reason2'
|
367
|
-
}
|
368
|
-
@confines_array = [ {
|
369
|
-
:platform => platform_regex,
|
370
|
-
:tag_reason_hash => tag_reason_hash
|
371
|
-
}
|
372
|
-
]
|
373
|
-
|
374
|
-
internal_hash = confiner.instance_variable_get( :@tag_confine_details_hash )
|
375
|
-
expect( internal_hash.keys() ).to include( 'tag1' )
|
376
|
-
expect( internal_hash.keys() ).to include( 'tag2' )
|
377
|
-
expect( internal_hash.keys().length() ).to be === 2
|
378
|
-
|
379
|
-
tag_reason_hash.each do |tag, reason|
|
380
|
-
tag_array = internal_hash[tag]
|
381
|
-
expect( tag_array.length() ).to be === 1
|
382
|
-
tag_hash = tag_array[0]
|
383
|
-
expect( tag_hash[:platform_regex] ).to eql( platform_regex )
|
384
|
-
expect( tag_hash[:log_message] ).to match( /#{reason}/ )
|
385
|
-
expect( tag_hash[:type] ).to be === :except
|
386
|
-
end
|
387
|
-
end
|
388
|
-
|
389
|
-
it 'deals with the same tag being used on multiple platforms correctly' do
|
390
|
-
@confines_array = [
|
391
|
-
{
|
392
|
-
:platform => /^el-/,
|
393
|
-
:tag_reason_hash => {
|
394
|
-
'tag1' => 'reason el 1',
|
395
|
-
'tag2' => 'reason2'
|
396
|
-
}
|
397
|
-
}, {
|
398
|
-
:platform => /^cisco-/,
|
399
|
-
:tag_reason_hash => {
|
400
|
-
'tag1' => 'reason cisco 1',
|
401
|
-
'tag3' => 'reason3'
|
402
|
-
}
|
403
|
-
}
|
404
|
-
]
|
405
|
-
|
406
|
-
internal_hash = confiner.instance_variable_get( :@tag_confine_details_hash )
|
407
|
-
expect( internal_hash.keys() ).to include( 'tag1' )
|
408
|
-
expect( internal_hash.keys() ).to include( 'tag2' )
|
409
|
-
expect( internal_hash.keys() ).to include( 'tag3' )
|
410
|
-
expect( internal_hash.keys().length() ).to be === 3
|
411
|
-
|
412
|
-
shared_tag_array = internal_hash['tag1']
|
413
|
-
expect( shared_tag_array.length() ).to be === 2
|
414
|
-
|
415
|
-
platform_el_found = false
|
416
|
-
platform_cisco_found = false
|
417
|
-
shared_tag_array.each do |confine_details|
|
418
|
-
case confine_details[:log_message]
|
419
|
-
when /\ el\ 1/
|
420
|
-
platform_el_found = true
|
421
|
-
platform_to_match = /^el-/
|
422
|
-
reason_to_match = /reason\ el\ 1/
|
423
|
-
when /\ cisco\ 1/
|
424
|
-
platform_cisco_found = true
|
425
|
-
platform_to_match = /^cisco-/
|
426
|
-
reason_to_match = /reason\ cisco\ 1/
|
427
|
-
else
|
428
|
-
log_msg = "unexpected log message for confine_details: "
|
429
|
-
log_msg << confine_details[:log_message]
|
430
|
-
fail( log_msg )
|
431
|
-
end
|
432
|
-
|
433
|
-
expect( confine_details[:platform_regex] ).to eql( platform_to_match )
|
434
|
-
expect( confine_details[:log_message] ).to match( reason_to_match )
|
435
|
-
end
|
436
|
-
expect( platform_el_found ).to be === true
|
437
|
-
expect( platform_cisco_found ).to be === true
|
438
|
-
end
|
439
|
-
end
|
440
|
-
|
441
|
-
describe '#confine_details' do
|
442
|
-
it 'returns an empty array if no tags match' do
|
443
|
-
fake_confine_details_hash = { 'tag1' => [ {:type => 1}, {:type => 2} ]}
|
444
|
-
confiner.instance_variable_set(
|
445
|
-
:@tag_confine_details_hash, fake_confine_details_hash
|
446
|
-
)
|
447
|
-
expect( confiner.confine_details( [ 'tag2', 'tag3' ] ) ).to be === []
|
448
|
-
end
|
449
|
-
|
450
|
-
context 'descriminates on tag name' do
|
451
|
-
fake_confine_details_hash = {
|
452
|
-
'tag0' => [ 10, 20, 30, 40 ],
|
453
|
-
'tag1' => [ 41, 51, 61, 71 ],
|
454
|
-
'tag2' => [ 22, 32, 42, 52 ],
|
455
|
-
'tag3' => [ 63, 73, 83, 93 ],
|
456
|
-
'tag4' => [ 34, 44, 54, 64 ],
|
457
|
-
}
|
458
|
-
|
459
|
-
key_combos_to_test = fake_confine_details_hash.keys.map { |key| [key] }
|
460
|
-
key_combos_to_test << [ 'tag0', 'tag2' ]
|
461
|
-
key_combos_to_test << [ 'tag1', 'tag4' ]
|
462
|
-
key_combos_to_test << [ 'tag2', 'tag3', 'tag4' ]
|
463
|
-
key_combos_to_test << fake_confine_details_hash.keys()
|
464
|
-
|
465
|
-
before :each do
|
466
|
-
confiner.instance_variable_set(
|
467
|
-
:@tag_confine_details_hash, fake_confine_details_hash
|
468
|
-
)
|
469
|
-
end
|
470
|
-
|
471
|
-
key_combos_to_test.each do |key_combo_to_have|
|
472
|
-
it "selects key(s) #{key_combo_to_have} from #{fake_confine_details_hash.keys}" do
|
473
|
-
haves = []
|
474
|
-
key_combo_to_have.each do |key_to_have|
|
475
|
-
haves += fake_confine_details_hash[key_to_have]
|
476
|
-
end
|
477
|
-
keys_not_to_have = fake_confine_details_hash.keys.reject { |key_trial|
|
478
|
-
key_combo_to_have.include?( key_trial )
|
479
|
-
}
|
480
|
-
have_nots = []
|
481
|
-
keys_not_to_have.each do |key_not_to_have|
|
482
|
-
have_nots += fake_confine_details_hash[key_not_to_have]
|
483
|
-
end
|
484
|
-
|
485
|
-
details = confiner.confine_details( key_combo_to_have )
|
486
|
-
have_nots.each do |confine_details|
|
487
|
-
expect( details ).to_not include( confine_details )
|
488
|
-
end
|
489
|
-
haves.each do |confine_details|
|
490
|
-
expect( details ).to include( confine_details )
|
491
|
-
end
|
492
|
-
end
|
493
|
-
end
|
494
|
-
end
|
495
|
-
end
|
496
|
-
end
|
283
|
+
end
|