beaker 3.12.0 → 3.13.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (39) hide show
  1. checksums.yaml +8 -8
  2. data/acceptance/tests/subcommands/init.rb +17 -15
  3. data/acceptance/tests/subcommands/provision.rb +45 -0
  4. data/beaker.gemspec +5 -9
  5. data/bin/beaker +1 -1
  6. data/docs/concepts/test_tagging.md +27 -14
  7. data/docs/how_to/archive_sut_files.md +19 -1
  8. data/docs/how_to/hypervisors/README.md +20 -3
  9. data/docs/how_to/hypervisors/ec2.md +4 -0
  10. data/docs/how_to/hypervisors/vmpooler.md +24 -0
  11. data/docs/how_to/hypervisors/vsphere.md +0 -3
  12. data/docs/tutorials/installation.md +22 -7
  13. data/lib/beaker/cli.rb +28 -12
  14. data/lib/beaker/dsl.rb +2 -1
  15. data/lib/beaker/dsl/helpers/puppet_helpers.rb +1 -1
  16. data/lib/beaker/dsl/helpers/tk_helpers.rb +1 -1
  17. data/lib/beaker/dsl/structure.rb +0 -130
  18. data/lib/beaker/dsl/test_tagging.rb +157 -0
  19. data/lib/beaker/host/unix/exec.rb +9 -1
  20. data/lib/beaker/host_prebuilt_steps.rb +1 -1
  21. data/lib/beaker/hypervisor/openstack.rb +8 -9
  22. data/lib/beaker/options/command_line_parser.rb +19 -4
  23. data/lib/beaker/options/parser.rb +18 -9
  24. data/lib/beaker/options/presets.rb +6 -4
  25. data/lib/beaker/options/validator.rb +11 -5
  26. data/lib/beaker/subcommand.rb +84 -6
  27. data/lib/beaker/subcommands/subcommand_util.rb +58 -7
  28. data/lib/beaker/version.rb +1 -1
  29. data/spec/beaker/cli_spec.rb +44 -1
  30. data/spec/beaker/dsl/structure_spec.rb +1 -214
  31. data/spec/beaker/dsl/test_tagging_spec.rb +274 -0
  32. data/spec/beaker/host/cisco_spec.rb +4 -4
  33. data/spec/beaker/host/unix/exec_spec.rb +2 -2
  34. data/spec/beaker/host_prebuilt_steps_spec.rb +1 -1
  35. data/spec/beaker/options/command_line_parser_spec.rb +2 -2
  36. data/spec/beaker/options/parser_spec.rb +33 -24
  37. data/spec/beaker/options/validator_spec.rb +18 -3
  38. data/spec/beaker/subcommand/subcommand_util_spec.rb +121 -10
  39. 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', 'var2' => 'ans2' }
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 = { 'var1' => 'ans1', 'var2' => 'ans2' }
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 == "env HOME=\"/\""
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=/usr/gnu/bin:$PATH bash" ).exactly( 3 ).times
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", "--version", "--log-level", "info", "--package-proxy", "http://192.168.100.1:3128", "--collect-perf-data", "--parse-only", "--validate", "--timeout", "40", "--log-prefix", "pants", "--configure", "--tag", "1,2,3", "--exclude-tag", "4,5,6", "--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, :tag_includes => "1,2,3", :tag_excludes => "4,5,6", :xml_time_enabled => 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 (:tag_includes) { @tag_includes || [] }
483
- let (:tag_excludes) { @tag_excludes || [] }
484
- let (:options) {
485
- opts = Beaker::Options::OptionsHash.new
486
- opts[:tag_includes] = tag_includes
487
- opts[:tag_excludes] = tag_excludes
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
- @tag_includes = 'can,tommies,potatoes,plant'
493
- @tag_excludes = 'joey,long_running,pants'
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.normalize_tags! }.not_to raise_error
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
- @tag_includes = 'can,tommies,potatoes,plant'
501
- @tag_excludes = 'joey,long_running,pants'
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.normalize_tags!
505
- expect(options[:tag_includes]).to be === ['can', 'tommies', 'potatoes', 'plant']
506
- expect(options[:tag_excludes]).to be === ['joey', 'long_running', 'pants']
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
- @tag_includes = ''
511
- @tag_excludes = ''
515
+ @test_tag_and = ''
516
+ @test_tag_or = ''
517
+ @test_tag_exclude = ''
512
518
  parser.instance_variable_set(:@options, options)
513
519
 
514
- parser.normalize_tags!
515
- expect(options[:tag_includes]).to be === []
516
- expect(options[:tag_excludes]).to be === []
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
- @tag_includes = 'jeRRy_And_tOM,PARka'
521
- @tag_excludes = 'lEet_spEAK,pOland'
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.normalize_tags!
525
- expect(options[:tag_includes]).to be === ['jerry_and_tom', 'parka']
526
- expect(options[:tag_excludes]).to be === ['leet_speak', 'poland']
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 '#validate_tags' do
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 { validator.validate_tags(tag_includes, tag_excludes) }.to raise_error(ArgumentError)
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 { validator.validate_tags(tag_includes, tag_excludes) }.to_not raise_error
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