diff --git a/lib/inspec/reporters/cli.rb b/lib/inspec/reporters/cli.rb index 4185affa4..a78393a92 100644 --- a/lib/inspec/reporters/cli.rb +++ b/lib/inspec/reporters/cli.rb @@ -170,7 +170,7 @@ module Inspec::Reporters end def all_unique_controls - @unique_controls ||= begin + @unique_controls ||= begin # rubocop:disable Style/RedundantBegin run_data[:profiles].flat_map do |profile| profile[:controls] end.uniq diff --git a/lib/inspec/utils/filter.rb b/lib/inspec/utils/filter.rb index aec87c9ac..ff4517e4e 100644 --- a/lib/inspec/utils/filter.rb +++ b/lib/inspec/utils/filter.rb @@ -36,14 +36,20 @@ module FilterTable # RSpec will check the object returned to see if it responds to a method # before calling it. We need to fake it out and tell it that it does. This # allows it to skip past that check and fall through to #method_missing - def respond_to?(_method) + def respond_to?(_method, include_all = false) true end def to_s - @original_resource.to_s + "#{@original_resource} (#{@original_exception.message})" end alias inspect to_s + + # Rspec is not able to convert FilterTable::ExceptionCatcher issue https://github.com/inspec/inspec/issues/5369 + # which result into not showing actual exception message this allows to convert it properly. + def to_ary + [ to_s ] + end end class Trace diff --git a/test/fixtures/profiles/filter_table/controls/filter-table-exception-catcher.rb b/test/fixtures/profiles/filter_table/controls/filter-table-exception-catcher.rb new file mode 100644 index 000000000..cf84e3159 --- /dev/null +++ b/test/fixtures/profiles/filter_table/controls/filter-table-exception-catcher.rb @@ -0,0 +1,5 @@ +control 'exception_catcher_test' do + describe shadow('/tmp/no-file').users('root') do + its(:passwords) { should_not include('*') } + end +end \ No newline at end of file diff --git a/test/functional/filter_table_test.rb b/test/functional/filter_table_test.rb index f5a9564b3..0e828e72c 100644 --- a/test/functional/filter_table_test.rb +++ b/test/functional/filter_table_test.rb @@ -22,6 +22,18 @@ describe "filtertable functional tests" do control_hash end + def skipped_control_test_outcomes(run_result) + skipped_controls = @json["profiles"][0]["controls"].select { |ctl| ctl["results"][0]["status"] == "skipped" } + + # Re-package any skipped controls into a hash mapping control_id => message + # We will later test against this, as it provides more informative test output + control_hash = {} + skipped_controls.each do |ctl| + control_hash[ctl["id"]] = ctl["results"][0]["skip_message"] + end + control_hash + end + def expect_clean_run(controls) run_result = run_result_for_controls(controls) outcome_hash = failed_control_test_outcomes(run_result) @@ -123,4 +135,15 @@ describe "filtertable functional tests" do expect_clean_run(controls) end end + + describe "if control fails" do + it "should show the exact error message" do + skip_windows! + controls = ["exception_catcher_test"] + run_result = run_result_for_controls(controls) + outcome_hash = skipped_control_test_outcomes(run_result) + _(outcome_hash["exception_catcher_test"]).must_include "Can't find file: \/tmp\/no-file" + assert_exit_code 101, run_result + end + end end