Class: RSpec::Puppet::Coverage
- Inherits:
-
Object
- Object
- RSpec::Puppet::Coverage
- Extended by:
- Forwardable
- Defined in:
- lib/rspec-puppet/coverage.rb
Defined Under Namespace
Classes: ResourceWrapper
Class Attribute Summary collapse
Instance Attribute Summary collapse
-
#filters ⇒ Object
Returns the value of attribute filters.
Instance Method Summary collapse
- #add(resource) ⇒ Object
- #add_filter(type, title) ⇒ Object
-
#add_from_catalog(catalog, test_module) ⇒ Object
add all resources from catalog declared in module test_module.
- #capitalize_name(name) ⇒ Object
- #cover!(resource) ⇒ Object
- #coverage_test(coverage_desired, report) ⇒ Object
- #filtered?(resource) ⇒ Boolean
-
#initialize ⇒ Coverage
constructor
A new instance of Coverage.
- #load_filters(path) ⇒ Object
- #load_results(path) ⇒ Object
- #merge_filters ⇒ Object
- #merge_results ⇒ Object
- #parallel_tests? ⇒ Boolean
- #report!(coverage_desired = nil) ⇒ Object
- #results ⇒ Object
- #run_report(coverage_desired = nil) ⇒ Object
- #save_results ⇒ Object
Constructor Details
#initialize ⇒ Coverage
Returns a new instance of Coverage.
35 36 37 38 |
# File 'lib/rspec-puppet/coverage.rb', line 35 def initialize @collection = {} @filters = ['Stage[main]', 'Class[Settings]', 'Class[main]', 'Node[default]'] end |
Class Attribute Details
.instance ⇒ Object
30 31 32 |
# File 'lib/rspec-puppet/coverage.rb', line 30 def instance @instance ||= new end |
Instance Attribute Details
#filters ⇒ Object
Returns the value of attribute filters.
20 21 22 |
# File 'lib/rspec-puppet/coverage.rb', line 20 def filters @filters end |
Instance Method Details
#add(resource) ⇒ Object
82 83 84 85 86 |
# File 'lib/rspec-puppet/coverage.rb', line 82 def add(resource) if !exists?(resource) && !filtered?(resource) @collection[resource.to_s] = ResourceWrapper.new(resource) end end |
#add_filter(type, title) ⇒ Object
88 89 90 91 92 93 94 95 96 97 98 99 |
# File 'lib/rspec-puppet/coverage.rb', line 88 def add_filter(type, title) def capitalize_name(name) name.split('::').map { |subtitle| subtitle.capitalize }.join('::') end type = capitalize_name(type) if type == 'Class' title = capitalize_name(title) end @filters << "#{type}[#{title}]" end |
#add_from_catalog(catalog, test_module) ⇒ Object
add all resources from catalog declared in module test_module
102 103 104 105 106 107 |
# File 'lib/rspec-puppet/coverage.rb', line 102 def add_from_catalog(catalog, test_module) coverable_resources = catalog.to_a.reject { |resource| !test_module.nil? && filter_resource?(resource, test_module) } coverable_resources.each do |resource| add(resource) end end |
#capitalize_name(name) ⇒ Object
89 90 91 |
# File 'lib/rspec-puppet/coverage.rb', line 89 def capitalize_name(name) name.split('::').map { |subtitle| subtitle.capitalize }.join('::') end |
#cover!(resource) ⇒ Object
113 114 115 116 117 |
# File 'lib/rspec-puppet/coverage.rb', line 113 def cover!(resource) if !filtered?(resource) && (wrapper = find(resource)) wrapper.touch! end end |
#coverage_test(coverage_desired, report) ⇒ Object
151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 |
# File 'lib/rspec-puppet/coverage.rb', line 151 def coverage_test(coverage_desired, report) coverage_actual = report[:coverage] coverage_desired ||= 0 if coverage_desired.is_a?(Numeric) && coverage_desired.to_f <= 100.00 && coverage_desired.to_f >= 0.0 coverage_test = RSpec.describe("Code coverage") coverage_results = coverage_test.example("must cover at least #{coverage_desired}% of resources") do expect( coverage_actual.to_f ).to be >= coverage_desired.to_f end coverage_test.run(RSpec.configuration.reporter) if coverage_results.execution_result[:status] == :failed RSpec.world.non_example_failure = true RSpec.world.wants_to_quit = true end # This is not available on RSpec 2.x if coverage_results.execution_result.respond_to?(:pending_message) coverage_results.execution_result. = report[:text] end else puts "The desired coverage must be 0 <= x <= 100, not '#{coverage_desired.inspect}'" end end |
#filtered?(resource) ⇒ Boolean
109 110 111 |
# File 'lib/rspec-puppet/coverage.rb', line 109 def filtered?(resource) filters.include?(resource.to_s) end |
#load_filters(path) ⇒ Object
74 75 76 77 78 79 80 |
# File 'lib/rspec-puppet/coverage.rb', line 74 def load_filters(path) saved_filters = JSON.parse(File.read(path)) saved_filters.each do |resource| @filters << resource @collection.delete(resource) if @collection.key?(resource) end end |
#load_results(path) ⇒ Object
66 67 68 69 70 71 72 |
# File 'lib/rspec-puppet/coverage.rb', line 66 def load_results(path) saved_results = JSON.parse(File.read(path)) saved_results.each do |resource, data| add(resource) cover!(resource) if data['touched'] end end |
#merge_filters ⇒ Object
58 59 60 61 62 63 64 |
# File 'lib/rspec-puppet/coverage.rb', line 58 def merge_filters pattern = File.join(Dir.tmpdir, "rspec-puppet-filter-#{Digest::MD5.hexdigest(Dir.pwd)}-*") Dir[pattern].each do |result_file| load_filters(result_file) FileUtils.rm(result_file) end end |
#merge_results ⇒ Object
50 51 52 53 54 55 56 |
# File 'lib/rspec-puppet/coverage.rb', line 50 def merge_results pattern = File.join(Dir.tmpdir, "rspec-puppet-coverage-#{Digest::MD5.hexdigest(Dir.pwd)}-*") Dir[pattern].each do |result_file| load_results(result_file) FileUtils.rm(result_file) end end |
#parallel_tests? ⇒ Boolean
134 135 136 |
# File 'lib/rspec-puppet/coverage.rb', line 134 def parallel_tests? !!ENV['TEST_ENV_NUMBER'] end |
#report!(coverage_desired = nil) ⇒ Object
119 120 121 122 123 124 125 126 127 128 129 130 131 132 |
# File 'lib/rspec-puppet/coverage.rb', line 119 def report!(coverage_desired = nil) if parallel_tests? require 'parallel_tests' if ParallelTests.first_process? ParallelTests.wait_for_other_processes_to_finish run_report(coverage_desired) else save_results end else run_report(coverage_desired) end end |
#results ⇒ Object
176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 |
# File 'lib/rspec-puppet/coverage.rb', line 176 def results report = {} @collection.delete_if { |name, _| filtered?(name) } report[:total] = @collection.size report[:touched] = @collection.count { |_, resource| resource.touched? } report[:untouched] = report[:total] - report[:touched] report[:coverage] = "%5.2f" % ((report[:touched].to_f / report[:total].to_f) * 100) report[:resources] = Hash[*@collection.map do |name, wrapper| [name, wrapper.to_hash] end.flatten] text = [ "Total resources: #{report[:total]}", "Touched resources: #{report[:touched]}", "Resource coverage: #{report[:coverage]}%", ] if report[:untouched] > 0 text += ['', 'Untouched resources:'] untouched_resources = report[:resources].reject { |_, r| r[:touched] } text += untouched_resources.map { |name, _| " #{name}" }.sort end report[:text] = text.join("\n") report end |
#run_report(coverage_desired = nil) ⇒ Object
138 139 140 141 142 143 144 145 146 147 148 149 |
# File 'lib/rspec-puppet/coverage.rb', line 138 def run_report(coverage_desired = nil) if ENV['TEST_ENV_NUMBER'] merge_filters merge_results end report = results coverage_test(coverage_desired, report) puts report[:text] end |
#save_results ⇒ Object
40 41 42 43 44 45 46 47 48 |
# File 'lib/rspec-puppet/coverage.rb', line 40 def save_results slug = "#{Digest::MD5.hexdigest(Dir.pwd)}-#{Process.pid}" File.open(File.join(Dir.tmpdir, "rspec-puppet-filter-#{slug}"), 'w+') do |f| f.puts @filters.to_json end File.open(File.join(Dir.tmpdir, "rspec-puppet-coverage-#{slug}"), 'w+') do |f| f.puts @collection.to_json end end |