meson-junit 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/README.md +113 -0
- data/Rakefile +16 -0
- data/bin/meson-junit +7 -0
- data/lib/meson-junit.rb +13 -0
- data/lib/meson-junit/cli.rb +20 -0
- data/lib/meson-junit/junit.rb +6 -0
- data/lib/meson-junit/junit/xml-builder.rb +173 -0
- data/lib/meson-junit/meson.rb +7 -0
- data/lib/meson-junit/meson/test-log.rb +18 -0
- data/lib/meson-junit/meson/test.rb +48 -0
- data/test/data/testlog.json +5 -0
- data/test/test_junit.rb +24 -0
- data/test/test_meson.rb +59 -0
- metadata +105 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 14fb11afe0ddfca3654a9d4e9603072b30a4b39448156140691ed49247e2cd4b
|
4
|
+
data.tar.gz: 4fa62e089335d45d9127cf0efc3169a0078363bc9fe3e01d2eb52dec05ad384a
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 6c8b2efa2b3f70624ed8e20fb77185bae8acecd2c1fb6d337425c34bbc24468f939e1a792298010c5fc61cb4d6d78ca394f2d54cbfa79789e1f9c7045d2a13ce
|
7
|
+
data.tar.gz: 82caabd3b3a07102cf54decdf54a3553d01acaecdefbcdc196ad8861f1c4e17adbdfc99a194e719edf85ea2937dccf5461319b3ca5e5bca69c50fbb8ad5eebac
|
data/README.md
ADDED
@@ -0,0 +1,113 @@
|
|
1
|
+
meson-junit
|
2
|
+
===========
|
3
|
+
|
4
|
+
Overview
|
5
|
+
--------
|
6
|
+
Command-line tool to convert [Meson][] test results to a
|
7
|
+
[Jenkins][]-compatible [JUnit][] [XML][].
|
8
|
+
|
9
|
+
Usage:
|
10
|
+
|
11
|
+
#
|
12
|
+
# This command does the following:
|
13
|
+
#
|
14
|
+
# - Read Meson test results in JSON format from the file
|
15
|
+
# "meson-logs/testlog.json".
|
16
|
+
#
|
17
|
+
# - Convert the input from JSON to Jenkins-friendly, JUnit XML.
|
18
|
+
#
|
19
|
+
# - Write the generated XML to "junit.xml".
|
20
|
+
#
|
21
|
+
meson-junit < meson-logs/testlog.json > junit.xml
|
22
|
+
|
23
|
+
If you are running your [Meson][] tests via [Jenkins Pipeline][], you
|
24
|
+
would include `meson-junit` in your `steps` like this:
|
25
|
+
|
26
|
+
steps {
|
27
|
+
// run tests, generate output in build-dir/meson-logs/testlog.json
|
28
|
+
sh 'cd build && meson test || true'
|
29
|
+
|
30
|
+
// generate build/testlog.xml
|
31
|
+
sh 'cd build && meson-junit < meson-logs/testlog.json > testlog.xml'
|
32
|
+
|
33
|
+
// read junit results
|
34
|
+
junit 'build/testlog.xml'
|
35
|
+
}
|
36
|
+
|
37
|
+
Notes:
|
38
|
+
|
39
|
+
* [Meson][] test results are converted to [JUnit][] `<testsuite>`
|
40
|
+
elements, rather than `<testcase>` elements. This is so we can expose
|
41
|
+
the attributes of the [Meson][] test results (the test command,
|
42
|
+
return code, environment variables, etc) as `<property>` elements.
|
43
|
+
* The reference used to generate the [JUnit][] [XML][] is available here:
|
44
|
+
[JUnit XML reporting file format][junit-ref].
|
45
|
+
|
46
|
+
Installation
|
47
|
+
------------
|
48
|
+
Install `meson-junit` via [RubyGems][], like so:
|
49
|
+
|
50
|
+
# install meson-junit using rubygems
|
51
|
+
gem install meson-junit
|
52
|
+
|
53
|
+
Documentation
|
54
|
+
-------------
|
55
|
+
You can generate the API documentation in the `docs/` directory via
|
56
|
+
[RDoc][], like so:
|
57
|
+
|
58
|
+
# generate API documentation in docs/ directory
|
59
|
+
rake docs
|
60
|
+
|
61
|
+
Tests
|
62
|
+
-----
|
63
|
+
You can run the [minitest][] test suite via [Rake][], like so:
|
64
|
+
|
65
|
+
# run the test suite
|
66
|
+
rake test
|
67
|
+
|
68
|
+
To generate a [JUnit][]-compatible XML report, install the
|
69
|
+
[minitest-junit][] gem and then do the following:
|
70
|
+
|
71
|
+
# run the test suite and generate a junit-compatible report.xml
|
72
|
+
rake test TESTOPTS=--junit
|
73
|
+
|
74
|
+
Author
|
75
|
+
------
|
76
|
+
Paul Duncan ([pabs@pablotron.org][me])<br/>
|
77
|
+
<https://pablotron.org/>
|
78
|
+
|
79
|
+
License
|
80
|
+
-------
|
81
|
+
Copyright 2019 Paul Duncan ([pabs@pablotron.org][me])
|
82
|
+
|
83
|
+
Permission is hereby granted, free of charge, to any person obtaining a
|
84
|
+
copy of this software and associated documentation files (the
|
85
|
+
"Software"), to deal in the Software without restriction, including
|
86
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
87
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
88
|
+
permit persons to whom the Software is furnished to do so, subject to
|
89
|
+
the following conditions:
|
90
|
+
|
91
|
+
The above copyright notice and this permission notice shall be included
|
92
|
+
in all copies or substantial portions of the Software.
|
93
|
+
|
94
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
95
|
+
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
96
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
97
|
+
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
98
|
+
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
99
|
+
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
100
|
+
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
101
|
+
|
102
|
+
[junit-ref]: https://llg.cubic.org/docs/junit/
|
103
|
+
[xml]: https://en.wikipedia.org/wiki/XML
|
104
|
+
[meson]: https://mesonbuild.com/
|
105
|
+
[jenkins]: https://jenkins-ci.org/
|
106
|
+
[jenkins pipeline]: https://jenkins.io/doc/book/pipeline/
|
107
|
+
[RubyGems]: https://rubygems.org/
|
108
|
+
[JUnit]: https://junit.org/
|
109
|
+
[me]: mailto:pabs@pablotron.org
|
110
|
+
[minitest]: https://github.com/seattlerb/minitest
|
111
|
+
[minitest-junit]: https://github.com/aespinosa/minitest-junit
|
112
|
+
[RDoc]: https://github.com/ruby/rdoc
|
113
|
+
[Rake]: https://github.com/ruby/rake
|
data/Rakefile
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'rake/testtask'
|
2
|
+
require 'rdoc/task'
|
3
|
+
|
4
|
+
Rake::TestTask.new do |t|
|
5
|
+
t.libs << 'test'
|
6
|
+
end
|
7
|
+
|
8
|
+
RDoc::Task.new :docs do |t|
|
9
|
+
t.main = "lib/meson-junit"
|
10
|
+
t.rdoc_files.include('lib/**/*.rb')
|
11
|
+
t.rdoc_dir = 'docs'
|
12
|
+
# t.options << "--all"
|
13
|
+
end
|
14
|
+
|
15
|
+
desc "Run tests"
|
16
|
+
task :default => :test
|
data/bin/meson-junit
ADDED
data/lib/meson-junit.rb
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
require 'json'
|
2
|
+
require 'nokogiri'
|
3
|
+
|
4
|
+
#
|
5
|
+
# Meson to JUnit test case generator.
|
6
|
+
#
|
7
|
+
module MesonJunit
|
8
|
+
VERSION = '0.1.0'
|
9
|
+
|
10
|
+
autoload :Meson, File.join(__dir__, 'meson-junit', 'meson.rb')
|
11
|
+
autoload :Junit, File.join(__dir__, 'meson-junit', 'junit.rb')
|
12
|
+
autoload :CLI, File.join(__dir__, 'meson-junit', 'cli.rb')
|
13
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
#
|
2
|
+
# Command-line interface.
|
3
|
+
#
|
4
|
+
module MesonJunit::CLI
|
5
|
+
#
|
6
|
+
# Allow command-line invocation.
|
7
|
+
#
|
8
|
+
def self.run(app, args)
|
9
|
+
# TODO: parse command-line arguments
|
10
|
+
|
11
|
+
# parse meson test log json from standard input
|
12
|
+
log = MesonJunit::Meson::TestLog.new(STDIN)
|
13
|
+
|
14
|
+
# build junit xml from meson testlog
|
15
|
+
xml = MesonJunit::Junit::XMLBuilder.build(log)
|
16
|
+
|
17
|
+
# write xml to standard output
|
18
|
+
puts xml
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,173 @@
|
|
1
|
+
#
|
2
|
+
# Read parsed Meson test log and build JUnit-compatible XML.
|
3
|
+
#
|
4
|
+
class MesonJunit::Junit::XMLBuilder
|
5
|
+
def self.build(log)
|
6
|
+
new.build(log)
|
7
|
+
end
|
8
|
+
|
9
|
+
#
|
10
|
+
# Build JUnit-compatible XML from parsed Meson test log.
|
11
|
+
#
|
12
|
+
def build(log)
|
13
|
+
::Nokogiri::XML::Builder.new do |xml|
|
14
|
+
xml.testsuites(**testsuites_el_attrs(log)) do
|
15
|
+
emit_testsuite_els(xml, log)
|
16
|
+
end
|
17
|
+
end.to_xml
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
#
|
23
|
+
# Convert Meson test log to a series of JUnit test suites.
|
24
|
+
#
|
25
|
+
# We map Meson tests to a series of JUnit test suites with a single
|
26
|
+
# test case because that allows us to map the per-test attributes and
|
27
|
+
# environment variables to JUnit test suite properties.
|
28
|
+
#
|
29
|
+
def emit_testsuite_els(xml, log)
|
30
|
+
log.tests.each_with_index do |test, test_num|
|
31
|
+
xml.testsuite(**testsuite_el_attrs(test, test_num)) do
|
32
|
+
# emit testsuite properties
|
33
|
+
emit_properties(xml, test)
|
34
|
+
|
35
|
+
# emit testcase
|
36
|
+
emit_testcase(xml, test)
|
37
|
+
|
38
|
+
# emit standard output and standard error
|
39
|
+
xml.send('system-out', test.data['stdout'])
|
40
|
+
xml.send('system-err', test.data['stderr'])
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
#
|
46
|
+
# Emit Meson test attributes as JUnit `testsuite` properties.
|
47
|
+
#
|
48
|
+
def emit_properties(xml, test)
|
49
|
+
xml.properties do
|
50
|
+
# convert all non-environment variable meson test attributes to
|
51
|
+
# junit test suite properties
|
52
|
+
test.data.each do |key, val|
|
53
|
+
unless key == 'env'
|
54
|
+
emit_property(xml, key, val)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
# convert meson test environment variables to junit test suite
|
59
|
+
# properties
|
60
|
+
(test.data['env'] || {}).each do |key, val|
|
61
|
+
emit_property(xml, 'env.%s' % [key], val)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
#
|
67
|
+
# Emit details of Meson test as a JUnit `testcase` element.
|
68
|
+
def emit_testcase(xml, test)
|
69
|
+
xml.testcase(**testcase_el_attrs(test)) do
|
70
|
+
if test.failed?
|
71
|
+
# emit a `failure` element with a body that contains the
|
72
|
+
# standard error output from the Meson test.
|
73
|
+
xml.failure(test.data['stderr'], message: 'Test failed.')
|
74
|
+
end
|
75
|
+
|
76
|
+
# emit standard io elements
|
77
|
+
emit_stdio(xml, test)
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
#
|
82
|
+
# Emit standard output and standard error from a Meson test case as
|
83
|
+
# JUnit-compatible `system-out` and `system-err` elements.
|
84
|
+
#
|
85
|
+
def emit_stdio(xml, test)
|
86
|
+
# emit standard output and standard error
|
87
|
+
xml.send('system-out', test.data['stdout'])
|
88
|
+
xml.send('system-err', test.data['stderr'])
|
89
|
+
end
|
90
|
+
|
91
|
+
#
|
92
|
+
# Emit a Meson test attribute as a JUnit test suite property.
|
93
|
+
#
|
94
|
+
def emit_property(xml, key, val)
|
95
|
+
case val
|
96
|
+
when Array, Hash
|
97
|
+
# serialize arrays and hashes as JSON
|
98
|
+
xml.property(name: key, value: ::JSON.unparse(val))
|
99
|
+
else
|
100
|
+
xml.property(name: key, value: val)
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
#
|
105
|
+
# Get hash of attributes for root JUnit `testsuites` element.
|
106
|
+
#
|
107
|
+
def testsuites_el_attrs(log)
|
108
|
+
{
|
109
|
+
# total number of tests
|
110
|
+
tests: log.tests.size,
|
111
|
+
|
112
|
+
# total number of failed tests
|
113
|
+
failures: log.tests.reduce(0) do |r, test|
|
114
|
+
r + (test.failed? ? 1 : 0)
|
115
|
+
end,
|
116
|
+
|
117
|
+
# total amount of time across all tests
|
118
|
+
time: log.tests.reduce(0) do |r, test|
|
119
|
+
r + test.duration
|
120
|
+
end,
|
121
|
+
}
|
122
|
+
end
|
123
|
+
|
124
|
+
#
|
125
|
+
# Get hash of attributes for JUnit `testsuite` element.
|
126
|
+
#
|
127
|
+
def testsuite_el_attrs(test, test_num)
|
128
|
+
{
|
129
|
+
# test number, starting from zero
|
130
|
+
id: test_num,
|
131
|
+
|
132
|
+
# junit-friendly class name
|
133
|
+
name: safe_name(test.name),
|
134
|
+
|
135
|
+
# total number of tests (always 1)
|
136
|
+
tests: 1,
|
137
|
+
|
138
|
+
# total number of errors (always either 0 or 1)
|
139
|
+
errors: test.failed? ? 1 : 0,
|
140
|
+
|
141
|
+
# total amount of time for this test
|
142
|
+
time: test.duration,
|
143
|
+
}
|
144
|
+
end
|
145
|
+
|
146
|
+
#
|
147
|
+
# Get hash of attributes for JUnit `testcase` element.
|
148
|
+
#
|
149
|
+
def testcase_el_attrs(test)
|
150
|
+
{
|
151
|
+
# test case name
|
152
|
+
name: 'main',
|
153
|
+
|
154
|
+
# test case class name
|
155
|
+
classname: safe_name(test.name),
|
156
|
+
|
157
|
+
# time taken (in seconds) to execute test.
|
158
|
+
time: test.duration,
|
159
|
+
}
|
160
|
+
end
|
161
|
+
|
162
|
+
#
|
163
|
+
# Invalid characters in JUnit class name.
|
164
|
+
#
|
165
|
+
BAD_CHARS = /[^a-z0-9_]+/
|
166
|
+
|
167
|
+
#
|
168
|
+
# Sanitize a Meson test name as a JUnit-friendly class name.
|
169
|
+
#
|
170
|
+
def safe_name(s)
|
171
|
+
s.gsub(BAD_CHARS, '_')
|
172
|
+
end
|
173
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
#
|
2
|
+
# Single Meson test result.
|
3
|
+
#
|
4
|
+
class MesonJunit::Meson::TestLog
|
5
|
+
#
|
6
|
+
# Individual Meson test results.
|
7
|
+
#
|
8
|
+
attr :tests
|
9
|
+
|
10
|
+
#
|
11
|
+
# Parse a testlog.json file.
|
12
|
+
#
|
13
|
+
def initialize(io)
|
14
|
+
@tests = io.readlines.map do |line|
|
15
|
+
::MesonJunit::Meson::Test.new(::JSON.parse(line))
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
#
|
2
|
+
# Single Meson test result.
|
3
|
+
#
|
4
|
+
class MesonJunit::Meson::Test
|
5
|
+
#
|
6
|
+
# Parsed JSON data.
|
7
|
+
#
|
8
|
+
attr :data
|
9
|
+
|
10
|
+
#
|
11
|
+
# Test name.
|
12
|
+
#
|
13
|
+
attr :name
|
14
|
+
|
15
|
+
#
|
16
|
+
# Duration of test run, in seconds.
|
17
|
+
#
|
18
|
+
attr :duration
|
19
|
+
|
20
|
+
#
|
21
|
+
# Test result (either :OK or :FAIL).
|
22
|
+
#
|
23
|
+
attr :result
|
24
|
+
|
25
|
+
#
|
26
|
+
# Create a test case from parsed Meson JSON data.
|
27
|
+
#
|
28
|
+
def initialize(data)
|
29
|
+
@data = data.freeze
|
30
|
+
@name = @data['name']
|
31
|
+
@duration = @data['duration'] || 0
|
32
|
+
@result = @data['result'].intern
|
33
|
+
end
|
34
|
+
|
35
|
+
#
|
36
|
+
# Did this test succeed?
|
37
|
+
#
|
38
|
+
def ok?
|
39
|
+
@result == :OK
|
40
|
+
end
|
41
|
+
|
42
|
+
#
|
43
|
+
# Did this test fail?
|
44
|
+
#
|
45
|
+
def failed?
|
46
|
+
@result == :FAIL
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,5 @@
|
|
1
|
+
{"name": "test-io-logger", "stdout": "", "result": "OK", "duration": 0.017489910125732422, "returncode": 0, "command": ["/var/lib/jenkins/workspace/raggle_master/build/sanitize/address/test-io-logger"], "env": {"GIT_PREVIOUS_SUCCESSFUL_COMMIT": "980602362882ea45fe08b67e01eecf8114e663b9", "HOSTNAME": "d38bcdc0a0f0", "RUN_CHANGES_DISPLAY_URL": "http://hive:9090/job/raggle/job/master/32/display/redirect?page=changes", "GIT_COMMIT": "0a342a9d5f2058e9f2872078c45d791cd62a3b61", "NODE_LABELS": "master", "HUDSON_URL": "http://hive:9090/", "HOME": "/", "OLDPWD": "/var/lib/jenkins/workspace/raggle_master", "BUILD_URL": "http://hive:9090/job/raggle/job/master/32/", "GIT_LOCAL_BRANCH": "master", "JENKINS_SERVER_COOKIE": "durable-a623a7ae73afbc86e3205e2d30ff0631", "LDFLAGS": "-lasan", "WORKSPACE": "/var/lib/jenkins/workspace/raggle_master", "NODE_NAME": "master", "EXECUTOR_NUMBER": "1", "GIT_BRANCH": "master", "STAGE_NAME": "address", "BUILD_DISPLAY_NAME": "#32", "HUDSON_HOME": "/var/lib/jenkins", "JOB_BASE_NAME": "master", "PATH": "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin", "BUILD_ID": "32", "CFLAGS": "-g", "BUILD_TAG": "jenkins-raggle-master-32", "JENKINS_URL": "http://hive:9090/", "JOB_URL": "http://hive:9090/job/raggle/job/master/", "GIT_URL": "git://u3/raggle.git", "BUILD_NUMBER": "32", "JENKINS_NODE_COOKIE": "5384bb4a-0b67-4e96-8d36-afa4e39e8bff", "RUN_DISPLAY_URL": "http://hive:9090/job/raggle/job/master/32/display/redirect", "HUDSON_SERVER_COOKIE": "44bd36d136089097", "JOB_DISPLAY_URL": "http://hive:9090/job/raggle/job/master/display/redirect", "CLASSPATH": "", "JOB_NAME": "raggle/master", "PWD": "/var/lib/jenkins/workspace/raggle_master/build/sanitize/address", "GIT_PREVIOUS_COMMIT": "d1721a6594f2688dbac2be0c1142edf49ff634da", "CC": "clang-7", "BRANCH_NAME": "master", "LC_CTYPE": "C.UTF-8"}}
|
2
|
+
{"name": "test-file-logger", "stdout": "", "result": "OK", "duration": 0.027406692504882812, "returncode": 0, "command": ["/var/lib/jenkins/workspace/raggle_master/build/sanitize/address/test-file-logger"], "env": {"GIT_PREVIOUS_SUCCESSFUL_COMMIT": "980602362882ea45fe08b67e01eecf8114e663b9", "HOSTNAME": "d38bcdc0a0f0", "RUN_CHANGES_DISPLAY_URL": "http://hive:9090/job/raggle/job/master/32/display/redirect?page=changes", "GIT_COMMIT": "0a342a9d5f2058e9f2872078c45d791cd62a3b61", "NODE_LABELS": "master", "HUDSON_URL": "http://hive:9090/", "HOME": "/", "OLDPWD": "/var/lib/jenkins/workspace/raggle_master", "BUILD_URL": "http://hive:9090/job/raggle/job/master/32/", "GIT_LOCAL_BRANCH": "master", "JENKINS_SERVER_COOKIE": "durable-a623a7ae73afbc86e3205e2d30ff0631", "LDFLAGS": "-lasan", "WORKSPACE": "/var/lib/jenkins/workspace/raggle_master", "NODE_NAME": "master", "EXECUTOR_NUMBER": "1", "GIT_BRANCH": "master", "STAGE_NAME": "address", "BUILD_DISPLAY_NAME": "#32", "HUDSON_HOME": "/var/lib/jenkins", "JOB_BASE_NAME": "master", "PATH": "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin", "BUILD_ID": "32", "CFLAGS": "-g", "BUILD_TAG": "jenkins-raggle-master-32", "JENKINS_URL": "http://hive:9090/", "JOB_URL": "http://hive:9090/job/raggle/job/master/", "GIT_URL": "git://u3/raggle.git", "BUILD_NUMBER": "32", "JENKINS_NODE_COOKIE": "5384bb4a-0b67-4e96-8d36-afa4e39e8bff", "RUN_DISPLAY_URL": "http://hive:9090/job/raggle/job/master/32/display/redirect", "HUDSON_SERVER_COOKIE": "44bd36d136089097", "JOB_DISPLAY_URL": "http://hive:9090/job/raggle/job/master/display/redirect", "CLASSPATH": "", "JOB_NAME": "raggle/master", "PWD": "/var/lib/jenkins/workspace/raggle_master/build/sanitize/address", "GIT_PREVIOUS_COMMIT": "d1721a6594f2688dbac2be0c1142edf49ff634da", "CC": "clang-7", "BRANCH_NAME": "master", "LC_CTYPE": "C.UTF-8"}}
|
3
|
+
{"name": "test-mem-store", "stdout": "", "result": "FAIL", "duration": 0.3238527774810791, "returncode": 1, "command": ["/var/lib/jenkins/workspace/raggle_master/build/sanitize/address/test-mem-store"], "env": {"GIT_PREVIOUS_SUCCESSFUL_COMMIT": "980602362882ea45fe08b67e01eecf8114e663b9", "HOSTNAME": "d38bcdc0a0f0", "RUN_CHANGES_DISPLAY_URL": "http://hive:9090/job/raggle/job/master/32/display/redirect?page=changes", "GIT_COMMIT": "0a342a9d5f2058e9f2872078c45d791cd62a3b61", "NODE_LABELS": "master", "HUDSON_URL": "http://hive:9090/", "HOME": "/", "OLDPWD": "/var/lib/jenkins/workspace/raggle_master", "BUILD_URL": "http://hive:9090/job/raggle/job/master/32/", "GIT_LOCAL_BRANCH": "master", "JENKINS_SERVER_COOKIE": "durable-a623a7ae73afbc86e3205e2d30ff0631", "LDFLAGS": "-lasan", "WORKSPACE": "/var/lib/jenkins/workspace/raggle_master", "NODE_NAME": "master", "EXECUTOR_NUMBER": "1", "GIT_BRANCH": "master", "STAGE_NAME": "address", "BUILD_DISPLAY_NAME": "#32", "HUDSON_HOME": "/var/lib/jenkins", "JOB_BASE_NAME": "master", "PATH": "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin", "BUILD_ID": "32", "CFLAGS": "-g", "BUILD_TAG": "jenkins-raggle-master-32", "JENKINS_URL": "http://hive:9090/", "JOB_URL": "http://hive:9090/job/raggle/job/master/", "GIT_URL": "git://u3/raggle.git", "BUILD_NUMBER": "32", "JENKINS_NODE_COOKIE": "5384bb4a-0b67-4e96-8d36-afa4e39e8bff", "RUN_DISPLAY_URL": "http://hive:9090/job/raggle/job/master/32/display/redirect", "HUDSON_SERVER_COOKIE": "44bd36d136089097", "JOB_DISPLAY_URL": "http://hive:9090/job/raggle/job/master/display/redirect", "CLASSPATH": "", "JOB_NAME": "raggle/master", "PWD": "/var/lib/jenkins/workspace/raggle_master/build/sanitize/address", "GIT_PREVIOUS_COMMIT": "d1721a6594f2688dbac2be0c1142edf49ff634da", "CC": "clang-7", "BRANCH_NAME": "master", "LC_CTYPE": "C.UTF-8"}, "stderr": "\n=================================================================\n==305==ERROR: LeakSanitizer: detected memory leaks\n\nDirect leak of 384 byte(s) in 1 object(s) allocated from:\n #0 0x4c5552 in realloc (/var/lib/jenkins/workspace/raggle_master/build/sanitize/address/test-mem-store+0x4c5552)\n #1 0x4f4759 in on_rg_ctx_realloc /var/lib/jenkins/workspace/raggle_master/build/sanitize/address/../../../src/core/rg-ctx.c:27:26\n #2 0x4f4539 in rg_ctx_realloc /var/lib/jenkins/workspace/raggle_master/build/sanitize/address/../../../src/core/rg-ctx.c:125:10\n #3 0x4f891f in rg_mem_store_resize_folders /var/lib/jenkins/workspace/raggle_master/build/sanitize/address/../../../src/core/rg-mem-store.c:43:37\n #4 0x4f8656 in rg_mem_store_init /var/lib/jenkins/workspace/raggle_master/build/sanitize/address/../../../src/core/rg-mem-store.c:377:8\n #5 0x4fb769 in mem_store_test_run /var/lib/jenkins/workspace/raggle_master/build/sanitize/address/../../../src/tests/shared/mem-store-test.c:23:8\n #6 0x4fb8ce in main /var/lib/jenkins/workspace/raggle_master/build/sanitize/address/../../../src/tests/mem-store/main.c:18:3\n #7 0x7f47cc22f09a in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2409a)\n\nSUMMARY: AddressSanitizer: 384 byte(s) leaked in 1 allocation(s).\n"}
|
4
|
+
{"name": "test-mem-store-add-feeds", "stdout": "", "result": "FAIL", "duration": 0.325427770614624, "returncode": 1, "command": ["/var/lib/jenkins/workspace/raggle_master/build/sanitize/address/test-mem-store-add-feeds"], "env": {"GIT_PREVIOUS_SUCCESSFUL_COMMIT": "980602362882ea45fe08b67e01eecf8114e663b9", "HOSTNAME": "d38bcdc0a0f0", "RUN_CHANGES_DISPLAY_URL": "http://hive:9090/job/raggle/job/master/32/display/redirect?page=changes", "GIT_COMMIT": "0a342a9d5f2058e9f2872078c45d791cd62a3b61", "NODE_LABELS": "master", "HUDSON_URL": "http://hive:9090/", "HOME": "/", "OLDPWD": "/var/lib/jenkins/workspace/raggle_master", "BUILD_URL": "http://hive:9090/job/raggle/job/master/32/", "GIT_LOCAL_BRANCH": "master", "JENKINS_SERVER_COOKIE": "durable-a623a7ae73afbc86e3205e2d30ff0631", "LDFLAGS": "-lasan", "WORKSPACE": "/var/lib/jenkins/workspace/raggle_master", "NODE_NAME": "master", "EXECUTOR_NUMBER": "1", "GIT_BRANCH": "master", "STAGE_NAME": "address", "BUILD_DISPLAY_NAME": "#32", "HUDSON_HOME": "/var/lib/jenkins", "JOB_BASE_NAME": "master", "PATH": "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin", "BUILD_ID": "32", "CFLAGS": "-g", "BUILD_TAG": "jenkins-raggle-master-32", "JENKINS_URL": "http://hive:9090/", "JOB_URL": "http://hive:9090/job/raggle/job/master/", "GIT_URL": "git://u3/raggle.git", "BUILD_NUMBER": "32", "JENKINS_NODE_COOKIE": "5384bb4a-0b67-4e96-8d36-afa4e39e8bff", "RUN_DISPLAY_URL": "http://hive:9090/job/raggle/job/master/32/display/redirect", "HUDSON_SERVER_COOKIE": "44bd36d136089097", "JOB_DISPLAY_URL": "http://hive:9090/job/raggle/job/master/display/redirect", "CLASSPATH": "", "JOB_NAME": "raggle/master", "PWD": "/var/lib/jenkins/workspace/raggle_master/build/sanitize/address", "GIT_PREVIOUS_COMMIT": "d1721a6594f2688dbac2be0c1142edf49ff634da", "CC": "clang-7", "BRANCH_NAME": "master", "LC_CTYPE": "C.UTF-8"}, "stderr": "\n=================================================================\n==307==ERROR: LeakSanitizer: detected memory leaks\n\nDirect leak of 384 byte(s) in 1 object(s) allocated from:\n #0 0x4c5552 in realloc (/var/lib/jenkins/workspace/raggle_master/build/sanitize/address/test-mem-store-add-feeds+0x4c5552)\n #1 0x4f4759 in on_rg_ctx_realloc /var/lib/jenkins/workspace/raggle_master/build/sanitize/address/../../../src/core/rg-ctx.c:27:26\n #2 0x4f4539 in rg_ctx_realloc /var/lib/jenkins/workspace/raggle_master/build/sanitize/address/../../../src/core/rg-ctx.c:125:10\n #3 0x4f891f in rg_mem_store_resize_folders /var/lib/jenkins/workspace/raggle_master/build/sanitize/address/../../../src/core/rg-mem-store.c:43:37\n #4 0x4f8656 in rg_mem_store_init /var/lib/jenkins/workspace/raggle_master/build/sanitize/address/../../../src/core/rg-mem-store.c:377:8\n #5 0x4fb769 in mem_store_test_run /var/lib/jenkins/workspace/raggle_master/build/sanitize/address/../../../src/tests/shared/mem-store-test.c:23:8\n #6 0x4fb8ce in main /var/lib/jenkins/workspace/raggle_master/build/sanitize/address/../../../src/tests/mem-store-add-feeds/main.c:34:3\n #7 0x7f92456a509a in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2409a)\n\nSUMMARY: AddressSanitizer: 384 byte(s) leaked in 1 allocation(s).\n"}
|
5
|
+
{"name": "test-mem-store-add-folders", "stdout": "", "result": "FAIL", "duration": 0.37346959114074707, "returncode": 1, "command": ["/var/lib/jenkins/workspace/raggle_master/build/sanitize/address/test-mem-store-add-folders"], "env": {"GIT_PREVIOUS_SUCCESSFUL_COMMIT": "980602362882ea45fe08b67e01eecf8114e663b9", "HOSTNAME": "d38bcdc0a0f0", "RUN_CHANGES_DISPLAY_URL": "http://hive:9090/job/raggle/job/master/32/display/redirect?page=changes", "GIT_COMMIT": "0a342a9d5f2058e9f2872078c45d791cd62a3b61", "NODE_LABELS": "master", "HUDSON_URL": "http://hive:9090/", "HOME": "/", "OLDPWD": "/var/lib/jenkins/workspace/raggle_master", "BUILD_URL": "http://hive:9090/job/raggle/job/master/32/", "GIT_LOCAL_BRANCH": "master", "JENKINS_SERVER_COOKIE": "durable-a623a7ae73afbc86e3205e2d30ff0631", "LDFLAGS": "-lasan", "WORKSPACE": "/var/lib/jenkins/workspace/raggle_master", "NODE_NAME": "master", "EXECUTOR_NUMBER": "1", "GIT_BRANCH": "master", "STAGE_NAME": "address", "BUILD_DISPLAY_NAME": "#32", "HUDSON_HOME": "/var/lib/jenkins", "JOB_BASE_NAME": "master", "PATH": "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin", "BUILD_ID": "32", "CFLAGS": "-g", "BUILD_TAG": "jenkins-raggle-master-32", "JENKINS_URL": "http://hive:9090/", "JOB_URL": "http://hive:9090/job/raggle/job/master/", "GIT_URL": "git://u3/raggle.git", "BUILD_NUMBER": "32", "JENKINS_NODE_COOKIE": "5384bb4a-0b67-4e96-8d36-afa4e39e8bff", "RUN_DISPLAY_URL": "http://hive:9090/job/raggle/job/master/32/display/redirect", "HUDSON_SERVER_COOKIE": "44bd36d136089097", "JOB_DISPLAY_URL": "http://hive:9090/job/raggle/job/master/display/redirect", "CLASSPATH": "", "JOB_NAME": "raggle/master", "PWD": "/var/lib/jenkins/workspace/raggle_master/build/sanitize/address", "GIT_PREVIOUS_COMMIT": "d1721a6594f2688dbac2be0c1142edf49ff634da", "CC": "clang-7", "BRANCH_NAME": "master", "LC_CTYPE": "C.UTF-8"}, "stderr": "\n=================================================================\n==304==ERROR: LeakSanitizer: detected memory leaks\n\nDirect leak of 384 byte(s) in 1 object(s) allocated from:\n #0 0x4c5552 in realloc (/var/lib/jenkins/workspace/raggle_master/build/sanitize/address/test-mem-store-add-folders+0x4c5552)\n #1 0x4f4759 in on_rg_ctx_realloc /var/lib/jenkins/workspace/raggle_master/build/sanitize/address/../../../src/core/rg-ctx.c:27:26\n #2 0x4f4539 in rg_ctx_realloc /var/lib/jenkins/workspace/raggle_master/build/sanitize/address/../../../src/core/rg-ctx.c:125:10\n #3 0x4f891f in rg_mem_store_resize_folders /var/lib/jenkins/workspace/raggle_master/build/sanitize/address/../../../src/core/rg-mem-store.c:43:37\n #4 0x4f8656 in rg_mem_store_init /var/lib/jenkins/workspace/raggle_master/build/sanitize/address/../../../src/core/rg-mem-store.c:377:8\n #5 0x4fb769 in mem_store_test_run /var/lib/jenkins/workspace/raggle_master/build/sanitize/address/../../../src/tests/shared/mem-store-test.c:23:8\n #6 0x4fb8ce in main /var/lib/jenkins/workspace/raggle_master/build/sanitize/address/../../../src/tests/mem-store-add-folders/main.c:34:3\n #7 0x7f967de4a09a in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2409a)\n\nIndirect leak of 12 byte(s) in 3 object(s) allocated from:\n #0 0x4c5552 in realloc (/var/lib/jenkins/workspace/raggle_master/build/sanitize/address/test-mem-store-add-folders+0x4c5552)\n #1 0x4f4759 in on_rg_ctx_realloc /var/lib/jenkins/workspace/raggle_master/build/sanitize/address/../../../src/core/rg-ctx.c:27:26\n #2 0x4f4539 in rg_ctx_realloc /var/lib/jenkins/workspace/raggle_master/build/sanitize/address/../../../src/core/rg-ctx.c:125:10\n #3 0x4f44b3 in rg_ctx_malloc /var/lib/jenkins/workspace/raggle_master/build/sanitize/address/../../../src/core/rg-ctx.c:116:10\n #4 0x4f45cf in rg_ctx_strndup /var/lib/jenkins/workspace/raggle_master/build/sanitize/address/../../../src/core/rg-ctx.c:149:22\n #5 0x4fb0b1 in rg_folder_set_str /var/lib/jenkins/workspace/raggle_master/build/sanitize/address/../../../src/core/rg-folder.c:68:38\n #6 0x4f91ec in on_mem_store_folder_add /var/lib/jenkins/workspace/raggle_master/build/sanitize/address/../../../src/core/rg-mem-store.c:92:8\n #7 0x4f68b1 in rg_store_folder_add /var/lib/jenkins/workspace/raggle_master/build/sanitize/address/../../../src/core/rg-store.c:76:5\n #8 0x4fba48 in run /var/lib/jenkins/workspace/raggle_master/build/sanitize/address/../../../src/tests/mem-store-add-folders/main.c:23:10\n #9 0x4fb793 in mem_store_test_run /var/lib/jenkins/workspace/raggle_master/build/sanitize/address/../../../src/tests/shared/mem-store-test.c:28:3\n #10 0x4fb8ce in main /var/lib/jenkins/workspace/raggle_master/build/sanitize/address/../../../src/tests/mem-store-add-folders/main.c:34:3\n #11 0x7f967de4a09a in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2409a)\n\nSUMMARY: AddressSanitizer: 396 byte(s) leaked in 4 allocation(s).\n"}
|
data/test/test_junit.rb
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'minitest/autorun'
|
2
|
+
require 'meson-junit'
|
3
|
+
|
4
|
+
class JunitTest < MiniTest::Test
|
5
|
+
def test_junit_xmlbuilder_new
|
6
|
+
builder = ::MesonJunit::Junit::XMLBuilder.new
|
7
|
+
assert_instance_of ::MesonJunit::Junit::XMLBuilder, builder
|
8
|
+
end
|
9
|
+
|
10
|
+
TESTLOG_PATH = File.join(__dir__, 'data', 'testlog.json')
|
11
|
+
|
12
|
+
def test_junit_xmlbuilder_build
|
13
|
+
# parse sample testlog.json
|
14
|
+
log = File.open(TESTLOG_PATH) do |fh|
|
15
|
+
# parse input file as a Meson::TestLog
|
16
|
+
::MesonJunit::Meson::TestLog.new(fh)
|
17
|
+
end
|
18
|
+
|
19
|
+
# build junit xml
|
20
|
+
xml = ::MesonJunit::Junit::XMLBuilder.build(log)
|
21
|
+
|
22
|
+
assert_instance_of String, xml
|
23
|
+
end
|
24
|
+
end
|
data/test/test_meson.rb
ADDED
@@ -0,0 +1,59 @@
|
|
1
|
+
require 'minitest/autorun'
|
2
|
+
require 'json'
|
3
|
+
require 'meson-junit'
|
4
|
+
|
5
|
+
class MesonTest < MiniTest::Test
|
6
|
+
# sample JSON
|
7
|
+
MOCK_JSON = '{
|
8
|
+
"name": "test-something",
|
9
|
+
"stdout": "",
|
10
|
+
"result": "OK",
|
11
|
+
"duration": 0.017489910125732422,
|
12
|
+
"returncode": 0,
|
13
|
+
"command": [
|
14
|
+
"/path/to/tests/test-something"
|
15
|
+
],
|
16
|
+
"env": {
|
17
|
+
"FOO": "some foo data",
|
18
|
+
"BAR": "some bar data",
|
19
|
+
"BAZ": "some baz data"
|
20
|
+
}
|
21
|
+
}'.freeze
|
22
|
+
|
23
|
+
def test_meson_test_new
|
24
|
+
data = ::JSON.parse(MOCK_JSON)
|
25
|
+
t = ::MesonJunit::Meson::Test.new(data)
|
26
|
+
assert_instance_of ::MesonJunit::Meson::Test, t
|
27
|
+
end
|
28
|
+
|
29
|
+
# path to sample testlog.json
|
30
|
+
TESTLOG_PATH = File.join(__dir__, 'data', 'testlog.json').freeze
|
31
|
+
|
32
|
+
# expected sums
|
33
|
+
EXPECTED_SUMS = {
|
34
|
+
all: 5,
|
35
|
+
OK: 2,
|
36
|
+
FAIL: 3,
|
37
|
+
}
|
38
|
+
|
39
|
+
def test_meson_testlog_new
|
40
|
+
# parse sample testlog.json
|
41
|
+
log = File.open(TESTLOG_PATH) do |fh|
|
42
|
+
::MesonJunit::Meson::TestLog.new(fh)
|
43
|
+
end
|
44
|
+
|
45
|
+
# verify that it parsed as a test log
|
46
|
+
assert_instance_of ::MesonJunit::Meson::TestLog, log
|
47
|
+
|
48
|
+
sums = log.tests.reduce(Hash.new { |h, k| h[k] = 0 }) do |r, test|
|
49
|
+
r[:all] += 1
|
50
|
+
r[test.result] += 1
|
51
|
+
r
|
52
|
+
end
|
53
|
+
|
54
|
+
# verify test counts
|
55
|
+
EXPECTED_SUMS.each do |key, sum|
|
56
|
+
assert_equal sum, sums[key]
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
metadata
ADDED
@@ -0,0 +1,105 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: meson-junit
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Paul Duncan
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2019-12-01 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: nokogiri
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: minitest
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '5'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '5'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: minitest-junit
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: 0.2.0
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: 0.2.0
|
55
|
+
description: "\n Command-line tool and library to convert Meson testlog JSOn files
|
56
|
+
to\n Jenkins-compatible JUnit XML files.\n "
|
57
|
+
email: pabs@pablotron.org
|
58
|
+
executables:
|
59
|
+
- meson-junit
|
60
|
+
extensions: []
|
61
|
+
extra_rdoc_files: []
|
62
|
+
files:
|
63
|
+
- README.md
|
64
|
+
- Rakefile
|
65
|
+
- bin/meson-junit
|
66
|
+
- lib/meson-junit.rb
|
67
|
+
- lib/meson-junit/cli.rb
|
68
|
+
- lib/meson-junit/junit.rb
|
69
|
+
- lib/meson-junit/junit/xml-builder.rb
|
70
|
+
- lib/meson-junit/meson.rb
|
71
|
+
- lib/meson-junit/meson/test-log.rb
|
72
|
+
- lib/meson-junit/meson/test.rb
|
73
|
+
- test/data/testlog.json
|
74
|
+
- test/test_junit.rb
|
75
|
+
- test/test_meson.rb
|
76
|
+
homepage: https://github.com/pablotron/meson-junit
|
77
|
+
licenses:
|
78
|
+
- MIT
|
79
|
+
metadata:
|
80
|
+
bug_tracker_uri: https://github.com/pablotron/meson-junit/issues
|
81
|
+
documentation_uri: https://pablotron.github.io/meson-junit/
|
82
|
+
homepage_uri: https://github.com/pablotron/meson-junit
|
83
|
+
source_code_uri: https://github.com/pablotron/meson-junit
|
84
|
+
wiki_uri: https://github.com/pablotron/meson-junit/wiki
|
85
|
+
post_install_message:
|
86
|
+
rdoc_options: []
|
87
|
+
require_paths:
|
88
|
+
- lib
|
89
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
90
|
+
requirements:
|
91
|
+
- - ">="
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
version: '0'
|
94
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
95
|
+
requirements:
|
96
|
+
- - ">="
|
97
|
+
- !ruby/object:Gem::Version
|
98
|
+
version: '0'
|
99
|
+
requirements: []
|
100
|
+
rubyforge_project:
|
101
|
+
rubygems_version: 2.7.6.2
|
102
|
+
signing_key:
|
103
|
+
specification_version: 4
|
104
|
+
summary: Convert Meson testlog JSON to JUnit XML.
|
105
|
+
test_files: []
|