2019-06-11 22:24:35 +00:00
require " functional/helper "
2016-08-19 22:58:39 +00:00
2019-06-11 22:24:35 +00:00
describe " inspec shell tests " do
2016-08-19 22:58:39 +00:00
include FunctionalHelper
2021-04-08 07:28:36 +00:00
let ( :input_file_from_basic_input_profile ) { File . join ( profile_path , " inputs " , " basic " , " files " , " flat.yaml " ) }
2016-08-19 22:58:39 +00:00
2019-09-14 00:54:06 +00:00
parallelize_me!
2019-06-11 22:24:35 +00:00
describe " cmd " do
2019-07-24 23:51:18 +00:00
def assert_shell_c ( code , exit_status , json = false , stderr = " " )
2018-02-08 09:06:58 +00:00
json_suffix = " --reporter 'json' " if json
2019-07-09 00:20:30 +00:00
command = " shell -c ' #{ code . tr ( " ' " , '\\\'' ) } ' #{ json_suffix } "
2020-08-17 12:27:58 +00:00
# On darwin this value is:
# shell -c 'describe file(\"/Users/nickschwaderer/Documents/inspec/inspec/test/functional/inspec_shell_test.rb\") do it { should exist } end' --reporter 'json'"
# appears to break in windows.
2018-11-08 17:00:14 +00:00
out = inspec ( command )
2019-07-23 01:44:43 +00:00
2019-08-13 22:18:11 +00:00
actual = out . stderr . gsub ( / \ e \ [( \ d+)(; \ d+)*m / , " " ) # strip ANSI color codes
_ ( actual ) . must_equal stderr
2019-07-23 01:44:43 +00:00
assert_exit_code exit_status , out
2016-08-19 22:58:39 +00:00
out
end
2017-12-04 21:40:14 +00:00
2021-04-08 10:34:06 +00:00
def assert_shell_c_with_inputs ( code , input_cmd , input , exit_status , json = false , stderr = " " )
2021-04-08 07:28:36 +00:00
json_suffix = " --reporter 'json' " if json
command = " shell -c ' #{ code . tr ( " ' " , '\\\'' ) } ' #{ input_cmd } #{ input } #{ json_suffix } "
# On darwin this value is:
# shell -c 'describe file(\"/Users/nickschwaderer/Documents/inspec/inspec/test/functional/inspec_shell_test.rb\") do it { should exist } end' --reporter 'json'"
# appears to break in windows.
out = inspec ( command )
actual = out . stderr . gsub ( / \ e \ [( \ d+)(; \ d+)*m / , " " ) # strip ANSI color codes
_ ( actual ) . must_equal stderr
assert_exit_code exit_status , out
out
end
2019-06-11 22:24:35 +00:00
it " loads a dependency " do
2019-10-09 07:08:28 +00:00
res = inspec ( " shell -c 'example_config' --depends #{ example_profile } " )
2019-07-23 01:44:43 +00:00
2019-10-09 07:08:28 +00:00
_ ( res . stdout . chop ) . must_equal " example_config "
2019-07-23 01:44:43 +00:00
2019-09-30 22:31:55 +00:00
_ ( res . stderr ) . must_equal " "
2019-07-23 01:44:43 +00:00
assert_exit_code 0 , res
2018-01-04 19:39:01 +00:00
end
2019-06-11 22:24:35 +00:00
it " confirm file caching is disabled " do
2019-07-24 23:51:18 +00:00
out = assert_shell_c ( " inspec.backend.cache_enabled?(:file) " , 0 )
2019-07-23 01:44:43 +00:00
2019-09-30 22:31:55 +00:00
_ ( out . stdout . chop ) . must_equal " false "
2017-12-04 21:40:14 +00:00
end
2019-06-11 22:24:35 +00:00
it " confirm command caching is disabled " do
2019-07-24 23:51:18 +00:00
out = assert_shell_c ( " inspec.backend.cache_enabled?(:command) " , 0 )
2019-07-23 01:44:43 +00:00
2019-09-30 22:31:55 +00:00
_ ( out . stdout . chop ) . must_equal " false "
2017-12-04 21:40:14 +00:00
end
2016-08-19 22:58:39 +00:00
2019-06-11 22:24:35 +00:00
it " can run ruby expressions (json output) " do
2016-08-19 22:58:39 +00:00
x = rand
y = rand
2019-07-24 23:51:18 +00:00
out = assert_shell_c ( " #{ x } + #{ y } " , 0 , true )
2019-07-23 01:44:43 +00:00
2016-08-19 22:58:39 +00:00
j = JSON . load ( out . stdout )
2019-09-30 22:31:55 +00:00
_ ( j ) . must_equal x + y
2016-08-19 22:58:39 +00:00
end
2019-06-11 22:24:35 +00:00
it " can run ruby expressions " do
2016-08-19 22:58:39 +00:00
x = rand
y = rand
2019-07-24 23:51:18 +00:00
out = assert_shell_c ( " #{ x } + #{ y } " , 0 )
2019-07-23 01:44:43 +00:00
2019-09-30 22:31:55 +00:00
_ ( out . stdout ) . must_equal " #{ x + y } \n "
2016-08-19 22:58:39 +00:00
end
2019-06-11 22:24:35 +00:00
it " can run arbitrary ruby (json output) " do
2018-11-08 17:00:14 +00:00
# You cannot have a pipe in a windows command line
return if is_windows?
2019-07-09 00:20:30 +00:00
2019-07-24 23:51:18 +00:00
out = assert_shell_c ( " x = [1,2,3].inject(0) {|a,v| a + v*v}; x+10 " , 0 , true )
2019-07-23 01:44:43 +00:00
2016-08-19 22:58:39 +00:00
j = JSON . load ( out . stdout )
2019-09-30 22:31:55 +00:00
_ ( j ) . must_equal 24 # 1^2 + 2^2 + 3^2 + 10
2016-08-19 22:58:39 +00:00
end
2019-06-11 22:24:35 +00:00
it " can run arbitrary ruby " do
2018-11-08 17:00:14 +00:00
# You cannot have a pipe in a windows command line
return if is_windows?
2019-07-09 00:20:30 +00:00
2019-07-24 23:51:18 +00:00
out = assert_shell_c ( " x = [1,2,3].inject(0) {|a,v| a + v*v}; x+10 " , 0 )
2019-09-30 22:31:55 +00:00
_ ( out . stdout ) . must_equal " 24 \n "
2016-08-19 22:58:39 +00:00
end
2019-06-11 22:24:35 +00:00
it " retrieves resources (json output) " do
2019-07-24 23:51:18 +00:00
out = assert_shell_c ( " platform.params " , 0 , true )
2016-08-19 22:58:39 +00:00
j = JSON . load ( out . stdout )
2019-09-30 22:31:55 +00:00
_ ( j . keys ) . must_include " name "
_ ( j . keys ) . must_include " families "
_ ( j . keys ) . must_include " arch "
_ ( j . keys ) . must_include " release "
2016-08-19 22:58:39 +00:00
end
2019-06-11 22:24:35 +00:00
it " retrieves resources " do
2019-07-24 23:51:18 +00:00
out = assert_shell_c ( " os.params " , 0 )
2019-09-30 22:31:55 +00:00
_ ( out . stdout ) . must_include " name "
_ ( out . stdout ) . must_include " families "
_ ( out . stdout ) . must_include " arch "
_ ( out . stdout ) . must_include " release "
2016-08-19 22:58:39 +00:00
end
2019-06-11 22:24:35 +00:00
it " runs anonymous tests that succeed (json output) " do
2020-06-03 08:38:10 +00:00
skip_windows! # Breakage confirmed
2020-08-17 12:27:58 +00:00
# All skip_windows breakages have this output:
# Expected: ""
# C:/Users/some/path/inspec/inspec/lib/inspec/profile_context.rb:168:in `instance_eval': (eval):1: syntax error, unexpected tIDENTIFIER, expecting ')' (SyntaxError)
# describe file(" "foo/bar/baz) do it { should exis...
# ^~~
# (eval):1: syntax error, unexpected ')', expecting end-of-input
# describe file(" "foo/bar/baz) do it { should exist } end
# ^
# from C:/Users/some/path/inspec/inspec/lib/inspec/profile_context.rb:168:in `load_with_context'
# from C:/Users/some/path/inspec/inspec/lib/inspec/profile_context.rb:154:in `load_control_file'
# from C:/Users/some/path/inspec/inspec/lib/inspec/runner.rb:250:in `eval_with_virtual_profile'
# from C:/Users/some/path/inspec/inspec/lib/inspec/cli.rb:400:in `run_command'
# from C:/Users/some/path/inspec/inspec/lib/inspec/cli.rb:339:in `shell_func'
# from C:/Ruby/lib/ruby/gems/2.6.0/gems/thor-1.0.1/lib/thor/command.rb:27:in `run'
# from C:/Ruby/lib/ruby/gems/2.6.0/gems/thor-1.0.1/lib/thor/invocation.rb:127:in `invoke_command'
# from C:/Ruby/lib/ruby/gems/2.6.0/gems/thor-1.0.1/lib/thor.rb:392:in `dispatch'
# from C:/Ruby/lib/ruby/gems/2.6.0/gems/thor-1.0.1/lib/thor/base.rb:485:in `start'
# from C:/Users/some/path/inspec/inspec/lib/inspec/base_cli.rb:35:in `start'
# from C:/Users/some/path/inspec/inspec/inspec-bin/bin/inspec:11:in `<main>'
2019-07-24 23:51:18 +00:00
out = assert_shell_c ( " describe file( \" #{ __FILE__ } \" ) do it { should exist } end " , 0 , true )
2016-08-19 22:58:39 +00:00
j = JSON . load ( out . stdout )
2019-09-30 22:31:55 +00:00
_ ( j . keys ) . must_include " version "
_ ( j . keys ) . must_include " profiles "
_ ( j . keys ) . must_include " statistics "
2016-08-19 22:58:39 +00:00
end
2019-06-11 22:24:35 +00:00
it " runs anonymous tests that succeed " do
2020-06-03 08:38:10 +00:00
skip_windows! # Breakage confirmed
2019-07-24 23:51:18 +00:00
out = assert_shell_c ( " describe file( \" #{ __FILE__ } \" ) do it { should exist } end " , 0 )
2019-09-30 22:31:55 +00:00
_ ( out . stdout ) . must_include " 1 successful "
_ ( out . stdout ) . must_include " 0 failures "
2016-08-19 22:58:39 +00:00
end
2019-06-11 22:24:35 +00:00
it " runs anonymous tests that fail (json output) " do
2020-06-03 08:38:10 +00:00
skip_windows! # Breakage confirmed
2019-07-24 23:51:18 +00:00
out = assert_shell_c ( " describe file( \" foo/bar/baz \" ) do it { should exist } end " , 100 , true )
2016-08-19 22:58:39 +00:00
j = JSON . load ( out . stdout )
2019-09-30 22:31:55 +00:00
_ ( j . keys ) . must_include " version "
_ ( j . keys ) . must_include " profiles "
_ ( j . keys ) . must_include " statistics "
2016-08-19 22:58:39 +00:00
end
2019-06-11 22:24:35 +00:00
it " runs anonymous tests that fail " do
2020-06-03 08:38:10 +00:00
skip_windows! # Breakage confirmed
2019-07-24 23:51:18 +00:00
out = assert_shell_c ( " describe file( \" foo/bar/baz \" ) do it { should exist } end " , 100 )
2019-09-30 22:31:55 +00:00
_ ( out . stdout ) . must_include " 0 successful "
_ ( out . stdout ) . must_include " 1 failure "
2016-08-19 22:58:39 +00:00
end
2019-06-11 22:24:35 +00:00
it " runs controls with tests (json output) " do
2020-06-03 08:38:10 +00:00
skip_windows! # Breakage confirmed
2019-07-24 23:51:18 +00:00
out = assert_shell_c ( " control \" test \" do describe file( \" #{ __FILE__ } \" ) do it { should exist } end end " , 0 , true )
2016-08-19 22:58:39 +00:00
j = JSON . load ( out . stdout )
2019-09-30 22:31:55 +00:00
_ ( j . keys ) . must_include " version "
_ ( j . keys ) . must_include " profiles "
_ ( j . keys ) . must_include " statistics "
2016-08-19 22:58:39 +00:00
end
2019-06-11 22:24:35 +00:00
it " runs controls with tests " do
2020-06-03 08:38:10 +00:00
skip_windows! # Breakage confirmed
2019-07-24 23:51:18 +00:00
out = assert_shell_c ( " control \" test \" do describe file( \" #{ __FILE__ } \" ) do it { should exist } end end " , 0 )
2019-09-30 22:31:55 +00:00
_ ( out . stdout ) . must_include " 1 successful "
_ ( out . stdout ) . must_include " 0 failures "
2016-08-19 22:58:39 +00:00
end
2019-06-11 22:24:35 +00:00
it " runs controls with multiple tests (json output) " do
2020-06-03 08:38:10 +00:00
skip_windows! # Breakage confirmed
2019-07-24 23:51:18 +00:00
out = assert_shell_c ( " control \" test \" do describe file( \" #{ __FILE__ } \" ) do it { should exist } end; describe file( \" foo/bar/baz \" ) do it { should exist } end end " , 100 , true )
2016-08-19 22:58:39 +00:00
j = JSON . load ( out . stdout )
2019-09-30 22:31:55 +00:00
_ ( j . keys ) . must_include " version "
_ ( j . keys ) . must_include " profiles "
_ ( j . keys ) . must_include " statistics "
2016-08-19 22:58:39 +00:00
end
2019-06-11 22:24:35 +00:00
it " runs controls with multiple tests " do
2020-06-03 08:38:10 +00:00
skip_windows! # Breakage confirmed
2019-07-24 23:51:18 +00:00
out = assert_shell_c ( " control \" test \" do describe file( \" #{ __FILE__ } \" ) do it { should exist } end; describe file( \" foo/bar/baz \" ) do it { should exist } end end " , 100 )
2019-09-30 22:31:55 +00:00
_ ( out . stdout ) . must_include " 0 successful "
_ ( out . stdout ) . must_include " 1 failure "
2016-08-19 22:58:39 +00:00
end
2021-04-08 07:28:36 +00:00
it " loads input from external input file " do
skip_windows! # Breakage confirmed
out = assert_shell_c_with_inputs ( " describe input( \" a_quoted_string \" ) do it { should cmp \" Should not have quotes \" } end " , " --input-file " , input_file_from_basic_input_profile , 0 )
_ ( out . stdout ) . must_include " 1 successful "
_ ( out . stdout ) . must_include " 0 failures "
end
it " loads input from input cli " do
skip_windows! # Breakage confirmed
out = assert_shell_c_with_inputs ( " describe input( \" test_input_01 \" ) do it { should cmp \" value_from_cli_01 \" } end " , " --input " , " test_input_01='value_from_cli_01' " , 0 )
_ ( out . stdout ) . must_include " 1 successful "
_ ( out . stdout ) . must_include " 0 failures "
end
2016-08-19 22:58:39 +00:00
end
2018-11-08 17:00:14 +00:00
# Pry does not support STDIN from windows currently. Skipping these for now.
unless FunctionalHelper . is_windows?
2019-06-11 22:24:35 +00:00
describe " shell " do
2019-08-13 22:18:11 +00:00
attr_accessor :out
def stdout
out . stdout . gsub ( / \ e \ [( \ d+)(; \ d+)*m / , " " ) # strip ANSI color codes
end
def stderr
out . stderr . gsub ( / \ e \ [( \ d+)(; \ d+)*m / , " " ) # strip ANSI color codes
end
2019-06-11 22:24:35 +00:00
def do_shell ( code , exit_status = 0 , stderr = " " )
2019-07-09 00:20:30 +00:00
cmd = " echo ' #{ code . tr ( " ' " , '\\\'' ) } ' | #{ exec_inspec } shell "
2019-08-13 22:18:11 +00:00
self . out = CMD . run_command ( cmd )
2019-07-23 01:44:43 +00:00
assert_exit_code exit_status , out
2018-11-08 17:00:14 +00:00
out
end
2019-06-11 22:24:35 +00:00
it " loads a dependency " do
2019-10-09 07:08:28 +00:00
cmd = " echo 'example_config' | #{ exec_inspec } shell --depends #{ example_profile } "
2018-11-08 17:00:14 +00:00
res = CMD . run_command ( cmd )
2019-07-23 01:44:43 +00:00
2019-10-09 07:08:28 +00:00
_ ( res . stdout ) . must_include " => example_config "
2019-07-23 01:44:43 +00:00
assert_exit_code 0 , res
2018-11-08 17:00:14 +00:00
end
2019-06-11 22:24:35 +00:00
it " displays the target device information for the user without requiring the help command " do
out = do_shell ( " 1+1 " )
2019-09-30 22:31:55 +00:00
_ ( out . stdout ) . must_include " You are currently running on: "
2018-11-08 17:00:14 +00:00
end
2019-06-11 22:24:35 +00:00
it " provides a help command " do
out = do_shell ( " help " )
2019-09-30 22:31:55 +00:00
_ ( out . stdout ) . must_include " Available commands: "
_ ( out . stdout ) . must_include " You are currently running on: "
2018-11-08 17:00:14 +00:00
end
2019-06-11 22:24:35 +00:00
it " provides resource help " do
out = do_shell ( " help file " )
2019-09-30 22:31:55 +00:00
_ ( out . stdout ) . must_include " Use the file InSpec audit resource "
2018-11-08 17:00:14 +00:00
end
2019-06-11 22:24:35 +00:00
it " provides helpful feedback if an invalid resource is provided " do
out = do_shell ( " help not_a_valid_resource " )
2019-09-30 22:31:55 +00:00
_ ( out . stdout ) . must_include " The resource not_a_valid_resource does not exist. "
2018-11-08 17:00:14 +00:00
end
2019-06-11 22:24:35 +00:00
it " provides a list of resources " do
out = do_shell ( " help resources " )
2019-09-30 22:31:55 +00:00
_ ( out . stdout ) . must_include " - command "
_ ( out . stdout ) . must_include " - file "
_ ( out . stdout ) . must_include " - sshd_config "
2018-11-08 17:00:14 +00:00
end
2019-06-11 22:24:35 +00:00
it " provides matchers help " do
out = do_shell ( " help matchers " )
2020-09-14 19:46:58 +00:00
_ ( out . stdout ) . must_include " For more examples, see: https://docs.chef.io/inspec/matchers/ "
2018-11-08 17:00:14 +00:00
end
2019-06-11 22:24:35 +00:00
it " provides empty example help " do
out = do_shell ( " help file " )
2019-09-30 22:31:55 +00:00
_ ( out . stdout ) . must_include " Name "
_ ( out . stdout ) . must_include " Description "
_ ( out . stdout ) . must_include " Example "
_ ( out . stdout ) . must_include " Web Reference "
2018-11-08 17:00:14 +00:00
end
2019-06-11 22:24:35 +00:00
it " exposes all resources " do
out = do_shell ( " os " )
2019-09-30 22:31:55 +00:00
_ ( out . stdout ) . must_match ( / \ => .*Operating.* .*System.* .*Detection / )
2018-11-08 17:00:14 +00:00
end
2019-06-11 22:24:35 +00:00
it " can run ruby expressions " do
2018-11-08 17:00:14 +00:00
x = rand
y = rand
out = do_shell ( " #{ x } + #{ y } " )
2019-09-30 22:31:55 +00:00
_ ( out . stdout ) . must_include " #{ x + y } "
2018-11-08 17:00:14 +00:00
end
2019-06-11 22:24:35 +00:00
it " can run arbitrary ruby " do
out = do_shell ( " x = [1,2,3].inject(0) {|a,v| a + v*v}; x+10 " )
2019-09-30 22:31:55 +00:00
_ ( out . stdout ) . must_include " 24 "
2018-11-08 17:00:14 +00:00
end
2019-06-11 22:24:35 +00:00
it " runs anonymous tests that succeed " do
2018-11-08 17:00:14 +00:00
out = do_shell ( " describe file( \" #{ __FILE__ } \" ) do it { should exist } end " )
2019-09-30 22:31:55 +00:00
_ ( out . stdout ) . must_include " 1 successful "
_ ( out . stdout ) . must_include " 0 failures "
2018-11-08 17:00:14 +00:00
end
2019-06-11 22:24:35 +00:00
it " runs anonymous tests that fail " do
2018-11-08 17:00:14 +00:00
out = do_shell ( " describe file( \" foo/bar/baz \" ) do it { should exist } end " )
2019-09-30 22:31:55 +00:00
_ ( out . stdout ) . must_include " 0 successful "
_ ( out . stdout ) . must_include " 1 failure "
2018-11-08 17:00:14 +00:00
end
2019-06-11 22:24:35 +00:00
it " runs controls with tests " do
2018-11-08 17:00:14 +00:00
out = do_shell ( " control \" test \" do describe file( \" #{ __FILE__ } \" ) do it { should exist } end end " )
2019-09-30 22:31:55 +00:00
_ ( out . stdout ) . must_include " 1 successful "
_ ( out . stdout ) . must_include " 0 failures "
2018-11-08 17:00:14 +00:00
end
2019-06-11 22:24:35 +00:00
it " runs controls with multiple tests " do
2018-11-08 17:00:14 +00:00
out = do_shell ( " control \" test \" do describe file( \" #{ __FILE__ } \" ) do it { should exist } end; describe file( \" foo/bar/baz \" ) do it { should exist } end end " )
2019-09-30 22:31:55 +00:00
_ ( out . stdout ) . must_include " 0 successful "
_ ( out . stdout ) . must_include " 1 failure "
2018-11-08 17:00:14 +00:00
end
2019-06-11 22:24:35 +00:00
it " reruns controls when redefined " do
2018-11-08 17:00:14 +00:00
out = do_shell ( " control \" test \" do describe file( \" #{ __FILE__ } \" ) do it { should exist } end end \n control \" test \" do describe file( \" foo/bar/baz \" ) do it { should exist } end end " )
2019-09-30 22:31:55 +00:00
_ ( out . stdout ) . must_include " 1 successful "
_ ( out . stdout ) . must_include " 1 failure "
2018-11-08 17:00:14 +00:00
end
2016-08-19 22:58:39 +00:00
end
end
end