beaker 3.12.0 → 3.13.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|