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
@@ -0,0 +1,274 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
class ClassMixedWithDSLStructure
|
4
|
+
include Beaker::DSL::TestTagging
|
5
|
+
include Beaker::DSL::Helpers::TestHelpers
|
6
|
+
end
|
7
|
+
|
8
|
+
describe ClassMixedWithDSLStructure do
|
9
|
+
include Beaker::DSL::Assertions
|
10
|
+
|
11
|
+
let (:logger) { double }
|
12
|
+
let (:metadata) { @metadata ||= {} }
|
13
|
+
|
14
|
+
before :each do
|
15
|
+
allow( subject ).to receive(:metadata).and_return(metadata)
|
16
|
+
end
|
17
|
+
|
18
|
+
describe '#tag' do
|
19
|
+
let ( :test_tag_and ) { @test_tag_and || [] }
|
20
|
+
let ( :test_tag_or ) { @test_tag_or || [] }
|
21
|
+
let ( :test_tag_exclude ) { @test_tag_exclude || [] }
|
22
|
+
let ( :options ) {
|
23
|
+
opts = Beaker::Options::OptionsHash.new
|
24
|
+
opts[:test_tag_and] = test_tag_and
|
25
|
+
opts[:test_tag_or] = test_tag_or
|
26
|
+
opts[:test_tag_exclude] = test_tag_exclude
|
27
|
+
opts
|
28
|
+
}
|
29
|
+
|
30
|
+
before :each do
|
31
|
+
allow( subject ).to receive( :platform_specific_tag_confines )
|
32
|
+
end
|
33
|
+
|
34
|
+
it 'sets tags on the TestCase\'s metadata object' do
|
35
|
+
subject.instance_variable_set(:@options, options)
|
36
|
+
tags = ['pants', 'jayjay', 'moguely']
|
37
|
+
subject.tag(*tags)
|
38
|
+
expect( metadata[:case][:tags] ).to be === tags
|
39
|
+
end
|
40
|
+
|
41
|
+
it 'lowercases the tags' do
|
42
|
+
subject.instance_variable_set(:@options, options)
|
43
|
+
tags_upper = ['pANTs', 'jAYJAy', 'moGUYly']
|
44
|
+
tags_lower = tags_upper.map(&:downcase)
|
45
|
+
subject.tag(*tags_upper)
|
46
|
+
expect( metadata[:case][:tags] ).to be === tags_lower
|
47
|
+
end
|
48
|
+
|
49
|
+
it 'skips the test if any of the requested tags isn\'t included in this test' do
|
50
|
+
test_tags = ['pants', 'jayjay', 'moguely']
|
51
|
+
@test_tag_and = test_tags.compact.push('needed_tag_not_in_test')
|
52
|
+
subject.instance_variable_set(:@options, options)
|
53
|
+
|
54
|
+
allow( subject ).to receive( :path )
|
55
|
+
expect( subject ).to receive( :skip_test )
|
56
|
+
subject.tag(*test_tags)
|
57
|
+
end
|
58
|
+
|
59
|
+
it 'runs the test if all requested tags are included in this test' do
|
60
|
+
@test_tag_and = ['pants_on_head', 'jayjay_jayjay', 'mo']
|
61
|
+
test_tags = @test_tag_and.compact.push('extra_asdf')
|
62
|
+
subject.instance_variable_set(:@options, options)
|
63
|
+
|
64
|
+
allow( subject ).to receive( :path )
|
65
|
+
expect( subject ).to receive( :skip_test ).never
|
66
|
+
subject.tag(*test_tags)
|
67
|
+
end
|
68
|
+
|
69
|
+
it 'skips the test if any of the excluded tags are included in this test' do
|
70
|
+
test_tags = ['ports', 'jay_john_mary', 'mog_the_dog']
|
71
|
+
@test_tag_exclude = [test_tags[0]]
|
72
|
+
subject.instance_variable_set(:@options, options)
|
73
|
+
|
74
|
+
allow( subject ).to receive( :path )
|
75
|
+
expect( subject ).to receive( :skip_test )
|
76
|
+
subject.tag(*test_tags)
|
77
|
+
end
|
78
|
+
|
79
|
+
it 'skips the test if an and-included & excluded tag are in this test' do
|
80
|
+
test_tags = ['ports', 'jay_john_mary', 'mog_the_dog']
|
81
|
+
@test_tag_and = [test_tags[1]]
|
82
|
+
@test_tag_exclude = [test_tags[0]]
|
83
|
+
subject.instance_variable_set(:@options, options)
|
84
|
+
|
85
|
+
allow( subject ).to receive( :path )
|
86
|
+
expect( subject ).to receive( :skip_test )
|
87
|
+
subject.tag(*test_tags)
|
88
|
+
end
|
89
|
+
|
90
|
+
it 'runs the test if none of the excluded tags are included in this test' do
|
91
|
+
@test_tag_exclude = ['pants_on_head', 'jayjay_jayjay', 'mo']
|
92
|
+
test_tags = ['pants_at_head', 'jayj00_jayjay', 'motly_crew']
|
93
|
+
subject.instance_variable_set(:@options, options)
|
94
|
+
|
95
|
+
allow( subject ).to receive( :path )
|
96
|
+
expect( subject ).to receive( :skip_test ).never
|
97
|
+
subject.tag(*test_tags)
|
98
|
+
end
|
99
|
+
|
100
|
+
it 'skips the test if none of the OR tags are included in this test' do
|
101
|
+
test_tags = ['portmanteau', 'foolios']
|
102
|
+
@test_tag_or = ['fish', 'crayons', 'parkas']
|
103
|
+
subject.instance_variable_set(:@options, options)
|
104
|
+
|
105
|
+
allow( subject ).to receive( :path )
|
106
|
+
expect( subject ).to receive( :skip_test )
|
107
|
+
subject.tag(*test_tags)
|
108
|
+
end
|
109
|
+
|
110
|
+
it 'runs the test if only one of the OR tags are included in this test' do
|
111
|
+
test_tags = ['portmanteau', 'foolios']
|
112
|
+
@test_tag_or = ['foolios', 'crayons', 'parkas']
|
113
|
+
subject.instance_variable_set(:@options, options)
|
114
|
+
|
115
|
+
allow( subject ).to receive( :path )
|
116
|
+
expect( subject ).to receive( :skip_test ).never
|
117
|
+
subject.tag(*test_tags)
|
118
|
+
end
|
119
|
+
|
120
|
+
it 'skips the test if an or-included & excluded tag are included in this test' do
|
121
|
+
test_tags = ['ports', 'jay_john_mary', 'mog_the_dog']
|
122
|
+
@test_tag_or = [test_tags[1]]
|
123
|
+
@test_tag_exclude = [test_tags[0]]
|
124
|
+
subject.instance_variable_set(:@options, options)
|
125
|
+
|
126
|
+
allow( subject ).to receive( :path )
|
127
|
+
expect( subject ).to receive( :skip_test )
|
128
|
+
subject.tag(*test_tags)
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
describe Beaker::DSL::TestTagging::PlatformTagConfiner do
|
134
|
+
let ( :confines_array ) { @confines_array || [] }
|
135
|
+
let ( :confiner ) {
|
136
|
+
Beaker::DSL::TestTagging::PlatformTagConfiner.new( confines_array )
|
137
|
+
}
|
138
|
+
|
139
|
+
describe '#initialize' do
|
140
|
+
it 'transforms one entry' do
|
141
|
+
platform_regex = /^ubuntu$/
|
142
|
+
tag_reason_hash = {
|
143
|
+
'tag1' => 'reason1',
|
144
|
+
'tag2' => 'reason2'
|
145
|
+
}
|
146
|
+
@confines_array = [ {
|
147
|
+
:platform => platform_regex,
|
148
|
+
:tag_reason_hash => tag_reason_hash
|
149
|
+
}
|
150
|
+
]
|
151
|
+
|
152
|
+
internal_hash = confiner.instance_variable_get( :@tag_confine_details_hash )
|
153
|
+
expect( internal_hash.keys() ).to include( 'tag1' )
|
154
|
+
expect( internal_hash.keys() ).to include( 'tag2' )
|
155
|
+
expect( internal_hash.keys().length() ).to be === 2
|
156
|
+
|
157
|
+
tag_reason_hash.each do |tag, reason|
|
158
|
+
tag_array = internal_hash[tag]
|
159
|
+
expect( tag_array.length() ).to be === 1
|
160
|
+
tag_hash = tag_array[0]
|
161
|
+
expect( tag_hash[:platform_regex] ).to eql( platform_regex )
|
162
|
+
expect( tag_hash[:log_message] ).to match( /#{reason}/ )
|
163
|
+
expect( tag_hash[:type] ).to be === :except
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
167
|
+
it 'deals with the same tag being used on multiple platforms correctly' do
|
168
|
+
@confines_array = [
|
169
|
+
{
|
170
|
+
:platform => /^el-/,
|
171
|
+
:tag_reason_hash => {
|
172
|
+
'tag1' => 'reason el 1',
|
173
|
+
'tag2' => 'reason2'
|
174
|
+
}
|
175
|
+
}, {
|
176
|
+
:platform => /^cisco-/,
|
177
|
+
:tag_reason_hash => {
|
178
|
+
'tag1' => 'reason cisco 1',
|
179
|
+
'tag3' => 'reason3'
|
180
|
+
}
|
181
|
+
}
|
182
|
+
]
|
183
|
+
|
184
|
+
internal_hash = confiner.instance_variable_get( :@tag_confine_details_hash )
|
185
|
+
expect( internal_hash.keys() ).to include( 'tag1' )
|
186
|
+
expect( internal_hash.keys() ).to include( 'tag2' )
|
187
|
+
expect( internal_hash.keys() ).to include( 'tag3' )
|
188
|
+
expect( internal_hash.keys().length() ).to be === 3
|
189
|
+
|
190
|
+
shared_tag_array = internal_hash['tag1']
|
191
|
+
expect( shared_tag_array.length() ).to be === 2
|
192
|
+
|
193
|
+
platform_el_found = false
|
194
|
+
platform_cisco_found = false
|
195
|
+
shared_tag_array.each do |confine_details|
|
196
|
+
case confine_details[:log_message]
|
197
|
+
when /\ el\ 1/
|
198
|
+
platform_el_found = true
|
199
|
+
platform_to_match = /^el-/
|
200
|
+
reason_to_match = /reason\ el\ 1/
|
201
|
+
when /\ cisco\ 1/
|
202
|
+
platform_cisco_found = true
|
203
|
+
platform_to_match = /^cisco-/
|
204
|
+
reason_to_match = /reason\ cisco\ 1/
|
205
|
+
else
|
206
|
+
log_msg = "unexpected log message for confine_details: "
|
207
|
+
log_msg << confine_details[:log_message]
|
208
|
+
fail( log_msg )
|
209
|
+
end
|
210
|
+
|
211
|
+
expect( confine_details[:platform_regex] ).to eql( platform_to_match )
|
212
|
+
expect( confine_details[:log_message] ).to match( reason_to_match )
|
213
|
+
end
|
214
|
+
expect( platform_el_found ).to be === true
|
215
|
+
expect( platform_cisco_found ).to be === true
|
216
|
+
end
|
217
|
+
end
|
218
|
+
|
219
|
+
describe '#confine_details' do
|
220
|
+
it 'returns an empty array if no tags match' do
|
221
|
+
fake_confine_details_hash = { 'tag1' => [ {:type => 1}, {:type => 2} ]}
|
222
|
+
confiner.instance_variable_set(
|
223
|
+
:@tag_confine_details_hash, fake_confine_details_hash
|
224
|
+
)
|
225
|
+
expect( confiner.confine_details( [ 'tag2', 'tag3' ] ) ).to be === []
|
226
|
+
end
|
227
|
+
|
228
|
+
context 'descriminates on tag name' do
|
229
|
+
fake_confine_details_hash = {
|
230
|
+
'tag0' => [ 10, 20, 30, 40 ],
|
231
|
+
'tag1' => [ 41, 51, 61, 71 ],
|
232
|
+
'tag2' => [ 22, 32, 42, 52 ],
|
233
|
+
'tag3' => [ 63, 73, 83, 93 ],
|
234
|
+
'tag4' => [ 34, 44, 54, 64 ],
|
235
|
+
}
|
236
|
+
|
237
|
+
key_combos_to_test = fake_confine_details_hash.keys.map { |key| [key] }
|
238
|
+
key_combos_to_test << [ 'tag0', 'tag2' ]
|
239
|
+
key_combos_to_test << [ 'tag1', 'tag4' ]
|
240
|
+
key_combos_to_test << [ 'tag2', 'tag3', 'tag4' ]
|
241
|
+
key_combos_to_test << fake_confine_details_hash.keys()
|
242
|
+
|
243
|
+
before :each do
|
244
|
+
confiner.instance_variable_set(
|
245
|
+
:@tag_confine_details_hash, fake_confine_details_hash
|
246
|
+
)
|
247
|
+
end
|
248
|
+
|
249
|
+
key_combos_to_test.each do |key_combo_to_have|
|
250
|
+
it "selects key(s) #{key_combo_to_have} from #{fake_confine_details_hash.keys}" do
|
251
|
+
haves = []
|
252
|
+
key_combo_to_have.each do |key_to_have|
|
253
|
+
haves += fake_confine_details_hash[key_to_have]
|
254
|
+
end
|
255
|
+
keys_not_to_have = fake_confine_details_hash.keys.reject { |key_trial|
|
256
|
+
key_combo_to_have.include?( key_trial )
|
257
|
+
}
|
258
|
+
have_nots = []
|
259
|
+
keys_not_to_have.each do |key_not_to_have|
|
260
|
+
have_nots += fake_confine_details_hash[key_not_to_have]
|
261
|
+
end
|
262
|
+
|
263
|
+
details = confiner.confine_details( key_combo_to_have )
|
264
|
+
have_nots.each do |confine_details|
|
265
|
+
expect( details ).to_not include( confine_details )
|
266
|
+
end
|
267
|
+
haves.each do |confine_details|
|
268
|
+
expect( details ).to include( confine_details )
|
269
|
+
end
|
270
|
+
end
|
271
|
+
end
|
272
|
+
end
|
273
|
+
end
|
274
|
+
end
|
@@ -107,8 +107,8 @@ module Cisco
|
|
107
107
|
|
108
108
|
it 'turns env maps into paired strings correctly' do
|
109
109
|
@options = { :user => 'root' }
|
110
|
-
env_map = { 'var1' => 'ans1', '
|
111
|
-
answer_correct = 'source /etc/profile; export VAR1="ans1" VAR2="ans2";'
|
110
|
+
env_map = { 'var1' => 'ans1', 'VAR2' => 'ans2' }
|
111
|
+
answer_correct = 'source /etc/profile; export var1="ans1" VAR1="ans1" VAR2="ans2";'
|
112
112
|
answer_test = host.environment_string( env_map )
|
113
113
|
expect( answer_test ).to be === answer_correct
|
114
114
|
end
|
@@ -141,8 +141,8 @@ module Cisco
|
|
141
141
|
|
142
142
|
it 'turns env maps into paired strings correctly' do
|
143
143
|
@options = { :user => 'root' }
|
144
|
-
env_map = { '
|
145
|
-
answer_correct = 'source /etc/profile; env VAR1="ans1" VAR2="ans2"'
|
144
|
+
env_map = { 'VAR1' => 'ans1', 'var2' => 'ans2' }
|
145
|
+
answer_correct = 'source /etc/profile; env VAR1="ans1" var2="ans2" VAR2="ans2"'
|
146
146
|
answer_test = host.environment_string( env_map )
|
147
147
|
expect( answer_test ).to be === answer_correct
|
148
148
|
end
|
@@ -60,8 +60,8 @@ module Beaker
|
|
60
60
|
end
|
61
61
|
|
62
62
|
it 'takes an env hash with var_name/value pairs' do
|
63
|
-
expect( instance.environment_string( {:HOME => '/'} ) ).
|
64
|
-
to be ==
|
63
|
+
expect( instance.environment_string( {:HOME => '/', :http_proxy => 'http://foo'} ) ).
|
64
|
+
to be == 'env HOME="/" http_proxy="http://foo" HTTP_PROXY="http://foo"'
|
65
65
|
end
|
66
66
|
|
67
67
|
it 'takes an env hash with var_name/value[Array] pairs' do
|
@@ -349,7 +349,7 @@ describe Beaker do
|
|
349
349
|
|
350
350
|
it "can sync keys on a non-solaris host" do
|
351
351
|
|
352
|
-
expect( Beaker::Command ).to receive( :new ).with( sync_cmd % "env PATH
|
352
|
+
expect( Beaker::Command ).to receive( :new ).with( sync_cmd % "env PATH=\"/usr/gnu/bin:$PATH\" bash" ).exactly( 3 ).times
|
353
353
|
|
354
354
|
subject.sync_root_keys( hosts, options )
|
355
355
|
|
@@ -6,8 +6,8 @@ module Beaker
|
|
6
6
|
|
7
7
|
let(:parser) {Beaker::Options::CommandLineParser.new}
|
8
8
|
let(:test_opts) {["-h", "vcloud.cfg", "--debug", "--tests", "test.rb", "--help"]}
|
9
|
-
let(:full_opts_in) {["--hosts", "host.cfg", "--options", "opts_file", "--helper", "path_to_helper", "--load-path", "load_path", "--tests", "test1.rb,test2.rb,test3.rb", "--pre-suite", "pre_suite.rb", "--post-suite", "post_suite.rb", "--pre-cleanup", "pre_cleanup.rb", "--no-provision", "--preserve-hosts", "always", "--root-keys", "--keyfile", "../.ssh/id_rsa", "--install", "gitrepopath", "-m", "module", "-q", "--dry-run", "--no-ntp", "--repo-proxy", "--add-el-extras", "--config", "anotherfile.cfg", "--fail-mode", "fast", "--no-color", "--no-color-host-output",
|
10
|
-
let(:full_opts_out) {{:hosts_file=>"anotherfile.cfg",:options_file=>"opts_file", :helper => "path_to_helper", :load_path => "load_path", :tests => "test1.rb,test2.rb,test3.rb", :pre_suite => "pre_suite.rb", :post_suite => "post_suite.rb", :pre_cleanup => "pre_cleanup.rb", :provision=>false, :preserve_hosts => "always", :root_keys=>true, :keyfile => "../.ssh/id_rsa", :install => "gitrepopath", :modules=>"module", :quiet=>true, :dry_run=>true, :timesync=>false, :repo_proxy=>true, :add_el_extras=>true, :fail_mode => "fast", :color=>false, :color_host_output=>false, :beaker_version_print=>true, :log_level => "info", :package_proxy => "http://192.168.100.1:3128", :collect_perf_data=>"normal", :parse_only=>true, :validate=>true, :timeout => "40", :log_prefix => "pants", :configure => true,
|
9
|
+
let(:full_opts_in) {["--hosts", "host.cfg", "--options", "opts_file", "--helper", "path_to_helper", "--load-path", "load_path", "--tests", "test1.rb,test2.rb,test3.rb", "--pre-suite", "pre_suite.rb", "--post-suite", "post_suite.rb", "--pre-cleanup", "pre_cleanup.rb", "--no-provision", "--preserve-hosts", "always", "--root-keys", "--keyfile", "../.ssh/id_rsa", "--install", "gitrepopath", "-m", "module", "-q", "--dry-run", "--no-ntp", "--repo-proxy", "--add-el-extras", "--config", "anotherfile.cfg", "--fail-mode", "fast", "--no-color", "--no-color-host-output", "--version", "--log-level", "info", "--package-proxy", "http://192.168.100.1:3128", "--collect-perf-data", "--parse-only", "--validate", "--timeout", "40", "--log-prefix", "pants", "--configure", "--test-tag-and", "1,2,3", "--test-tag-or", "4,5,6", "--test-tag-exclude", "7,8,9", "--xml-time-order"]}
|
10
|
+
let(:full_opts_out) {{:hosts_file=>"anotherfile.cfg",:options_file=>"opts_file", :helper => "path_to_helper", :load_path => "load_path", :tests => "test1.rb,test2.rb,test3.rb", :pre_suite => "pre_suite.rb", :post_suite => "post_suite.rb", :pre_cleanup => "pre_cleanup.rb", :provision=>false, :preserve_hosts => "always", :root_keys=>true, :keyfile => "../.ssh/id_rsa", :install => "gitrepopath", :modules=>"module", :quiet=>true, :dry_run=>true, :timesync=>false, :repo_proxy=>true, :add_el_extras=>true, :fail_mode => "fast", :color=>false, :color_host_output=>false, :beaker_version_print=>true, :log_level => "info", :package_proxy => "http://192.168.100.1:3128", :collect_perf_data=>"normal", :parse_only=>true, :validate=>true, :timeout => "40", :log_prefix => "pants", :configure => true, :test_tag_and => "1,2,3", :test_tag_or => "4,5,6", :test_tag_exclude => "7,8,9", :xml_time_enabled => true}}
|
11
11
|
let(:validate_true) {["--validate"]}
|
12
12
|
let(:validate_false) {["--no-validate"]}
|
13
13
|
let(:configure_true) {['--configure']}
|
@@ -479,51 +479,60 @@ module Beaker
|
|
479
479
|
end
|
480
480
|
|
481
481
|
describe '#normalize_tags!' do
|
482
|
-
let (:
|
483
|
-
let (:
|
484
|
-
let (:
|
485
|
-
|
486
|
-
opts
|
487
|
-
opts[:
|
482
|
+
let (:test_tag_and ) { @test_tag_and || [] }
|
483
|
+
let (:test_tag_or ) { @test_tag_or || [] }
|
484
|
+
let (:test_tag_exclude ) { @test_tag_exclude || [] }
|
485
|
+
let (:options ) {
|
486
|
+
opts = Beaker::Options::OptionsHash.new
|
487
|
+
opts[:test_tag_and] = test_tag_and
|
488
|
+
opts[:test_tag_or] = test_tag_or
|
489
|
+
opts[:test_tag_exclude] = test_tag_exclude
|
488
490
|
opts
|
489
491
|
}
|
490
492
|
|
491
493
|
it 'does not error if no tags overlap' do
|
492
|
-
@
|
493
|
-
@
|
494
|
+
@test_tag_and = 'can,tommies,potatoes,plant'
|
495
|
+
@test_tag_or = 'juicy,zoomba,plantation'
|
496
|
+
@test_tag_exclude = 'joey,long_running,pants'
|
494
497
|
parser.instance_variable_set(:@options, options)
|
495
498
|
|
496
|
-
expect { parser.
|
499
|
+
expect { parser.normalize_test_tags! }.not_to raise_error
|
497
500
|
end
|
498
501
|
|
499
502
|
it 'splits the basic case correctly' do
|
500
|
-
@
|
501
|
-
@
|
503
|
+
@test_tag_and = 'can,tommies,potatoes,plant'
|
504
|
+
@test_tag_or = 'johnny,wordsmith,zebra'
|
505
|
+
@test_tag_exclude = 'joey,long_running,pants'
|
502
506
|
parser.instance_variable_set(:@options, options)
|
503
507
|
|
504
|
-
parser.
|
505
|
-
expect(options[:
|
506
|
-
expect(options[:
|
508
|
+
parser.normalize_test_tags!
|
509
|
+
expect(options[:test_tag_and] ).to be === ['can', 'tommies', 'potatoes', 'plant']
|
510
|
+
expect(options[:test_tag_or] ).to be === ['johnny', 'wordsmith', 'zebra']
|
511
|
+
expect(options[:test_tag_exclude]).to be === ['joey', 'long_running', 'pants']
|
507
512
|
end
|
508
513
|
|
509
514
|
it 'returns empty arrays for empty strings' do
|
510
|
-
@
|
511
|
-
@
|
515
|
+
@test_tag_and = ''
|
516
|
+
@test_tag_or = ''
|
517
|
+
@test_tag_exclude = ''
|
512
518
|
parser.instance_variable_set(:@options, options)
|
513
519
|
|
514
|
-
parser.
|
515
|
-
expect(options[:
|
516
|
-
expect(options[:
|
520
|
+
parser.normalize_test_tags!
|
521
|
+
expect(options[:test_tag_and] ).to be === []
|
522
|
+
expect(options[:test_tag_or] ).to be === []
|
523
|
+
expect(options[:test_tag_exclude]).to be === []
|
517
524
|
end
|
518
525
|
|
519
526
|
it 'lowercases all tags correctly for later use' do
|
520
|
-
@
|
521
|
-
@
|
527
|
+
@test_tag_and = 'jeRRy_And_tOM,PARka'
|
528
|
+
@test_tag_or = 'clearLy_They,Neva'
|
529
|
+
@test_tag_exclude = 'lEet_spEAK,pOland'
|
522
530
|
parser.instance_variable_set(:@options, options)
|
523
531
|
|
524
|
-
parser.
|
525
|
-
expect(options[:
|
526
|
-
expect(options[:
|
532
|
+
parser.normalize_test_tags!
|
533
|
+
expect(options[:test_tag_and] ).to be === ['jerry_and_tom', 'parka']
|
534
|
+
expect(options[:test_tag_or] ).to be === ['clearly_they', 'neva']
|
535
|
+
expect(options[:test_tag_exclude]).to be === ['leet_speak', 'poland']
|
527
536
|
end
|
528
537
|
end
|
529
538
|
|
@@ -93,19 +93,34 @@ module Beaker
|
|
93
93
|
end
|
94
94
|
end
|
95
95
|
|
96
|
-
describe '#
|
96
|
+
describe '#validate_test_tags' do
|
97
97
|
it 'does error if tags overlap' do
|
98
98
|
tag_includes = %w(can tommies should_error potatoes plant)
|
99
99
|
tag_excludes = %w(joey long_running pants should_error)
|
100
100
|
|
101
|
-
expect {
|
101
|
+
expect {
|
102
|
+
validator.validate_test_tags(tag_includes, [], tag_excludes)
|
103
|
+
}.to raise_error(ArgumentError)
|
102
104
|
end
|
103
105
|
|
104
106
|
it 'does not raise an error if tags do not overlap' do
|
105
107
|
tag_includes = %w(horse dog cat)
|
106
108
|
tag_excludes = %w(car truck train)
|
107
109
|
|
108
|
-
expect {
|
110
|
+
expect {
|
111
|
+
validator.validate_test_tags(tag_includes, [], tag_excludes)
|
112
|
+
}.to_not raise_error
|
113
|
+
end
|
114
|
+
|
115
|
+
it 'raises an error if AND and OR are both used' do
|
116
|
+
# this is because we don't have a way to specify how they
|
117
|
+
# should interact
|
118
|
+
tag_and = %w(square)
|
119
|
+
tag_or = %w(circle)
|
120
|
+
|
121
|
+
expect {
|
122
|
+
validator.validate_test_tags(tag_and, tag_or, [])
|
123
|
+
}.to raise_error(ArgumentError)
|
109
124
|
end
|
110
125
|
end
|
111
126
|
|