From 8a77b740db337008bd96c2660dfc3369ee1e61c6 Mon Sep 17 00:00:00 2001 From: Vasu1105 Date: Wed, 24 Mar 2021 06:22:03 +0530 Subject: [PATCH 01/10] Fixes deprecation warning messages for respond_to? method Signed-off-by: Vasu1105 --- lib/inspec/utils/filter.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/inspec/utils/filter.rb b/lib/inspec/utils/filter.rb index aec87c9ac..77861675d 100644 --- a/lib/inspec/utils/filter.rb +++ b/lib/inspec/utils/filter.rb @@ -36,7 +36,7 @@ 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 From 805cf468482abae4a3870d156505cef5a998cd80 Mon Sep 17 00:00:00 2001 From: Vasu1105 Date: Wed, 24 Mar 2021 06:37:30 +0530 Subject: [PATCH 02/10] Profile to test the FilterTable::ExceptionCatcher issue Signed-off-by: Vasu1105 --- .../profiles/filter-table-test/README.md | 3 ++ .../filter-table-test/controls/example.rb | 11 ++++ .../profiles/filter-table-test/inspec.yml | 10 ++++ .../filter-table-test/libraries/dummy.rb | 50 +++++++++++++++++++ 4 files changed, 74 insertions(+) create mode 100644 test/fixtures/profiles/filter-table-test/README.md create mode 100644 test/fixtures/profiles/filter-table-test/controls/example.rb create mode 100644 test/fixtures/profiles/filter-table-test/inspec.yml create mode 100644 test/fixtures/profiles/filter-table-test/libraries/dummy.rb diff --git a/test/fixtures/profiles/filter-table-test/README.md b/test/fixtures/profiles/filter-table-test/README.md new file mode 100644 index 000000000..2aee95cbf --- /dev/null +++ b/test/fixtures/profiles/filter-table-test/README.md @@ -0,0 +1,3 @@ +# Example InSpec Profile + +This example shows the implementation of an InSpec profile. diff --git a/test/fixtures/profiles/filter-table-test/controls/example.rb b/test/fixtures/profiles/filter-table-test/controls/example.rb new file mode 100644 index 000000000..53cd19f7f --- /dev/null +++ b/test/fixtures/profiles/filter-table-test/controls/example.rb @@ -0,0 +1,11 @@ +describe dummy([{'name' => 'foo'}]).valid? do + it { should eq '' } +end + +describe dummy([{'name' => 'foo'}]) do + its('valid?') { should eq '' } +end + +describe dummy([{'name' => 'foo'}]) do + it { should be_valid } +end diff --git a/test/fixtures/profiles/filter-table-test/inspec.yml b/test/fixtures/profiles/filter-table-test/inspec.yml new file mode 100644 index 000000000..53e5e6389 --- /dev/null +++ b/test/fixtures/profiles/filter-table-test/inspec.yml @@ -0,0 +1,10 @@ +name: filter-table-test +title: InSpec Profile +maintainer: The Authors +copyright: The Authors +copyright_email: you@example.com +license: Apache-2.0 +summary: An InSpec Compliance Profile +version: 0.1.0 +supports: + platform: os \ No newline at end of file diff --git a/test/fixtures/profiles/filter-table-test/libraries/dummy.rb b/test/fixtures/profiles/filter-table-test/libraries/dummy.rb new file mode 100644 index 000000000..1dc448523 --- /dev/null +++ b/test/fixtures/profiles/filter-table-test/libraries/dummy.rb @@ -0,0 +1,50 @@ +module Dummy + class Test + attr_reader :filter_data + + def initialize(data) + @filter_data = data + end + + filter = FilterTable.create + filter.register_column(:names, field: 'name') + filter.register_column( + :tags, + field: :tags, + # ref: https://github.com/inspec/inspec/blob/master/docs/dev/filtertable-usage.md#lazy-loading + lazy: lambda do |row, _criterion, _table| + tags = row['tags'] + if tags.nil? + raise(Inspec::Exceptions::ResourceSkipped, '`tags` for resource is missing') + end + + row[:tags] = tags + end + ) + filter.install_filter_methods_on_resource(self, :filter_data) + end +end + +class DummyTest < Inspec.resource(1) + name 'dummy' + + attr_reader :data + + def initialize(data) + @data = data + end + + def valid? + tags + end + + private + + def tags + r_data.tags[0] + end + + def r_data + Dummy::Test.new(data) + end +end From 45e9288e902c22c16f3f88ab486549bce320f4c0 Mon Sep 17 00:00:00 2001 From: Vasu1105 Date: Wed, 24 Mar 2021 12:21:57 +0530 Subject: [PATCH 03/10] Revert "Profile to test the FilterTable::ExceptionCatcher issue" This reverts commit 33e096f0854c0f156130fe610ab3ab8f8b65cad4. --- .../profiles/filter-table-test/README.md | 3 -- .../filter-table-test/controls/example.rb | 11 ---- .../profiles/filter-table-test/inspec.yml | 10 ---- .../filter-table-test/libraries/dummy.rb | 50 ------------------- 4 files changed, 74 deletions(-) delete mode 100644 test/fixtures/profiles/filter-table-test/README.md delete mode 100644 test/fixtures/profiles/filter-table-test/controls/example.rb delete mode 100644 test/fixtures/profiles/filter-table-test/inspec.yml delete mode 100644 test/fixtures/profiles/filter-table-test/libraries/dummy.rb diff --git a/test/fixtures/profiles/filter-table-test/README.md b/test/fixtures/profiles/filter-table-test/README.md deleted file mode 100644 index 2aee95cbf..000000000 --- a/test/fixtures/profiles/filter-table-test/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# Example InSpec Profile - -This example shows the implementation of an InSpec profile. diff --git a/test/fixtures/profiles/filter-table-test/controls/example.rb b/test/fixtures/profiles/filter-table-test/controls/example.rb deleted file mode 100644 index 53cd19f7f..000000000 --- a/test/fixtures/profiles/filter-table-test/controls/example.rb +++ /dev/null @@ -1,11 +0,0 @@ -describe dummy([{'name' => 'foo'}]).valid? do - it { should eq '' } -end - -describe dummy([{'name' => 'foo'}]) do - its('valid?') { should eq '' } -end - -describe dummy([{'name' => 'foo'}]) do - it { should be_valid } -end diff --git a/test/fixtures/profiles/filter-table-test/inspec.yml b/test/fixtures/profiles/filter-table-test/inspec.yml deleted file mode 100644 index 53e5e6389..000000000 --- a/test/fixtures/profiles/filter-table-test/inspec.yml +++ /dev/null @@ -1,10 +0,0 @@ -name: filter-table-test -title: InSpec Profile -maintainer: The Authors -copyright: The Authors -copyright_email: you@example.com -license: Apache-2.0 -summary: An InSpec Compliance Profile -version: 0.1.0 -supports: - platform: os \ No newline at end of file diff --git a/test/fixtures/profiles/filter-table-test/libraries/dummy.rb b/test/fixtures/profiles/filter-table-test/libraries/dummy.rb deleted file mode 100644 index 1dc448523..000000000 --- a/test/fixtures/profiles/filter-table-test/libraries/dummy.rb +++ /dev/null @@ -1,50 +0,0 @@ -module Dummy - class Test - attr_reader :filter_data - - def initialize(data) - @filter_data = data - end - - filter = FilterTable.create - filter.register_column(:names, field: 'name') - filter.register_column( - :tags, - field: :tags, - # ref: https://github.com/inspec/inspec/blob/master/docs/dev/filtertable-usage.md#lazy-loading - lazy: lambda do |row, _criterion, _table| - tags = row['tags'] - if tags.nil? - raise(Inspec::Exceptions::ResourceSkipped, '`tags` for resource is missing') - end - - row[:tags] = tags - end - ) - filter.install_filter_methods_on_resource(self, :filter_data) - end -end - -class DummyTest < Inspec.resource(1) - name 'dummy' - - attr_reader :data - - def initialize(data) - @data = data - end - - def valid? - tags - end - - private - - def tags - r_data.tags[0] - end - - def r_data - Dummy::Test.new(data) - end -end From 0a62a6ac3b6e1ea79ad11d309afc1ce2ec6fd62b Mon Sep 17 00:00:00 2001 From: Vasu1105 Date: Wed, 24 Mar 2021 14:15:06 +0530 Subject: [PATCH 04/10] Added functional test for FilterTable::ExceptionCatcher Signed-off-by: Vasu1105 --- .../filter-table-exception-catcher.rb | 5 ++ .../profiles/filter_table/libraries/dummy.rb | 50 +++++++++++++++++++ test/functional/filter_table_test.rb | 11 ++++ 3 files changed, 66 insertions(+) create mode 100644 test/fixtures/profiles/filter_table/controls/filter-table-exception-catcher.rb create mode 100644 test/fixtures/profiles/filter_table/libraries/dummy.rb 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..4fa0858a3 --- /dev/null +++ b/test/fixtures/profiles/filter_table/controls/filter-table-exception-catcher.rb @@ -0,0 +1,5 @@ +control 'exception_catcher_test' do + describe dummy([{'name' => 'foo'}]) do + its('valid?') { should eq '' } + end +end \ No newline at end of file diff --git a/test/fixtures/profiles/filter_table/libraries/dummy.rb b/test/fixtures/profiles/filter_table/libraries/dummy.rb new file mode 100644 index 000000000..b85c03af3 --- /dev/null +++ b/test/fixtures/profiles/filter_table/libraries/dummy.rb @@ -0,0 +1,50 @@ +module Dummy + class Test + attr_reader :filter_data + + def initialize(data) + @filter_data = data + end + + filter = FilterTable.create + filter.register_column(:names, field: 'name') + filter.register_column( + :tags, + field: :tags, + # ref: https://github.com/inspec/inspec/blob/master/docs/dev/filtertable-usage.md#lazy-loading + lazy: lambda do |row, _criterion, _table| + tags = row['tags'] + if tags.nil? + raise(Inspec::Exceptions::ResourceFailed, '`tags` for resource is missing') + end + + row[:tags] = tags + end + ) + filter.install_filter_methods_on_resource(self, :filter_data) + end +end + +class DummyTest < Inspec.resource(1) + name 'dummy' + + attr_reader :data + + def initialize(data) + @data = data + end + + def valid? + tags + end + + private + + def tags + r_data.tags[0] + end + + def r_data + Dummy::Test.new(data) + 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..bf230cf1d 100644 --- a/test/functional/filter_table_test.rb +++ b/test/functional/filter_table_test.rb @@ -123,4 +123,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 + controls = ["exception_catcher_test"] + cmd = "exec " + ft_profile_path + " --controls " + controls.join(" ") + " --no-sudo" + run_result = run_result_for_controls(controls) + outcome_hash = failed_control_test_outcomes(run_result) + _(outcome_hash["exception_catcher_test"]).must_include "`tags` for resource is missing" + assert_exit_code 100, run_result + end + end end From 9af59c21644c6c61979254f2b22d09d2e628d2bc Mon Sep 17 00:00:00 2001 From: Vasu1105 Date: Wed, 24 Mar 2021 15:00:16 +0530 Subject: [PATCH 05/10] Fixes #5369 the FilterTable::ExceptionCatcher error and now shows exact exception message Signed-off-by: Vasu1105 --- lib/inspec/utils/filter.rb | 6 +++++- test/functional/filter_table_test.rb | 1 - 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/lib/inspec/utils/filter.rb b/lib/inspec/utils/filter.rb index 77861675d..a82171bd1 100644 --- a/lib/inspec/utils/filter.rb +++ b/lib/inspec/utils/filter.rb @@ -41,9 +41,13 @@ module FilterTable end def to_s - @original_resource.to_s + "#{@original_resource.to_s} (#{@original_exception.message})" end alias inspect to_s + + def to_ary + [ to_s ] + end end class Trace diff --git a/test/functional/filter_table_test.rb b/test/functional/filter_table_test.rb index bf230cf1d..345ce297f 100644 --- a/test/functional/filter_table_test.rb +++ b/test/functional/filter_table_test.rb @@ -127,7 +127,6 @@ describe "filtertable functional tests" do describe "if control fails" do it "should show the exact error message" do controls = ["exception_catcher_test"] - cmd = "exec " + ft_profile_path + " --controls " + controls.join(" ") + " --no-sudo" run_result = run_result_for_controls(controls) outcome_hash = failed_control_test_outcomes(run_result) _(outcome_hash["exception_catcher_test"]).must_include "`tags` for resource is missing" From abde5244702a407b882275330079d29cc690c782 Mon Sep 17 00:00:00 2001 From: Vasu1105 Date: Wed, 24 Mar 2021 15:19:45 +0530 Subject: [PATCH 06/10] Fixed lint and added code comments Signed-off-by: Vasu1105 --- lib/inspec/utils/filter.rb | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/inspec/utils/filter.rb b/lib/inspec/utils/filter.rb index a82171bd1..ff4517e4e 100644 --- a/lib/inspec/utils/filter.rb +++ b/lib/inspec/utils/filter.rb @@ -41,10 +41,12 @@ module FilterTable end def to_s - "#{@original_resource.to_s} (#{@original_exception.message})" + "#{@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 From 7c25a2b5df670574873c9b1dd88b939e85934832 Mon Sep 17 00:00:00 2001 From: Vasu1105 Date: Thu, 25 Mar 2021 14:02:19 +0530 Subject: [PATCH 07/10] Updated test Signed-off-by: Vasu1105 --- .../filter-table-exception-catcher.rb | 4 +- .../profiles/filter_table/libraries/dummy.rb | 50 ------------------- test/functional/filter_table_test.rb | 25 ++++++++-- 3 files changed, 23 insertions(+), 56 deletions(-) delete mode 100644 test/fixtures/profiles/filter_table/libraries/dummy.rb 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 index 4fa0858a3..2ddc4c32f 100644 --- a/test/fixtures/profiles/filter_table/controls/filter-table-exception-catcher.rb +++ b/test/fixtures/profiles/filter_table/controls/filter-table-exception-catcher.rb @@ -1,5 +1,5 @@ control 'exception_catcher_test' do - describe dummy([{'name' => 'foo'}]) do - its('valid?') { should eq '' } + describe shadow.users('root') do + its(:passwords) { should_not include('*') } end end \ No newline at end of file diff --git a/test/fixtures/profiles/filter_table/libraries/dummy.rb b/test/fixtures/profiles/filter_table/libraries/dummy.rb deleted file mode 100644 index b85c03af3..000000000 --- a/test/fixtures/profiles/filter_table/libraries/dummy.rb +++ /dev/null @@ -1,50 +0,0 @@ -module Dummy - class Test - attr_reader :filter_data - - def initialize(data) - @filter_data = data - end - - filter = FilterTable.create - filter.register_column(:names, field: 'name') - filter.register_column( - :tags, - field: :tags, - # ref: https://github.com/inspec/inspec/blob/master/docs/dev/filtertable-usage.md#lazy-loading - lazy: lambda do |row, _criterion, _table| - tags = row['tags'] - if tags.nil? - raise(Inspec::Exceptions::ResourceFailed, '`tags` for resource is missing') - end - - row[:tags] = tags - end - ) - filter.install_filter_methods_on_resource(self, :filter_data) - end -end - -class DummyTest < Inspec.resource(1) - name 'dummy' - - attr_reader :data - - def initialize(data) - @data = data - end - - def valid? - tags - end - - private - - def tags - r_data.tags[0] - end - - def r_data - Dummy::Test.new(data) - 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 345ce297f..619be68e7 100644 --- a/test/functional/filter_table_test.rb +++ b/test/functional/filter_table_test.rb @@ -10,6 +10,11 @@ describe "filtertable functional tests" do run_inspec_process(cmd, run_opts) end + def run_result_for_controls_without_sudo(controls) + cmd = "exec " + ft_profile_path + " --controls " + controls.join(" ") + " --no-sudo" + run_inspec_process(cmd, run_opts) + end + def failed_control_test_outcomes(run_result) failed_controls = @json["profiles"][0]["controls"].select { |ctl| ctl["results"][0]["status"] == "failed" } @@ -22,6 +27,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) @@ -127,10 +144,10 @@ describe "filtertable functional tests" do describe "if control fails" do it "should show the exact error message" do controls = ["exception_catcher_test"] - run_result = run_result_for_controls(controls) - outcome_hash = failed_control_test_outcomes(run_result) - _(outcome_hash["exception_catcher_test"]).must_include "`tags` for resource is missing" - assert_exit_code 100, run_result + run_result = run_result_for_controls_without_sudo(controls) + outcome_hash = skipped_control_test_outcomes(run_result) + _(outcome_hash["exception_catcher_test"]).must_include "Can't read file: \/etc\/shadow" + assert_exit_code 101, run_result end end end From a0d669a0f07199af89d7051acd959d96764c6de9 Mon Sep 17 00:00:00 2001 From: Vasu1105 Date: Thu, 25 Mar 2021 19:15:50 +0530 Subject: [PATCH 08/10] Updated test so that can run in the test enviornment Signed-off-by: Vasu1105 --- .../controls/filter-table-exception-catcher.rb | 2 +- test/functional/filter_table_test.rb | 9 ++------- 2 files changed, 3 insertions(+), 8 deletions(-) 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 index 2ddc4c32f..cf84e3159 100644 --- a/test/fixtures/profiles/filter_table/controls/filter-table-exception-catcher.rb +++ b/test/fixtures/profiles/filter_table/controls/filter-table-exception-catcher.rb @@ -1,5 +1,5 @@ control 'exception_catcher_test' do - describe shadow.users('root') 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 619be68e7..1a38d4e40 100644 --- a/test/functional/filter_table_test.rb +++ b/test/functional/filter_table_test.rb @@ -10,11 +10,6 @@ describe "filtertable functional tests" do run_inspec_process(cmd, run_opts) end - def run_result_for_controls_without_sudo(controls) - cmd = "exec " + ft_profile_path + " --controls " + controls.join(" ") + " --no-sudo" - run_inspec_process(cmd, run_opts) - end - def failed_control_test_outcomes(run_result) failed_controls = @json["profiles"][0]["controls"].select { |ctl| ctl["results"][0]["status"] == "failed" } @@ -144,9 +139,9 @@ describe "filtertable functional tests" do describe "if control fails" do it "should show the exact error message" do controls = ["exception_catcher_test"] - run_result = run_result_for_controls_without_sudo(controls) + run_result = run_result_for_controls(controls) outcome_hash = skipped_control_test_outcomes(run_result) - _(outcome_hash["exception_catcher_test"]).must_include "Can't read file: \/etc\/shadow" + _(outcome_hash["exception_catcher_test"]).must_include "Can't find file: \/tmp\/no-file" assert_exit_code 101, run_result end end From edf8d4d7edd1682a68cc37267bb21b5f802637ae Mon Sep 17 00:00:00 2001 From: Vasu1105 Date: Thu, 25 Mar 2021 20:22:40 +0530 Subject: [PATCH 09/10] Skipping on windows Signed-off-by: Vasu1105 --- test/functional/filter_table_test.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/test/functional/filter_table_test.rb b/test/functional/filter_table_test.rb index 1a38d4e40..0e828e72c 100644 --- a/test/functional/filter_table_test.rb +++ b/test/functional/filter_table_test.rb @@ -138,6 +138,7 @@ describe "filtertable functional tests" do 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) From a2d3218536f4e1e3b387e735a2fa6ca19dd573bf Mon Sep 17 00:00:00 2001 From: Vasu1105 Date: Thu, 25 Mar 2021 22:00:12 +0530 Subject: [PATCH 10/10] Disable rubocop for begin block Signed-off-by: Vasu1105 --- lib/inspec/reporters/cli.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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