Merge pull request #2601 from chef/jq/add_generic_report_output

Fix runner report and json newline
This commit is contained in:
Jared Quick 2018-02-09 13:49:30 -05:00 committed by GitHub
commit 9420204d60
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
12 changed files with 126 additions and 52 deletions

View file

@ -210,10 +210,12 @@ module Inspec
opts = BaseCLI.default_options[type] unless type.nil? || BaseCLI.default_options[type].nil?
# merge in any options from json-config
opts.merge!(options_json)
json_config = options_json
opts.merge!(json_config)
# remove the default reporter if we are setting a legacy format on the cli
opts.delete('reporter') if options['format']
# or via json-config
opts.delete('reporter') if options['format'] || json_config['format']
# merge in any options defined via thor
opts.merge!(options)
@ -299,7 +301,7 @@ module Inspec
Inspec::Log.init(loc)
Inspec::Log.level = get_log_level(o.log_level)
o[:logger] = Logger.new(STDOUT)
o[:logger] = Logger.new(loc)
# output json if we have activated the json formatter
if o['log-format'] == 'json'
o[:logger].formatter = Logger::JSONFormatter.new

View file

@ -6,7 +6,7 @@ require 'inspec/reporters/junit'
module Inspec::Reporters
def self.render(reporter, run_data)
name, config = reporter
name, config = reporter.dup
config[:run_data] = run_data
case name
when 'cli'
@ -27,7 +27,24 @@ module Inspec::Reporters
if config['file']
File.write(config['file'], output)
elsif config['stdout'] == true
puts output
print output
STDOUT.flush
end
end
def self.report(reporter, run_data)
name, config = reporter.dup
config[:run_data] = run_data
case name
when 'json'
reporter = Inspec::Reporters::Json.new(config)
when 'json-min'
reporter = Inspec::Reporters::JsonMin.new(config)
else
# use base run_data hash for any other report
return run_data
end
reporter.report
end
end

View file

@ -7,8 +7,9 @@ module Inspec::Reporters
@output = ''
end
def output(str)
@output << "#{str}\n"
def output(str, newline = true)
@output << str
@output << "\n" if newline
end
def rendered_output

View file

@ -5,7 +5,11 @@ require 'json'
module Inspec::Reporters
class Json < Base
def render
report = {
output(report.to_json, false)
end
def report
{
platform: platform,
profiles: profiles,
statistics: { duration: run_data[:statistics][:duration] },
@ -13,8 +17,6 @@ module Inspec::Reporters
controls: controls,
other_checks: run_data[:other_checks],
}
output(report.to_json)
end
private

View file

@ -4,7 +4,11 @@ require 'json'
module Inspec::Reporters
class JsonMin < Base
def render # rubocop:disable Metrics/AbcSize
def render
output(report.to_json, false)
end
def report # rubocop:disable Metrics/AbcSize
report = {
controls: [],
statistics: { duration: run_data[:statistics][:duration] },
@ -38,7 +42,7 @@ module Inspec::Reporters
end
end
output(report.to_json)
report
end
end
end

View file

@ -31,8 +31,6 @@ module Inspec
class Runner
extend Forwardable
def_delegator :@test_collector, :report
attr_reader :backend, :rules, :attributes
def initialize(conf = {})
@rules = []
@ -112,6 +110,10 @@ module Inspec
end
end
def report
Inspec::Reporters.report(@conf['reporter'].first, @run_data)
end
def write_lockfile(profile)
return false if !profile.writable?
@ -125,8 +127,9 @@ module Inspec
end
def run_tests(with = nil)
status, run_data = @test_collector.run(with)
render_output(run_data)
status, @run_data = @test_collector.run(with)
# dont output anything if we want a report
render_output(@run_data) unless @conf['report']
status
end

View file

@ -78,15 +78,6 @@ module Inspec
[status, @formatter.run_data]
end
# Provide an output hash of the run's report
#
# @return [Hash] a run's output hash
def report
reporter = @formatter || RSpec.configuration.formatters[0]
return nil if reporter.nil? || !reporter.respond_to?(:output_hash)
reporter.output_hash
end
# Empty the list of registered tests.
#
# @return [nil]
@ -140,11 +131,6 @@ module Inspec
RSpec.configuration.add_formatter(Inspec::Formatters::ShowProgress, $stderr) if @conf[:show_progress]
set_optional_formatters
RSpec.configuration.color = @conf['color']
setup_reporting if @conf['report']
end
def setup_reporting
RSpec.configuration.add_formatter(Inspec::RSpecReporter)
end
# Make sure that all RSpec example groups use the provided ID.
@ -174,12 +160,4 @@ module Inspec
metadata[:source_location] = rule.instance_variable_get(:@__source_location)
end
end
class RSpecReporter < RSpec::Core::Formatters::JsonFormatter
RSpec::Core::Formatters.register Inspec::RSpecReporter
def initialize(*)
super(StringIO.new)
end
end
end

View file

@ -8,29 +8,30 @@ describe 'BaseCLI' do
let(:cli) { Inspec::BaseCLI.new }
describe 'merge_options' do
let(:default_options) do
{ exec: { 'reporter' => ['json'], 'backend_cache' => false }}
end
it 'cli defaults populate correctly' do
default_options = { exec: { format: 'json', backend_cache: false }}
Inspec::BaseCLI.stubs(:default_options).returns(default_options)
opts = cli.send(:merged_opts, :exec)
expected = { 'format' => 'json', 'backend_cache' => false }
expected = {"backend_cache"=>false, "reporter"=>{"json"=>{"stdout"=>true}}}
opts.must_equal expected
end
it 'json-config options override cli defaults' do
default_options = { exec: { format: 'json', backend_cache: false }}
Inspec::BaseCLI.stubs(:default_options).returns(default_options)
parsed_json = { 'backend_cache' => true }
cli.expects(:options_json).returns(parsed_json)
opts = cli.send(:merged_opts, :exec)
expected = { 'format' => 'json', 'backend_cache' => true }
expected = {"backend_cache"=>true, "reporter"=>{"json"=>{"stdout"=>true}}}
opts.must_equal expected
end
it 'cli options override json-config and default' do
default_options = { exec: { format: 'json', backend_cache: false }}
Inspec::BaseCLI.stubs(:default_options).returns(default_options)
parsed_json = { 'backend_cache' => false }
@ -40,18 +41,68 @@ describe 'BaseCLI' do
cli.instance_variable_set(:@options, cli_options)
opts = cli.send(:merged_opts, :exec)
expected = { 'format' => 'json', 'backend_cache' => true }
expected = {"backend_cache"=>true, "reporter"=>{"json"=>{"stdout"=>true}}}
opts.must_equal expected
end
it 'make sure shell does not get exec defaults' do
default_options = { exec: { format: 'json', backend_cache: false }}
Inspec::BaseCLI.stubs(:default_options).returns(default_options)
opts = cli.send(:merged_opts)
expected = {}
opts.must_equal expected
end
it 'make sure default reporter is overriden by json-config format' do
default_options['reporter'] = ['cli']
Inspec::BaseCLI.stubs(:default_options).returns(default_options)
parsed_json = { 'format' => 'json' }
cli.expects(:options_json).returns(parsed_json)
opts = cli.send(:merged_opts, :exec)
expected = {"backend_cache"=>false, "reporter"=>{"json"=>{"stdout"=>true}}}
opts.must_equal expected
end
end
describe 'configure_logger' do
let(:options) do
o = {
'log_location' => STDERR,
'log_level' => 'debug',
'reporter' => {
'json' => {
'stdout' => true,
},
},
}
Thor::CoreExt::HashWithIndifferentAccess.new(o)
end
let(:format) do
device = options[:logger].instance_variable_get(:"@logdev")
device.instance_variable_get(:"@dev")
end
it 'sets to stderr for log_location' do
cli.send(:configure_logger, options)
format.must_equal STDERR
end
it 'sets to stderr for json' do
options.delete('log_location')
options.delete('log_level')
cli.send(:configure_logger, options)
format.must_equal STDERR
end
it 'sets defaults to stdout for everything else' do
options.delete('log_location')
options.delete('log_level')
options.delete('reporter')
cli.send(:configure_logger, options)
format.must_equal STDOUT
end
end
describe 'parse_reporters' do

View file

@ -11,9 +11,17 @@ describe Inspec::Reporters::JsonMin do
describe '#render' do
it 'confirm render output' do
cli_output = File.read(path + '/../mock/reporters/json_min_output')
output = File.read(path + '/../mock/reporters/json_min_output')
report.render
report.rendered_output.must_equal cli_output
report.rendered_output.must_equal output
end
end
describe '#report' do
it 'confirm report output' do
output = File.read(path + '/../mock/reporters/json_min_output')
output = JSON.parse(output, symbolize_names: true)
report.report.must_equal output
end
end
end

View file

@ -13,9 +13,17 @@ describe Inspec::Reporters::Json do
describe '#render' do
it 'confirm render output' do
cli_output = File.read(path + '/../mock/reporters/json_output')
output = File.read(path + '/../mock/reporters/json_output')
report.render
report.rendered_output.must_equal cli_output
report.rendered_output.must_equal output
end
end
describe '#report' do
it 'confirm report output' do
output = File.read(path + '/../mock/reporters/json_output')
output = JSON.parse(output, symbolize_names: true)
report.report.must_equal output
end
end