1 /* 2 * Test result reporting 3 * 4 * Copyright (c) Siemens AG, 2014 5 * 6 * Authors: 7 * Jan Kiszka <jan.kiszka@siemens.com> 8 * Andrew Jones <drjones@redhat.com> 9 * 10 * This work is licensed under the terms of the GNU LGPL, version 2. 11 */ 12 13 #include "libcflat.h" 14 #include "asm/spinlock.h" 15 16 static unsigned int tests, failures, xfailures, skipped; 17 static char prefixes[256]; 18 static struct spinlock lock; 19 20 #define PREFIX_DELIMITER ": " 21 22 void report_prefix_pushf(const char *prefix_fmt, ...) 23 { 24 va_list va; 25 int len; 26 int start; 27 28 spin_lock(&lock); 29 30 len = strlen(prefixes); 31 assert_msg(len < sizeof(prefixes), "%d >= %lu", len, sizeof(prefixes)); 32 start = len; 33 34 va_start(va, prefix_fmt); 35 len += vsnprintf(&prefixes[len], sizeof(prefixes) - len, prefix_fmt, 36 va); 37 va_end(va); 38 assert_msg(len < sizeof(prefixes), "%d >= %lu", len, sizeof(prefixes)); 39 40 assert_msg(!strstr(&prefixes[start], PREFIX_DELIMITER), 41 "Prefix \"%s\" contains delimiter \"" PREFIX_DELIMITER "\"", 42 &prefixes[start]); 43 44 len += snprintf(&prefixes[len], sizeof(prefixes) - len, 45 PREFIX_DELIMITER); 46 assert_msg(len < sizeof(prefixes), "%d >= %lu", len, sizeof(prefixes)); 47 48 spin_unlock(&lock); 49 } 50 51 void report_prefix_push(const char *prefix) 52 { 53 report_prefix_pushf("%s", prefix); 54 } 55 56 void report_prefix_pop(void) 57 { 58 char *p, *q; 59 60 spin_lock(&lock); 61 62 if (!*prefixes) 63 return; 64 65 for (p = prefixes, q = strstr(p, PREFIX_DELIMITER) + 2; 66 *q; 67 p = q, q = strstr(p, PREFIX_DELIMITER) + 2) 68 ; 69 *p = '\0'; 70 71 spin_unlock(&lock); 72 } 73 74 static void va_report(const char *msg_fmt, 75 bool pass, bool xfail, bool skip, va_list va) 76 { 77 char *prefix = skip ? "SKIP" 78 : xfail ? (pass ? "XPASS" : "XFAIL") 79 : (pass ? "PASS" : "FAIL"); 80 81 spin_lock(&lock); 82 83 tests++; 84 printf("%s: ", prefix); 85 puts(prefixes); 86 vprintf(msg_fmt, va); 87 puts("\n"); 88 if (skip) 89 skipped++; 90 else if (xfail && !pass) 91 xfailures++; 92 else if (xfail || !pass) 93 failures++; 94 95 spin_unlock(&lock); 96 } 97 98 void report(const char *msg_fmt, bool pass, ...) 99 { 100 va_list va; 101 va_start(va, pass); 102 va_report(msg_fmt, pass, false, false, va); 103 va_end(va); 104 } 105 106 void report_xfail(const char *msg_fmt, bool xfail, bool pass, ...) 107 { 108 va_list va; 109 va_start(va, pass); 110 va_report(msg_fmt, pass, xfail, false, va); 111 va_end(va); 112 } 113 114 void report_skip(const char *msg_fmt, ...) 115 { 116 va_list va; 117 va_start(va, msg_fmt); 118 va_report(msg_fmt, false, false, true, va); 119 va_end(va); 120 } 121 122 void report_info(const char *msg_fmt, ...) 123 { 124 va_list va; 125 126 spin_lock(&lock); 127 puts("INFO: "); 128 puts(prefixes); 129 va_start(va, msg_fmt); 130 vprintf(msg_fmt, va); 131 va_end(va); 132 puts("\n"); 133 spin_unlock(&lock); 134 } 135 136 int report_summary(void) 137 { 138 spin_lock(&lock); 139 140 printf("SUMMARY: %d tests", tests); 141 if (failures) 142 printf(", %d unexpected failures", failures); 143 if (xfailures) 144 printf(", %d expected failures", xfailures); 145 if (skipped) 146 printf(", %d skipped", skipped); 147 printf("\n"); 148 149 if (tests == skipped) 150 /* Blame AUTOTOOLS for using 77 for skipped test and QEMU for 151 * mangling error codes in a way that gets 77 if we ... */ 152 return 77 >> 1; 153 154 return failures > 0 ? 1 : 0; 155 156 spin_unlock(&lock); 157 } 158 159 void report_abort(const char *msg_fmt, ...) 160 { 161 va_list va; 162 163 spin_lock(&lock); 164 puts("ABORT: "); 165 puts(prefixes); 166 va_start(va, msg_fmt); 167 vprintf(msg_fmt, va); 168 va_end(va); 169 puts("\n"); 170 spin_unlock(&lock); 171 report_summary(); 172 abort(); 173 } 174