Spaces:
Runtime error
Runtime error
| /* | |
| * Test result reporting | |
| * | |
| * Copyright (c) Siemens AG, 2014 | |
| * | |
| * Authors: | |
| * Jan Kiszka <jan.kiszka@siemens.com> | |
| * Andrew Jones <drjones@redhat.com> | |
| * | |
| * This work is licensed under the terms of the GNU LGPL, version 2. | |
| */ | |
| static unsigned int tests, failures, xfailures, skipped; | |
| static char prefixes[256]; | |
| static struct spinlock lock; | |
| void report_pass(void) | |
| { | |
| spin_lock(&lock); | |
| tests++; | |
| spin_unlock(&lock); | |
| } | |
| void report_prefix_pushf(const char *prefix_fmt, ...) | |
| { | |
| va_list va; | |
| unsigned int len; | |
| int start; | |
| spin_lock(&lock); | |
| len = strlen(prefixes); | |
| assert_msg(len < sizeof(prefixes), "%d >= %zu", len, sizeof(prefixes)); | |
| start = len; | |
| va_start(va, prefix_fmt); | |
| len += vsnprintf(&prefixes[len], sizeof(prefixes) - len, prefix_fmt, | |
| va); | |
| va_end(va); | |
| assert_msg(len < sizeof(prefixes), "%d >= %zu", len, sizeof(prefixes)); | |
| assert_msg(!strstr(&prefixes[start], PREFIX_DELIMITER), | |
| "Prefix \"%s\" contains delimiter \"" PREFIX_DELIMITER "\"", | |
| &prefixes[start]); | |
| len += snprintf(&prefixes[len], sizeof(prefixes) - len, | |
| PREFIX_DELIMITER); | |
| assert_msg(len < sizeof(prefixes), "%d >= %zu", len, sizeof(prefixes)); | |
| spin_unlock(&lock); | |
| } | |
| void report_prefix_push(const char *prefix) | |
| { | |
| report_prefix_pushf("%s", prefix); | |
| } | |
| void report_prefix_pop(void) | |
| { | |
| char *p, *q; | |
| spin_lock(&lock); | |
| if (!*prefixes) | |
| return; | |
| for (p = prefixes, q = strstr(p, PREFIX_DELIMITER) + 2; | |
| *q; | |
| p = q, q = strstr(p, PREFIX_DELIMITER) + 2) | |
| ; | |
| *p = '\0'; | |
| spin_unlock(&lock); | |
| } | |
| static void va_report(const char *msg_fmt, | |
| bool pass, bool xfail, bool skip, va_list va) | |
| { | |
| const char *prefix = skip ? "SKIP" | |
| : xfail ? (pass ? "XPASS" : "XFAIL") | |
| : (pass ? "PASS" : "FAIL"); | |
| spin_lock(&lock); | |
| tests++; | |
| printf("%s: ", prefix); | |
| puts(prefixes); | |
| vprintf(msg_fmt, va); | |
| puts("\n"); | |
| if (skip) | |
| skipped++; | |
| else if (xfail && !pass) | |
| xfailures++; | |
| else if (xfail || !pass) | |
| failures++; | |
| spin_unlock(&lock); | |
| } | |
| void report(const char *msg_fmt, bool pass, ...) | |
| { | |
| va_list va; | |
| va_start(va, pass); | |
| va_report(msg_fmt, pass, false, false, va); | |
| va_end(va); | |
| } | |
| void report_xfail(const char *msg_fmt, bool xfail, bool pass, ...) | |
| { | |
| va_list va; | |
| va_start(va, pass); | |
| va_report(msg_fmt, pass, xfail, false, va); | |
| va_end(va); | |
| } | |
| void report_skip(const char *msg_fmt, ...) | |
| { | |
| va_list va; | |
| va_start(va, msg_fmt); | |
| va_report(msg_fmt, false, false, true, va); | |
| va_end(va); | |
| } | |
| void report_info(const char *msg_fmt, ...) | |
| { | |
| va_list va; | |
| spin_lock(&lock); | |
| puts("INFO: "); | |
| puts(prefixes); | |
| va_start(va, msg_fmt); | |
| vprintf(msg_fmt, va); | |
| va_end(va); | |
| puts("\n"); | |
| spin_unlock(&lock); | |
| } | |
| int report_summary(void) | |
| { | |
| spin_lock(&lock); | |
| printf("SUMMARY: %d tests", tests); | |
| if (failures) | |
| printf(", %d unexpected failures", failures); | |
| if (xfailures) | |
| printf(", %d expected failures", xfailures); | |
| if (skipped) | |
| printf(", %d skipped", skipped); | |
| printf("\n"); | |
| if (tests == skipped) | |
| /* Blame AUTOTOOLS for using 77 for skipped test and QEMU for | |
| * mangling error codes in a way that gets 77 if we ... */ | |
| return 77 >> 1; | |
| return failures > 0 ? 1 : 0; | |
| spin_unlock(&lock); | |
| } | |
| void report_abort(const char *msg_fmt, ...) | |
| { | |
| va_list va; | |
| spin_lock(&lock); | |
| puts("ABORT: "); | |
| puts(prefixes); | |
| va_start(va, msg_fmt); | |
| vprintf(msg_fmt, va); | |
| va_end(va); | |
| puts("\n"); | |
| spin_unlock(&lock); | |
| report_summary(); | |
| abort(); | |
| } | |