2019-06-11 22:24:35 +00:00
require " functional/helper "
2016-03-25 00:31:19 +00:00
2019-06-11 22:24:35 +00:00
describe " inspec exec " do
2019-09-14 00:53:11 +00:00
parallelize_me!
2016-03-25 00:31:19 +00:00
include FunctionalHelper
2019-01-08 22:12:42 +00:00
let ( :looks_like_a_stacktrace ) { %r{ lib/inspec/.+ \ .rb: \ d+:in } }
2016-03-25 00:31:19 +00:00
2019-07-18 08:20:30 +00:00
attr_accessor :out
def inspec ( commandline , prefix = nil )
@stdout = @stderr = nil
self . out = super
end
def stdout
2019-08-12 22:13:11 +00:00
@stdout || = out . stdout
. force_encoding ( Encoding :: UTF_8 )
. gsub ( / \ e \ [( \ d+)(; \ d+)*m / , " " ) # strip ANSI color codes
2019-07-18 08:20:30 +00:00
end
def stderr
2019-08-12 22:13:11 +00:00
@stderr || = out . stderr
. force_encoding ( Encoding :: UTF_8 )
. gsub ( / \ e \ [( \ d+)(; \ d+)*m / , " " ) # strip ANSI color codes
2019-07-18 08:20:30 +00:00
end
2019-06-11 22:24:35 +00:00
before do
2019-12-07 00:50:09 +00:00
prof = " test/fixtures/profiles "
2019-08-13 02:06:23 +00:00
FileUtils . rm_f " #{ prof } /aws-profile/inspec.lock "
FileUtils . rm_f " #{ prof } /simple-inheritance/inspec.lock "
FileUtils . rm_f " #{ prof } /simple-metadata/inspec.lock "
2019-06-11 22:24:35 +00:00
end
2019-06-04 06:08:14 +00:00
2020-07-07 13:48:12 +00:00
it " handles '=' character on input " do
# This test handles a bug discovered at: https://github.com/inspec/inspec/issues/5131
inspec (
" exec " +
File . join ( profile_path , " inputs " , " with_various_values " ) +
" --no-create-lockfile " +
" --input my_input='ab=cde' "
)
_ ( stdout ) . must_include " 0 failures "
end
2019-07-18 08:42:14 +00:00
it " cleanly fails if mixing incompatible resource and transports " do
2020-06-25 12:52:29 +00:00
# TODO: It should be possible to test this more directly.
2019-07-18 08:42:14 +00:00
inspec " exec -t aws:// #{ profile_path } /incompatible_resource_for_transport.rb "
2020-06-25 12:52:29 +00:00
_ ( stderr ) . must_be_empty
_ ( stdout ) . must_include " Unsupported resource/backend combination: file / aws. Exiting. "
assert_exit_code 100 , out
2019-07-18 08:42:14 +00:00
end
2019-06-11 22:24:35 +00:00
it " can execute the profile " do
2020-01-28 23:52:02 +00:00
inspec ( " exec " + complete_profile + " --no-create-lockfile " )
2019-07-23 01:44:43 +00:00
2020-01-28 23:52:02 +00:00
_ ( stdout ) . must_include " Host example.com "
_ ( stdout ) . must_include " 1 successful control, " \
" 0 control failures, 0 controls skipped "
_ ( stderr ) . must_be_empty
2019-07-23 01:44:43 +00:00
2020-01-28 23:52:02 +00:00
assert_exit_code 0 , out
2016-03-25 00:31:19 +00:00
end
2019-06-11 22:24:35 +00:00
it " executes a minimum metadata-only profile " do
2019-07-18 08:20:30 +00:00
inspec ( " exec " + File . join ( profile_path , " simple-metadata " ) + " --no-create-lockfile " )
2019-07-23 01:44:43 +00:00
2019-09-30 22:31:55 +00:00
_ ( stdout ) . must_equal "
2016-06-14 12:41:45 +00:00
Profile : yumyum profile
2017-02-13 18:04:46 +00:00
Version : ( not specified )
2016-06-16 07:19:25 +00:00
Target : local : / /
2016-06-14 12:41:45 +00:00
2017-05-01 23:18:23 +00:00
No tests executed .
2016-06-14 12:41:45 +00:00
2017-08-23 14:29:09 +00:00
Test Summary : 0 successful , 0 failures , 0 skipped
2016-06-14 12:41:45 +00:00
"
2019-09-30 22:31:55 +00:00
_ ( stderr ) . must_equal " "
2019-07-23 01:44:43 +00:00
assert_exit_code 0 , out
2016-03-25 00:31:19 +00:00
end
2019-06-11 22:24:35 +00:00
it " can execute the profile and write to directory " do
2018-03-08 20:45:59 +00:00
outpath = Dir . tmpdir
2020-01-28 23:52:02 +00:00
inspec ( " exec #{ complete_profile } --no-create-lockfile --reporter json: #{ outpath } /foo/bar/test.json " )
2019-07-23 01:44:43 +00:00
2019-09-30 22:31:55 +00:00
_ ( File . exist? ( " #{ outpath } /foo/bar/test.json " ) ) . must_equal true
_ ( File . stat ( " #{ outpath } /foo/bar/test.json " ) . size ) . must_be :> , 0
2019-07-23 01:44:43 +00:00
2019-09-30 22:31:55 +00:00
_ ( stderr ) . must_equal " "
2019-07-23 01:44:43 +00:00
2020-01-28 23:52:02 +00:00
assert_exit_code 0 , out
2018-03-08 20:45:59 +00:00
end
2019-06-11 22:24:35 +00:00
it " can execute --help after exec command " do
2019-07-18 08:20:30 +00:00
inspec ( " exec --help " )
2019-07-23 01:44:43 +00:00
2019-09-30 22:31:55 +00:00
_ ( stdout ) . must_include " Usage: \n inspec exec LOCATIONS "
2019-07-23 01:44:43 +00:00
2019-09-30 22:31:55 +00:00
_ ( stderr ) . must_equal " "
2019-07-23 01:44:43 +00:00
assert_exit_code 0 , out
2018-11-01 17:04:59 +00:00
end
2019-06-11 22:24:35 +00:00
it " can execute help after exec command " do
2019-07-18 08:20:30 +00:00
inspec ( " exec help " )
2019-07-23 01:44:43 +00:00
2019-09-30 22:31:55 +00:00
_ ( stdout ) . must_include " Usage: \n inspec exec LOCATIONS "
2019-07-23 01:44:43 +00:00
2019-09-30 22:31:55 +00:00
_ ( stderr ) . must_equal " "
2019-07-23 01:44:43 +00:00
assert_exit_code 0 , out
2018-11-01 17:04:59 +00:00
end
2019-06-11 22:24:35 +00:00
it " can execute help before exec command " do
2019-07-18 08:20:30 +00:00
inspec ( " help exec " )
2019-07-23 01:44:43 +00:00
2019-09-30 22:31:55 +00:00
_ ( stdout ) . must_include " Usage: \n inspec exec LOCATIONS "
2019-07-23 01:44:43 +00:00
2019-09-30 22:31:55 +00:00
_ ( stderr ) . must_equal " "
2019-07-23 01:44:43 +00:00
assert_exit_code 0 , out
2018-11-01 17:04:59 +00:00
end
2019-06-11 22:24:35 +00:00
it " can execute the profile with a target_id passthrough " do
2020-01-28 23:52:02 +00:00
inspec ( " exec #{ complete_profile } --no-create-lockfile --target-id 1d3e399f-4d71-4863-ac54-84d437fbc444 " )
2019-07-23 01:44:43 +00:00
2019-09-30 22:31:55 +00:00
_ ( stdout ) . must_include " Target ID: 1d3e399f-4d71-4863-ac54-84d437fbc444 "
2019-07-23 01:44:43 +00:00
2019-09-30 22:31:55 +00:00
_ ( stderr ) . must_equal " "
2019-07-23 01:44:43 +00:00
2020-01-28 23:52:02 +00:00
assert_exit_code 0 , out
2018-09-05 19:07:34 +00:00
end
2019-06-11 22:24:35 +00:00
it " executes a metadata-only profile " do
2019-07-18 08:20:30 +00:00
inspec ( " exec " + File . join ( profile_path , " complete-metadata " ) + " --no-create-lockfile " )
2019-07-23 01:44:43 +00:00
2019-09-30 22:31:55 +00:00
_ ( stdout ) . must_equal "
2016-06-14 12:41:45 +00:00
Profile : title ( name )
Version : 1 . 2 . 3
2016-06-16 07:19:25 +00:00
Target : local : / /
2016-06-14 12:41:45 +00:00
2017-05-01 23:18:23 +00:00
No tests executed .
2016-06-14 12:41:45 +00:00
2017-08-23 14:29:09 +00:00
Test Summary : 0 successful , 0 failures , 0 skipped
2016-06-14 12:41:45 +00:00
"
2019-07-23 01:44:43 +00:00
2019-09-30 22:31:55 +00:00
_ ( stderr ) . must_equal " "
2019-07-23 01:44:43 +00:00
assert_exit_code 0 , out
2016-03-25 00:31:19 +00:00
end
2019-02-12 23:02:54 +00:00
it " executes a profile and reads inputs " do
2019-07-18 08:20:30 +00:00
inspec ( " exec #{ File . join ( examples_path , " profile-attribute " ) } --no-create-lockfile --input-file #{ File . join ( examples_path , " profile-attribute.yml " ) } " )
2019-07-23 01:44:43 +00:00
2019-08-12 22:13:11 +00:00
_ ( stdout ) . must_include " Test Summary: 2 successful, 0 failures, 0 skipped "
2019-07-23 01:44:43 +00:00
2019-09-30 22:31:55 +00:00
_ ( stderr ) . must_equal " "
2019-07-23 01:44:43 +00:00
assert_exit_code 0 , out
2016-09-06 23:40:07 +00:00
end
2019-06-11 22:24:35 +00:00
it " executes a specs-only profile " do
2019-07-18 08:20:30 +00:00
inspec ( " exec " + File . join ( profile_path , " spec_only " ) + " --no-create-lockfile " )
2019-07-23 01:44:43 +00:00
2019-09-30 22:31:55 +00:00
_ ( stdout ) . must_include " Target: local:// "
_ ( stdout ) . must_include " working "
2019-12-07 00:50:09 +00:00
_ ( stdout ) . must_include " ✔ is expected to eq \" working \" "
2019-09-30 22:31:55 +00:00
_ ( stdout ) . must_include " skippy \n "
_ ( stdout ) . must_include " ↺ This will be skipped intentionally "
_ ( stdout ) . must_include " failing "
2019-12-07 00:50:09 +00:00
_ ( stdout ) . must_include " × is expected to eq \" as intended \" "
2019-08-12 22:13:11 +00:00
_ ( stdout ) . must_include " Test Summary: 1 successful, 1 failure, 1 skipped \n "
2019-07-23 01:44:43 +00:00
2019-09-30 22:31:55 +00:00
_ ( stderr ) . must_equal " "
2019-07-23 01:44:43 +00:00
assert_exit_code 100 , out
2016-04-11 14:30:35 +00:00
end
2019-06-11 22:24:35 +00:00
it " executes only specified controls when selecting passing controls by literal names " do
2019-07-18 08:20:30 +00:00
inspec ( " exec " + File . join ( profile_path , " filter_table " ) + " --no-create-lockfile --controls 2943_pass_undeclared_field_in_hash 2943_pass_irregular_row_key " )
2019-07-23 01:44:43 +00:00
2019-08-12 22:13:11 +00:00
_ ( stdout ) . must_include " \n Profile Summary: 2 successful controls, 0 control failures, 0 controls skipped \n "
2019-07-23 01:44:43 +00:00
2019-09-30 22:31:55 +00:00
_ ( stderr ) . must_equal " "
2019-07-23 01:44:43 +00:00
assert_exit_code 0 , out
2018-07-05 19:44:30 +00:00
end
2019-06-11 22:24:35 +00:00
it " executes only specified controls when selecting failing controls by literal names " do
2019-07-18 08:20:30 +00:00
inspec ( " exec " + File . join ( profile_path , " filter_table " ) + " --no-create-lockfile --controls 2943_fail_derail_check " )
2019-07-23 01:44:43 +00:00
2019-08-12 22:13:11 +00:00
_ ( stdout ) . must_include " \n Profile Summary: 0 successful controls, 1 control failure, 0 controls skipped "
2019-07-23 01:44:43 +00:00
2019-09-30 22:31:55 +00:00
_ ( stderr ) . must_equal " "
2019-07-23 01:44:43 +00:00
assert_exit_code 100 , out
2018-07-05 19:44:30 +00:00
end
2019-06-11 22:24:35 +00:00
it " executes only specified controls when selecting passing controls by regex " do
2019-07-18 08:20:30 +00:00
inspec ( " exec " + File . join ( profile_path , " filter_table " ) + " --no-create-lockfile --controls '/^2943_pass/' " )
2019-07-23 01:44:43 +00:00
2019-08-12 22:13:11 +00:00
_ ( stdout ) . must_include " Profile Summary: 6 successful controls, 0 control failures, 0 controls skipped "
2019-07-23 01:44:43 +00:00
assert_exit_code 0 , out
2018-07-05 19:44:30 +00:00
end
2019-06-11 22:24:35 +00:00
it " executes only specified controls when selecting failing controls by regex " do
2019-07-18 08:20:30 +00:00
inspec ( " exec " + File . join ( profile_path , " filter_table " ) + " --no-create-lockfile --controls '/^2943_fail/' " )
2019-07-23 01:44:43 +00:00
2019-08-12 22:13:11 +00:00
_ ( stdout ) . must_include " Profile Summary: 0 successful controls, 1 control failure, 0 controls skipped "
2019-07-23 01:44:43 +00:00
2019-09-30 22:31:55 +00:00
_ ( stderr ) . must_equal " "
2019-07-23 01:44:43 +00:00
assert_exit_code 100 , out
2016-04-11 14:30:35 +00:00
end
2020-06-25 12:52:29 +00:00
it " reports whan a profile cannot be loaded " do
inspec ( " exec " + File . join ( profile_path , " raise_outside_control " ) + " --no-create-lockfile " )
2020-07-01 15:12:17 +00:00
_ ( stdout ) . must_match ( / Profile:[ \ W]+InSpec Profile \ (raise_outside_control \ ) / )
2020-06-25 12:52:29 +00:00
_ ( stdout ) . must_include " ERROR: Failed to load profile raise_outside_control: Failed to load source for controls/raises.rb: Something unforeseen... "
assert_exit_code 102 , out
end
2019-06-11 22:24:35 +00:00
it " can execute a simple file with the default formatter " do
2019-07-18 08:20:30 +00:00
inspec ( " exec " + example_control + " --no-create-lockfile " )
2019-07-23 01:44:43 +00:00
2019-08-12 22:13:11 +00:00
_ ( stdout ) . must_include " \n Profile Summary: 1 successful control, 0 control failures, 0 controls skipped \n "
_ ( stdout ) . must_include " \n Test Summary: 2 successful, 0 failures, 0 skipped \n "
2019-07-23 01:44:43 +00:00
2019-09-30 22:31:55 +00:00
_ ( stderr ) . must_equal " "
2019-07-23 01:44:43 +00:00
assert_exit_code 0 , out
2016-03-25 00:31:19 +00:00
end
2019-06-11 22:24:35 +00:00
it " does not vendor profiles when using the a local path dependecy " do
2018-09-07 03:28:08 +00:00
Dir . mktmpdir do | tmpdir |
2020-01-28 23:52:02 +00:00
command = " exec " + inheritance_profile + " --no-create-lockfile " \
" --input-file= #{ examples_path } /profile-attribute.yml "
2019-07-18 08:20:30 +00:00
inspec_with_env ( command , INSPEC_CONFIG_DIR : tmpdir )
2019-07-23 01:44:43 +00:00
2018-09-12 22:04:16 +00:00
if is_windows?
2020-01-28 23:52:02 +00:00
_ ( stdout ) . must_include " No tests executed. "
assert_exit_code 1 , out
2018-09-12 22:04:16 +00:00
else
2020-01-28 23:52:02 +00:00
_ ( stdout ) . must_include " Profile Summary: 2 successful controls, 0 control failures, 0 controls skipped \n "
_ ( stdout ) . must_include " Test Summary: 5 successful, 0 failures, 0 skipped \n "
assert_exit_code 0 , out
2018-09-12 22:04:16 +00:00
end
2019-08-13 02:06:23 +00:00
2019-06-11 22:24:35 +00:00
cache_dir = File . join ( tmpdir , " cache " )
2019-09-30 22:31:55 +00:00
_ ( Dir . exist? ( cache_dir ) ) . must_equal true
_ ( Dir . glob ( File . join ( cache_dir , " ** " , " * " ) ) ) . must_be_empty
2019-07-23 01:44:43 +00:00
2020-01-28 23:52:02 +00:00
_ ( stderr ) . must_equal " "
2018-09-07 03:28:08 +00:00
end
end
2019-06-11 22:24:35 +00:00
describe " with a profile that is not supported on this OS/platform " do
let ( :out ) { inspec ( " exec " + File . join ( profile_path , " skippy-profile-os " ) + " --no-create-lockfile " ) }
2019-07-23 01:44:43 +00:00
let ( :json ) { JSON . load ( stdout ) }
2016-04-05 16:07:00 +00:00
2019-06-11 22:24:35 +00:00
it " exits with skip message " do
2019-09-30 22:31:55 +00:00
_ ( stdout ) . must_include ( " Skipping profile: 'skippy' on unsupported platform: " )
2019-07-23 01:44:43 +00:00
2019-09-30 22:31:55 +00:00
_ ( stderr ) . must_equal " "
2019-07-23 01:44:43 +00:00
assert_exit_code 101 , out
2016-04-05 16:07:00 +00:00
end
2016-04-17 00:04:10 +00:00
end
2016-04-05 16:07:00 +00:00
2019-06-11 22:24:35 +00:00
describe " with a profile that contains skipped controls " do
let ( :out ) { inspec ( " exec " + File . join ( profile_path , " skippy-controls " ) + " --no-create-lockfile " ) }
2019-07-23 01:44:43 +00:00
let ( :json ) { JSON . load ( stdout ) }
2016-09-20 16:03:43 +00:00
2019-06-11 22:24:35 +00:00
it " exits with an error " do
2019-08-12 22:13:11 +00:00
_ ( stdout ) . must_include " skippy \n ↺ This will be skipped super intentionally. \n "
_ ( stdout ) . must_include " ↺ CONTROL database: MySQL Session \n ↺ Can't run MySQL SQL checks without authentication \n "
_ ( stdout ) . must_include " Profile Summary: 0 successful controls, 0 control failures, 2 controls skipped \n Test Summary: 0 successful, 0 failures, 2 skipped \n "
2019-07-23 01:44:43 +00:00
2019-09-30 22:31:55 +00:00
_ ( stderr ) . must_equal " "
2019-07-23 01:44:43 +00:00
assert_exit_code 101 , out
2016-09-20 16:03:43 +00:00
end
end
2019-06-11 22:24:35 +00:00
describe " with a profile that contains skipped controls and the --no-distinct-exit flag " do
let ( :out ) { inspec ( " exec " + File . join ( profile_path , " skippy-controls " ) + " --no-distinct-exit --no-create-lockfile " ) }
2018-06-29 12:43:34 +00:00
2019-06-11 22:24:35 +00:00
it " exits with code 0 and skipped tests in output " do
2019-08-12 22:13:11 +00:00
_ ( stdout ) . must_include " Profile Summary: 0 successful controls, 0 control failures, 2 controls skipped \n Test Summary: 0 successful, 0 failures, 2 skipped \n "
2019-07-23 01:44:43 +00:00
2019-09-30 22:31:55 +00:00
_ ( stderr ) . must_equal " "
2019-07-23 01:44:43 +00:00
assert_exit_code 0 , out
2018-06-29 12:43:34 +00:00
end
end
2019-06-11 22:24:35 +00:00
describe " with a profile that contains failing controls and the --no-distinct-exit flag " do
let ( :out ) { inspec ( " exec " + File . join ( profile_path , " failures " ) + " --no-distinct-exit --no-create-lockfile " ) }
2018-06-29 12:43:34 +00:00
2019-06-11 22:24:35 +00:00
it " exits with code 1 " do
2020-05-01 10:33:48 +00:00
_ ( stdout ) . must_include " Profile Summary: 0 successful controls, 4 control failures, 0 controls skipped "
2019-07-23 01:44:43 +00:00
2019-09-30 22:31:55 +00:00
_ ( stderr ) . must_equal " "
2019-07-23 01:44:43 +00:00
assert_exit_code 1 , out
2018-06-29 12:43:34 +00:00
end
end
2019-06-11 22:24:35 +00:00
describe " with a profile that contains skipped resources " do
let ( :out ) { inspec ( " exec " + File . join ( profile_path , " aws-profile " ) ) }
it " exits with an error " do
2019-06-07 23:33:56 +00:00
skip if ENV [ " NO_AWS " ]
2019-09-30 22:31:55 +00:00
_ ( stdout ) . must_include " Unsupported resource/backend combination: aws_iam_users "
_ ( stdout ) . must_include " Unsupported resource/backend combination: aws_iam_access_keys "
_ ( stdout ) . must_include " Unsupported resource/backend combination: aws_s3_bucket "
_ ( stdout ) . must_include " 3 failures "
2019-07-23 01:44:43 +00:00
assert_exit_code 100 , out
2018-02-16 20:15:53 +00:00
end
end
2019-06-11 22:24:35 +00:00
describe " with a profile that is supported on this version of inspec " do
let ( :out ) { inspec ( " exec " + File . join ( profile_path , " supported_inspec " ) + " --no-create-lockfile " ) }
2016-04-16 19:34:23 +00:00
2019-06-11 22:24:35 +00:00
it " exits cleanly " do
2019-09-30 22:31:55 +00:00
_ ( stderr ) . must_equal " "
2019-07-23 01:44:43 +00:00
assert_exit_code 0 , out
2016-04-16 19:34:23 +00:00
end
end
2019-06-11 22:24:35 +00:00
describe " with a profile that is not supported on this version of inspec " do
let ( :out ) { inspec ( " exec " + File . join ( profile_path , " unsupported_inspec " ) + " --no-create-lockfile " ) }
2016-04-16 19:34:23 +00:00
2019-06-11 22:24:35 +00:00
it " does not support this profile " do
2019-09-30 22:31:55 +00:00
_ ( stderr ) . must_equal " This profile requires Chef InSpec version >= 99.0.0. You are running Chef InSpec v #{ Inspec :: VERSION } . \n "
2019-07-23 01:44:43 +00:00
assert_exit_code 1 , out
2016-04-16 19:34:23 +00:00
end
end
2016-06-03 19:36:16 +00:00
2019-06-11 22:24:35 +00:00
describe " with a profile that loads a library and reference " do
let ( :out ) { inspec ( " exec " + File . join ( profile_path , " library " ) + " --no-create-lockfile " ) }
2016-06-03 19:36:16 +00:00
2019-06-11 22:24:35 +00:00
it " executes the profile without error " do
2019-09-30 22:31:55 +00:00
_ ( stderr ) . must_equal " "
2019-07-23 01:44:43 +00:00
assert_exit_code 0 , out
2016-06-03 19:36:16 +00:00
end
end
2016-08-22 15:57:33 +00:00
2019-06-11 22:24:35 +00:00
describe " given a profile with controls and anonymous describe blocks " do
let ( :out ) { inspec ( " exec " + example_control + " --no-create-lockfile " ) }
2016-08-22 15:57:33 +00:00
2019-06-11 22:24:35 +00:00
it " prints the control results, then the anonymous describe block results " do
2019-11-09 03:08:20 +00:00
_ ( stdout ) . must_match ( / Profile: tests from .*test.fixtures.profiles.old-examples.profile.controls.example-tmp.rb / )
2019-09-30 22:31:55 +00:00
_ ( stdout ) . must_include "
2017-02-13 18:04:46 +00:00
Version : ( not specified )
2016-08-22 15:57:33 +00:00
Target : local : / /
2019-11-07 00:12:58 +00:00
\ xE2 \ x9C \ x94 tmp - 1 . 0 : Create / directory
2019-12-07 00:50:09 +00:00
\ xE2 \ x9C \ x94 File / is expected to be directory
2016-08-22 15:57:33 +00:00
2019-11-07 00:12:58 +00:00
File /
2019-12-07 00:50:09 +00:00
\ xE2 \ x9C \ x94 is expected to be directory
2016-08-22 15:57:33 +00:00
2019-08-12 22:13:11 +00:00
Profile Summary : 1 successful control , 0 control failures , 0 controls skipped
Test Summary : 2 successful , 0 failures , 0 skipped \ n "
2016-08-22 15:57:33 +00:00
end
end
2016-09-01 12:25:56 +00:00
2019-06-11 22:24:35 +00:00
describe " given a profile with an anonymous describe block " do
let ( :out ) { inspec ( " exec " + failure_control + " --no-create-lockfile " ) }
2016-09-01 12:25:56 +00:00
2019-06-11 22:24:35 +00:00
it " prints the exception message when a test has a syntax error " do
2019-09-30 22:31:55 +00:00
_ ( stdout ) . must_include " undefined method `should_nota' "
2016-09-01 12:25:56 +00:00
end
end
2016-09-01 22:54:03 +00:00
2019-06-11 22:24:35 +00:00
describe " given an inherited profile that has more that one test per control block " do
let ( :out ) { inspec ( " exec " + simple_inheritance + " --no-create-lockfile " ) }
2016-09-01 22:54:03 +00:00
2019-06-11 22:24:35 +00:00
it " should print all the results " do
2019-11-07 00:12:58 +00:00
_ ( stdout ) . must_include " × tmp-1.0: Create / directory (1 failed)"
2019-12-07 00:50:09 +00:00
_ ( stdout ) . must_include " × is expected not to be directory\n "
2020-05-01 10:33:48 +00:00
_ ( stdout ) . must_include " × File / \n undefined method `should_nota' "
2020-12-10 18:09:27 +00:00
_ ( stdout ) . must_include " × is expected not to be directory\n expected `File /.directory?` to be falsey, got true "
2019-12-07 00:50:09 +00:00
_ ( stdout ) . must_include " × 7 is expected to cmp >= 9\n "
_ ( stdout ) . must_include " × 7 is expected not to cmp == /^\\ d$/ \n "
_ ( stdout ) . must_include " ✔ 7 is expected to cmp == \" 7 \" "
2020-01-28 22:46:00 +00:00
_ ( stdout ) . must_include " expected: %s " % [ " 01147 " ]
_ ( stdout ) . must_include " got: %s " % [ is_windows? ? " 040755 " : " 0755 " ]
2016-09-01 22:54:03 +00:00
end
end
2016-09-02 16:33:21 +00:00
2019-06-11 22:24:35 +00:00
describe " when passing in two profiles given an inherited profile that has more that one test per control block " do
let ( :out ) { inspec ( " exec " + File . join ( profile_path , " dependencies " , " profile_d " ) + " " + simple_inheritance + " --no-create-lockfile " ) }
2016-09-02 16:33:21 +00:00
2019-06-11 22:24:35 +00:00
it " should print all the results " do
2019-11-07 00:12:58 +00:00
_ ( stdout ) . must_include " × tmp-1.0: Create / directory (1 failed)"
2019-09-30 22:31:55 +00:00
_ ( stdout ) . must_include " × cmp-1.0: Using the cmp matcher for numbers (2 failed)"
2020-05-01 10:33:48 +00:00
_ ( stdout ) . must_include " × File / \n undefined method `should_nota' "
2020-12-10 18:09:27 +00:00
_ ( stdout ) . must_include " × is expected not to be directory\n expected `File /.directory?` to be falsey, got true "
2019-11-07 00:12:58 +00:00
_ ( stdout ) . must_include " ✔ profiled-1: Create / directory (profile d) "
2016-09-15 00:10:06 +00:00
end
end
2019-06-11 22:24:35 +00:00
describe " given an inherited profile " do
let ( :out ) { inspec ( " exec " + simple_inheritance ) }
2016-09-26 16:10:43 +00:00
2019-06-11 22:24:35 +00:00
it " should print the profile information and then the test results " do
2019-12-07 00:50:09 +00:00
_ ( stdout ) . must_include " × tmp-1.0: Create / directory (1 failed) \n ✔ File / is expected to be directory \n × File / is expected not to be directory \n "
2016-09-26 16:10:43 +00:00
end
end
2019-06-11 22:24:35 +00:00
describe " using namespaced resources " do
it " works " do
2019-07-18 08:20:30 +00:00
inspec ( " exec " + File . join ( profile_path , " dependencies " , " resource-namespace " ) + " --no-create-lockfile " )
2019-07-23 01:44:43 +00:00
2019-08-12 22:13:11 +00:00
_ ( stdout ) . must_include " Profile Summary: 1 successful control, 0 control failures, 0 controls skipped \n "
2019-07-23 01:44:43 +00:00
2019-09-30 22:31:55 +00:00
_ ( stderr ) . must_equal " "
2019-07-23 01:44:43 +00:00
assert_exit_code 0 , out
2016-09-15 07:54:15 +00:00
end
end
2019-06-11 22:24:35 +00:00
describe " with require_controls " do
it " does not run rules you did not include " do
2019-07-18 08:20:30 +00:00
inspec ( " exec " + File . join ( profile_path , " dependencies " , " require_controls_test " ) + " --no-create-lockfile " )
2019-07-23 01:44:43 +00:00
2019-08-12 22:13:11 +00:00
_ ( stdout ) . must_include " Profile Summary: 1 successful control, 0 control failures, 0 controls skipped \n "
2019-07-23 01:44:43 +00:00
2019-09-30 22:31:55 +00:00
_ ( stderr ) . must_equal " "
2019-07-23 01:44:43 +00:00
assert_exit_code 0 , out
2016-09-26 12:38:27 +00:00
end
end
2016-09-15 00:10:06 +00:00
describe " with a 2-level dependency tree " do
2019-06-11 22:24:35 +00:00
it " correctly runs tests from the whole tree " do
2019-07-18 08:20:30 +00:00
inspec ( " exec " + File . join ( profile_path , " dependencies " , " inheritance " ) + " --no-create-lockfile " )
2019-07-23 01:44:43 +00:00
2019-08-12 22:13:11 +00:00
_ ( stdout ) . must_include " Profile Summary: 6 successful controls, 0 control failures, 0 controls skipped \n "
2019-07-23 01:44:43 +00:00
2019-09-30 22:31:55 +00:00
_ ( stderr ) . must_equal " "
2019-07-23 01:44:43 +00:00
assert_exit_code 0 , out
2016-09-02 16:33:21 +00:00
end
end
2016-09-13 10:03:24 +00:00
2019-06-11 22:24:35 +00:00
describe " when using profiles on the supermarket " do
it " can run supermarket profiles directly from the command line " do
2019-11-07 00:12:58 +00:00
2020-08-17 12:27:58 +00:00
skip_windows! # Breakage confirmed, only on CI: https://buildkite.com/chef-oss/inspec-inspec-master-verify/builds/2355#2c9d032e-4a24-4e7c-aef2-1c9e2317d9e2
2019-07-18 08:20:30 +00:00
inspec ( " exec supermarket://nathenharvey/tmp-compliance-profile --no-create-lockfile " )
2019-07-23 01:44:43 +00:00
2018-09-12 22:04:16 +00:00
if is_windows?
2019-08-12 22:13:11 +00:00
_ ( stdout ) . must_include " Profile Summary: 1 successful control, 1 control failure, 0 controls skipped \n "
2018-09-12 22:04:16 +00:00
else
2019-08-12 22:13:11 +00:00
_ ( stdout ) . must_include " Profile Summary: 2 successful controls, 0 control failures, 0 controls skipped \n "
2018-09-12 22:04:16 +00:00
end
2019-07-23 01:44:43 +00:00
2019-09-30 22:31:55 +00:00
_ ( stderr ) . must_equal " "
2019-07-23 01:44:43 +00:00
2019-08-13 02:06:23 +00:00
if is_windows?
assert_exit_code 100 , out # references root
else
assert_exit_code 0 , out
end
2016-09-13 10:03:24 +00:00
end
2019-06-11 22:24:35 +00:00
it " can run supermarket profiles from inspec.yml " do
2020-08-17 12:27:58 +00:00
skip_windows! # Breakage confirmed, only on CI: https://buildkite.com/chef-oss/inspec-inspec-master-verify/builds/2355#2c9d032e-4a24-4e7c-aef2-1c9e2317d9e2
2019-11-07 00:12:58 +00:00
2019-07-18 08:20:30 +00:00
inspec ( " exec #{ File . join ( profile_path , " supermarket-dep " ) } --no-create-lockfile " )
2019-08-13 02:06:23 +00:00
2018-09-12 22:04:16 +00:00
if is_windows?
2019-08-12 22:13:11 +00:00
_ ( stdout ) . must_include " Profile Summary: 1 successful control, 1 control failure, 0 controls skipped \n "
2018-09-12 22:04:16 +00:00
else
2019-08-12 22:13:11 +00:00
_ ( stdout ) . must_include " Profile Summary: 2 successful controls, 0 control failures, 0 controls skipped \n "
2018-09-12 22:04:16 +00:00
end
2019-07-23 01:44:43 +00:00
2019-09-30 22:31:55 +00:00
_ ( stderr ) . must_equal " "
2019-07-23 01:44:43 +00:00
2019-08-13 02:06:23 +00:00
if is_windows?
assert_exit_code 1 , out
else
assert_exit_code 0 , out
end
2016-09-13 10:03:24 +00:00
end
end
2016-09-14 07:41:19 +00:00
2019-06-11 22:24:35 +00:00
describe " when a dependency does not support our backend platform " do
it " skips the controls from that profile " do
2019-07-18 08:20:30 +00:00
inspec ( " exec #{ File . join ( profile_path , " profile-support-skip " ) } --no-create-lockfile " )
2019-07-23 01:44:43 +00:00
2019-09-30 22:31:55 +00:00
_ ( stdout ) . must_include " WARN: Skipping profile "
_ ( stdout ) . must_include " 0 successful, 0 failures, 0 skipped \n "
2019-07-23 01:44:43 +00:00
2019-09-30 22:31:55 +00:00
_ ( stderr ) . must_equal " "
2019-07-23 01:44:43 +00:00
assert_exit_code 0 , out
2016-09-14 07:41:19 +00:00
end
end
2017-04-28 21:30:05 +00:00
2019-06-11 22:24:35 +00:00
describe " when trying to use --sudo with a local target " do
it " must print an error and exit " do
2019-07-18 08:20:30 +00:00
inspec ( " exec #{ File . join ( profile_path , " profile-support-skip " ) } --sudo " )
2017-05-31 03:38:18 +00:00
str = " Sudo is only valid when running against a remote host. To run this locally with elevated privileges, run the command with `sudo ...`. \n "
2019-07-23 01:44:43 +00:00
2019-09-30 22:31:55 +00:00
_ ( stderr ) . must_include str
2019-07-23 01:44:43 +00:00
assert_exit_code 1 , out
2019-01-08 22:12:42 +00:00
# TODO: check for stacktrace
2017-04-28 21:30:05 +00:00
end
end
2017-05-01 23:18:23 +00:00
2019-06-11 22:24:35 +00:00
describe " when --no-color is used " do
it " does not output color control characters " do
2019-07-18 08:20:30 +00:00
inspec ( " exec " + File . join ( profile_path , " simple-metadata " ) + " --no-color " )
2019-07-23 01:44:43 +00:00
2019-09-30 22:31:55 +00:00
_ ( stdout ) . wont_include " \e [38 "
2019-07-23 01:44:43 +00:00
2019-09-30 22:31:55 +00:00
_ ( stderr ) . must_equal " "
2019-07-23 01:44:43 +00:00
assert_exit_code 0 , out
2017-05-01 23:18:23 +00:00
end
end
2017-06-12 21:33:16 +00:00
2019-06-11 22:24:35 +00:00
describe " when --password is used " do
it " raises an exception if no password is provided " do
2020-01-28 23:52:02 +00:00
inspec ( " exec " + complete_profile + " --password " )
2019-07-23 01:44:43 +00:00
2019-09-30 22:31:55 +00:00
_ ( stderr ) . must_include " Please provide a value for --password. For example: --password=hello. "
2019-07-23 01:44:43 +00:00
assert_exit_code 1 , out
2017-06-12 21:33:16 +00:00
end
end
2019-06-11 22:24:35 +00:00
describe " when --sudo-password is used " do
it " raises an exception if no sudo password is provided " do
2020-01-28 23:52:02 +00:00
inspec ( " exec " + complete_profile + " --sudo-password " )
2019-07-23 01:44:43 +00:00
2019-09-30 22:31:55 +00:00
_ ( stderr ) . must_include " Please provide a value for --sudo-password. For example: --sudo-password=hello. "
2019-07-23 01:44:43 +00:00
assert_exit_code 1 , out
2017-06-12 21:33:16 +00:00
end
end
2017-08-25 20:21:49 +00:00
2019-06-11 22:24:35 +00:00
describe " when --bastion-host and --proxy_command is used " do
it " raises an exception when both flags are provided " do
2020-01-28 23:52:02 +00:00
inspec ( " exec " + complete_profile + " -t ssh://dummy@dummy --password dummy --proxy_command dummy --bastion_host dummy " )
2019-07-23 01:44:43 +00:00
2019-09-30 22:31:55 +00:00
_ ( stderr ) . must_include " Client error, can't connect to 'ssh' backend: Only one of proxy_command or bastion_host needs to be specified "
2019-07-23 01:44:43 +00:00
assert_exit_code 1 , out
2018-07-05 19:37:04 +00:00
end
end
2019-06-11 22:24:35 +00:00
describe " when --winrm-transport is used " do
it " raises an exception when an invalid transport is given " do
2020-01-28 23:52:02 +00:00
inspec ( " exec " + complete_profile + " -t winrm://administrator@dummy --password dummy --winrm-transport nonesuch " )
2019-07-23 01:44:43 +00:00
2019-09-30 22:31:55 +00:00
_ ( stderr ) . must_include " Client error, can't connect to 'winrm' backend: Unsupported transport type: :nonesuch \n "
2019-07-23 01:44:43 +00:00
assert_exit_code 1 , out
2018-12-20 16:57:53 +00:00
end
end
2019-06-11 22:24:35 +00:00
describe " with sensitive resources " do
it " hides sensitive output " do
2019-07-18 08:20:30 +00:00
inspec ( " exec " + sensitive_profile + " --no-create-lockfile " )
2019-07-23 01:44:43 +00:00
2019-12-07 00:50:09 +00:00
_ ( stdout ) . must_include '× is expected to eq "billy"'
2019-09-30 22:31:55 +00:00
_ ( stdout ) . must_include 'expected: "billy"'
_ ( stdout ) . must_include 'got: "bob"'
2019-12-07 00:50:09 +00:00
_ ( stdout ) . must_include '× is expected to eq "secret"'
2019-09-30 22:31:55 +00:00
_ ( stdout ) . must_include " *** sensitive output suppressed *** "
2019-08-12 22:13:11 +00:00
_ ( stdout ) . must_include " \n Test Summary: 2 successful, 2 failures, 0 skipped \n "
2019-07-23 01:44:43 +00:00
2019-09-30 22:31:55 +00:00
_ ( stderr ) . must_equal " "
2019-07-23 01:44:43 +00:00
assert_exit_code 100 , out
2017-08-25 20:21:49 +00:00
end
end
2018-04-26 19:44:16 +00:00
2019-06-11 22:24:35 +00:00
describe " with a profile that loads dependencies " do
let ( :out ) { inspec ( " exec " + File . join ( profile_path , " profile-support-skip " ) + " --no-create-lockfile --reporter json " ) }
2019-07-23 01:44:43 +00:00
let ( :json ) { JSON . load ( stdout ) }
2019-06-11 22:24:35 +00:00
let ( :controls ) { json [ " profiles " ] [ 0 ] [ " controls " ] }
2018-10-15 22:25:27 +00:00
2019-06-11 22:24:35 +00:00
it " skips loaded inherited profiles on unsupported platforms " do
2019-09-30 22:31:55 +00:00
_ ( json [ " profiles " ] [ 0 ] [ " depends " ] [ 0 ] [ " name " ] ) . must_equal " unsupported_inspec "
_ ( controls ) . must_be_empty
2019-07-23 01:44:43 +00:00
2019-09-30 22:31:55 +00:00
_ ( stderr ) . must_include " WARN: Skipping profile "
2018-10-15 22:25:27 +00:00
end
end
2019-06-11 22:24:35 +00:00
describe " with a profile containing exceptions in the controls " do
let ( :out ) { inspec ( " exec " + File . join ( profile_path , " exception-in-control " ) + " --no-create-lockfile --reporter json " ) }
2019-07-23 01:44:43 +00:00
let ( :json ) { JSON . load ( stdout ) }
2019-06-11 22:24:35 +00:00
let ( :controls ) { json [ " profiles " ] [ 0 ] [ " controls " ] }
2018-04-26 19:44:16 +00:00
2019-06-11 22:24:35 +00:00
it " completes the run with failed controls but no exception " do
2019-09-30 22:31:55 +00:00
_ ( stderr ) . must_be_empty
2019-07-23 01:44:43 +00:00
2019-09-30 22:31:55 +00:00
_ ( controls . count ) . must_equal 10
_ ( controls . select { | c | c [ " results " ] [ 0 ] [ " status " ] == " failed " } . count ) . must_be :> , 1
_ ( controls . select { | c | c [ " results " ] [ 0 ] [ " status " ] == " passed " } . count ) . must_be :> , 1
2019-07-23 01:44:43 +00:00
assert_exit_code 100 , out
2018-04-26 19:44:16 +00:00
end
end
2018-06-06 15:56:51 +00:00
2020-07-01 15:12:17 +00:00
describe " with a profile containing exceptions outside controls " do
let ( :out ) { inspec ( " exec " + File . join ( profile_path , " raise_outside_control " ) + " --no-create-lockfile " ) }
it " gives the failure reason " do
_ ( stdout ) . must_include " Failure Message: Failed to load source for controls/raises.rb: Something unforeseen... "
end
it " exits non-zero " do
assert_exit_code 102 , out
end
end
describe " when running both a valid profile and one that fails to load " do
let ( :out ) { inspec ( " exec " + File . join ( profile_path , " raise_outside_control " ) + " " + File . join ( profile_path , " basic_profile " ) + " --no-create-lockfile --no-color " ) }
it " gives the failure reason for the failing profile " do
_ ( stdout ) . must_include " Failure Message: Failed to load source for controls/raises.rb: Something unforeseen... "
end
it " reports results for the working profile " do
_ ( stdout ) . must_include " Profile Summary: 1 successful control "
end
it " exits non-zero " do
assert_exit_code 102 , out
end
end
2019-06-11 22:24:35 +00:00
describe " with a profile containing control overrides " do
let ( :out ) { inspec ( " exec " + File . join ( profile_path , " wrapper-override " ) + " --no-create-lockfile --vendor-cache " + File . join ( profile_path , " wrapper-override " , " vendor " ) + " --reporter json " ) }
2019-07-23 01:44:43 +00:00
let ( :json ) { JSON . load ( stdout ) }
2019-06-11 22:24:35 +00:00
let ( :controls ) { json [ " profiles " ] [ 0 ] [ " controls " ] }
let ( :child_profile ) { json [ " profiles " ] . select { | p | p [ " name " ] == " myprofile1 " } . first }
let ( :child_control ) { child_profile [ " controls " ] . select { | c | c [ " title " ] == " Profile 1 - Control 2-updated " } . first }
let ( :override ) { controls . select { | c | c [ " title " ] == " Profile 1 - Control 2-updated " } . first }
2018-06-21 17:37:47 +00:00
2019-06-11 22:24:35 +00:00
it " completes the run with parent control overrides " do
2019-09-30 22:31:55 +00:00
_ ( stderr ) . must_be_empty
2019-08-13 02:06:23 +00:00
2018-09-12 22:04:16 +00:00
if is_windows?
2019-08-13 02:06:23 +00:00
assert_exit_code 100 , out
2018-09-12 22:04:16 +00:00
else
2019-08-13 02:06:23 +00:00
assert_exit_code 0 , out
2018-09-12 22:04:16 +00:00
end
2019-08-13 02:06:23 +00:00
2019-09-30 22:31:55 +00:00
_ ( controls . count ) . must_equal 2
2018-06-21 17:37:47 +00:00
# check for json override
2019-05-31 21:59:06 +00:00
# TODO: Brittle test expects the leading spaces.
expected_value = <<-END
2019-06-11 23:13:05 +00:00
control 'pro1-con2' do
2019-05-31 21:59:06 +00:00
impact 0 . 999
2019-06-11 23:13:05 +00:00
title 'Profile 1 - Control 2-updated'
desc 'Profile 1 - Control 2 description-updated'
desc 'overwrite me' , 'it is overwritten'
desc 'new entry' , 'this is appended to the description list'
tag 'password-updated'
ref 'Section 3.5.2.1' , url : 'https://example.com'
describe file ( '/etc/passwd' ) do
2019-05-31 21:59:06 +00:00
it { should exist }
end
end
END
2019-09-30 22:31:55 +00:00
_ ( override [ " code " ] ) . must_equal expected_value
_ ( override [ " impact " ] ) . must_equal 0 . 999
_ ( override [ " descriptions " ] ) . must_equal ( [
2019-06-11 22:24:35 +00:00
{ " label " = > " default " ,
" data " = > " Profile 1 - Control 2 description-updated " ,
2018-09-26 17:28:58 +00:00
} ,
2019-06-11 22:24:35 +00:00
{ " label " = > " overwrite me " ,
" data " = > " it is overwritten " ,
2018-09-26 17:28:58 +00:00
} ,
2019-06-11 22:24:35 +00:00
{ " label " = > " new entry " ,
" data " = > " this is appended to the description list " ,
2018-09-26 17:28:58 +00:00
} ,
] )
2019-09-30 22:31:55 +00:00
_ ( override [ " title " ] ) . must_equal " Profile 1 - Control 2-updated "
2019-06-11 22:24:35 +00:00
tags_assert = { " password " = > nil , " password-updated " = > nil }
2019-09-30 22:31:55 +00:00
_ ( override [ " tags " ] ) . must_equal tags_assert
_ ( child_profile [ " parent_profile " ] ) . must_equal " wrapper-override "
2018-08-02 18:39:11 +00:00
# check for original code on child profile
2019-05-31 21:59:06 +00:00
expected_value = << ~ END
2019-06-11 23:13:05 +00:00
control 'pro1-con2' do
2019-06-01 20:08:50 +00:00
impact 0 . 9
2019-06-11 23:13:05 +00:00
title 'Profile 1 - Control 2'
desc 'Profile 1 - Control 2 description'
desc 'overwrite me' , 'overwrite this'
tag 'password'
describe file ( '/etc/passwdddddddddd' ) do
2019-06-01 20:08:50 +00:00
it { should exist }
end
2019-05-31 21:59:06 +00:00
end
END
2019-09-30 22:31:55 +00:00
_ ( child_control [ " code " ] ) . must_equal expected_value
2019-07-23 01:44:43 +00:00
2019-09-30 22:31:55 +00:00
_ ( stderr ) . must_be_empty
2019-07-23 01:44:43 +00:00
if is_windows?
assert_exit_code 100 , out
else
assert_exit_code 0 , out
end
2018-06-21 17:37:47 +00:00
end
end
2019-06-11 22:24:35 +00:00
describe " when using multiple custom resources with each other " do
let ( :out ) { inspec ( " exec " + File . join ( examples_path , " custom-resource " ) + " --no-create-lockfile " ) }
2018-06-06 15:56:51 +00:00
2019-06-11 22:24:35 +00:00
it " completes the run with failed controls but no exception " do
2019-09-30 22:31:55 +00:00
_ ( stderr ) . must_be_empty
2019-07-23 01:44:43 +00:00
assert_exit_code 0 , out
2018-06-06 15:56:51 +00:00
end
end
2018-09-10 18:37:43 +00:00
2019-06-11 22:24:35 +00:00
describe " when using a profile with non-UTF characters and wrong encoding " do
let ( :out ) { inspec ( " exec " + File . join ( profile_path , " wrong-char-profile " ) + " --no-create-lockfile " ) }
2018-09-10 18:37:43 +00:00
2019-06-11 22:24:35 +00:00
it " completes the run with failed controls but no exception " do
2019-09-30 22:31:55 +00:00
_ ( stderr ) . must_be_empty
2019-07-23 01:44:43 +00:00
assert_exit_code 0 , out
2018-09-10 18:37:43 +00:00
end
end
2018-11-07 18:59:48 +00:00
2019-06-11 22:24:35 +00:00
describe " when targeting private GitHub profiles " do
let ( :private_profile ) do
URI . parse ( " https://github.com/chef/inspec-test-profile-private.git " )
end
2018-11-08 20:55:15 +00:00
# This tests requires that a private SSH key be provided for a user that has
# access to the private profile repo
2019-06-11 22:24:35 +00:00
if ENV [ " INSPEC_TEST_SSH_KEY_PATH " ]
it " can use SSH + Git " do
target = " git@ " + private_profile . host + " : " + private_profile . path
2018-11-08 20:55:15 +00:00
ssh_prefix = 'GIT_SSH_COMMAND="ssh -i ' +
2019-06-11 22:24:35 +00:00
ENV [ " INSPEC_TEST_SSH_KEY_PATH " ] +
'"'
inspec_command = " exec " + target + " --reporter json-min "
2019-07-18 08:20:30 +00:00
inspec ( inspec_command , ssh_prefix )
2019-07-23 01:44:43 +00:00
2019-09-30 22:31:55 +00:00
_ ( JSON . parse ( stdout ) [ " controls " ] [ 0 ] [ " status " ] ) . must_equal " passed "
2019-07-23 01:44:43 +00:00
2019-09-30 22:31:55 +00:00
_ ( stderr ) . must_equal " "
2019-07-23 01:44:43 +00:00
assert_exit_code 0 , out
2018-11-08 20:55:15 +00:00
end
end
# This tests requires that a GitHub API token be provided for a user that
# has access to the private profile repo
2019-06-11 22:24:35 +00:00
if ENV [ " INSPEC_TEST_GITHUB_TOKEN " ]
it " can use HTTPS + token + Git " do
private_profile . userinfo = ENV [ " INSPEC_TEST_GITHUB_TOKEN " ]
inspec_command = " exec " + private_profile . to_s + " --reporter json-min "
2019-07-18 08:20:30 +00:00
inspec ( inspec_command )
2019-07-23 01:44:43 +00:00
2019-09-30 22:31:55 +00:00
_ ( JSON . parse ( stdout ) [ " controls " ] [ 0 ] [ " status " ] ) . must_equal " passed "
2019-07-23 01:44:43 +00:00
2019-09-30 22:31:55 +00:00
_ ( stderr ) . must_equal " "
2019-07-23 01:44:43 +00:00
assert_exit_code 0 , out
2018-11-08 20:55:15 +00:00
end
end
end
2019-01-08 22:12:42 +00:00
2019-06-11 22:24:35 +00:00
describe " when specifying a config file " do
let ( :run_result ) { run_inspec_process ( " exec " + File . join ( profile_path , " simple-metadata " ) + " " + cli_args , json : true , env : env ) }
2019-10-21 23:13:03 +00:00
let ( :seen_target_id ) { @json [ " platform " ] [ " target_id " ] }
2019-01-08 22:12:42 +00:00
let ( :stderr ) { run_result . stderr }
let ( :env ) { { } }
2019-06-11 22:24:35 +00:00
describe " when using the legacy --json-config option " do
let ( :cli_args ) { " --json-config " + File . join ( config_dir_path , " json-config " , " good.json " ) }
it " should see the custom target ID value " do
2019-09-30 22:31:55 +00:00
_ ( stderr ) . must_be_empty # TODO: one day deprecate the --json-config option
_ ( seen_target_id ) . must_equal " from-config-file "
2019-01-08 22:12:42 +00:00
end
end
2019-06-11 22:24:35 +00:00
describe " when using the --config option to read from a custom file " do
let ( :cli_args ) { " --config " + File . join ( config_dir_path , " json-config " , " good.json " ) }
it " should see the custom target ID value " do
2019-09-30 22:31:55 +00:00
_ ( stderr ) . must_be_empty
_ ( seen_target_id ) . must_equal " from-config-file "
2019-01-08 22:12:42 +00:00
end
end
2019-02-01 18:00:46 +00:00
unless windows?
2019-06-11 22:24:35 +00:00
describe " when using the --config option to read from STDIN " do
let ( :json_path ) { File . join ( config_dir_path , " json-config " , " good.json " ) }
let ( :cli_args ) { " --config - " }
let ( :opts ) { { prefix : " cat " + json_path + " | " , json : true , env : env } }
2019-10-10 23:40:23 +00:00
let ( :njopts ) { opts . merge ( json : false ) }
2019-02-08 17:03:57 +00:00
# DO NOT use the `let`-defined run_result through here
# If you do, it will execute twice, and cause STDIN to read empty on the second time
2019-06-11 22:24:35 +00:00
it " exec should see the custom target ID value " do
result = run_inspec_process ( " exec " + File . join ( profile_path , " simple-metadata " ) + " " + cli_args + " " , opts )
2019-07-23 01:44:43 +00:00
2019-09-30 22:31:55 +00:00
_ ( result . stderr ) . must_be_empty
2019-10-21 23:13:03 +00:00
_ ( @json [ " platform " ] [ " target_id " ] ) . must_equal " from-config-file "
2019-02-01 18:00:46 +00:00
end
2019-02-08 17:03:57 +00:00
2019-06-11 22:24:35 +00:00
it " detect should exit 0 " do
2019-10-10 23:40:23 +00:00
result = run_inspec_process ( " detect " + cli_args + " " , njopts )
2019-07-23 01:44:43 +00:00
2019-09-30 22:31:55 +00:00
_ ( result . stderr ) . must_be_empty
2019-07-23 01:44:43 +00:00
assert_exit_code 0 , result
2019-02-08 17:03:57 +00:00
end
2019-06-11 22:24:35 +00:00
it " shell should exit 0 " do
2019-10-10 23:40:23 +00:00
result = run_inspec_process ( 'shell -c "platform.family" ' + cli_args + " " , njopts )
2019-07-23 01:44:43 +00:00
2019-09-30 22:31:55 +00:00
_ ( result . stderr ) . must_be_empty
2019-07-23 01:44:43 +00:00
assert_exit_code 0 , result
2019-02-01 18:00:46 +00:00
end
end
end
2019-01-08 22:12:42 +00:00
2019-06-11 22:24:35 +00:00
describe " when reading from the default location " do
2019-01-08 22:12:42 +00:00
# Should read from File.join(config_dir_path, 'fakehome-2', '.inspec', 'config.json')
2019-06-11 22:24:35 +00:00
let ( :env ) { { " HOME " = > File . join ( config_dir_path , " fakehome-2 " ) } }
let ( :cli_args ) { " " }
it " should see the homedir target ID value " do
2019-09-30 22:31:55 +00:00
_ ( stderr ) . must_be_empty
2019-07-23 01:44:43 +00:00
2019-09-30 22:31:55 +00:00
_ ( seen_target_id ) . must_equal " from-fakehome-config-file "
2019-01-08 22:12:42 +00:00
end
end
2019-06-11 22:24:35 +00:00
describe " when --config points to a nonexistant location " do
let ( :cli_args ) { " --config " + " no/such/path " }
it " should issue an error with the file path " do
2019-09-30 22:31:55 +00:00
_ ( stderr ) . wont_match looks_like_a_stacktrace
_ ( stderr ) . must_include " Could not read configuration file " # Should specify error
_ ( stderr ) . must_include " no/such/path " # Should include error value seen
2019-07-23 01:44:43 +00:00
assert_exit_code 1 , run_result
2019-01-08 22:12:42 +00:00
end
end
2019-06-11 22:24:35 +00:00
describe " when --config points to a malformed file " do
let ( :cli_args ) { " --config " + File . join ( config_dir_path , " json-config " , " malformed.json " ) }
it " should issue an error with the parse message " do
2019-09-30 22:31:55 +00:00
_ ( stderr ) . wont_match looks_like_a_stacktrace
_ ( stderr ) . must_include " Failed to load JSON "
_ ( stderr ) . must_include " Config was: "
2019-07-23 01:44:43 +00:00
assert_exit_code 1 , run_result
2019-01-08 22:12:42 +00:00
end
end
2019-06-11 22:24:35 +00:00
describe " when --config points to an invalid file " do
let ( :cli_args ) { " --config " + File . join ( config_dir_path , " json-config " , " invalid.json " ) }
it " should issue an error with the parse message " do
2019-09-30 22:31:55 +00:00
_ ( stderr ) . wont_match looks_like_a_stacktrace
_ ( stderr ) . must_include " Unrecognized top-level configuration "
_ ( stderr ) . must_include " this_key_is_invalid "
2019-07-23 01:44:43 +00:00
assert_exit_code 1 , run_result
2019-01-08 22:12:42 +00:00
end
end
end
2019-06-11 22:24:35 +00:00
describe " when specifying the execution target " do
2019-01-08 22:12:42 +00:00
let ( :local_plat ) do
2019-06-11 22:24:35 +00:00
json = run_inspec_process ( " detect --format json " , { } ) . stdout
2019-01-08 22:12:42 +00:00
# .slice is available in ruby 2.5+
2019-06-11 22:24:35 +00:00
JSON . parse ( json ) . select { | k , v | %w{ name release } . include? k }
2019-01-08 22:12:42 +00:00
end
2019-06-11 22:24:35 +00:00
let ( :run_result ) { run_inspec_process ( " exec " + File . join ( profile_path , " simple-metadata " ) + " " + cli_args , json : true ) }
2019-10-21 23:13:03 +00:00
let ( :seen_platform ) { run_result ; @json [ " platform " ] . select { | k , v | %w{ name release target_id } . include? k } }
2019-01-08 22:12:42 +00:00
let ( :stderr ) { run_result . stderr }
2019-06-11 22:24:35 +00:00
describe " when neither target nor backend is specified " do
let ( :cli_args ) { " " }
it " should connect to the local platform " do
2019-09-30 22:31:55 +00:00
_ ( seen_platform ) . must_equal local_plat
2019-01-08 22:12:42 +00:00
end
end
2019-06-11 22:24:35 +00:00
describe " when local:// is specified " do
let ( :cli_args ) { " -t local:// " }
it " should connect to the local platform " do
2019-09-30 22:31:55 +00:00
_ ( seen_platform ) . must_equal local_plat
2019-01-08 22:12:42 +00:00
end
end
2019-06-11 22:24:35 +00:00
describe " when an unrecognized backend is specified " do
let ( :cli_args ) { " -b garble " }
it " should exit with an error " do
2019-09-30 22:31:55 +00:00
_ ( stderr ) . wont_match looks_like_a_stacktrace
2019-01-08 22:12:42 +00:00
# "Can't find train plugin garble. Please install it first"
2019-09-30 22:31:55 +00:00
_ ( stderr ) . must_include " Can't find train plugin "
_ ( stderr ) . must_include " garble "
2019-07-23 01:44:43 +00:00
assert_exit_code 1 , run_result
2019-01-08 22:12:42 +00:00
end
end
2019-06-11 22:24:35 +00:00
describe " when an unrecognized target schema is specified " do
let ( :cli_args ) { " -t garble:// " }
it " should exit with an error " do
2019-09-30 22:31:55 +00:00
_ ( stderr ) . wont_match looks_like_a_stacktrace
2019-01-08 22:12:42 +00:00
# "Can't find train plugin garble. Please install it first"
2019-09-30 22:31:55 +00:00
_ ( stderr ) . must_include " Can't find train plugin "
_ ( stderr ) . must_include " garble "
2019-07-23 01:44:43 +00:00
assert_exit_code 1 , run_result
2019-01-08 22:12:42 +00:00
end
end
2019-06-11 22:24:35 +00:00
describe " when a schemaless URI is specified " do
let ( :cli_args ) { " -t garble " }
it " should exit with an error " do
2019-09-30 22:31:55 +00:00
_ ( stderr ) . wont_match looks_like_a_stacktrace
2019-01-08 22:12:42 +00:00
# "Could not recognize a backend from the target garble - use a URI
# format with the backend name as the URI schema. Example: 'ssh://somehost.com'
# or 'transport://credset' or 'transport://' if credentials are provided
# outside of InSpec."
2019-09-30 22:31:55 +00:00
_ ( stderr ) . must_include " Could not recognize a backend "
_ ( stderr ) . must_include " garble "
_ ( stderr ) . must_include " ssh://somehost.com "
_ ( stderr ) . must_include " transport://credset "
2019-07-23 01:44:43 +00:00
assert_exit_code 1 , run_result
2019-01-08 22:12:42 +00:00
end
end
2019-01-09 06:58:28 +00:00
2019-06-11 22:24:35 +00:00
describe " when a target URI with a known credset is used " do
let ( :cli_args ) { " --target mock://mycredset " + " --config " + File . join ( config_dir_path , " json-config " , " mock-credset.json " ) }
it " should connect to the mock platform " do
2019-09-30 22:31:55 +00:00
_ ( seen_platform ) . must_equal ( { " name " = > " mock " , " release " = > " unknown " , " target_id " = > " from-mock-credset-config-file " } )
2019-01-09 06:58:28 +00:00
end
end
2019-01-08 22:12:42 +00:00
end
2020-02-26 19:41:38 +00:00
describe " when targeting cloud resource packs " do
let ( :cloud_path ) { profile_path + " /cloud/ " }
let ( :run_result ) { run_inspec_process ( " exec " + cloud_profile + " " + args , env : env ) }
let ( :env ) { { } }
describe " when targeting aws " do
let ( :cloud_profile ) { cloud_path + " test-aws " }
# Use log level FATAL to absorb WARNs from deprecataions and ERRORs from not having credentials set.
# An actual stacktrace then will appear as sole stderr output
let ( :args ) { " -t aws://fakecreds --log-level fatal " }
it " should fail to connect to aws due to lack of creds but not stacktrace " do
_ ( run_result . stderr ) . must_be_empty
end
end
describe " when targeting azure " do
let ( :cloud_profile ) { cloud_path + " test-azure " }
let ( :args ) { " -t azure:// " }
it " should fail to connect to azure due to lack of creds but not stacktrace " do
2020-03-02 19:32:12 +00:00
_ ( run_result . stderr ) . must_equal " Tenant id cannot be nil \n "
2020-02-26 19:41:38 +00:00
end
end
describe " when targeting gcp " do
let ( :cloud_profile ) { cloud_path + " test-gcp " }
let ( :args ) { " -t gcp:// --input gcp_project_id=fakeproject " }
let ( :env ) { { GOOGLE_AUTH_SUPPRESS_CREDENTIALS_WARNINGS : 1 } }
it " should fail to connect to gcp due to lack of creds but not stacktrace " do
2020-03-02 19:32:12 +00:00
_ ( run_result . stderr ) . must_include " Could not load the default credentials. "
2020-02-26 19:41:38 +00:00
end
end
end
2020-05-19 22:49:03 +00:00
describe " when evaluating profiles with only_if " do
let ( :run_result ) { run_inspec_process ( " exec #{ profile } " , json : true ) }
describe " when running a profile with a variety of skips " do
let ( :profile ) { " #{ profile_path } /only_if/skip-control " }
it " should correctly skip in individual controls " do
run_result
_ ( @json . dig ( " profiles " , 0 , " controls " , 0 , " results " , 0 , " status " ) ) . must_equal " passed "
_ ( @json . dig ( " profiles " , 0 , " controls " , 1 , " results " , 0 , " status " ) ) . must_equal " skipped "
_ ( @json . dig ( " profiles " , 0 , " controls " , 1 , " results " , 0 , " skip_message " ) ) . must_equal " Skipped control due to only_if condition. "
_ ( @json . dig ( " profiles " , 0 , " controls " , 2 , " results " , 0 , " status " ) ) . must_equal " skipped "
_ ( @json . dig ( " profiles " , 0 , " controls " , 2 , " results " , 0 , " skip_message " ) ) . must_equal " Skipped control due to only_if condition: here is a message "
# 1/0 in test body
_ ( @json . dig ( " profiles " , 0 , " controls " , 3 , " results " , 0 , " status " ) ) . must_equal " skipped "
_ ( @json . dig ( " profiles " , 0 , " controls " , 3 , " results " , 0 , " skip_message " ) ) . must_equal " Skipped control due to only_if condition. "
# 1/0 in resource declaration but it follows the only_if
_ ( @json . dig ( " profiles " , 0 , " controls " , 4 , " results " , 0 , " status " ) ) . must_equal " skipped "
_ ( @json . dig ( " profiles " , 0 , " controls " , 4 , " results " , 0 , " skip_message " ) ) . must_equal " Skipped control due to only_if condition. "
2020-05-22 16:09:27 +00:00
# resource declaration but it precedes the only_if
2020-05-22 16:16:04 +00:00
_ ( @json . dig ( " profiles " , 0 , " controls " , 5 , " results " , 0 , " status " ) ) . must_equal " skipped "
_ ( @json . dig ( " profiles " , 0 , " controls " , 5 , " results " , 0 , " skip_message " ) ) . must_equal " Skipped control due to only_if condition. "
2020-05-22 16:09:27 +00:00
# multiple only_ifs
2020-05-22 16:16:04 +00:00
_ ( @json . dig ( " profiles " , 0 , " controls " , 6 , " results " , 0 , " status " ) ) . must_equal " skipped "
_ ( @json . dig ( " profiles " , 0 , " controls " , 6 , " results " , 0 , " skip_message " ) ) . must_equal " Skipped control due to only_if condition: here is a different message "
2020-05-19 22:49:03 +00:00
end
end
describe " when running a profile with an only_if at the top-level " do
let ( :profile ) { " #{ profile_path } /only_if/skip-file " }
it " should correctly skip entire files " do
run_result
# first control is in a separate file
_ ( @json . dig ( " profiles " , 0 , " controls " , 0 , " results " , 0 , " status " ) ) . must_equal " passed "
# Latter three are in the same file
_ ( @json . dig ( " profiles " , 0 , " controls " , 1 , " results " , 0 , " status " ) ) . must_equal " skipped "
_ ( @json . dig ( " profiles " , 0 , " controls " , 2 , " results " , 0 , " status " ) ) . must_equal " skipped "
_ ( @json . dig ( " profiles " , 0 , " controls " , 3 , " results " , 0 , " status " ) ) . must_equal " skipped "
end
end
end
2016-03-25 00:31:19 +00:00
end