From 98ae89e6cc747c2b749eb0e761cdc20e1aeb212b Mon Sep 17 00:00:00 2001 From: Clinton Wolfe Date: Thu, 4 Jun 2020 19:46:10 -0400 Subject: [PATCH 1/2] Convert JUnit reporter to plugin, RunData is still Hash-based Signed-off-by: Clinton Wolfe --- lib/inspec/config.rb | 1 - lib/inspec/reporters.rb | 3 --- lib/plugins/inspec-reporter-junit/README.md | 15 +++++++++++++ .../lib/inspec-reporter-junit.rb | 12 ++++++++++ .../lib/inspec-reporter-junit/reporter.rb} | 22 ++++++++----------- .../lib/inspec-reporter-junit/version.rb | 5 +++++ test/unit/reporters/junit_test.rb | 15 +++++++------ 7 files changed, 49 insertions(+), 24 deletions(-) create mode 100644 lib/plugins/inspec-reporter-junit/README.md create mode 100644 lib/plugins/inspec-reporter-junit/lib/inspec-reporter-junit.rb rename lib/{inspec/reporters/junit.rb => plugins/inspec-reporter-junit/lib/inspec-reporter-junit/reporter.rb} (84%) create mode 100644 lib/plugins/inspec-reporter-junit/lib/inspec-reporter-junit/version.rb diff --git a/lib/inspec/config.rb b/lib/inspec/config.rb index 50a1f7489..cddd4499c 100644 --- a/lib/inspec/config.rb +++ b/lib/inspec/config.rb @@ -344,7 +344,6 @@ module Inspec cli json json-automate - junit yaml } diff --git a/lib/inspec/reporters.rb b/lib/inspec/reporters.rb index 9d8398a01..daf8ad436 100644 --- a/lib/inspec/reporters.rb +++ b/lib/inspec/reporters.rb @@ -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" diff --git a/lib/plugins/inspec-reporter-junit/README.md b/lib/plugins/inspec-reporter-junit/README.md new file mode 100644 index 000000000..4a7c13349 --- /dev/null +++ b/lib/plugins/inspec-reporter-junit/README.md @@ -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. diff --git a/lib/plugins/inspec-reporter-junit/lib/inspec-reporter-junit.rb b/lib/plugins/inspec-reporter-junit/lib/inspec-reporter-junit.rb new file mode 100644 index 000000000..2a14b5c12 --- /dev/null +++ b/lib/plugins/inspec-reporter-junit/lib/inspec-reporter-junit.rb @@ -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 diff --git a/lib/inspec/reporters/junit.rb b/lib/plugins/inspec-reporter-junit/lib/inspec-reporter-junit/reporter.rb similarity index 84% rename from lib/inspec/reporters/junit.rb rename to lib/plugins/inspec-reporter-junit/lib/inspec-reporter-junit/reporter.rb index a175fc868..4eb08ba7b 100644 --- a/lib/inspec/reporters/junit.rb +++ b/lib/plugins/inspec-reporter-junit/lib/inspec-reporter-junit/reporter.rb @@ -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 @@ -18,8 +22,6 @@ 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]) @@ -28,8 +30,6 @@ module Inspec::Reporters 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)) end @@ -58,18 +58,14 @@ module Inspec::Reporters def count_profile_tests(profile) profile[:controls].reduce(0) do |acc, elem| - acc + (elem[:results].nil? ? 0 : elem[:results].count) + 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 + 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 diff --git a/lib/plugins/inspec-reporter-junit/lib/inspec-reporter-junit/version.rb b/lib/plugins/inspec-reporter-junit/lib/inspec-reporter-junit/version.rb new file mode 100644 index 000000000..4faf630fb --- /dev/null +++ b/lib/plugins/inspec-reporter-junit/lib/inspec-reporter-junit/version.rb @@ -0,0 +1,5 @@ +module InspecPlugins + module JUnitReporter + VERSION = "0.1.0".freeze + end +end diff --git a/test/unit/reporters/junit_test.rb b/test/unit/reporters/junit_test.rb index 2534c0e47..e4cb20a6a 100644 --- a/test/unit/reporters/junit_test.rb +++ b/test/unit/reporters/junit_test.rb @@ -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 From 3651f85a7c239bc553e3947651098d865240846e Mon Sep 17 00:00:00 2001 From: Clinton Wolfe Date: Thu, 4 Jun 2020 19:51:48 -0400 Subject: [PATCH 2/2] Use methods to access RunData Signed-off-by: Clinton Wolfe --- .../lib/inspec-reporter-junit/reporter.rb | 32 +++++++++---------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/lib/plugins/inspec-reporter-junit/lib/inspec-reporter-junit/reporter.rb b/lib/plugins/inspec-reporter-junit/lib/inspec-reporter-junit/reporter.rb index 4eb08ba7b..f88d19913 100644 --- a/lib/plugins/inspec-reporter-junit/lib/inspec-reporter-junit/reporter.rb +++ b/lib/plugins/inspec-reporter-junit/lib/inspec-reporter-junit/reporter.rb @@ -12,7 +12,7 @@ module InspecPlugins::JUnitReporter 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 @@ -24,14 +24,14 @@ module InspecPlugins::JUnitReporter 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| - 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 InspecPlugins::JUnitReporter 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,15 +57,15 @@ module InspecPlugins::JUnitReporter end def count_profile_tests(profile) - profile[:controls].reduce(0) do |acc, elem| - acc + 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| - acc + elem[:results].reduce(0) do |fail_test_total, test_case| - test_case[:status] == "failed" ? fail_test_total + 1 : fail_test_total + 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