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
|
# File 'lib/chef/knife/knife-testcoverage.rb', line 19
def run
if @name_args.length == 0
stdout.puts "You must provide the name of the cookbook to review."
stdout.puts opt_parser
exit 1
end
self.config = Chef::Config.merge!(config)
unless config[:cookbook_path]
stdout.puts("No cookbook path set in Chef config, cannot install cookbook.")
exit 1
end
cookbook = @name_args[0]
cbpath=''
config[:cookbook_path].each do |cookbookdir|
cbpathtest = cookbookdir + cookbook
if File.directory?(cbpathtest)
cbpath = cbpathtest
end
end
if not File.directory?(cbpath)
stdout.puts "#{cookbook} does not exist in any known location"
exit 1
end
recipes = cbpath + "/recipes"
tests = cbpath + "/files/default/tests/minitest/"
if not File.directory?(recipes)
stdout.puts "#{cookbook} exists but contains no recipes"
exit 1
end
recipecount = 0
testcount = 0
missingtests = []
Dir.foreach(recipes) do |recipe|
if recipe[-3,3] == ".rb"
recipecount += 1
basename = File.basename(recipe, ".rb")
testfile = basename + "_test.rb"
if not File.exists?("#{tests}#{testfile}")
missingtests.push(testfile)
else
testcount += 1
end
end
end
coverage = (testcount.to_f / recipecount.to_f * 100).round
@fail = config[:fail_threshold]
if config[:show_missing]
print "Missing tests:\n"
missingtests.each do |missingtest|
print "#{missingtest}\n"
end
end
print "Cookbook #{cookbook} contains #{recipecount} recipes and #{testcount} tests.\n"
if coverage >= config[:fail_threshold].to_i
print "Validation passed. Test coverage #{coverage}% exceeds the required threshold (#{config[:fail_threshold]}%)\n"
exit 0
else
print "Validation failed. Test coverage #{coverage}% is less than the required threshold (#{config[:fail_threshold]}%)\n"
exit 1
end
end
|