Merge pull request #5084 from inspec/cw/reporter-plugin-junit

Convert JUnit Reporter to a Plugin
This commit is contained in:
Nick Schwaderer 2020-08-07 18:06:43 +01:00 committed by GitHub
commit cc521b5400
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 62 additions and 37 deletions

View file

@ -344,7 +344,6 @@ module Inspec
cli
json
json-automate
junit
yaml
}

View file

@ -2,7 +2,6 @@ require "inspec/reporters/base"
require "inspec/reporters/cli"
require "inspec/reporters/json"
require "inspec/reporters/json_automate"
require "inspec/reporters/junit"
require "inspec/reporters/automate"
require "inspec/reporters/yaml"
@ -20,8 +19,6 @@ module Inspec::Reporters
# right to introduce breaking changes to this reporter at any time.
when "json-automate"
reporter = Inspec::Reporters::JsonAutomate.new(config)
when "junit"
reporter = Inspec::Reporters::Junit.new(config)
when "automate"
reporter = Inspec::Reporters::Automate.new(config)
when "yaml"

View file

@ -0,0 +1,15 @@
# junit reporter
This is the implementation of the junit XML reporter.
## To Install This Plugin
This plugin is included with inspec. There is no need to install it separately.
## What This Plugin Does
This reporter generates an XML report in Apache Ant JUnit format.
## Implementation Note
This reporter uses the REXML XML generator, but may use more advanced XML systems for testing. This is to keep packaging requirements for CHef InSpec lightweight and free of compiled dependencies.

View file

@ -0,0 +1,12 @@
require_relative "inspec-reporter-junit/version"
module InspecPlugins
module JUnitReporter
class Plugin < ::Inspec.plugin(2)
plugin_name :'inspec-reporter-junit'
reporter :junit do
require_relative "inspec-reporter-junit/reporter"
InspecPlugins::JUnitReporter::Reporter
end
end
end
end

View file

@ -1,5 +1,9 @@
module Inspec::Reporters
class Junit < Base
module InspecPlugins::JUnitReporter
class Reporter < Inspec.plugin(2, :reporter)
def self.run_data_schema_constraints
"~> 0.0"
end
def render
require "rexml/document"
xml_output = REXML::Document.new
@ -8,7 +12,7 @@ module Inspec::Reporters
testsuites = REXML::Element.new("testsuites")
xml_output.add(testsuites)
run_data[:profiles].each do |profile|
run_data.profiles.each do |profile|
testsuites.add(build_profile_xml(profile))
end
@ -18,20 +22,16 @@ module Inspec::Reporters
output(formatter.write(xml_output.root, ""))
end
private
def build_profile_xml(profile)
profile_xml = REXML::Element.new("testsuite")
profile_xml.add_attribute("name", profile[:name])
profile_xml.add_attribute("name", profile.name)
profile_xml.add_attribute("tests", count_profile_tests(profile))
profile_xml.add_attribute("failed", count_profile_failed_tests(profile))
profile_xml.add_attribute("failures", count_profile_failed_tests(profile))
profile[:controls].each do |control|
next if control[:results].nil?
control[:results].each do |result|
profile_xml.add(build_result_xml(profile[:name], control, result))
profile.controls.each do |control|
control.results.each do |result|
profile_xml.add(build_result_xml(profile.name, control, result))
end
end
@ -40,16 +40,16 @@ module Inspec::Reporters
def build_result_xml(profile_name, control, result)
result_xml = REXML::Element.new("testcase")
result_xml.add_attribute("name", result[:code_desc])
result_xml.add_attribute("classname", control[:title].nil? ? "#{profile_name}.Anonymous" : "#{profile_name}.#{control[:id]}")
result_xml.add_attribute("target", run_data[:platform][:target].nil? ? "" : run_data[:platform][:target].to_s)
result_xml.add_attribute("time", result[:run_time])
result_xml.add_attribute("name", result.code_desc)
result_xml.add_attribute("classname", control.title.nil? ? "#{profile_name}.Anonymous" : "#{profile_name}.#{control.id}")
result_xml.add_attribute("target", run_data.platform.target.nil? ? "" : run_data.platform.target.to_s)
result_xml.add_attribute("time", result.run_time)
if result[:status] == "failed"
if result.status == "failed"
failure_element = REXML::Element.new("failure")
failure_element.add_attribute("message", result[:message])
result_xml.add(failure_element)
elsif result[:status] == "skipped"
elsif result.status == "skipped"
result_xml.add_element("skipped")
end
@ -57,19 +57,15 @@ module Inspec::Reporters
end
def count_profile_tests(profile)
profile[:controls].reduce(0) do |acc, elem|
acc + (elem[:results].nil? ? 0 : elem[:results].count)
profile.controls.reduce(0) do |acc, elem|
acc + elem.results.count
end
end
def count_profile_failed_tests(profile)
profile[:controls].reduce(0) do |acc, elem|
if elem[:results].nil?
acc
else
acc + elem[:results].reduce(0) do |fail_test_total, test_case|
test_case[:status] == "failed" ? fail_test_total + 1 : fail_test_total
end
profile.controls.reduce(0) do |acc, elem|
acc + elem.results.reduce(0) do |fail_test_total, test_case|
test_case.status == "failed" ? fail_test_total + 1 : fail_test_total
end
end
end

View file

@ -0,0 +1,5 @@
module InspecPlugins
module JUnitReporter
VERSION = "0.1.0".freeze
end
end

View file

@ -1,18 +1,19 @@
require "helper"
require "inspec/reporters"
require_relative "../../../lib/plugins/inspec-reporter-junit/lib/inspec-reporter-junit"
require_relative "../../../lib/plugins/inspec-reporter-junit/lib/inspec-reporter-junit/reporter"
describe Inspec::Reporters::Junit do
let(:report) do
describe InspecPlugins::JUnitReporter::Reporter do
let(:reporter) do
data = JSON.parse(File.read("test/fixtures/reporters/run_data.json"),
symbolize_names: true)
Inspec::Reporters::Junit.new({ run_data: data })
InspecPlugins::JUnitReporter::Reporter.new({ run_data: data })
end
describe "#render" do
it "confirm render output" do
cli_output = File.read("test/fixtures/reporters/junit_output")
report.render
_(report.rendered_output).must_equal cli_output
junit_output = File.read("test/fixtures/reporters/junit_output")
reporter.render
_(reporter.rendered_output).must_equal junit_output
end
end
end