mirror of
https://github.com/inspec/inspec
synced 2024-11-30 08:30:39 +00:00
Merge pull request #1621 from chef/adamleff/replace-nokogiri
Replace Nokogiri with REXML in the JUnit formatter
This commit is contained in:
commit
5e94600eb3
6 changed files with 60 additions and 65 deletions
|
@ -51,18 +51,11 @@ do_build() {
|
||||||
local _libxslt_dir
|
local _libxslt_dir
|
||||||
|
|
||||||
_bundler_dir="$(pkg_path_for bundler)"
|
_bundler_dir="$(pkg_path_for bundler)"
|
||||||
_libxml2_dir="$(pkg_path_for libxml2)"
|
|
||||||
_libxslt_dir="$(pkg_path_for libxslt)"
|
|
||||||
|
|
||||||
export GEM_HOME=${pkg_path}/vendor/bundle
|
export GEM_HOME=${pkg_path}/vendor/bundle
|
||||||
export GEM_PATH=${_bundler_dir}:${GEM_HOME}
|
export GEM_PATH=${_bundler_dir}:${GEM_HOME}
|
||||||
export BUNDLE_SILENCE_ROOT_WARNING=1
|
export BUNDLE_SILENCE_ROOT_WARNING=1
|
||||||
|
|
||||||
# don't let bundler split up the nokogiri config string (it breaks
|
|
||||||
# the build), so specify it as an env var instead
|
|
||||||
export NOKOGIRI_CONFIG="--use-system-libraries --with-zlib-dir=${_zlib_dir} --with-xslt-dir=${_libxslt_dir} --with-xml2-include=${_libxml2_dir}/include/libxml2 --with-xml2-lib=${_libxml2_dir}/lib"
|
|
||||||
bundle config build.nokogiri "${NOKOGIRI_CONFIG}"
|
|
||||||
|
|
||||||
bundle install --jobs "$(nproc)" --retry 5 --standalone \
|
bundle install --jobs "$(nproc)" --retry 5 --standalone \
|
||||||
--path "$pkg_prefix/bundle" \
|
--path "$pkg_prefix/bundle" \
|
||||||
--binstubs "$pkg_prefix/bin"
|
--binstubs "$pkg_prefix/bin"
|
||||||
|
|
|
@ -39,7 +39,6 @@ Gem::Specification.new do |spec|
|
||||||
spec.add_dependency 'mixlib-log'
|
spec.add_dependency 'mixlib-log'
|
||||||
spec.add_dependency 'sslshake', '~> 1'
|
spec.add_dependency 'sslshake', '~> 1'
|
||||||
spec.add_dependency 'parallel', '~> 1.9'
|
spec.add_dependency 'parallel', '~> 1.9'
|
||||||
spec.add_dependency 'nokogiri', '~> 1.6'
|
|
||||||
spec.add_dependency 'faraday', '>=0.9.0'
|
spec.add_dependency 'faraday', '>=0.9.0'
|
||||||
spec.add_dependency 'toml', '~> 0.1'
|
spec.add_dependency 'toml', '~> 0.1'
|
||||||
spec.add_dependency 'addressable', '~> 2.5'
|
spec.add_dependency 'addressable', '~> 2.5'
|
||||||
|
|
|
@ -795,51 +795,61 @@ class InspecRspecJUnit < InspecRspecJson
|
||||||
|
|
||||||
#
|
#
|
||||||
# This is the last method is invoked through the formatter interface.
|
# This is the last method is invoked through the formatter interface.
|
||||||
# Converts the junit formatter constructed output_hash into nokogiri generated
|
# Converts the junit formatter constructed output_hash into REXML generated
|
||||||
# XML and writes it to output.
|
# XML and writes it to output.
|
||||||
#
|
#
|
||||||
def close(_notification)
|
def close(_notification)
|
||||||
require 'nokogiri'
|
require 'rexml/document'
|
||||||
xml_output = Nokogiri::XML::Builder.new { |xml|
|
xml_output = REXML::Document.new
|
||||||
xml.testsuites do
|
xml_output.add(REXML::XMLDecl.new)
|
||||||
|
|
||||||
|
testsuites = REXML::Element.new('testsuites')
|
||||||
|
xml_output.add(testsuites)
|
||||||
|
|
||||||
@output_hash[:profiles].each do |profile|
|
@output_hash[:profiles].each do |profile|
|
||||||
build_profile_xml(xml, profile)
|
testsuites.add(build_profile_xml(profile))
|
||||||
end
|
end
|
||||||
end
|
|
||||||
}.to_xml
|
formatter = REXML::Formatters::Pretty.new
|
||||||
output.puts xml_output
|
formatter.compact = true
|
||||||
|
output.puts formatter.write(xml_output.xml_decl, '')
|
||||||
|
output.puts formatter.write(xml_output.root, '')
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def build_profile_xml(xml, profile)
|
def build_profile_xml(profile)
|
||||||
xml.testsuite(
|
profile_xml = REXML::Element.new('testsuite')
|
||||||
name: profile[:name],
|
profile_xml.add_attribute('name', profile[:name])
|
||||||
tests: count_profile_tests(profile),
|
profile_xml.add_attribute('tests', count_profile_tests(profile))
|
||||||
failed: count_profile_failed_tests(profile),
|
profile_xml.add_attribute('failed', count_profile_failed_tests(profile))
|
||||||
) do
|
|
||||||
profile[:controls].each do |control|
|
profile[:controls].each do |control|
|
||||||
build_control_xml(xml, control)
|
next if control[:results].nil?
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def build_control_xml(xml, control)
|
|
||||||
return if control[:results].nil?
|
|
||||||
control[:results].each do |result|
|
control[:results].each do |result|
|
||||||
build_result_xml(xml, control, result)
|
profile_xml.add(build_result_xml(control, result))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def build_result_xml(xml, control, result)
|
profile_xml
|
||||||
test_class = control[:title].nil? ? 'Anonymous' : control[:id]
|
end
|
||||||
xml.testcase(name: result[:code_desc], class: test_class, time: result[:run_time]) do
|
|
||||||
|
def build_result_xml(control, result)
|
||||||
|
result_xml = REXML::Element.new('testcase')
|
||||||
|
result_xml.add_attribute('name', result[:code_desc])
|
||||||
|
result_xml.add_attribute('class', control[:title].nil? ? 'Anonymous' : control[:id])
|
||||||
|
result_xml.add_attribute('time', result[:run_time])
|
||||||
|
|
||||||
if result[:status] == 'failed'
|
if result[:status] == 'failed'
|
||||||
xml.failure(message: result[:message])
|
failure_element = REXML::Element.new('failure')
|
||||||
|
failure_element.add_attribute('message', result[:message])
|
||||||
|
result_xml.add(failure_element)
|
||||||
elsif result[:status] == 'skipped'
|
elsif result[:status] == 'skipped'
|
||||||
xml.skipped
|
result_xml.add_element('skipped')
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
result_xml
|
||||||
end
|
end
|
||||||
|
|
||||||
def count_profile_tests(profile)
|
def count_profile_tests(profile)
|
||||||
|
|
|
@ -23,7 +23,6 @@ dependency 'ruby'
|
||||||
dependency 'rubygems'
|
dependency 'rubygems'
|
||||||
dependency 'bundler'
|
dependency 'bundler'
|
||||||
dependency 'rb-readline'
|
dependency 'rb-readline'
|
||||||
dependency 'nokogiri'
|
|
||||||
dependency 'appbundler'
|
dependency 'appbundler'
|
||||||
|
|
||||||
license :project_license
|
license :project_license
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
# author: John Kerry
|
# author: John Kerry
|
||||||
|
|
||||||
require 'functional/helper'
|
require 'functional/helper'
|
||||||
require 'nokogiri'
|
require 'rexml/document'
|
||||||
|
|
||||||
describe 'inspec exec with junit formatter' do
|
describe 'inspec exec with junit formatter' do
|
||||||
include FunctionalHelper
|
include FunctionalHelper
|
||||||
|
@ -11,47 +11,47 @@ describe 'inspec exec with junit formatter' do
|
||||||
out = inspec('exec ' + example_control + ' --format junit --no-create-lockfile')
|
out = inspec('exec ' + example_control + ' --format junit --no-create-lockfile')
|
||||||
out.stderr.must_equal ''
|
out.stderr.must_equal ''
|
||||||
out.exit_status.must_equal 0
|
out.exit_status.must_equal 0
|
||||||
doc = Nokogiri::XML(out.stdout)
|
doc = REXML::Document.new(out.stdout)
|
||||||
doc.errors.length.must_equal 0
|
doc.has_elements?.must_equal true
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'can execute the profile with the junit formatter' do
|
it 'can execute the profile with the junit formatter' do
|
||||||
out = inspec('exec ' + example_profile + ' --format junit --no-create-lockfile')
|
out = inspec('exec ' + example_profile + ' --format junit --no-create-lockfile')
|
||||||
out.stderr.must_equal ''
|
out.stderr.must_equal ''
|
||||||
out.exit_status.must_equal 0
|
out.exit_status.must_equal 0
|
||||||
doc = Nokogiri::XML(out.stdout)
|
doc = REXML::Document.new(out.stdout)
|
||||||
doc.errors.length.must_equal 0
|
doc.has_elements?.must_equal true
|
||||||
end
|
end
|
||||||
|
|
||||||
describe 'execute a profile with junit formatting' do
|
describe 'execute a profile with junit formatting' do
|
||||||
let(:doc) { Nokogiri::XML(inspec('exec ' + example_profile + ' --format junit --no-create-lockfile').stdout) }
|
let(:doc) { REXML::Document.new(inspec('exec ' + example_profile + ' --format junit --no-create-lockfile').stdout) }
|
||||||
|
|
||||||
describe 'the document' do
|
describe 'the document' do
|
||||||
it 'has only one testsuite' do
|
it 'has only one testsuite' do
|
||||||
doc.xpath("//testsuite").length.must_equal 1
|
doc.elements.to_a("//testsuite").length.must_equal 1
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
describe 'the test suite' do
|
describe 'the test suite' do
|
||||||
let(:suite) { doc.xpath("//testsuites/testsuite").first}
|
let(:suite) { doc.elements.to_a("//testsuites/testsuite").first }
|
||||||
|
|
||||||
it 'must have 5 testcase children' do
|
it 'must have 5 testcase children' do
|
||||||
suite.xpath("//testcase").length.must_equal 5
|
suite.elements.to_a("//testcase").length.must_equal 5
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'has the tests attribute with 5 total tests' do
|
it 'has the tests attribute with 5 total tests' do
|
||||||
suite["tests"].must_equal "5"
|
suite.attribute('tests').value.must_equal "5"
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'has the failures attribute with 0 total tests' do
|
it 'has the failures attribute with 0 total tests' do
|
||||||
suite["failed"].must_equal "0"
|
suite.attribute('failed').value.must_equal "0"
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'has 2 elements named "File /tmp should be directory"' do
|
it 'has 2 elements named "File /tmp should be directory"' do
|
||||||
suite.xpath("//testcase[@name='File /tmp should be directory']").length.must_equal 2
|
REXML::XPath.match(suite, "//testcase[@name='File /tmp should be directory']").length.must_equal 2
|
||||||
end
|
end
|
||||||
|
|
||||||
describe 'the testcase named "gordon_config Can\'t find file ..."' do
|
describe 'the testcase named "gordon_config Can\'t find file ..."' do
|
||||||
let(:gordon_yml_tests) { suite.xpath("//testcase[@class='gordon-1.0' and @name='gordon_config']") }
|
let(:gordon_yml_tests) { REXML::XPath.match(suite, "//testcase[@class='gordon-1.0' and @name='gordon_config']") }
|
||||||
let(:first_gordon_test) {gordon_yml_tests.first}
|
let(:first_gordon_test) {gordon_yml_tests.first}
|
||||||
|
|
||||||
it 'should be unique' do
|
it 'should be unique' do
|
||||||
|
@ -59,7 +59,7 @@ describe 'inspec exec with junit formatter' do
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'should be skipped' do
|
it 'should be skipped' do
|
||||||
first_gordon_test.xpath("//skipped").length.must_equal 1
|
first_gordon_test.elements.to_a('//skipped').length.must_equal 1
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -8,7 +8,6 @@ PATH
|
||||||
json (>= 1.8, < 3.0)
|
json (>= 1.8, < 3.0)
|
||||||
method_source (~> 0.8)
|
method_source (~> 0.8)
|
||||||
mixlib-log
|
mixlib-log
|
||||||
nokogiri (~> 1.6)
|
|
||||||
parallel (~> 1.9)
|
parallel (~> 1.9)
|
||||||
pry (~> 0)
|
pry (~> 0)
|
||||||
rainbow (~> 2)
|
rainbow (~> 2)
|
||||||
|
@ -56,7 +55,7 @@ GEM
|
||||||
concurrent-ruby (1.0.5)
|
concurrent-ruby (1.0.5)
|
||||||
contracts (0.13.0)
|
contracts (0.13.0)
|
||||||
diff-lcs (1.3)
|
diff-lcs (1.3)
|
||||||
docker-api (1.33.2)
|
docker-api (1.33.3)
|
||||||
excon (>= 0.38.0)
|
excon (>= 0.38.0)
|
||||||
json
|
json
|
||||||
dotenv (2.2.0)
|
dotenv (2.2.0)
|
||||||
|
@ -67,13 +66,12 @@ GEM
|
||||||
eventmachine (1.2.3)
|
eventmachine (1.2.3)
|
||||||
excon (0.55.0)
|
excon (0.55.0)
|
||||||
execjs (2.7.0)
|
execjs (2.7.0)
|
||||||
faraday (0.11.0)
|
faraday (0.12.0.1)
|
||||||
multipart-post (>= 1.2, < 3)
|
multipart-post (>= 1.2, < 3)
|
||||||
fast_blank (1.0.0)
|
fast_blank (1.0.0)
|
||||||
fastimage (2.1.0)
|
fastimage (2.1.0)
|
||||||
ffi (1.9.18)
|
ffi (1.9.18)
|
||||||
github-markup (1.5.0)
|
github-markup (1.6.0)
|
||||||
rinku
|
|
||||||
gssapi (1.2.0)
|
gssapi (1.2.0)
|
||||||
ffi (>= 1.0.1)
|
ffi (>= 1.0.1)
|
||||||
gyoku (1.3.1)
|
gyoku (1.3.1)
|
||||||
|
@ -148,7 +146,6 @@ GEM
|
||||||
middleman-syntax (3.0.0)
|
middleman-syntax (3.0.0)
|
||||||
middleman-core (>= 3.2)
|
middleman-core (>= 3.2)
|
||||||
rouge (~> 2.0)
|
rouge (~> 2.0)
|
||||||
mini_portile2 (2.1.0)
|
|
||||||
minitest (5.10.1)
|
minitest (5.10.1)
|
||||||
mixlib-log (1.7.1)
|
mixlib-log (1.7.1)
|
||||||
mixlib-shellout (2.2.7)
|
mixlib-shellout (2.2.7)
|
||||||
|
@ -157,8 +154,6 @@ GEM
|
||||||
net-scp (1.2.1)
|
net-scp (1.2.1)
|
||||||
net-ssh (>= 2.6.5)
|
net-ssh (>= 2.6.5)
|
||||||
net-ssh (4.1.0)
|
net-ssh (4.1.0)
|
||||||
nokogiri (1.7.1)
|
|
||||||
mini_portile2 (~> 2.1.0)
|
|
||||||
nori (2.6.0)
|
nori (2.6.0)
|
||||||
padrino-helpers (0.13.3.3)
|
padrino-helpers (0.13.3.3)
|
||||||
i18n (~> 0.6, >= 0.6.7)
|
i18n (~> 0.6, >= 0.6.7)
|
||||||
|
@ -183,7 +178,6 @@ GEM
|
||||||
rb-inotify (0.9.8)
|
rb-inotify (0.9.8)
|
||||||
ffi (>= 0.5.0)
|
ffi (>= 0.5.0)
|
||||||
redcarpet (3.4.0)
|
redcarpet (3.4.0)
|
||||||
rinku (2.0.2)
|
|
||||||
rouge (2.0.7)
|
rouge (2.0.7)
|
||||||
rspec (3.5.0)
|
rspec (3.5.0)
|
||||||
rspec-core (~> 3.5.0)
|
rspec-core (~> 3.5.0)
|
||||||
|
@ -233,7 +227,7 @@ GEM
|
||||||
winrm-fs (~> 1.0)
|
winrm-fs (~> 1.0)
|
||||||
tzinfo (1.2.3)
|
tzinfo (1.2.3)
|
||||||
thread_safe (~> 0.1)
|
thread_safe (~> 0.1)
|
||||||
uglifier (3.1.11)
|
uglifier (3.1.13)
|
||||||
execjs (>= 0.3.0, < 3)
|
execjs (>= 0.3.0, < 3)
|
||||||
winrm (2.1.3)
|
winrm (2.1.3)
|
||||||
builder (>= 2.1.2)
|
builder (>= 2.1.2)
|
||||||
|
|
Loading…
Reference in a new issue