5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
|
# File 'lib/onceover/octocatalog/diff/cli.rb', line 5
def self.command
@cmd ||= Cri::Command.define do
name 'diff'
usage 'diff'
summary "Diff two versions of the controlrepo's compiled catalogs"
description <<-DESCRIPTION
This uses octocatalog-diff to run diffs on all things in the test matrix
instead of actually testing them. Requires two branches, tags or
revisions to compare between.
DESCRIPTION
option :f, :from, 'branch to compare from', argument: :required
option :t, :to, 'branch to compare to', argument: :required
run do |opts, args, cmd|
require 'pry'
require 'facter'
require 'colored'
repo = Onceover::Controlrepo.new(opts)
test_config = Onceover::TestConfig.new(repo.onceover_yaml, opts)
num_threads = (Facter.value('processors')['count'] / 2)
tests = test_config.run_filters(Onceover::Test.deduplicate(test_config.spec_tests))
@queue = tests.inject(Queue.new, :push)
@results = []
@threads = Array.new(num_threads) do
Thread.new do
r10k_cache_dir = Dir.mktmpdir('r10k_cache')
r10k_config = {
'cachedir' => r10k_cache_dir,
}
logger.debug "Creating r10k cache for thread at #{r10k_cache_dir}"
File.write("#{r10k_cache_dir}/r10k.yaml",r10k_config.to_yaml)
until @queue.empty?
test = @queue.shift
logger.info "Preparing environment for #{test.classes[0].name} on #{test.nodes[0].name}"
logger.debug "Creating temp directory"
tempdir = Dir.mktmpdir(test.to_s)
logger.debug "Temp directory created at #{tempdir}"
logger.debug "Copying controlrepo to #{tempdir}"
FileUtils.copy_entry(repo.root,tempdir)
logger.debug "Converting facts to yaml"
Onceover::Octocatalog::Diff.create_facts_yaml(repo,"#{tempdir}/spec/factsets")
logger.info "Deploying Puppetfile for #{test.classes[0].name} on #{test.nodes[0].name}"
r10k_cmd = "r10k puppetfile install --verbose --color --puppetfile #{repo.puppetfile} --config #{r10k_cache_dir}/r10k.yaml"
Open3.popen3(r10k_cmd) do |stdin, stdout, stderr, wait_thr|
exit_status = wait_thr.value
if exit_status.exitstatus != 0
STDOUT.puts stdout.read
STDERR.puts stderr.read
abort "R10k encountered an error, see the logs for details"
end
end
logger.debug "Creating before script that overwrites site.pp"
class_name = test.classes[0].name
template_dir = File.expand_path('../../../../templates',File.dirname(__FILE__))
template = File.read(File.expand_path("./change_manifest.rb.erb",template_dir))
File.write("#{tempdir}/bootstrap_script.rb",ERB.new(template, nil, '-').result(binding))
FileUtils.chmod("u=rwx","#{tempdir}/bootstrap_script.rb")
logger.debug "Getting Puppet binary"
binary = `which puppet`.chomp
logger.debug "Running Octocatalog diff"
logger.debug "Command: octocatalog-diff --fact-file #{tempdir}/spec/factsets/#{test.nodes[0].name}.yaml -f #{opts[:from]} -t #{opts[:to]} --basedir #{tempdir} --puppet-binary #{binary} --bootstrap-script #{tempdir}/bootstrap_script.rb"
logger.info "Compiling catalogs for #{test.classes[0].name} on #{test.nodes[0].name}"
cmd = "octocatalog-diff --fact-file #{tempdir}/spec/factsets/#{test.nodes[0].name}.yaml -f #{opts[:from]} -t #{opts[:to]} --basedir #{tempdir} --puppet-binary #{binary} --bootstrap-script '#{tempdir}/bootstrap_script.rb'"
Open3.popen3(cmd) do |stdin, stdout, stderr, wait_thr|
exit_status = wait_thr.value
@results << {
stdout: stdout.read,
stderr: stderr.read,
exit_status: exit_status.exitstatus,
test: test
}
end
logger.info "Storing results for #{test.classes[0].name} on #{test.nodes[0].name}"
FileUtils.rm_r(tempdir)
end
FileUtils.rm_r(r10k_cache_dir)
end
end
@threads.each(&:join)
@results.each do |result|
puts "#{"Test:".bold} #{result[:test].classes[0].name} on #{result[:test].nodes[0].name}"
puts "#{"Exit:".bold} #{result[:exit_status]}"
puts "#{"Status:".bold} #{"changes".yellow}" if result[:exit_status] == 2
puts "#{"Status:".bold} #{"no differences".green}" if result[:exit_status] == 0
puts "#{"Status:".bold} #{"failed".red}" if result[:exit_status] == 1
puts "#{"Results:".bold}\n#{result[:stdout]}\n" if result[:exit_status] == 2
puts "#{"Errors:".bold}\n#{result[:stderr]}\n" if result[:exit_status] == 1
puts ""
end
end
end
end
|