xref: /kvm-unit-tests/lib/report.c (revision 1bde9127da4c103603972cdf60b6c6c383866447)
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 void report_prefix_push(const char *prefix)
21 {
22 	spin_lock(&lock);
23 	strcat(prefixes, prefix);
24 	strcat(prefixes, ": ");
25 	spin_unlock(&lock);
26 }
27 
28 void report_prefix_pop(void)
29 {
30 	char *p, *q;
31 
32 	spin_lock(&lock);
33 
34 	if (!*prefixes)
35 		return;
36 
37 	for (p = prefixes, q = strstr(p, ": ") + 2;
38 			*q;
39 			p = q, q = strstr(p, ": ") + 2)
40 		;
41 	*p = '\0';
42 
43 	spin_unlock(&lock);
44 }
45 
46 static void va_report(const char *msg_fmt,
47 		bool pass, bool xfail, bool skip, va_list va)
48 {
49 	char *prefix = skip ? "SKIP"
50 	                    : xfail ? (pass ? "XPASS" : "XFAIL")
51 	                            : (pass ? "PASS"  : "FAIL");
52 
53 	spin_lock(&lock);
54 
55 	tests++;
56 	printf("%s: ", prefix);
57 	puts(prefixes);
58 	vprintf(msg_fmt, va);
59 	puts("\n");
60 	if (skip)
61 		skipped++;
62 	else if (xfail && !pass)
63 		xfailures++;
64 	else if (xfail || !pass)
65 		failures++;
66 
67 	spin_unlock(&lock);
68 }
69 
70 void report(const char *msg_fmt, bool pass, ...)
71 {
72 	va_list va;
73 	va_start(va, pass);
74 	va_report(msg_fmt, pass, false, false, va);
75 	va_end(va);
76 }
77 
78 void report_xfail(const char *msg_fmt, bool xfail, bool pass, ...)
79 {
80 	va_list va;
81 	va_start(va, pass);
82 	va_report(msg_fmt, pass, xfail, false, va);
83 	va_end(va);
84 }
85 
86 void report_skip(const char *msg_fmt, ...)
87 {
88 	va_list va;
89 	va_start(va, msg_fmt);
90 	va_report(msg_fmt, false, false, true, va);
91 	va_end(va);
92 }
93 
94 void report_info(const char *msg_fmt, ...)
95 {
96 	va_list va;
97 
98 	spin_lock(&lock);
99 	puts("INFO: ");
100 	puts(prefixes);
101 	va_start(va, msg_fmt);
102 	vprintf(msg_fmt, va);
103 	va_end(va);
104 	puts("\n");
105 	spin_unlock(&lock);
106 }
107 
108 int report_summary(void)
109 {
110 	spin_lock(&lock);
111 
112 	printf("\nSUMMARY: %d tests", tests);
113 	if (failures)
114 		printf(", %d unexpected failures", failures);
115 	if (xfailures)
116 		printf(", %d expected failures", xfailures);
117 	if (skipped)
118 		printf(", %d skipped", skipped);
119 	printf("\n");
120 
121 	if (tests == skipped)
122 		/* Blame AUTOTOOLS for using 77 for skipped test and QEMU for
123 		 * mangling error codes in a way that gets 77 if we ... */
124 		return 77 >> 1;
125 
126 	return failures > 0 ? 1 : 0;
127 
128 	spin_unlock(&lock);
129 }
130 
131 void report_abort(const char *msg_fmt, ...)
132 {
133 	va_list va;
134 
135 	spin_lock(&lock);
136 	puts("ABORT: ");
137 	puts(prefixes);
138 	va_start(va, msg_fmt);
139 	vprintf(msg_fmt, va);
140 	va_end(va);
141 	puts("\n");
142 	spin_unlock(&lock);
143 	report_summary();
144 	abort();
145 }
146