aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoseph Hunkeler <jhunkeler@gmail.com>2024-12-24 01:36:47 -0500
committerJoseph Hunkeler <jhunkeler@gmail.com>2024-12-24 01:36:47 -0500
commit1f21976f8ed09adb73c115f0f8067ed0eee1d861 (patch)
tree6e2fff82575e109993f4ee83e932c6b45c13a6e8
parent4f7d8227615695c1bc8d7f9c6938df88fe084941 (diff)
downloadstasis-1f21976f8ed09adb73c115f0f8067ed0eee1d861.tar.gz
indexer: Rewrite indexer_junitxml_report from scratch
-rw-r--r--src/cli/stasis_indexer/callbacks.c6
-rw-r--r--src/cli/stasis_indexer/junitxml_report.c233
2 files changed, 105 insertions, 134 deletions
diff --git a/src/cli/stasis_indexer/callbacks.c b/src/cli/stasis_indexer/callbacks.c
index 0186e1c..603aef9 100644
--- a/src/cli/stasis_indexer/callbacks.c
+++ b/src/cli/stasis_indexer/callbacks.c
@@ -25,13 +25,15 @@ int callback_sort_deliveries_cmpfn(const void *a, const void *b) {
int callback_sort_deliveries_dynamic_cmpfn(const void *a, const void *b) {
const struct Delivery *delivery1 = a;
const size_t delivery1_python = strtoul(delivery1->meta.python_compact, NULL, 10);
+ const int delivery1_rc = delivery1->meta.rc;
const struct Delivery *delivery2 = b;
const size_t delivery2_python = strtoul(delivery2->meta.python_compact, NULL, 10);
+ const int delivery2_rc = delivery2->meta.rc;
- if (delivery2_python > delivery1_python) {
+ if (delivery2_python > delivery1_python && delivery2_rc > delivery1_rc) {
return 1;
}
- if (delivery2_python < delivery1_python) {
+ if (delivery2_python < delivery1_python && delivery2_rc < delivery1_rc) {
return -1;
}
return 0;
diff --git a/src/cli/stasis_indexer/junitxml_report.c b/src/cli/stasis_indexer/junitxml_report.c
index 15adec3..65ec4f5 100644
--- a/src/cli/stasis_indexer/junitxml_report.c
+++ b/src/cli/stasis_indexer/junitxml_report.c
@@ -7,14 +7,85 @@
#include "junitxml.h"
#include "junitxml_report.h"
-int indexer_junitxml_report(struct Delivery ctx[], const size_t nelem) {
- struct Delivery *latest = get_latest_deliveries(ctx, nelem);
- if (!latest) {
- return -1;
+static int is_file_in_listing(struct StrList *list, const char *pattern) {
+ for (size_t i = 0; i < strlist_count(list); i++) {
+ char const *path = strlist_item(list, i);
+ if (!fnmatch(pattern, path, 0)) {
+ return 1;
+ }
}
- size_t latest_count;
- ARRAY_COUNT_BY_STRUCT_MEMBER(latest, meta.name, latest_count);
+ return 0;
+}
+
+static int write_report_output(struct Delivery *ctx, FILE *destfp, const char *xmlfilename) {
+ struct JUNIT_Testsuite *testsuite = junitxml_testsuite_read(xmlfilename);
+ if (testsuite) {
+ if (globals.verbose) {
+ printf("%s: duration: %0.4f, total: %d, passed: %d, failed: %d, skipped: %d, errors: %d\n", xmlfilename,
+ testsuite->time, testsuite->tests,
+ testsuite->passed, testsuite->failures,
+ testsuite->skipped, testsuite->errors);
+ }
+
+ char *bname_tmp = strdup(xmlfilename);
+ char *bname = path_basename(bname_tmp);
+ bname[strlen(bname) - 4] = 0;
+ guard_free(bname_tmp);
+
+ char result_outfile[PATH_MAX] = {0};
+ char *short_name_pattern = NULL;
+ asprintf(&short_name_pattern, "-%s", ctx->info.release_name);
+
+ char short_name[PATH_MAX] = {0};
+ strncpy(short_name, bname, sizeof(short_name) - 1);
+ replace_text(short_name, short_name_pattern, "", 0);
+ replace_text(short_name, "results-", "", 0);
+ guard_free(short_name_pattern);
+
+ fprintf(destfp, "|[%s](%s.html)|%0.4f|%d|%d|%d|%d|%d|\n", short_name, bname,
+ testsuite->time, testsuite->tests,
+ testsuite->passed, testsuite->failures,
+ testsuite->skipped, testsuite->errors);
+
+ snprintf(result_outfile, sizeof(result_outfile) - strlen(bname) - 3, "%s.md",
+ bname);
+ FILE *resultfp = fopen(result_outfile, "w+");
+ if (!resultfp) {
+ SYSERROR("Unable to open %s for writing", result_outfile);
+ return -1;
+ }
+ for (size_t i = 0; i < testsuite->_tc_inuse; i++) {
+ const char *type_str = NULL;
+ const int state = testsuite->testcase[i]->tc_result_state_type;
+ const char *message = NULL;
+ if (state == JUNIT_RESULT_STATE_FAILURE) {
+ message = testsuite->testcase[i]->result_state.failure->message;
+ type_str = "[FAILED]";
+ } else if (state == JUNIT_RESULT_STATE_ERROR) {
+ message = testsuite->testcase[i]->result_state.error->message;
+ type_str = "[ERROR]";
+ } else if (state == JUNIT_RESULT_STATE_SKIPPED) {
+ message = testsuite->testcase[i]->result_state.skipped->message;
+ type_str = "[SKIPPED]";
+ } else {
+ message = testsuite->testcase[i]->message ? testsuite->testcase[i]->message : "";
+ type_str = "[PASSED]";
+ }
+ fprintf(resultfp, "### %s %s :: %s\n", type_str,
+ testsuite->testcase[i]->classname, testsuite->testcase[i]->name);
+ fprintf(resultfp, "\nDuration: %0.04fs\n", testsuite->testcase[i]->time);
+ fprintf(resultfp, "\n```\n%s\n```\n\n", message);
+ }
+ junitxml_testsuite_free(&testsuite);
+ fclose(resultfp);
+ } else {
+ fprintf(stderr, "bad test suite: %s: %s\n", strerror(errno), xmlfilename);
+ }
+ return 0;
+}
+
+int indexer_junitxml_report(struct Delivery ctx[], const size_t nelem) {
char indexfile[PATH_MAX] = {0};
sprintf(indexfile, "%s/README.md", ctx->storage.results_dir);
@@ -30,144 +101,42 @@ int indexer_junitxml_report(struct Delivery ctx[], const size_t nelem) {
fprintf(stderr, "Unable to open %s for writing\n", indexfile);
return -1;
}
+ printf("index %s opened for writing", indexfile);
- struct StrList *archs = get_architectures(latest, nelem);
- struct StrList *platforms = get_platforms(latest, nelem);
- qsort(latest, latest_count, sizeof(*latest), callback_sort_deliveries_dynamic_cmpfn);
- fprintf(indexfp, "# %s-%s Test Report\n\n", ctx->meta.name, ctx->meta.version);
- size_t no_printable_data = 0;
-
- size_t delivery_count = get_latest_rc(latest, latest_count);
- for (size_t f = 0; f < strlist_count(file_listing); f++) {
- char *filename = strlist_item(file_listing, f);
- for (size_t p = 0; p < strlist_count(platforms); p++) {
- char *platform = strlist_item(platforms, p);
- for (size_t a = 0; a < strlist_count(archs); a++) {
- char *arch = strlist_item(archs, a);
-
- //fprintf(indexfp, "## %s-%s\n\n", platform, arch);
- for (size_t d = 0; d < latest_count; d++) {
- struct Delivery *current = &ctx[d];
- if (!endswith(filename, ".xml") || !strstr(current->system.arch, arch) ||
- !strstr(current->system.platform[DELIVERY_PLATFORM_RELEASE], platform)) {
- continue;
- }
-
- /*
- if (current->meta.rc == (int) d + 1
- && strcmp(current->system.arch, arch) != 0
- && strcmp(current->system.platform[DELIVERY_PLATFORM_RELEASE], platform) != 0) {
- continue;
- }
- */
-
- if (!strstr(filename, current->info.release_name)) {
- continue;
- }
- fprintf(indexfp, "### %s\n", current->info.release_name);
- fprintf(indexfp, "\n|Suite|Duration|Total|Pass|Fail |Skip |Error |\n");
- fprintf(indexfp, "|:----|:------:|:-----:|:----:|:------:|:---:|:----:|\n");
-
- char pattern[PATH_MAX] = {0};
- snprintf(pattern, sizeof(pattern) - 1, "*%s*", current->info.release_name);
- if (!fnmatch(pattern, filename, 0) && strstr(filename, platform) &&
- strstr(filename, arch)) {
- struct JUNIT_Testsuite *testsuite = junitxml_testsuite_read(filename);
- if (testsuite) {
- if (globals.verbose) {
- printf(
- "%s: duration: %0.4f, total: %d, passed: %d, failed: %d, skipped: %d, errors: %d\n",
- filename,
- testsuite->time, testsuite->tests,
- testsuite->passed, testsuite->failures,
- testsuite->skipped, testsuite->errors);
- }
-
- char *bname_tmp = strdup(filename);
- char *bname = path_basename(bname_tmp);
- bname[strlen(bname) - 4] = 0;
- guard_free(bname_tmp);
-
- char result_outfile[PATH_MAX] = {0};
- char *short_name_pattern = NULL;
- asprintf(&short_name_pattern, "-%s", current->info.release_name);
-
- char short_name[PATH_MAX] = {0};
- strncpy(short_name, bname, sizeof(short_name) - 1);
- replace_text(short_name, short_name_pattern, "", 0);
- replace_text(short_name, "results-", "", 0);
- guard_free(short_name_pattern);
-
- fprintf(indexfp, "|[%s](%s.html)|%0.4f|%d|%d|%d|%d|%d|\n", short_name, bname,
- testsuite->time, testsuite->tests,
- testsuite->passed, testsuite->failures,
- testsuite->skipped, testsuite->errors);
-
- snprintf(result_outfile, sizeof(result_outfile) - strlen(bname) - 3, "%s.md",
- bname);
- FILE *resultfp = fopen(result_outfile, "w+");
- if (!resultfp) {
- SYSERROR("Unable to open %s for writing", result_outfile);
- return -1;
- }
-
- for (size_t i = 0; i < testsuite->_tc_inuse; i++) {
- //if (testsuite->testcase[i]->tc_result_state_type) {
- const char *type_str = NULL;
- const int state = testsuite->testcase[i]->tc_result_state_type;
- const char *message = NULL;
- if (state == JUNIT_RESULT_STATE_FAILURE) {
- message = testsuite->testcase[i]->result_state.failure->message;
- type_str = "[FAILED]";
- } else if (state == JUNIT_RESULT_STATE_ERROR) {
- message = testsuite->testcase[i]->result_state.error->message;
- type_str = "[ERROR]";
- } else if (state == JUNIT_RESULT_STATE_SKIPPED) {
- message = testsuite->testcase[i]->result_state.skipped->message;
- type_str = "[SKIPPED]";
- } else {
- message = testsuite->testcase[i]->message ? testsuite->testcase[i]->message
- : "";
- type_str = "[PASSED]";
- }
- fprintf(resultfp, "### %s %s :: %s\n", type_str,
- testsuite->testcase[i]->classname, testsuite->testcase[i]->name);
- fprintf(resultfp, "\nDuration: %0.04fs\n", testsuite->testcase[i]->time);
- fprintf(resultfp, "\n```\n%s\n```\n", message);
- //}
- }
- junitxml_testsuite_free(&testsuite);
- fclose(resultfp);
- } else {
- fprintf(stderr, "bad test suite: %s: %s\n", strerror(errno), filename);
- }
- } else {
- if (!no_printable_data) {
- // Triggering for reasons unknown
- //fprintf(indexfp, "|No data|-|-|-|-|-|-|\n");
- no_printable_data = 1;
- }
- }
+ for (size_t d = 0; d < nelem; d++) {
+ char pattern[PATH_MAX] = {0};
+ snprintf(pattern, sizeof(pattern) - 1, "*%s*", ctx[d].info.release_name);
+
+ // if result directory contains this release name, print it
+ fprintf(indexfp, "### %s\n", ctx[d].info.release_name);
+ if (!is_file_in_listing(file_listing, pattern)) {
+ fprintf(indexfp, "No test results\n");
+ continue;
+ }
+ fprintf(indexfp, "\n|Suite|Duration|Total|Pass|Fail|Skip|Error|\n");
+ fprintf(indexfp, "|:----|:------:|:---:|:--:|:--:|:--:|:---:|\n");
+
+ for (size_t i = 0; i < strlist_count(file_listing); i++) {
+ const char *filename = strlist_item(file_listing, i);
+ // if not a xml file, skip it
+ if (!endswith(filename, ".xml")) {
+ continue;
+ }
+ if (!fnmatch(pattern, filename, 0)) {
+ if (write_report_output(&ctx[d], indexfp, filename)) {
+ // warn only
+ SYSERROR("Unable to write xml report file using %s", filename);
}
- fprintf(indexfp, "\n");
- no_printable_data = 0;
}
}
fprintf(indexfp, "\n");
}
- guard_strlist_free(&archs);
- guard_strlist_free(&platforms);
fclose(indexfp);
popd();
} else {
fprintf(stderr, "Unable to enter delivery directory: %s\n", ctx->storage.delivery_dir);
- guard_free(latest);
return -1;
}
- // "latest" is an array of pointers to ctxs[]. Do not free the contents of the array.
- guard_free(latest);
return 0;
}
-
-