Html reporter changes for enhanced outcomes and refactoring changes

Signed-off-by: Nikita Mathur <nikita.mathur@chef.io>
This commit is contained in:
Nikita Mathur 2022-06-28 16:33:04 +05:30
parent 1fc0076f1a
commit 82ab13dbe4
12 changed files with 132 additions and 52 deletions

View file

@ -0,0 +1,18 @@
module Inspec
module EnhancedOutcomes
def self.determine_status(results, impact)
if results.any? { |r| !r[:exception].nil? && !r[:backtrace].nil? }
"error"
elsif !impact.nil? && impact.to_f == 0.0
"not_applicable"
elsif results.all? { |r| r[:status] == "skipped" }
"not_reviewed"
elsif results.any? { |r| r[:status] == "failed" }
"failed"
else
"passed"
end
end
end
end

View file

@ -1,6 +1,7 @@
require "rspec/core"
require "rspec/core/formatters/base_formatter"
require "set" unless defined?(Set)
require "inspec/enhanced_outcomes"
module Inspec::Formatters
class Base < RSpec::Core::Formatters::BaseFormatter
@ -119,27 +120,13 @@ module Inspec::Formatters
end
def determine_control_enhanced_outcome(control)
if control_has_error(control)
{ name: "Error", abbrev: "ERR" }
elsif control[:impact].to_f == 0.0
{ name: "Not Applicable", abbrev: "N/A" }
elsif control_has_all_tests_skipped(control)
{ name: "Not Reviewed", abbrev: "N/R" }
elsif control[:results] && control[:results].any? { |r| r[:status] == "failed" }
{ name: "Failed", abbrev: "fail" }
if control[:results]
Inspec::EnhancedOutcomes.determine_status(control[:results], control[:impact])
else
{ name: "Passed", abbrev: "pass" }
"passed"
end
end
def control_has_all_tests_skipped(control)
control[:results] && control[:results].all? { |r| r[:status] == "skipped" }
end
def control_has_error(control)
control[:results] && (control[:results].any? { |r| !r[:exception].nil? && !r[:backtrace].nil? })
end
def all_unique_controls
unique_controls = Set.new
run_data[:profiles].each do |profile|
@ -150,25 +137,57 @@ module Inspec::Formatters
end
def statistics
error = 0
not_applicable = 0
not_reviewed = 0
failed = 0
skipped = 0
passed = 0
skipped = 0
enhanced_outcomes_summary = {}
if enhanced_outcomes
all_unique_controls.each do |control|
all_unique_controls.each do |control|
next unless control[:results]
if control[:results].any? { |r| r[:status] == "failed" }
failed += 1
elsif control[:results].any? { |r| r[:status] == "skipped" }
skipped += 1
else
passed += 1
if control[:status] == "error"
error += 1
elsif control[:status] == "not_applicable"
not_applicable += 1
elsif control[:status] == "not_reviewed"
not_reviewed += 1
elsif control[:results].any? { |r| r[:status] == "skipped" }
skipped += 1
elsif control[:status] == "failed"
failed += 1
elsif control[:status] == "passed"
passed += 1
end
end
total = error + not_applicable + not_reviewed + failed + passed
enhanced_outcomes_summary = {
not_applicable: {
total: not_applicable,
},
not_reviewed: {
total: not_reviewed,
},
error: {
total: error,
},
}
else
all_unique_controls.each do |control|
next unless control[:results]
if control[:results].any? { |r| r[:status] == "failed" }
failed += 1
elsif control[:results].any? { |r| r[:status] == "skipped" }
skipped += 1
else
passed += 1
end
end
total = failed + passed + skipped
end
total = failed + passed + skipped
{
final_summary = {
total: total,
passed: {
total: passed,
@ -180,6 +199,8 @@ module Inspec::Formatters
total: failed,
},
}
final_summary.merge!(enhanced_outcomes_summary)
end
def exception_message(exception)

View file

@ -7,6 +7,7 @@ module Inspec::Plugin::V2::PluginType
include Inspec::Utils::RunDataFilters
attr_reader :run_data
attr_accessor :enhanced_outcomes
def initialize(config)
@config = config

View file

@ -57,15 +57,15 @@ module Inspec::Plugin::V2::PluginType
def add_enhanced_outcomes(control_id)
if control_has_error(@notifications[control_id])
{ name: "Error", abbrev: "ERR" }
"error"
elsif control_has_impact_zero(@notifications[control_id])
{ name: "Not Applicable", abbrev: "N/A" }
"not_applicable"
elsif control_has_all_tests_skipped(@notifications[control_id])
{ name: "Not Reviewed", abbrev: "N/R" }
"not_reviewed"
elsif control_has_any_tests_failed(@notifications[control_id])
{ name: "Failed", abbrev: "fail" }
"failed"
else
{ name: "Passed", abbrev: "pass" }
"passed"
end
end

View file

@ -319,13 +319,13 @@ module Inspec::Reporters
all_unique_controls.each do |control|
next if control[:status].empty?
if control[:status][:name] == "Failed"
if control[:status] == "failed"
failed += 1
elsif control[:status][:name] == "Error"
elsif control[:status] == "error"
error += 1
elsif control[:status][:name] == "Not Reviewed"
elsif control[:status] == "not_reviewed"
not_reviewed += 1
elsif control[:status][:name] == "Not Applicable"
elsif control[:status] == "not_applicable"
not_applicable += 1
else
passed += 1
@ -483,7 +483,7 @@ module Inspec::Reporters
if impact.nil?
"unknown"
else
status[:name].downcase.gsub(" ", "_")
status
end
end

View file

@ -1,3 +1,5 @@
require "inspec/enhanced_outcomes"
module Inspec
class RunData
Control = Struct.new(
@ -31,6 +33,10 @@ module Inspec
].each do |field|
self[field] = raw_ctl_data[field]
end
def status
Inspec::EnhancedOutcomes.determine_status(results, impact)
end
end
end

View file

@ -16,14 +16,20 @@ module Inspec
:total,
:passed,
:skipped,
:failed
:failed,
:not_reviewed,
:not_applicable,
:error
) do
include HashLikeStruct
def initialize(raw_stat_ctl_data)
self.total = raw_stat_ctl_data[:total]
self.passed = Inspec::RunData::Statistics::Controls::Total.new(raw_stat_ctl_data[:passed][:total])
self.skipped = Inspec::RunData::Statistics::Controls::Total.new(raw_stat_ctl_data[:skipped][:total])
self.failed = Inspec::RunData::Statistics::Controls::Total.new(raw_stat_ctl_data[:failed][:total])
self.skipped = Inspec::RunData::Statistics::Controls::Total.new(raw_stat_ctl_data[:skipped][:total]) if raw_stat_ctl_data[:skipped]
self.not_reviewed = Inspec::RunData::Statistics::Controls::Total.new(raw_stat_ctl_data[:not_reviewed][:total]) if raw_stat_ctl_data[:not_reviewed]
self.not_applicable = Inspec::RunData::Statistics::Controls::Total.new(raw_stat_ctl_data[:not_applicable][:total]) if raw_stat_ctl_data[:not_applicable]
self.error = Inspec::RunData::Statistics::Controls::Total.new(raw_stat_ctl_data[:error][:total]) if raw_stat_ctl_data[:error]
end
end
class Controls

View file

@ -36,8 +36,14 @@
<caption>Control Statistics</caption>
<tr><th colspan="2"><h4 id="statistics-label">Control Statistics</h4></th></tr>
<tr class= "passed"><th>Passed:</th><td><%= run_data.statistics.controls.passed.total %></td></tr>
<tr class= "skipped"><th>Skipped:</th><td><%= run_data.statistics.controls.skipped.total %></td></tr>
<tr class= "failed"><th>Failed:</th><td><%= run_data.statistics.controls.failed.total %></td></tr>
<% if enhanced_outcomes %>
<tr class= "not_reviewed"><th>Not Reviewed:</th><td><%= run_data.statistics.controls.not_reviewed.total %></td></tr>
<tr class= "not_applicable"><th>Not Applicable:</th><td><%= run_data.statistics.controls.not_applicable.total %></td></tr>
<tr class= "error"><th>Error:</th><td><%= run_data.statistics.controls.error.total %></td></tr>
<% else %>
<tr class= "skipped"><th>Skipped:</th><td><%= run_data.statistics.controls.skipped.total %></td></tr>
<% end %>
<tr class= "duration"><th>Duration:</th><td><%= run_data.statistics.duration %> seconds</td></tr>
<tr class= "date"><th>Time Finished:</th><td><%= Time.now %></td></tr>
</table>

View file

@ -1,11 +1,15 @@
<% slugged_id = control.id.tr(" ", "_") %>
<%
# Determine status of control
status = "passed"
if control.results.any? { |r| r.status == "failed" }
status = "failed"
elsif control.results.any? { |r| r.status == "skipped" }
status = "skipped"
if enhanced_outcomes
status = control.status
else
# Determine status of control
status = "passed"
if control.results.any? { |r| r.status == "failed" }
status = "failed"
elsif control.results.any? { |r| r.status == "skipped" }
status = "skipped"
end
end
%>

View file

@ -60,6 +60,18 @@ pre code {
.result-metadata .status-skipped div {
background-color: grey;
}
.control-metadata .status-error div,
.result-metadata .status-error div {
background-color: rgb(63, 15, 183);
}
.control-metadata .status-not_applicable div,
.result-metadata .status-not_applicable div {
background-color: rgb(135, 206, 250);
}
.control-metadata .status-not_reviewed div,
.result-metadata .status-not_reviewed div {
background-color: rgb(255, 194, 0);
}
.result-metadata,
.control-metadata {
margin: 0 0 0 5%;

View file

@ -1,8 +1,14 @@
<div class="selector-panel">
<p id="selector-instructions">Display controls that are:</p>
<input class="selector-checkbox" id="passed-checkbox" type="checkbox" checked="checked"/><label for="passed-checkbox">Passed</label>
<input class="selector-checkbox" id="skipped-checkbox" type="checkbox" checked="checked"/><label for="skipped-checkbox">Skipped</label>
<input class="selector-checkbox" id="failed-checkbox" type="checkbox" checked="checked"/><label for="failed-checkbox">Failed</label>
<% if enhanced_outcomes %>
<input class="selector-checkbox" id="not_reviewed-checkbox" type="checkbox" checked="checked"/><label for="not_reviewed-checkbox">Not Reviewed</label>
<input class="selector-checkbox" id="not_applicable-checkbox" type="checkbox" checked="checked"/><label for="not_applicable-checkbox">Not Applicable</label>
<input class="selector-checkbox" id="error-checkbox" type="checkbox" checked="checked"/><label for="error-checkbox">Error</label>
<% else %>
<input class="selector-checkbox" id="skipped-checkbox" type="checkbox" checked="checked"/><label for="skipped-checkbox">Skipped</label>
<% end %>
<p id="selector-instructions">Display profiles that are:</p>
<input class="profile-selector-checkbox" id="child-profile-checkbox" type="checkbox" /><label for="child-profile-checkbox">Dependent Profiles</label>
</div>

View file

@ -103,7 +103,7 @@ module InspecPlugins::StreamingReporterProgressBar
def format_it(control_id, title, full_description, control_outcome)
if control_outcome
control_status = control_outcome[:name].downcase.gsub(" ", "_")
control_status = control_outcome
else
control_status = if @status_mapping[control_id].include? "failed"
"failed"