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