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
@@ -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
|
|