2019-06-11 22:24:35 +00:00
require " functional/helper "
require " mixlib/shellout "
2019-07-24 18:10:15 +00:00
require " json_schemer "
2016-03-25 00:31:19 +00:00
2019-06-11 22:24:35 +00:00
describe " inspec json " do
2016-03-25 00:31:19 +00:00
include FunctionalHelper
2019-09-17 00:40:51 +00:00
parallelize_me!
2019-06-11 22:24:35 +00:00
it " read the profile json " do
out = inspec ( " json " + example_profile )
2019-09-30 22:31:55 +00:00
_ ( out . stderr ) . must_equal " "
2019-07-23 01:44:43 +00:00
assert_exit_code 0 , out
2016-03-25 00:31:19 +00:00
s = out . stdout
2019-09-30 22:31:55 +00:00
_ ( JSON . load ( s ) ) . must_be_kind_of Hash
2016-03-25 00:31:19 +00:00
end
2019-06-11 22:24:35 +00:00
describe " json profile data " do
let ( :json ) { JSON . load ( inspec ( " json " + example_profile ) . stdout ) }
2016-03-25 00:31:19 +00:00
2019-06-11 22:24:35 +00:00
it " has a generator name " do
2019-09-30 22:31:55 +00:00
_ ( json [ " generator " ] [ " name " ] ) . must_equal " inspec "
2018-02-08 09:06:58 +00:00
end
2019-06-11 22:24:35 +00:00
it " has a generator inspec version " do
2019-09-30 22:31:55 +00:00
_ ( json [ " generator " ] [ " version " ] ) . must_equal Inspec :: VERSION
2018-02-08 09:06:58 +00:00
end
2022-05-12 07:55:33 +00:00
it " has empty array of inputs " do
_ ( json [ " inputs " ] ) . must_be_empty
end
2019-06-11 22:24:35 +00:00
it " has a name " do
2019-09-30 22:31:55 +00:00
_ ( json [ " name " ] ) . must_equal " profile "
2016-03-25 00:31:19 +00:00
end
2019-06-11 22:24:35 +00:00
it " has a title " do
2019-09-30 22:31:55 +00:00
_ ( json [ " title " ] ) . must_equal " InSpec Example Profile "
2016-03-25 00:31:19 +00:00
end
2019-06-11 22:24:35 +00:00
it " has a summary " do
2019-09-30 22:31:55 +00:00
_ ( json [ " summary " ] ) . must_equal " Demonstrates the use of InSpec Compliance Profile "
2016-03-25 00:31:19 +00:00
end
2019-06-11 22:24:35 +00:00
it " has a version " do
2019-09-30 22:31:55 +00:00
_ ( json [ " version " ] ) . must_equal " 1.0.0 "
2016-03-25 00:31:19 +00:00
end
2019-06-11 22:24:35 +00:00
it " has a maintainer " do
2019-09-30 22:31:55 +00:00
_ ( json [ " maintainer " ] ) . must_equal " Chef Software, Inc. "
2016-03-25 00:31:19 +00:00
end
2019-06-11 22:24:35 +00:00
it " has a copyright " do
2019-09-30 22:31:55 +00:00
_ ( json [ " copyright " ] ) . must_equal " Chef Software, Inc. "
2016-03-25 00:31:19 +00:00
end
2019-06-11 22:24:35 +00:00
it " has controls " do
2020-01-28 23:52:02 +00:00
_ ( json [ " controls " ] . length ) . must_equal 4
2016-03-25 00:31:19 +00:00
end
2019-06-11 22:24:35 +00:00
describe " a control " do
let ( :control ) { json [ " controls " ] . find { | x | x [ " id " ] == " tmp-1.0 " } }
2016-03-25 00:31:19 +00:00
2019-06-11 22:24:35 +00:00
it " has a title " do
2019-11-06 22:42:44 +00:00
_ ( control [ " title " ] ) . must_equal " Create / directory "
2016-03-25 00:31:19 +00:00
end
2019-06-11 22:24:35 +00:00
it " has a description " do
2019-09-30 22:31:55 +00:00
_ ( control [ " desc " ] ) . must_equal " An optional description... "
2016-03-25 00:31:19 +00:00
end
2019-06-11 22:24:35 +00:00
it " has an impact " do
2019-09-30 22:31:55 +00:00
_ ( control [ " impact " ] ) . must_equal 0 . 7
2016-03-25 00:31:19 +00:00
end
2019-06-11 22:24:35 +00:00
it " has a ref " do
2019-09-30 22:31:55 +00:00
_ ( control [ " refs " ] ) . must_equal ( [ { " ref " = > " Document A-12 " , " url " = > " http://... " } ] )
2016-03-25 00:31:19 +00:00
end
2019-06-11 22:24:35 +00:00
it " has a source location " do
2019-10-11 05:47:02 +00:00
loc = File . join ( example_profile , " /controls/example-tmp.rb " )
2019-09-30 22:31:55 +00:00
_ ( control [ " source_location " ] [ " ref " ] ) . must_equal loc
_ ( control [ " source_location " ] [ " line " ] ) . must_equal 6
2016-03-25 00:31:19 +00:00
end
2019-06-11 22:24:35 +00:00
it " has a the source code " do
2019-09-30 22:31:55 +00:00
_ ( control [ " code " ] ) . must_match ( / \ Acontrol 'tmp-1.0' do.*end \ n \ Z /m )
2016-03-25 00:31:19 +00:00
end
end
end
2022-05-12 07:55:33 +00:00
describe " json profile data with inputs " do
let ( :json ) { JSON . load ( inspec ( " json " + examples_path + " /profile-attribute " ) . stdout ) }
it " has a inputs " do
_ ( json [ " inputs " ] ) . must_equal [ { " name " = > " user " , " options " = > { " value " = > " alice " } } , { " name " = > " password " , " options " = > { " value " = > " Input 'password' does not have a value. Skipping test. " } } ]
end
end
2019-06-11 22:24:35 +00:00
describe " filter with --controls " do
let ( :out ) { inspec ( " json " + example_profile + " --controls tmp-1.0 " ) }
2016-03-25 00:58:59 +00:00
2019-06-11 22:24:35 +00:00
it " still succeeds " do
2019-09-30 22:31:55 +00:00
_ ( out . stderr ) . must_equal " "
2019-07-23 01:44:43 +00:00
assert_exit_code 0 , out
2016-03-25 00:58:59 +00:00
end
2019-06-11 22:24:35 +00:00
it " only has one control included " do
2016-03-25 00:58:59 +00:00
json = JSON . load ( out . stdout )
2019-09-30 22:31:55 +00:00
_ ( json [ " controls " ] . length ) . must_equal 1
_ ( json [ " controls " ] [ 0 ] [ " id " ] ) . must_equal " tmp-1.0 "
_ ( json [ " groups " ] . length ) . must_equal 1
2019-10-11 05:47:02 +00:00
_ ( json [ " groups " ] [ 0 ] [ " id " ] ) . must_equal " controls/example-tmp.rb "
2016-03-25 00:58:59 +00:00
end
end
2019-06-11 22:24:35 +00:00
it " writes json to file " do
out = inspec ( " json " + example_profile + " --output " + dst . path )
2019-07-23 01:44:43 +00:00
2016-03-25 00:31:19 +00:00
hm = JSON . load ( File . read ( dst . path ) )
2020-01-28 23:52:02 +00:00
_ ( hm [ " name " ] ) . must_equal " profile "
_ ( hm [ " controls " ] . length ) . must_equal 4
2019-07-23 01:44:43 +00:00
2020-05-04 15:42:59 +00:00
_ ( out . stderr ) . must_include " ----> creating #{ dst . path } "
2019-07-23 01:44:43 +00:00
assert_exit_code 0 , out
2016-03-25 00:31:19 +00:00
end
2017-10-10 09:36:57 +00:00
2019-06-11 22:24:35 +00:00
describe " json test for pax header archives " do
2017-10-10 09:36:57 +00:00
let ( :profile_tgz ) { File . join ( Dir . mktmpdir , " pax-profile-test.tar.gz " ) }
2019-06-11 22:24:35 +00:00
it " successfully reads a pax-formatted tar file " do
2018-11-08 17:00:14 +00:00
# TODO: this needs updated to also support windows taring
return if is_windows?
2019-07-09 00:20:30 +00:00
2017-10-10 09:36:57 +00:00
files = Dir . glob ( " #{ example_profile } /**/* " ) . delete_if { | x | ! File . file? ( x ) }
relatives = files . map { | e | Pathname . new ( e ) . relative_path_from ( Pathname . new ( example_profile ) ) . to_s }
2019-07-09 00:20:30 +00:00
cmd = Mixlib :: ShellOut . new ( " tar --format=pax -czf #{ profile_tgz } #{ relatives . join ( " " ) } " , cwd : example_profile )
2017-10-10 09:36:57 +00:00
cmd . run_command
cmd . error!
out = inspec ( " json #{ profile_tgz } " )
2019-07-23 01:44:43 +00:00
assert_exit_code 0 , out
2017-10-10 09:36:57 +00:00
end
end
2018-01-03 17:10:35 +00:00
2019-06-11 22:24:35 +00:00
describe " inspec json with a inheritance profile " do
let ( :profile ) { File . join ( profile_path , " export-json " , " empty-wrapper " ) }
2018-09-12 22:02:24 +00:00
2019-06-11 22:24:35 +00:00
it " can export a profile that uses inheritance " do
out = inspec ( " json " + profile )
2018-09-12 22:02:24 +00:00
2019-01-05 17:21:34 +00:00
# This will throw an exception if it is garbled
2018-09-12 22:02:24 +00:00
json = JSON . load ( out . stdout )
2019-01-05 17:21:34 +00:00
# and here we verify (very passingly!) that is a structure we expect
2019-09-30 22:31:55 +00:00
_ ( json ) . must_be_kind_of Hash
2019-01-05 17:21:34 +00:00
2019-06-11 22:24:35 +00:00
json [ " controls " ] . each do | control |
2019-09-30 22:31:55 +00:00
_ ( control [ " code " ] . empty? ) . must_equal false
2018-09-12 22:02:24 +00:00
end
2019-07-23 01:44:43 +00:00
2019-09-30 22:31:55 +00:00
_ ( out . stderr ) . must_be_empty
2019-07-23 01:44:43 +00:00
assert_exit_code 0 , out
2018-09-12 22:02:24 +00:00
end
end
2019-06-11 22:24:35 +00:00
describe " inspec json does not write logs to STDOUT " do
it " can execute a profile with warn calls and parse STDOUT as valid JSON " do
out = inspec ( " json " + File . join ( profile_path , " warn_logs " ) )
2019-07-23 01:44:43 +00:00
assert_equal " warn_logs " , JSON . load ( out . stdout ) [ " name " ]
2019-09-30 22:31:55 +00:00
_ ( out . stderr ) . must_include " This is a warn call "
2019-07-23 01:44:43 +00:00
assert_exit_code 0 , out
2018-09-13 17:05:10 +00:00
end
end
2019-06-11 22:24:35 +00:00
describe " inspec json with a profile containing only_if " do
it " ignores the `only_if` " do
out = inspec ( " json " + File . join ( profile_path , " only-if-os-nope " ) )
2019-07-23 01:44:43 +00:00
assert_equal " only-if-os-nope " , JSON . load ( out . stdout ) [ " name " ]
2019-09-30 22:31:55 +00:00
_ ( out . stderr ) . must_equal " "
2019-07-23 01:44:43 +00:00
assert_exit_code 0 , out
2018-01-03 17:10:35 +00:00
end
end
2019-07-24 18:10:15 +00:00
it " can format a profile and validate the json schema " do
out = inspec ( " json " + example_profile )
data = JSON . parse ( out . stdout )
sout = inspec ( " schema profile-json " )
schema = JSONSchemer . schema ( sout . stdout )
2020-01-28 23:52:02 +00:00
_ ( schema . validate ( data ) . to_a ) . must_equal [ ]
2019-07-24 18:10:15 +00:00
2020-01-28 23:52:02 +00:00
_ ( out . stderr ) . must_equal " "
2019-07-24 18:10:15 +00:00
assert_exit_code 0 , out
end
it " properly validates all (valid) unit tests against the schema " do
schema = JSONSchemer . schema ( JSON . parse ( inspec ( " schema profile-json " ) . stdout ) )
2020-01-28 23:52:02 +00:00
all_profile_folders . first ( 1 ) . each do | folder |
2021-05-10 03:59:04 +00:00
out = inspec ( " json " + folder )
# Ensure it parses properly; discard the result
out = JSON . parse ( out . stdout )
failures = schema . validate ( out ) . to_a
_ ( failures ) . must_equal [ ]
rescue JSON :: ParserError
# We don't actually care about these; cannot validate if parsing fails!
nil
2019-07-24 18:10:15 +00:00
end
end
2016-03-25 00:31:19 +00:00
end