onceover 3.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +2 -0
- data/Gemfile +6 -0
- data/Gemfile.lock +17 -0
- data/README.md +504 -0
- data/Rakefile +2 -0
- data/bin/onceover +17 -0
- data/controlrepo.gemspec +38 -0
- data/factsets/CentOS-5.11-32.json +263 -0
- data/factsets/CentOS-5.11-64.json +263 -0
- data/factsets/CentOS-6.6-32.json +305 -0
- data/factsets/CentOS-6.6-64.json +342 -0
- data/factsets/CentOS-7.0-64.json +352 -0
- data/factsets/Debian-6.0.10-32.json +322 -0
- data/factsets/Debian-6.0.10-64.json +322 -0
- data/factsets/Debian-7.8-32.json +338 -0
- data/factsets/Debian-7.8-64.json +338 -0
- data/factsets/Ubuntu-12.04-32.json +328 -0
- data/factsets/Ubuntu-12.04-64.json +328 -0
- data/factsets/Ubuntu-14.04-32.json +337 -0
- data/factsets/Ubuntu-14.04-64.json +373 -0
- data/factsets/Windows_Server-2008r2-64.json +183 -0
- data/factsets/Windows_Server-2012r2-64.json +164 -0
- data/lib/onceover/beaker.rb +225 -0
- data/lib/onceover/beaker/spec_helper.rb +70 -0
- data/lib/onceover/class.rb +29 -0
- data/lib/onceover/cli.rb +46 -0
- data/lib/onceover/cli/init.rb +31 -0
- data/lib/onceover/cli/run.rb +72 -0
- data/lib/onceover/cli/show.rb +74 -0
- data/lib/onceover/cli/update.rb +48 -0
- data/lib/onceover/controlrepo.rb +527 -0
- data/lib/onceover/group.rb +85 -0
- data/lib/onceover/logger.rb +31 -0
- data/lib/onceover/node.rb +44 -0
- data/lib/onceover/rake_tasks.rb +113 -0
- data/lib/onceover/runner.rb +90 -0
- data/lib/onceover/test.rb +157 -0
- data/lib/onceover/testconfig.rb +233 -0
- data/templates/.fixtures.yml.erb +24 -0
- data/templates/Rakefile.erb +6 -0
- data/templates/acceptance_test_spec.rb.erb +66 -0
- data/templates/controlrepo.yaml.erb +38 -0
- data/templates/factsets_README.md.erb +7 -0
- data/templates/nodeset.yaml.erb +12 -0
- data/templates/pre_conditions_README.md.erb +24 -0
- data/templates/spec_helper.rb.erb +16 -0
- data/templates/spec_helper_acceptance.rb.erb +1 -0
- data/templates/test_spec.rb.erb +34 -0
- metadata +345 -0
@@ -0,0 +1,85 @@
|
|
1
|
+
require 'onceover/class'
|
2
|
+
require 'onceover/node'
|
3
|
+
|
4
|
+
class Onceover
|
5
|
+
class Group
|
6
|
+
@@all = []
|
7
|
+
|
8
|
+
# Work out how to do class veriables so that I can keep track of all the groups easily
|
9
|
+
attr_accessor :name
|
10
|
+
attr_accessor :members
|
11
|
+
|
12
|
+
# You need to pass in an array of strings for members, not objects, it will find the objects
|
13
|
+
# by itself, and yes it will reference them, not just create additional ones, woo!
|
14
|
+
|
15
|
+
def initialize(name = nil, members = [])
|
16
|
+
@name = name
|
17
|
+
@members = []
|
18
|
+
|
19
|
+
if Onceover::Group.valid_members?(members)
|
20
|
+
# If it's already a valid list just chuck it in there
|
21
|
+
@members = members
|
22
|
+
elsif members.is_a?(Hash)
|
23
|
+
# if it's a hash then do subtractive stiff
|
24
|
+
@members = Onceover::Group.subtractive_to_list(members)
|
25
|
+
else
|
26
|
+
# Turn it into a full list
|
27
|
+
member_objects = []
|
28
|
+
|
29
|
+
# This should also handle lists that include groups
|
30
|
+
members.each { |member| member_objects << Onceover::TestConfig.find_list(member) }
|
31
|
+
member_objects.flatten!
|
32
|
+
|
33
|
+
# Check that they are all the same type
|
34
|
+
unless Onceover::Group.valid_members?(member_objects)
|
35
|
+
raise 'Groups must contain either all nodes or all classes. Either there was a mix, or something was spelled wrong'
|
36
|
+
end
|
37
|
+
|
38
|
+
# Smash it into the instance variable
|
39
|
+
@members = member_objects
|
40
|
+
end
|
41
|
+
|
42
|
+
# Finally add it to the list of all grops
|
43
|
+
@@all << self
|
44
|
+
end
|
45
|
+
|
46
|
+
def self.find(group_name)
|
47
|
+
@@all.each do |group|
|
48
|
+
if group.name == group_name
|
49
|
+
return group
|
50
|
+
end
|
51
|
+
end
|
52
|
+
nil
|
53
|
+
end
|
54
|
+
|
55
|
+
def self.all
|
56
|
+
@@all
|
57
|
+
end
|
58
|
+
|
59
|
+
def self.valid_members?(members)
|
60
|
+
# Check that they are all the same type
|
61
|
+
# Also catch any errors to assume it's invalid
|
62
|
+
begin
|
63
|
+
if members.all? { |item| item.is_a?(Onceover::Class) }
|
64
|
+
return true
|
65
|
+
elsif members.all? { |item| item.is_a?(Onceover::Node) }
|
66
|
+
return true
|
67
|
+
else
|
68
|
+
return false
|
69
|
+
end
|
70
|
+
rescue
|
71
|
+
return false
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
def self.subtractive_to_list(subtractive_hash)
|
76
|
+
# Take a hash that looks like this:
|
77
|
+
# { 'include' => 'somegroup'
|
78
|
+
# 'exclude' => 'other'}
|
79
|
+
# and return a list of classes/nodes
|
80
|
+
include_list = Onceover::TestConfig.find_list(subtractive_hash['include'])
|
81
|
+
exclude_list = Onceover::TestConfig.find_list(subtractive_hash['exclude'])
|
82
|
+
include_list - exclude_list
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'logging'
|
2
|
+
|
3
|
+
module Onceover::Logger
|
4
|
+
def logger
|
5
|
+
unless $logger
|
6
|
+
# here we setup a color scheme called 'bright'
|
7
|
+
Logging.color_scheme( 'bright',
|
8
|
+
:levels => {
|
9
|
+
:debug => :cyan,
|
10
|
+
:info => :green,
|
11
|
+
:warn => :yellow,
|
12
|
+
:error => :red,
|
13
|
+
:fatal => [:white, :on_red]
|
14
|
+
}
|
15
|
+
)
|
16
|
+
|
17
|
+
Logging.appenders.stdout(
|
18
|
+
'stdout',
|
19
|
+
:layout => Logging.layouts.pattern(
|
20
|
+
:pattern => '%l\t -> %m\n',
|
21
|
+
:color_scheme => 'bright'
|
22
|
+
)
|
23
|
+
)
|
24
|
+
|
25
|
+
$logger = Logging.logger['Colors']
|
26
|
+
$logger.add_appenders 'stdout'
|
27
|
+
$logger.level = :warn
|
28
|
+
end
|
29
|
+
$logger
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
require 'onceover/controlrepo'
|
2
|
+
|
3
|
+
class Onceover
|
4
|
+
class Node
|
5
|
+
@@all = []
|
6
|
+
|
7
|
+
|
8
|
+
attr_accessor :name
|
9
|
+
attr_accessor :beaker_node
|
10
|
+
attr_accessor :fact_set
|
11
|
+
|
12
|
+
def initialize(name)
|
13
|
+
@name = name
|
14
|
+
@beaker_node = nil
|
15
|
+
|
16
|
+
# If we can't find the factset it will fail, so just catch that error and ignore it
|
17
|
+
begin
|
18
|
+
@fact_set = Onceover::Controlrepo.facts[Onceover::Controlrepo.facts_files.index{|facts_file| File.basename(facts_file,'.json') == name}]
|
19
|
+
rescue TypeError
|
20
|
+
@fact_set = nil
|
21
|
+
end
|
22
|
+
@@all << self
|
23
|
+
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.find(node_name)
|
27
|
+
@@all.each do |node|
|
28
|
+
if node_name.is_a?(Onceover::Node)
|
29
|
+
if node = node_name
|
30
|
+
return node
|
31
|
+
end
|
32
|
+
elsif node.name == node_name
|
33
|
+
return node
|
34
|
+
end
|
35
|
+
end
|
36
|
+
logger.warn "Node #{node_name} not found"
|
37
|
+
nil
|
38
|
+
end
|
39
|
+
|
40
|
+
def self.all
|
41
|
+
@@all
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,113 @@
|
|
1
|
+
require 'onceover/controlrepo'
|
2
|
+
require 'pathname'
|
3
|
+
|
4
|
+
@repo = nil
|
5
|
+
@config = nil
|
6
|
+
|
7
|
+
task :generate_fixtures do
|
8
|
+
repo = Onceover::Controlrepo.new
|
9
|
+
raise ".fixtures.yml already exits, we won't overwrite because we are scared" if File.exists?(File.expand_path('./.fixtures.yml',repo.root))
|
10
|
+
File.write(File.expand_path('./.fixtures.yml',repo.root),repo.fixtures)
|
11
|
+
end
|
12
|
+
|
13
|
+
task :hiera_setup do
|
14
|
+
repo = Onceover::Controlrepo.new
|
15
|
+
current_config = repo.hiera_config
|
16
|
+
current_config.each do |key, value|
|
17
|
+
if value.is_a?(Hash)
|
18
|
+
if value.has_key?(:datadir)
|
19
|
+
current_config[key][:datadir] = Pathname.new(repo.hiera_data).relative_path_from(Pathname.new(File.expand_path('..',repo.hiera_config_file))).to_s
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
puts "Changing hiera config from \n#{repo.hiera_config}\nto\n#{current_config}"
|
24
|
+
repo.hiera_config = current_config
|
25
|
+
end
|
26
|
+
|
27
|
+
task :controlrepo_details do
|
28
|
+
require 'onceover/controlrepo'
|
29
|
+
puts Onceover::Controlrepo.new.to_s
|
30
|
+
end
|
31
|
+
|
32
|
+
task :generate_controlrepo_yaml do
|
33
|
+
require 'onceover/controlrepo'
|
34
|
+
repo = Onceover::Controlrepo.new
|
35
|
+
template_dir = File.expand_path('../../templates',File.dirname(__FILE__))
|
36
|
+
controlrepo_yaml_template = File.read(File.expand_path('./controlrepo.yaml.erb',template_dir))
|
37
|
+
puts ERB.new(controlrepo_yaml_template, nil, '-').result(binding)
|
38
|
+
end
|
39
|
+
|
40
|
+
|
41
|
+
task :generate_nodesets do
|
42
|
+
require 'onceover/beaker'
|
43
|
+
require 'net/http'
|
44
|
+
require 'json'
|
45
|
+
|
46
|
+
repo = Onceover::Controlrepo.new
|
47
|
+
|
48
|
+
puts "HOSTS:"
|
49
|
+
|
50
|
+
repo.facts.each do |fact_set|
|
51
|
+
node_name = File.basename(repo.facts_files[repo.facts.index(fact_set)],'.json')
|
52
|
+
boxname = Onceover::Beaker.facts_to_vagrant_box(fact_set)
|
53
|
+
platform = Onceover::Beaker.facts_to_platform(fact_set)
|
54
|
+
response = Net::HTTP.get(URI.parse("https://atlas.hashicorp.com/api/v1/box/#{boxname}"))
|
55
|
+
url = 'URL goes here'
|
56
|
+
|
57
|
+
if response =~ /Not Found/i
|
58
|
+
comment_out = true
|
59
|
+
else
|
60
|
+
comment_out = false
|
61
|
+
box_info = JSON.parse(response)
|
62
|
+
box_info['current_version']['providers'].each do |provider|
|
63
|
+
if provider['name'] == 'virtualbox'
|
64
|
+
url = provider['original_url']
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
# Use an ERB template
|
70
|
+
template_dir = File.expand_path('../../templates',File.dirname(__FILE__))
|
71
|
+
fixtures_template = File.read(File.expand_path('./nodeset.yaml.erb',template_dir))
|
72
|
+
puts ERB.new(fixtures_template, nil, '-').result(binding)
|
73
|
+
end
|
74
|
+
|
75
|
+
end
|
76
|
+
|
77
|
+
task :controlrepo_autotest_prep do
|
78
|
+
require 'onceover/testconfig'
|
79
|
+
require 'onceover/runner'
|
80
|
+
@repo = Onceover::Controlrepo.new
|
81
|
+
# TODO: This should be getting the location of controlrepo.yaml from @repo
|
82
|
+
@config = Onceover::TestConfig.new("#{@repo.spec_dir}/controlrepo.yaml")
|
83
|
+
|
84
|
+
@runner = Onceover::Runner.new(@repo, @config)
|
85
|
+
@runner.prepare!
|
86
|
+
end
|
87
|
+
|
88
|
+
task :controlrepo_autotest_spec do
|
89
|
+
@runner.run_spec!
|
90
|
+
end
|
91
|
+
|
92
|
+
task :controlrepo_autotest_acceptance do
|
93
|
+
@runner.run_acceptance!
|
94
|
+
end
|
95
|
+
|
96
|
+
task :controlrepo_spec => [
|
97
|
+
:controlrepo_autotest_prep,
|
98
|
+
:controlrepo_autotest_spec
|
99
|
+
]
|
100
|
+
|
101
|
+
task :controlrepo_acceptance => [
|
102
|
+
:controlrepo_autotest_prep,
|
103
|
+
:controlrepo_autotest_acceptance
|
104
|
+
]
|
105
|
+
|
106
|
+
task :controlrepo_temp_create do
|
107
|
+
require 'onceover/testconfig'
|
108
|
+
repo = Onceover::Controlrepo.new
|
109
|
+
config = Onceover::TestConfig.new("#{repo.spec_dir}/controlrepo.yaml")
|
110
|
+
FileUtils.rm_rf(repo.tempdir)
|
111
|
+
# Deploy r10k to a temp dir
|
112
|
+
config.r10k_deploy_local(repo)
|
113
|
+
end
|
@@ -0,0 +1,90 @@
|
|
1
|
+
class Onceover
|
2
|
+
class Runner
|
3
|
+
attr_reader :repo
|
4
|
+
attr_reader :config
|
5
|
+
|
6
|
+
def initialize(repo, config, mode = [:spec, :acceptance])
|
7
|
+
@repo = repo
|
8
|
+
@config = config
|
9
|
+
@mode = [mode].flatten
|
10
|
+
end
|
11
|
+
|
12
|
+
def prepare!
|
13
|
+
# Deploy the puppetfile
|
14
|
+
@config.r10k_deploy_local(@repo)
|
15
|
+
|
16
|
+
# Remove the entire spec directory to make sure we have
|
17
|
+
# all the latest tests
|
18
|
+
FileUtils.rm_rf("#{@repo.tempdir}/spec")
|
19
|
+
|
20
|
+
# Create the other directories we need
|
21
|
+
FileUtils.mkdir_p("#{@repo.tempdir}/spec/classes")
|
22
|
+
FileUtils.mkdir_p("#{@repo.tempdir}/spec/acceptance/nodesets")
|
23
|
+
|
24
|
+
# Copy our entire spec directory over
|
25
|
+
FileUtils.cp_r("#{@repo.spec_dir}","#{@repo.tempdir}")
|
26
|
+
|
27
|
+
# Create the Rakefile so that we can take advantage of the existing tasks
|
28
|
+
@config.write_rakefile(@repo.tempdir, "spec/classes/**/*_spec.rb")
|
29
|
+
|
30
|
+
# Create spec_helper.rb
|
31
|
+
@config.write_spec_helper("#{@repo.tempdir}/spec",@repo)
|
32
|
+
|
33
|
+
# Create spec_helper_accpetance.rb
|
34
|
+
@config.write_spec_helper_acceptance("#{@repo.tempdir}/spec",@repo)
|
35
|
+
|
36
|
+
# TODO: Remove all tests that do not match set tags
|
37
|
+
|
38
|
+
if @mode.include?(:spec)
|
39
|
+
# Verify all of the spec tests
|
40
|
+
@config.spec_tests.each { |test| @config.verify_spec_test(@repo,test) }
|
41
|
+
|
42
|
+
# Deduplicate and write the tests (Spec and Acceptance)
|
43
|
+
@config.run_filters(Onceover::Test.deduplicate(@config.spec_tests)).each do |test|
|
44
|
+
@config.write_spec_test("#{@repo.tempdir}/spec/classes",test)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
if @mode.include?(:acceptance)
|
49
|
+
# Verify all of the acceptance tests
|
50
|
+
@config.acceptance_tests.each { |test| @config.verify_acceptance_test(@repo,test) }
|
51
|
+
|
52
|
+
# Write them out
|
53
|
+
@config.write_acceptance_tests("#{@repo.tempdir}/spec/acceptance",@config.run_filters(Onceover::Test.deduplicate(@config.acceptance_tests)))
|
54
|
+
end
|
55
|
+
|
56
|
+
# Parse the current hiera config, modify, and write it to the temp dir
|
57
|
+
unless @repo.hiera_config ==nil
|
58
|
+
hiera_config = @repo.hiera_config
|
59
|
+
hiera_config.each do |setting,value|
|
60
|
+
if value.is_a?(Hash)
|
61
|
+
if value.has_key?(:datadir)
|
62
|
+
hiera_config[setting][:datadir] = "#{@repo.tempdir}/#{@repo.environmentpath}/production/#{value[:datadir]}"
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
File.write("#{@repo.tempdir}/#{@repo.environmentpath}/production/hiera.yaml",hiera_config.to_yaml)
|
67
|
+
end
|
68
|
+
|
69
|
+
@config.create_fixtures_symlinks(@repo)
|
70
|
+
end
|
71
|
+
|
72
|
+
def run_spec!
|
73
|
+
Dir.chdir(@repo.tempdir) do
|
74
|
+
#`bundle install --binstubs`
|
75
|
+
#`bin/rake spec_standalone`
|
76
|
+
logger.debug "Running bundle exec rake spec_standalone from #{@repo.tempdir}"
|
77
|
+
exec("bundle exec rake spec_standalone")
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
def run_acceptance!
|
82
|
+
Dir.chdir(@repo.tempdir) do
|
83
|
+
#`bundle install --binstubs`
|
84
|
+
#`bin/rake spec_standalone`
|
85
|
+
logger.debug "Running bundle exec rake acceptance from #{@repo.tempdir}"
|
86
|
+
exec("bundle exec rake acceptance")
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
@@ -0,0 +1,157 @@
|
|
1
|
+
class Onceover
|
2
|
+
class Test
|
3
|
+
@@all =[]
|
4
|
+
|
5
|
+
attr_accessor :nodes
|
6
|
+
attr_accessor :classes
|
7
|
+
attr_accessor :test_config
|
8
|
+
attr_reader :default_test_config
|
9
|
+
attr_reader :tags
|
10
|
+
|
11
|
+
# This can accept a bunch of stuff. It can accept nodes, classes or groups anywhere
|
12
|
+
# it will then detect them and expand them out into their respective objects so that
|
13
|
+
# we just end up with a list of nodes and classes
|
14
|
+
#def initialize(on_this,test_config['classes'],options = {})
|
15
|
+
def initialize(on_this,test_this,test_config)
|
16
|
+
|
17
|
+
@default_test_config = {
|
18
|
+
'check_idempotency' => true,
|
19
|
+
'runs_before_idempotency' => 1
|
20
|
+
}
|
21
|
+
|
22
|
+
# Add defaults if they do not exist
|
23
|
+
test_config = @default_test_config.merge(test_config)
|
24
|
+
|
25
|
+
@nodes = []
|
26
|
+
@classes = []
|
27
|
+
@test_config = test_config
|
28
|
+
@test_config.delete('classes') # remove classes from the config
|
29
|
+
@tags = @test_config['tags']
|
30
|
+
|
31
|
+
|
32
|
+
# Make sure that tags are an array
|
33
|
+
@test_config['tags'] = [@test_config['tags']].flatten if @test_config['tags']
|
34
|
+
|
35
|
+
# Get the nodes we are working on
|
36
|
+
if Onceover::Group.find(on_this)
|
37
|
+
@nodes << Onceover::Group.find(on_this).members
|
38
|
+
elsif Onceover::Node.find(on_this)
|
39
|
+
@nodes << Onceover::Node.find(on_this)
|
40
|
+
else
|
41
|
+
raise "#{on_this} was not found in the list of nodes or groups!"
|
42
|
+
end
|
43
|
+
|
44
|
+
@nodes.flatten!
|
45
|
+
|
46
|
+
# Check that our nodes list contains only nodes
|
47
|
+
raise "#{@nodes} contained a non-node object." unless @nodes.all? { |item| item.is_a?(Onceover::Node) }
|
48
|
+
|
49
|
+
if test_this.is_a?(String)
|
50
|
+
# If we have just given a string then grab all the classes it corresponds to
|
51
|
+
if Onceover::Group.find(test_this)
|
52
|
+
@classes << Onceover::Group.find(test_this).members
|
53
|
+
elsif Onceover::Class.find(test_this)
|
54
|
+
@classes << Onceover::Class.find(test_this)
|
55
|
+
else
|
56
|
+
raise "#{test_this} was not found in the list of classes or groups!"
|
57
|
+
end
|
58
|
+
@classes.flatten!
|
59
|
+
elsif test_this.is_a?(Hash)
|
60
|
+
# If it is a hash we need to get creative
|
61
|
+
|
62
|
+
# Get all of the included classes and add them
|
63
|
+
if Onceover::Group.find(test_this['include'])
|
64
|
+
@classes << Onceover::Group.find(test_this['include']).members
|
65
|
+
elsif Onceover::Class.find(test_this['include'])
|
66
|
+
@classes << Onceover::Class.find(test_this['include'])
|
67
|
+
else
|
68
|
+
raise "#{test_this['include']} was not found in the list of classes or groups!"
|
69
|
+
end
|
70
|
+
@classes.flatten!
|
71
|
+
|
72
|
+
# Then remove any excluded ones
|
73
|
+
if Onceover::Group.find(test_this['exclude'])
|
74
|
+
Onceover::Group.find(test_this['exclude']).members.each do |clarse|
|
75
|
+
@classes.delete(clarse)
|
76
|
+
end
|
77
|
+
elsif Onceover::Class.find(test_this['exclude'])
|
78
|
+
@classes.delete(Onceover::Class.find(test_this['exclude']))
|
79
|
+
else
|
80
|
+
raise "#{test_this['exclude']} was not found in the list of classes or groups!"
|
81
|
+
end
|
82
|
+
elsif test_this.is_a?(Onceover::Class)
|
83
|
+
@classes << test_this
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
def eql?(other)
|
88
|
+
(@nodes.sort.eql?(other.nodes.sort)) and (@classes.sort.eql?(other.classes.sort))
|
89
|
+
end
|
90
|
+
|
91
|
+
def to_s
|
92
|
+
class_msg = ""
|
93
|
+
node_msg = ""
|
94
|
+
if classes.count > 1
|
95
|
+
class_msg = "#{classes.count}_classes"
|
96
|
+
else
|
97
|
+
class_msg = classes[0].name
|
98
|
+
end
|
99
|
+
|
100
|
+
if nodes.count > 1
|
101
|
+
node_msg = "#{nodes.count}_nodes"
|
102
|
+
else
|
103
|
+
node_msg = nodes[0].name
|
104
|
+
end
|
105
|
+
|
106
|
+
"#{class_msg}_on_#{node_msg}"
|
107
|
+
end
|
108
|
+
|
109
|
+
def self.deduplicate(tests)
|
110
|
+
require 'deep_merge'
|
111
|
+
# This should take an array of tests and remove any duplicates from them
|
112
|
+
|
113
|
+
# this will be an array of arrays, or maybe hashes
|
114
|
+
combinations = []
|
115
|
+
new_tests = []
|
116
|
+
tests.each do |test|
|
117
|
+
test.nodes.each do |node|
|
118
|
+
test.classes.each do |cls|
|
119
|
+
combo = {node => cls}
|
120
|
+
if combinations.member?(combo)
|
121
|
+
|
122
|
+
# Find the right test object:
|
123
|
+
relevant_test = new_tests[new_tests.index do |a|
|
124
|
+
a.nodes[0] == node and a.classes[0] == cls
|
125
|
+
end]
|
126
|
+
|
127
|
+
# Delete all default values in the current options hash
|
128
|
+
test.test_config.delete_if do |key,value|
|
129
|
+
test.default_test_config[key] == value
|
130
|
+
end
|
131
|
+
|
132
|
+
# Merge the non-default options right on in there
|
133
|
+
relevant_test.test_config.deep_merge!(test.test_config)
|
134
|
+
else
|
135
|
+
combinations << combo
|
136
|
+
new_tests << Onceover::Test.new(node,cls,test.test_config)
|
137
|
+
end
|
138
|
+
end
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
# The array that this returns should be ephemeral, it does not
|
143
|
+
# represent anything defined in a controlrepo and should just
|
144
|
+
# be passed into the thing doing the testing and then killed,
|
145
|
+
# we don't want too many copies of the same shit going around
|
146
|
+
#
|
147
|
+
# Actually based on the way things are written I don't think this
|
148
|
+
# will duplicated node or class objects, just test objects,
|
149
|
+
# everything else is passed by reference
|
150
|
+
new_tests
|
151
|
+
end
|
152
|
+
|
153
|
+
def self.all
|
154
|
+
@@all
|
155
|
+
end
|
156
|
+
end
|
157
|
+
end
|