diff options
author | Joseph Hunkeler <jhunkeler@gmail.com> | 2024-12-24 01:36:47 -0500 |
---|---|---|
committer | Joseph Hunkeler <jhunkeler@gmail.com> | 2024-12-24 01:36:47 -0500 |
commit | 1f21976f8ed09adb73c115f0f8067ed0eee1d861 (patch) | |
tree | 6e2fff82575e109993f4ee83e932c6b45c13a6e8 | |
parent | 4f7d8227615695c1bc8d7f9c6938df88fe084941 (diff) | |
download | stasis-1f21976f8ed09adb73c115f0f8067ed0eee1d861.tar.gz |
indexer: Rewrite indexer_junitxml_report from scratch
-rw-r--r-- | src/cli/stasis_indexer/callbacks.c | 6 | ||||
-rw-r--r-- | src/cli/stasis_indexer/junitxml_report.c | 233 |
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; } - - |