xref: /kvm-unit-tests/lib/report.c (revision 3064cb5736c189f46c20a165098fec2d6e90803e)
1f3cdd159SJan Kiszka /*
2f3cdd159SJan Kiszka  * Test result reporting
3f3cdd159SJan Kiszka  *
4f3cdd159SJan Kiszka  * Copyright (c) Siemens AG, 2014
5f3cdd159SJan Kiszka  *
6f3cdd159SJan Kiszka  * Authors:
7f3cdd159SJan Kiszka  *  Jan Kiszka <jan.kiszka@siemens.com>
8a5af7b8aSAndrew Jones  *  Andrew Jones <drjones@redhat.com>
9f3cdd159SJan Kiszka  *
10f3cdd159SJan Kiszka  * This work is licensed under the terms of the GNU LGPL, version 2.
11f3cdd159SJan Kiszka  */
12f3cdd159SJan Kiszka 
13f3cdd159SJan Kiszka #include "libcflat.h"
14c5b6469dSAndrew Jones #include "asm/spinlock.h"
15f3cdd159SJan Kiszka 
167cd02206SNicholas Piggin static unsigned int tests, failures, xfailures, kfailures, skipped;
1753da5cc0SAndrew Jones static char prefixes[256];
18c5b6469dSAndrew Jones static struct spinlock lock;
1953da5cc0SAndrew Jones 
2017e80e71SPeter Feiner #define PREFIX_DELIMITER ": "
2117e80e71SPeter Feiner 
report_passed(void)227b18fa38SJanis Schoetterl-Glausch void report_passed(void)
230d78a090SDavid Matlack {
240d78a090SDavid Matlack 	spin_lock(&lock);
250d78a090SDavid Matlack 	tests++;
260d78a090SDavid Matlack 	spin_unlock(&lock);
270d78a090SDavid Matlack }
280d78a090SDavid Matlack 
report_prefix_pushf(const char * prefix_fmt,...)2917e80e71SPeter Feiner void report_prefix_pushf(const char *prefix_fmt, ...)
3017e80e71SPeter Feiner {
3117e80e71SPeter Feiner 	va_list va;
320537dbecSDavid Hildenbrand 	unsigned int len;
3317e80e71SPeter Feiner 	int start;
3417e80e71SPeter Feiner 
3517e80e71SPeter Feiner 	spin_lock(&lock);
3617e80e71SPeter Feiner 
3717e80e71SPeter Feiner 	len = strlen(prefixes);
382ff95b37SRadim Krčmář 	assert_msg(len < sizeof(prefixes), "%d >= %zu", len, sizeof(prefixes));
3917e80e71SPeter Feiner 	start = len;
4017e80e71SPeter Feiner 
4117e80e71SPeter Feiner 	va_start(va, prefix_fmt);
4217e80e71SPeter Feiner 	len += vsnprintf(&prefixes[len], sizeof(prefixes) - len, prefix_fmt,
4317e80e71SPeter Feiner 			 va);
4417e80e71SPeter Feiner 	va_end(va);
452ff95b37SRadim Krčmář 	assert_msg(len < sizeof(prefixes), "%d >= %zu", len, sizeof(prefixes));
4617e80e71SPeter Feiner 
4717e80e71SPeter Feiner 	assert_msg(!strstr(&prefixes[start], PREFIX_DELIMITER),
4817e80e71SPeter Feiner 		   "Prefix \"%s\" contains delimiter \"" PREFIX_DELIMITER "\"",
4917e80e71SPeter Feiner 		   &prefixes[start]);
5017e80e71SPeter Feiner 
5117e80e71SPeter Feiner 	len += snprintf(&prefixes[len], sizeof(prefixes) - len,
5217e80e71SPeter Feiner 			PREFIX_DELIMITER);
532ff95b37SRadim Krčmář 	assert_msg(len < sizeof(prefixes), "%d >= %zu", len, sizeof(prefixes));
5417e80e71SPeter Feiner 
5517e80e71SPeter Feiner 	spin_unlock(&lock);
5617e80e71SPeter Feiner }
5717e80e71SPeter Feiner 
report_prefix_push(const char * prefix)5853da5cc0SAndrew Jones void report_prefix_push(const char *prefix)
5953da5cc0SAndrew Jones {
6017e80e71SPeter Feiner 	report_prefix_pushf("%s", prefix);
6153da5cc0SAndrew Jones }
6253da5cc0SAndrew Jones 
__report_prefix_pop(void)63b2a8279bSJames Raphael Tiovalen static void __report_prefix_pop(void)
6453da5cc0SAndrew Jones {
6553da5cc0SAndrew Jones 	char *p, *q;
6653da5cc0SAndrew Jones 
67b2a8279bSJames Raphael Tiovalen 	if (!*prefixes)
6853da5cc0SAndrew Jones 		return;
6953da5cc0SAndrew Jones 
7017e80e71SPeter Feiner 	for (p = prefixes, q = strstr(p, PREFIX_DELIMITER) + 2;
7153da5cc0SAndrew Jones 			*q;
7217e80e71SPeter Feiner 			p = q, q = strstr(p, PREFIX_DELIMITER) + 2)
7353da5cc0SAndrew Jones 		;
7453da5cc0SAndrew Jones 	*p = '\0';
75b2a8279bSJames Raphael Tiovalen }
76c5b6469dSAndrew Jones 
report_prefix_pop(void)77b2a8279bSJames Raphael Tiovalen void report_prefix_pop(void)
78b2a8279bSJames Raphael Tiovalen {
79b2a8279bSJames Raphael Tiovalen 	spin_lock(&lock);
80b2a8279bSJames Raphael Tiovalen 	__report_prefix_pop();
81b2a8279bSJames Raphael Tiovalen 	spin_unlock(&lock);
82b2a8279bSJames Raphael Tiovalen }
83b2a8279bSJames Raphael Tiovalen 
report_prefix_popn(int n)84b2a8279bSJames Raphael Tiovalen void report_prefix_popn(int n)
85b2a8279bSJames Raphael Tiovalen {
86b2a8279bSJames Raphael Tiovalen 	spin_lock(&lock);
87b2a8279bSJames Raphael Tiovalen 	while (n--)
88b2a8279bSJames Raphael Tiovalen 		__report_prefix_pop();
89c5b6469dSAndrew Jones 	spin_unlock(&lock);
9053da5cc0SAndrew Jones }
91a5af7b8aSAndrew Jones 
va_report(const char * msg_fmt,bool pass,bool xfail,bool kfail,bool skip,va_list va)92*3064cb57SAndrew Jones static bool va_report(const char *msg_fmt,
937cd02206SNicholas Piggin 		bool pass, bool xfail, bool kfail, bool skip, va_list va)
94a5af7b8aSAndrew Jones {
95797d79a2SThomas Huth 	const char *prefix = skip ? "SKIP"
96a0833bfcSRadim Krčmář 				  : xfail ? (pass ? "XPASS" : "XFAIL")
977cd02206SNicholas Piggin 				          : kfail ? (pass ? "PASS" : "KFAIL")
98a0833bfcSRadim Krčmář 					          : (pass ? "PASS"  : "FAIL");
99a5af7b8aSAndrew Jones 
100c5b6469dSAndrew Jones 	spin_lock(&lock);
101c5b6469dSAndrew Jones 
102a5af7b8aSAndrew Jones 	tests++;
103a0833bfcSRadim Krčmář 	printf("%s: ", prefix);
10453da5cc0SAndrew Jones 	puts(prefixes);
105cb12ecccSAndrew Jones 	vprintf(msg_fmt, va);
106a5af7b8aSAndrew Jones 	puts("\n");
107a0833bfcSRadim Krčmář 	if (skip)
108a0833bfcSRadim Krčmář 		skipped++;
109a0833bfcSRadim Krčmář 	else if (xfail && !pass)
110a5af7b8aSAndrew Jones 		xfailures++;
1117cd02206SNicholas Piggin 	else if (kfail && !pass)
1127cd02206SNicholas Piggin 		kfailures++;
113a0833bfcSRadim Krčmář 	else if (xfail || !pass)
114a5af7b8aSAndrew Jones 		failures++;
115c5b6469dSAndrew Jones 
116c5b6469dSAndrew Jones 	spin_unlock(&lock);
117*3064cb57SAndrew Jones 
118*3064cb57SAndrew Jones 	return pass || xfail;
119a5af7b8aSAndrew Jones }
120f3cdd159SJan Kiszka 
report(bool pass,const char * msg_fmt,...)121*3064cb57SAndrew Jones bool report(bool pass, const char *msg_fmt, ...)
122f3cdd159SJan Kiszka {
123f3cdd159SJan Kiszka 	va_list va;
124*3064cb57SAndrew Jones 	bool ret;
125*3064cb57SAndrew Jones 
126a299895bSThomas Huth 	va_start(va, msg_fmt);
127*3064cb57SAndrew Jones 	ret = va_report(msg_fmt, pass, false, false, false, va);
128f3cdd159SJan Kiszka 	va_end(va);
129*3064cb57SAndrew Jones 
130*3064cb57SAndrew Jones 	return ret;
131a5af7b8aSAndrew Jones }
132a5af7b8aSAndrew Jones 
report_pass(const char * msg_fmt,...)1337b18fa38SJanis Schoetterl-Glausch void report_pass(const char *msg_fmt, ...)
1347b18fa38SJanis Schoetterl-Glausch {
1357b18fa38SJanis Schoetterl-Glausch 	va_list va;
1367b18fa38SJanis Schoetterl-Glausch 
1377b18fa38SJanis Schoetterl-Glausch 	va_start(va, msg_fmt);
1387cd02206SNicholas Piggin 	va_report(msg_fmt, true, false, false, false, va);
1397b18fa38SJanis Schoetterl-Glausch 	va_end(va);
1407b18fa38SJanis Schoetterl-Glausch }
1417b18fa38SJanis Schoetterl-Glausch 
report_fail(const char * msg_fmt,...)1427b18fa38SJanis Schoetterl-Glausch void report_fail(const char *msg_fmt, ...)
1437b18fa38SJanis Schoetterl-Glausch {
1447b18fa38SJanis Schoetterl-Glausch 	va_list va;
1457b18fa38SJanis Schoetterl-Glausch 
1467b18fa38SJanis Schoetterl-Glausch 	va_start(va, msg_fmt);
1477cd02206SNicholas Piggin 	va_report(msg_fmt, false, false, false, false, va);
1487b18fa38SJanis Schoetterl-Glausch 	va_end(va);
1497b18fa38SJanis Schoetterl-Glausch }
1507b18fa38SJanis Schoetterl-Glausch 
report_xfail(bool xfail,bool pass,const char * msg_fmt,...)151*3064cb57SAndrew Jones bool report_xfail(bool xfail, bool pass, const char *msg_fmt, ...)
152a5af7b8aSAndrew Jones {
153*3064cb57SAndrew Jones 	bool ret;
154*3064cb57SAndrew Jones 
155a5af7b8aSAndrew Jones 	va_list va;
156a299895bSThomas Huth 	va_start(va, msg_fmt);
157*3064cb57SAndrew Jones 	ret = va_report(msg_fmt, pass, xfail, false, false, va);
1587cd02206SNicholas Piggin 	va_end(va);
159*3064cb57SAndrew Jones 
160*3064cb57SAndrew Jones 	return ret;
1617cd02206SNicholas Piggin }
1627cd02206SNicholas Piggin 
1637cd02206SNicholas Piggin /*
1647cd02206SNicholas Piggin  * kfail is known failure. If kfail is true then test will succeed
1657cd02206SNicholas Piggin  * regardless of pass.
1667cd02206SNicholas Piggin  */
report_kfail(bool kfail,bool pass,const char * msg_fmt,...)167*3064cb57SAndrew Jones bool report_kfail(bool kfail, bool pass, const char *msg_fmt, ...)
1687cd02206SNicholas Piggin {
169*3064cb57SAndrew Jones 	bool ret;
170*3064cb57SAndrew Jones 
1717cd02206SNicholas Piggin 	va_list va;
1727cd02206SNicholas Piggin 	va_start(va, msg_fmt);
173*3064cb57SAndrew Jones 	ret = va_report(msg_fmt, pass, false, kfail, false, va);
174a0833bfcSRadim Krčmář 	va_end(va);
175*3064cb57SAndrew Jones 
176*3064cb57SAndrew Jones 	return ret;
177a0833bfcSRadim Krčmář }
178a0833bfcSRadim Krčmář 
report_skip(const char * msg_fmt,...)179a0833bfcSRadim Krčmář void report_skip(const char *msg_fmt, ...)
180a0833bfcSRadim Krčmář {
181a0833bfcSRadim Krčmář 	va_list va;
182a0833bfcSRadim Krčmář 	va_start(va, msg_fmt);
1837cd02206SNicholas Piggin 	va_report(msg_fmt, false, false, false, true, va);
184a5af7b8aSAndrew Jones 	va_end(va);
185f3cdd159SJan Kiszka }
186f3cdd159SJan Kiszka 
report_info(const char * msg_fmt,...)1872acf2e69SAndrew Jones void report_info(const char *msg_fmt, ...)
1882acf2e69SAndrew Jones {
1892acf2e69SAndrew Jones 	va_list va;
1902acf2e69SAndrew Jones 
1912acf2e69SAndrew Jones 	spin_lock(&lock);
1922acf2e69SAndrew Jones 	puts("INFO: ");
1932acf2e69SAndrew Jones 	puts(prefixes);
1942acf2e69SAndrew Jones 	va_start(va, msg_fmt);
1952acf2e69SAndrew Jones 	vprintf(msg_fmt, va);
1962acf2e69SAndrew Jones 	va_end(va);
1972acf2e69SAndrew Jones 	puts("\n");
1982acf2e69SAndrew Jones 	spin_unlock(&lock);
1992acf2e69SAndrew Jones }
2002acf2e69SAndrew Jones 
report_summary(void)201f3cdd159SJan Kiszka int report_summary(void)
202f3cdd159SJan Kiszka {
2039064d89bSPeng Hao 	int ret;
204c5b6469dSAndrew Jones 	spin_lock(&lock);
205c5b6469dSAndrew Jones 
206f1071c6dSAndrew Jones 	printf("SUMMARY: %d tests", tests);
2073d742d17SRadim Krčmář 	if (failures)
2083d742d17SRadim Krčmář 		printf(", %d unexpected failures", failures);
2097cd02206SNicholas Piggin 	if (kfailures)
2107cd02206SNicholas Piggin 		printf(", %d known failures", kfailures);
211a5af7b8aSAndrew Jones 	if (xfailures)
212a0833bfcSRadim Krčmář 		printf(", %d expected failures", xfailures);
213a0833bfcSRadim Krčmář 	if (skipped)
214a0833bfcSRadim Krčmář 		printf(", %d skipped", skipped);
215a5af7b8aSAndrew Jones 	printf("\n");
216a0833bfcSRadim Krčmář 
2179064d89bSPeng Hao 	if (tests == skipped) {
2189064d89bSPeng Hao 		spin_unlock(&lock);
219a0833bfcSRadim Krčmář 		/* Blame AUTOTOOLS for using 77 for skipped test and QEMU for
220a0833bfcSRadim Krčmář 		 * mangling error codes in a way that gets 77 if we ... */
221a0833bfcSRadim Krčmář 		return 77 >> 1;
2229064d89bSPeng Hao 	}
223a0833bfcSRadim Krčmář 
2249064d89bSPeng Hao 	ret = failures > 0 ? 1 : 0;
225c5b6469dSAndrew Jones 	spin_unlock(&lock);
2269064d89bSPeng Hao 	return ret;
227f3cdd159SJan Kiszka }
228e7c68b43SAndrew Jones 
report_abort(const char * msg_fmt,...)229e7c68b43SAndrew Jones void report_abort(const char *msg_fmt, ...)
230e7c68b43SAndrew Jones {
231e7c68b43SAndrew Jones 	va_list va;
232e7c68b43SAndrew Jones 
23375b3e681SAndrew Jones 	spin_lock(&lock);
234e7c68b43SAndrew Jones 	puts("ABORT: ");
235e7c68b43SAndrew Jones 	puts(prefixes);
236e7c68b43SAndrew Jones 	va_start(va, msg_fmt);
237e7c68b43SAndrew Jones 	vprintf(msg_fmt, va);
238e7c68b43SAndrew Jones 	va_end(va);
239e7c68b43SAndrew Jones 	puts("\n");
24075b3e681SAndrew Jones 	spin_unlock(&lock);
241e7c68b43SAndrew Jones 	report_summary();
242e7c68b43SAndrew Jones 	abort();
243e7c68b43SAndrew Jones }
244