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 175 176 177 178 179 180 |
# 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) status = if coverage_results.execution_result.respond_to?(:status) coverage_results.execution_result.status else coverage_results.execution_result[:status] end if 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
182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 |
# File 'lib/rspec-puppet/coverage.rb', line 182 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 |