inspec/test/functional/inspec_exec_json_test.rb
Ryan Davis 18ce4850f0 Initial pass to clean up functional testing wrt exit codes and output.
This should get windows tests running again? Hopefully? They're
running SO slowly on my vagrant box that I'm just pushing for now.
They're clean on the mac side.

Signed-off-by: Ryan Davis <zenspider@chef.io>
2019-07-24 18:06:25 -07:00

233 lines
8.6 KiB
Ruby

require "functional/helper"
require "json-schema"
describe "inspec exec with json formatter" do
include FunctionalHelper
it "can execute a simple file and validate the json schema" do
out = inspec("exec " + example_control + " --reporter json --no-create-lockfile")
data = JSON.parse(out.stdout)
sout = inspec("schema exec-json")
schema = JSON.parse(sout.stdout)
JSON::Validator.validate(schema, data).wont_equal false
out.stderr.must_equal ""
assert_exit_code 0, out
end
it "can execute a profile and validate the json schema" do
out = inspec("exec " + example_profile + " --reporter json --no-create-lockfile")
data = JSON.parse(out.stdout)
sout = inspec("schema exec-json")
schema = JSON.parse(sout.stdout)
JSON::Validator.validate(schema, data).wont_equal false
out.stderr.must_equal ""
assert_exit_code 101, out
end
it "can execute a simple file while using end of options after reporter cli option" do
out = inspec("exec --no-create-lockfile --reporter json -- " + example_control)
data = JSON.parse(out.stdout)
sout = inspec("schema exec-json")
schema = JSON.parse(sout.stdout)
JSON::Validator.validate(schema, data).wont_equal false
out.stderr.must_equal ""
assert_exit_code 0, out
end
it "can execute a profile and validate the json schema with target_id" do
out = inspec("exec " + example_profile + " --reporter json --no-create-lockfile --target-id 1d3e399f-4d71-4863-ac54-84d437fbc444")
data = JSON.parse(out.stdout)
data["platform"]["target_id"].must_equal "1d3e399f-4d71-4863-ac54-84d437fbc444"
sout = inspec("schema exec-json")
schema = JSON.parse(sout.stdout)
JSON::Validator.validate(schema, data).wont_equal false
out.stderr.must_equal ""
assert_exit_code 101, out
end
it "does not report skipped dependent profiles" do
out = inspec("exec " + File.join(profile_path, "unsupported_dependencies", "wrapper-profile") + " --reporter json --no-create-lockfile")
data = JSON.parse(out.stdout)
data["profiles"].count.must_equal 1
profile = data["profiles"].first
profile["controls"].count.must_equal 1
out.stderr.must_include "WARN: Skipping profile: 'child_profile' on unsupported platform:"
out.stderr.must_include "WARN: Skipping profile: 'child_profile2' on unsupported platform:"
assert_exit_code 0, out
end
it "flags skipped profiles with correct status" do
out = inspec("exec " + File.join(profile_path, "unsupported_dependencies", "wrapper-profile") + " --reporter json --no-create-lockfile")
data = JSON.parse(out.stdout)
data["profiles"].count.must_equal 1
profile = data["profiles"].first
profile["status"].must_equal "loaded"
profile["depends"].count.must_equal 2
profile["depends"].each do |d|
d["status"].must_equal "skipped"
d["skip_message"].must_include "Skipping profile: "
end
assert_exit_code 0, out
end
it "flags loaded profiles with correct status" do
out = inspec("exec " + File.join(profile_path, "dependencies", "inheritance") + " --reporter json --no-create-lockfile")
data = JSON.parse(out.stdout)
profile = data["profiles"].first
profile["status"].must_equal "loaded"
profile["depends"].count.must_equal 2
profile["depends"].each do |d|
d["status"].must_equal "loaded"
d.key?("skip_message").must_equal false
end
out.stderr.must_equal ""
assert_exit_code 0, out
end
it "flags profile with correct status when not supported" do
out = inspec("exec " + File.join(profile_path, "skippy-profile-os") + " --reporter json --no-create-lockfile")
data = JSON.parse(out.stdout)
profile = data["profiles"].first
profile["status"].must_equal "skipped"
profile["skip_message"].must_include "Skipping profile: 'skippy' on unsupported platform:"
out.stderr.must_equal ""
assert_exit_code 101, out
end
describe "execute a profile with json formatting" do
let(:json) { JSON.load(inspec("exec " + example_profile + " --reporter json --no-create-lockfile").stdout) }
let(:profile) { json["profiles"][0] }
let(:controls) { profile["controls"] }
let(:ex1) { controls.find { |x| x["id"] == "tmp-1.0" } }
let(:ex2) { controls.find { |x| x["id"] =~ /generated/ } }
let(:ex3) { profile["controls"].find { |x| x["id"] == "gordon-1.0" } }
let(:check_result) do
ex3["results"].find { |x| x["resource"] == "gordon_config" }
end
it "has only one profile" do
json["profiles"].must_be_kind_of(Array)
json["profiles"].length.must_equal 1
end
it "maps impact symbols to numbers" do
ex3["impact"].must_equal 0.9
end
it "has all the metadata" do
actual = profile.dup
key = actual.delete("controls")
.find { |x| x["id"] =~ /generated from example.rb/ }["id"]
groups = actual.delete("groups")
actual.must_equal({
"name" => "profile",
"title" => "InSpec Example Profile",
"maintainer" => "Chef Software, Inc.",
"copyright" => "Chef Software, Inc.",
"copyright_email" => "support@chef.io",
"license" => "Apache-2.0",
"summary" => "Demonstrates the use of InSpec Compliance Profile",
"version" => "1.0.0",
# TODO: this is brittle and nonsensical
"sha256" => "de67a044d7be7090982740755ff582af1cefaf37261c5adda57b9502ffefc973",
"supports" => [{ "platform-family" => "unix" }, { "platform-family" => "windows" }],
"status" => "loaded",
"attributes" => [],
})
groups.sort_by { |x| x["id"] }.must_equal([
{ "id" => "controls/example.rb", "title" => "/tmp profile", "controls" => ["tmp-1.0", key] },
{ "id" => "controls/gordon.rb", "title" => "Gordon Config Checks", "controls" => ["gordon-1.0"] },
{ "id" => "controls/meta.rb", "title" => "SSH Server Configuration", "controls" => ["ssh-1"] },
])
end
it "must have 4 controls" do
controls.length.must_equal 4
end
it "has an id for every control" do
controls.find { |x| x["id"].nil? }.must_be :nil?
end
it "has results for every control" do
ex1["results"].length.must_equal 1
ex2["results"].length.must_equal 1
ex3["results"].length.must_equal 2
end
it "has the right result for tmp-1.0" do
actual = ex1.dup
src = actual.delete("source_location")
src["ref"].must_match %r{test/unit/mock/profiles/old-examples/profile/controls/example.rb$}
src["line"].must_equal 6
result = actual.delete("results")[0]
result.wont_be :nil?
result["status"].must_equal "passed"
result["code_desc"].must_equal "File /tmp should be directory"
result["run_time"].wont_be :nil?
result["start_time"].wont_be :nil?
example_rb_code = <<~END
control 'tmp-1.0' do # A unique ID for this control
impact 0.7 # The criticality, if this control fails.
title 'Create /tmp directory' # A human-readable title
desc 'An optional description...' # Describe why this is needed
desc 'label', 'An optional description with a label' # Pair a part of the description with a label
tag data: 'temp data' # A tag allows you to associate key information
tag 'security' # to the test
ref 'Document A-12', url: 'http://...' # Additional references
describe file('/tmp') do # The actual test
it { should be_directory }
end
end
END
actual.must_equal({
"id" => "tmp-1.0",
"title" => "Create /tmp directory",
"desc" => "An optional description...",
"descriptions" => [{ "label" => "default", "data" => "An optional description..." }, { "label" => "label", "data" => "An optional description with a label" }],
"impact" => 0.7,
"refs" => [{ "url" => "http://...", "ref" => "Document A-12" }],
"tags" => { "data" => "temp data", "security" => nil },
"code" => example_rb_code,
})
end
end
describe "with a profile that is not supported on this OS/platform" do
let(:out) { inspec("exec " + File.join(profile_path, "skippy-profile-os") + " --reporter json --no-create-lockfile") }
let(:json) { JSON.load(out.stdout) }
# TODO: failure handling in json formatters...
it "never runs the actual resource" do
File.exist?("/tmp/inspec_test_DONT_CREATE").must_equal false
end
end
end