onceover 3.0.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 +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
|