inspec/test/functional/inspec_exec_json_test.rb

215 lines
7.4 KiB
Ruby

require "functional/helper"
require "json-schema"
require "inspec/schema"
describe "inspec exec with json formatter" do
include FunctionalHelper
let(:schema) { Inspec::Schema.json("exec-json") }
parallelize_me!
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)
_(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)
_(JSON::Validator.validate(schema, data)).wont_equal false
_(out.stderr).must_equal ""
assert_exit_code 101, 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"
_(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
profile = File.join(profile_path, "unsupported_dependencies", "wrapper-profile")
out = inspec("exec " + 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
profile = File.join(profile_path, "unsupported_dependencies", "wrapper-profile")
out = inspec("exec " + 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
profile = File.join(profile_path, "dependencies", "inheritance")
out = inspec("exec " + profile + " --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
profile = File.join(profile_path, "skippy-profile-os")
out = inspec("exec " + profile + " --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(:raw) { inspec("exec " + example_profile + " --reporter json --no-create-lockfile").stdout }
let(:json) { JSON.load(raw) }
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"] == "example-1.0" } }
let(:check_result) do
ex3["results"].find { |x| x["resource"] == "example_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/ }["id"]
groups = actual.delete("groups")
actual.delete("sha256")
_(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",
"supports" => [{ "platform-family" => "unix" }, { "platform-family" => "windows" }],
"status" => "loaded",
"attributes" => [],
})
_(groups.sort_by { |x| x["id"] }).must_equal([
{ "id" => "controls/example-tmp.rb",
"title" => "/ profile",
"controls" => ["tmp-1.0", key] },
{ "id" => "controls/example.rb",
"title" => "Example Config Checks",
"controls" => ["example-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/fixtures/profiles/old-examples/profile/controls/example-tmp.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 / should be directory"
_(result["run_time"]).wont_be :nil?
_(result["start_time"]).wont_be :nil?
code = actual.delete "code"
_(code).must_include "control 'tmp-1.0' do"
_(actual).must_equal({
"id" => "tmp-1.0",
"title" => "Create / 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 },
"waiver_data" => {},
})
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