XML: The output parameter --xml now generates xml-files with the elapsed time.

This commit is contained in:
commit 2016-04-19 16:22:23 +02:00
parent 1f7ca2f32b
commit f5340f8f27
2 changed files with 71 additions and 38 deletions

View file

@ -25,6 +25,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <locale.h>
#include "criterion/stats.h"
#include "criterion/options.h"
#include "criterion/internal/ordered-set.h"
@ -56,7 +57,9 @@
"failures=\"" CR_SIZE_T_FORMAT "\" " \
"errors=\"" CR_SIZE_T_FORMAT "\" " \
"disabled=\"" CR_SIZE_T_FORMAT "\" " \
"skipped=\"" CR_SIZE_T_FORMAT "\""
"skipped=\"" CR_SIZE_T_FORMAT "\" " \
"time=\"%.3f\""
#define XML_TESTSUITE_TEMPLATE_BEGIN \
" <testsuite " TESTSUITE_PROPERTIES ">\n"
@ -67,7 +70,8 @@
#define TEST_PROPERTIES \
"name=\"%s\" " \
"assertions=\"" CR_SIZE_T_FORMAT "\" " \
"status=\"%s\""
"status=\"%s\" " \
"time=\"%.3f\""
#define XML_TEST_TEMPLATE_BEGIN \
" <testcase " TEST_PROPERTIES ">\n" \
@ -98,7 +102,7 @@ static INLINE bool is_disabled(struct criterion_test *t, struct criterion_suite
return t->data->disabled || (s->data && s->data->disabled);
}
static CR_INLINE
static INLINE
const char *get_status_string(struct criterion_test_stats *ts,
struct criterion_suite_stats *ss) {
@ -112,14 +116,33 @@ const char *get_status_string(struct criterion_test_stats *ts,
return status;
}
/*
* floats are printed locale dependent, but the xml-specification
* requires a dot as the decimal separator.
* Therefore we set the locale temporarily to print dots.
*/
static int fprintf_locale(FILE *restrict stream,
const char *restrict format, ...) {
va_list args;
int result;
const char *locale = setlocale(LC_NUMERIC, NULL);
setlocale(LC_NUMERIC, "C");
va_start(args, format);
result = vfprintf(stream, format, args);
va_end(args);
setlocale(LC_NUMERIC, locale);
return result;
}
static void print_test(FILE *f,
struct criterion_test_stats *ts,
struct criterion_suite_stats *ss) {
fprintf(f, XML_TEST_TEMPLATE_BEGIN,
fprintf_locale(f, XML_TEST_TEMPLATE_BEGIN,
ts->test->name,
(size_t) (ts->passed_asserts + ts->failed_asserts),
get_status_string(ts, ss)
get_status_string(ts, ss),
ts->elapsed_time
);
if (is_disabled(ts->test, ss->suite)) {
@ -156,6 +179,15 @@ static void print_test(FILE *f,
fprintf(f, XML_TEST_TEMPLATE_END);
}
static INLINE float get_time_elapsed_suite(struct criterion_suite_stats *ss)
{
float result = 0;
for (struct criterion_test_stats *ts = ss->tests; ts; ts = ts->next) {
result += ts->elapsed_time;
}
return result;
}
void xml_report(FILE *f, struct criterion_global_stats *stats) {
fprintf(f, XML_BASE_TEMPLATE_BEGIN,
stats->nb_tests,
@ -166,13 +198,14 @@ void xml_report(FILE *f, struct criterion_global_stats *stats) {
for (struct criterion_suite_stats *ss = stats->suites; ss; ss = ss->next) {
fprintf(f, XML_TESTSUITE_TEMPLATE_BEGIN,
fprintf_locale(f, XML_TESTSUITE_TEMPLATE_BEGIN,
ss->suite->name,
ss->nb_tests,
ss->tests_failed,
ss->tests_crashed,
ss->tests_skipped,
ss->tests_skipped
ss->tests_skipped,
get_time_elapsed_suite(ss)
);
for (struct criterion_test_stats *ts = ss->tests; ts; ts = ts->next) {

View file

@ -4,10 +4,10 @@ Testing multiple samples with --xml
<?xml version="1.0" encoding="UTF-8"?>
<!-- Tests compiled with Criterion v2.2.1 -->
<testsuites name="Criterion Tests" tests="2" failures="1" errors="0" disabled="0">
<testsuite name="misc" tests="2" failures="1" errors="0" disabled="0" skipped="0">
<testcase name="passing" assertions="1" status="PASSED">
<testsuite name="misc" tests="2" failures="1" errors="0" disabled="0" skipped="0" time="0.000">
<testcase name="passing" assertions="1" status="PASSED" time="0.000">
</testcase>
<testcase name="failing" assertions="1" status="FAILED">
<testcase name="failing" assertions="1" status="FAILED" time="0.000">
<failure type="assert" message="1 assertion(s) failed.">simple.c:4: The expression 0 is false.&#10;</failure>
</testcase>
</testsuite>
@ -17,13 +17,13 @@ Testing multiple samples with --xml
<?xml version="1.0" encoding="UTF-8"?>
<!-- Tests compiled with Criterion v2.2.1 -->
<testsuites name="Criterion Tests" tests="3" failures="2" errors="1" disabled="0">
<testsuite name="simple" tests="3" failures="2" errors="1" disabled="0" skipped="0">
<testcase name="wrong_signal" assertions="0" status="FAILED">
<testsuite name="simple" tests="3" failures="2" errors="1" disabled="0" skipped="0" time="0.000">
<testcase name="wrong_signal" assertions="0" status="FAILED" time="0.000">
<failure type="assert" message="0 assertion(s) failed."></failure>
</testcase>
<testcase name="uncaught" assertions="0" status="ERRORED">
<testcase name="uncaught" assertions="0" status="ERRORED" time="0.000">
<error type="crash" message="The test crashed." /> </testcase>
<testcase name="caught" assertions="0" status="PASSED">
<testcase name="caught" assertions="0" status="PASSED" time="0.000">
</testcase>
</testsuite>
</testsuites>
@ -32,20 +32,20 @@ Testing multiple samples with --xml
<?xml version="1.0" encoding="UTF-8"?>
<!-- Tests compiled with Criterion v2.2.1 -->
<testsuites name="Criterion Tests" tests="6" failures="2" errors="0" disabled="0">
<testsuite name="asserts" tests="6" failures="2" errors="0" disabled="0" skipped="0">
<testcase name="string" assertions="10" status="PASSED">
<testsuite name="asserts" tests="6" failures="2" errors="0" disabled="0" skipped="0" time="0.000">
<testcase name="string" assertions="10" status="PASSED" time="0.000">
</testcase>
<testcase name="old_school" assertions="2" status="FAILED">
<testcase name="old_school" assertions="2" status="FAILED" time="0.000">
<failure type="assert" message="2 assertion(s) failed.">asserts.c:18: The conditions for this assertion were not met.&#10;asserts.c:17: You can fail an assertion with a message from anywhere&#10;</failure>
</testcase>
<testcase name="native" assertions="8" status="PASSED">
<testcase name="native" assertions="8" status="PASSED" time="0.000">
</testcase>
<testcase name="float" assertions="2" status="PASSED">
<testcase name="float" assertions="2" status="PASSED" time="0.000">
</testcase>
<testcase name="base" assertions="6" status="FAILED">
<testcase name="base" assertions="6" status="FAILED" time="0.000">
<failure type="assert" message="2 assertion(s) failed.">asserts.c:12: This assert runs&#10;asserts.c:11: assert is fatal, expect isn't&#10;</failure>
</testcase>
<testcase name="array" assertions="3" status="PASSED">
<testcase name="array" assertions="3" status="PASSED" time="0.000">
</testcase>
</testsuite>
</testsuites>
@ -54,16 +54,16 @@ Testing multiple samples with --xml
<?xml version="1.0" encoding="UTF-8"?>
<!-- Tests compiled with Criterion v2.2.1 -->
<testsuites name="Criterion Tests" tests="3" failures="0" errors="0" disabled="1">
<testsuite name="suite2" tests="1" failures="0" errors="0" disabled="0" skipped="0">
<testcase name="test" assertions="1" status="PASSED">
<testsuite name="suite2" tests="1" failures="0" errors="0" disabled="0" skipped="0" time="0.000">
<testcase name="test" assertions="1" status="PASSED" time="0.000">
</testcase>
</testsuite>
<testsuite name="suite1" tests="1" failures="0" errors="0" disabled="0" skipped="0">
<testcase name="test" assertions="1" status="PASSED">
<testsuite name="suite1" tests="1" failures="0" errors="0" disabled="0" skipped="0" time="0.000">
<testcase name="test" assertions="1" status="PASSED" time="0.000">
</testcase>
</testsuite>
<testsuite name="disabled" tests="1" failures="0" errors="0" disabled="1" skipped="1">
<testcase name="test" assertions="0" status="SKIPPED">
<testsuite name="disabled" tests="1" failures="0" errors="0" disabled="1" skipped="1" time="0.000">
<testcase name="test" assertions="0" status="SKIPPED" time="0.000">
<skipped/>
</testcase>
</testsuite>
@ -73,8 +73,8 @@ Testing multiple samples with --xml
<?xml version="1.0" encoding="UTF-8"?>
<!-- Tests compiled with Criterion v2.2.1 -->
<testsuites name="Criterion Tests" tests="1" failures="1" errors="0" disabled="0">
<testsuite name="sample" tests="1" failures="1" errors="0" disabled="0" skipped="0">
<testcase name="long_msg" assertions="1" status="FAILED">
<testsuite name="sample" tests="1" failures="1" errors="0" disabled="0" skipped="0" time="0.000">
<testcase name="long_msg" assertions="1" status="FAILED" time="0.000">
<failure type="assert" message="1 assertion(s) failed.">long-messages.c:4: This is&#10; A long message&#10; Spawning multiple lines.&#10; Formatting is respected.&#10;</failure>
</testcase>
</testsuite>
@ -84,11 +84,11 @@ Testing multiple samples with --xml
<?xml version="1.0" encoding="UTF-8"?>
<!-- Tests compiled with Criterion v2.2.1 -->
<testsuites name="Criterion Tests" tests="2" failures="1" errors="0" disabled="1">
<testsuite name="misc" tests="2" failures="1" errors="0" disabled="1" skipped="1">
<testcase name="skipped" assertions="0" status="SKIPPED">
<testsuite name="misc" tests="2" failures="1" errors="0" disabled="1" skipped="1" time="0.000">
<testcase name="skipped" assertions="0" status="SKIPPED" time="0.000">
<skipped/>
</testcase>
<testcase name="failing" assertions="1" status="FAILED">
<testcase name="failing" assertions="1" status="FAILED" time="0.000">
<failure type="assert" message="1 assertion(s) failed.">description.c:4: The expression 0 is false.&#10;</failure>
</testcase>
</testsuite>
@ -100,10 +100,10 @@ Testing --output=xml
<?xml version="1.0" encoding="UTF-8"?>
<!-- Tests compiled with Criterion v2.2.1 -->
<testsuites name="Criterion Tests" tests="2" failures="1" errors="0" disabled="0">
<testsuite name="misc" tests="2" failures="1" errors="0" disabled="0" skipped="0">
<testcase name="passing" assertions="1" status="PASSED">
<testsuite name="misc" tests="2" failures="1" errors="0" disabled="0" skipped="0" time="0.000">
<testcase name="passing" assertions="1" status="PASSED" time="0.000">
</testcase>
<testcase name="failing" assertions="1" status="FAILED">
<testcase name="failing" assertions="1" status="FAILED" time="0.000">
<failure type="assert" message="1 assertion(s) failed.">simple.c:4: The expression 0 is false.&#10;</failure>
</testcase>
</testsuite>
@ -115,10 +115,10 @@ Testing CRITERION_OUTPUTS
<?xml version="1.0" encoding="UTF-8"?>
<!-- Tests compiled with Criterion v2.2.1 -->
<testsuites name="Criterion Tests" tests="2" failures="1" errors="0" disabled="0">
<testsuite name="misc" tests="2" failures="1" errors="0" disabled="0" skipped="0">
<testcase name="passing" assertions="1" status="PASSED">
<testsuite name="misc" tests="2" failures="1" errors="0" disabled="0" skipped="0" time="0.000">
<testcase name="passing" assertions="1" status="PASSED" time="0.000">
</testcase>
<testcase name="failing" assertions="1" status="FAILED">
<testcase name="failing" assertions="1" status="FAILED" time="0.000">
<failure type="assert" message="1 assertion(s) failed.">simple.c:4: The expression 0 is false.&#10;</failure>
</testcase>
</testsuite>