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
@@ -245,12 +245,27 @@ module Beaker
245
245
  @cmd_options[:type] = type
246
246
  end
247
247
 
248
- opts.on '--tag TAGS', 'Run the set of tests matching ALL of the provided single or comma separated list of tags' do |value|
249
- @cmd_options[:tag_includes] = value
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', 'Run the set of tests that do not contain ANY of the provided single or command separated list of tags' do |value|
253
- @cmd_options[:tag_excludes] = value
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
- normalize_tags!
367
- @validator.validate_tags(@options[:tag_includes], @options[:tag_excludes])
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
- def normalize_tags!
415
- @options[:tag_includes] ||= ''
416
- @options[:tag_excludes] ||= ''
417
- @options[:tag_includes] = @options[:tag_includes].split(',') if @options[:tag_includes].respond_to?(:split)
418
- @options[:tag_excludes] = @options[:tag_excludes].split(',') if @options[:tag_excludes].respond_to?(:split)
419
- @options[:tag_includes].map!(&:downcase)
420
- @options[:tag_excludes].map!(&:downcase)
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
- :tag_includes => ['BEAKER_TAG'],
38
- :tag_excludes => ['BEAKER_EXCLUDE_TAG'],
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
- :tag_includes => '',
161
- :tag_excludes => '',
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
- # @param [Array] include included items
85
- # @param [Array] exclude excluded items
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 validate_tags(include, exclude)
88
- include.each do |included_tag|
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 exclude.select { |ex| ex == included_tag } != []
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
@@ -6,20 +6,98 @@ module Beaker
6
6
  class Subcommand < Thor
7
7
  SubcommandUtil = Beaker::Subcommands::SubcommandUtil
8
8
 
9
- desc "init", "Initialises the beaker test environment configuration"
10
- option :hypervisor, :type => :string, :enum => %w{vagrant vmpooler}
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
- Initialises a beaker environment configuration
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(options)
22
- say "Writing host config to .beaker/acceptance/config/default_#{options[:hypervisor]}_hosts.yaml"
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 0
90
- # @param [String] msg the message to print
91
- def self.exit_with(msg)
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
- exit(0)
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 [Array<Object>] options the options we want to query
98
- def self.init_hypervisor(options)
99
- case options[:hypervisor]
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
@@ -1,5 +1,5 @@
1
1
  module Beaker
2
2
  module Version
3
- STRING = '3.12.0'
3
+ STRING = '3.13.0'
4
4
  end
5
5
  end
@@ -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
- describe '#tag' do
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