xref: /linux-6.15/lib/tests/printf_kunit.c (revision 034bee68)
17a79e7daSTamir Duberstein // SPDX-License-Identifier: GPL-2.0-only
27a79e7daSTamir Duberstein /*
37a79e7daSTamir Duberstein  * Test cases for printf facility.
47a79e7daSTamir Duberstein  */
57a79e7daSTamir Duberstein 
67a79e7daSTamir Duberstein #include <kunit/test.h>
77a79e7daSTamir Duberstein #include <linux/kernel.h>
87a79e7daSTamir Duberstein #include <linux/module.h>
97a79e7daSTamir Duberstein #include <linux/printk.h>
107a79e7daSTamir Duberstein #include <linux/random.h>
117a79e7daSTamir Duberstein #include <linux/rtc.h>
127a79e7daSTamir Duberstein #include <linux/slab.h>
137a79e7daSTamir Duberstein #include <linux/sprintf.h>
147a79e7daSTamir Duberstein #include <linux/string.h>
157a79e7daSTamir Duberstein 
167a79e7daSTamir Duberstein #include <linux/bitmap.h>
177a79e7daSTamir Duberstein #include <linux/dcache.h>
187a79e7daSTamir Duberstein #include <linux/socket.h>
197a79e7daSTamir Duberstein #include <linux/in.h>
207a79e7daSTamir Duberstein 
217a79e7daSTamir Duberstein #include <linux/gfp.h>
227a79e7daSTamir Duberstein #include <linux/mm.h>
237a79e7daSTamir Duberstein 
247a79e7daSTamir Duberstein #include <linux/property.h>
257a79e7daSTamir Duberstein 
267a79e7daSTamir Duberstein #define BUF_SIZE 256
277a79e7daSTamir Duberstein #define PAD_SIZE 16
287a79e7daSTamir Duberstein #define FILL_CHAR '$'
297a79e7daSTamir Duberstein 
307a79e7daSTamir Duberstein #define NOWARN(option, comment, block) \
317a79e7daSTamir Duberstein 	__diag_push(); \
327a79e7daSTamir Duberstein 	__diag_ignore_all(#option, comment); \
337a79e7daSTamir Duberstein 	block \
347a79e7daSTamir Duberstein 	__diag_pop();
357a79e7daSTamir Duberstein 
367a79e7daSTamir Duberstein static unsigned int total_tests;
377a79e7daSTamir Duberstein 
387a79e7daSTamir Duberstein static char *test_buffer;
397a79e7daSTamir Duberstein static char *alloced_buffer;
407a79e7daSTamir Duberstein 
41*034bee68STamir Duberstein static void __printf(7, 0)
do_test(struct kunit * kunittest,const char * file,const int line,int bufsize,const char * expect,int elen,const char * fmt,va_list ap)42*034bee68STamir Duberstein do_test(struct kunit *kunittest, const char *file, const int line, int bufsize, const char *expect,
43*034bee68STamir Duberstein 	int elen, const char *fmt, va_list ap)
447a79e7daSTamir Duberstein {
457a79e7daSTamir Duberstein 	va_list aq;
467a79e7daSTamir Duberstein 	int ret, written;
477a79e7daSTamir Duberstein 
487a79e7daSTamir Duberstein 	total_tests++;
497a79e7daSTamir Duberstein 
507a79e7daSTamir Duberstein 	memset(alloced_buffer, FILL_CHAR, BUF_SIZE + 2*PAD_SIZE);
517a79e7daSTamir Duberstein 	va_copy(aq, ap);
527a79e7daSTamir Duberstein 	ret = vsnprintf(test_buffer, bufsize, fmt, aq);
537a79e7daSTamir Duberstein 	va_end(aq);
547a79e7daSTamir Duberstein 
557a79e7daSTamir Duberstein 	if (ret != elen) {
56*034bee68STamir Duberstein 		KUNIT_FAIL(kunittest,
57*034bee68STamir Duberstein 			   "%s:%d: vsnprintf(buf, %d, \"%s\", ...) returned %d, expected %d\n",
58*034bee68STamir Duberstein 			   file, line, bufsize, fmt, ret, elen);
597a79e7daSTamir Duberstein 		return;
607a79e7daSTamir Duberstein 	}
617a79e7daSTamir Duberstein 
627a79e7daSTamir Duberstein 	if (memchr_inv(alloced_buffer, FILL_CHAR, PAD_SIZE)) {
63*034bee68STamir Duberstein 		KUNIT_FAIL(kunittest,
64*034bee68STamir Duberstein 			   "%s:%d: vsnprintf(buf, %d, \"%s\", ...) wrote before buffer\n",
65*034bee68STamir Duberstein 			   file, line, bufsize, fmt);
667a79e7daSTamir Duberstein 		return;
677a79e7daSTamir Duberstein 	}
687a79e7daSTamir Duberstein 
697a79e7daSTamir Duberstein 	if (!bufsize) {
707a79e7daSTamir Duberstein 		if (memchr_inv(test_buffer, FILL_CHAR, BUF_SIZE + PAD_SIZE)) {
71*034bee68STamir Duberstein 			KUNIT_FAIL(kunittest,
72*034bee68STamir Duberstein 				   "%s:%d: vsnprintf(buf, 0, \"%s\", ...) wrote to buffer\n",
73*034bee68STamir Duberstein 				   file, line, fmt);
747a79e7daSTamir Duberstein 		}
757a79e7daSTamir Duberstein 		return;
767a79e7daSTamir Duberstein 	}
777a79e7daSTamir Duberstein 
787a79e7daSTamir Duberstein 	written = min(bufsize-1, elen);
797a79e7daSTamir Duberstein 	if (test_buffer[written]) {
807a79e7daSTamir Duberstein 		KUNIT_FAIL(kunittest,
81*034bee68STamir Duberstein 			   "%s:%d: vsnprintf(buf, %d, \"%s\", ...) did not nul-terminate buffer\n",
82*034bee68STamir Duberstein 			   file, line, bufsize, fmt);
837a79e7daSTamir Duberstein 		return;
847a79e7daSTamir Duberstein 	}
857a79e7daSTamir Duberstein 
867a79e7daSTamir Duberstein 	if (memchr_inv(test_buffer + written + 1, FILL_CHAR, bufsize - (written + 1))) {
877a79e7daSTamir Duberstein 		KUNIT_FAIL(kunittest,
88*034bee68STamir Duberstein 			   "%s:%d: vsnprintf(buf, %d, \"%s\", ...) wrote beyond the nul-terminator\n",
89*034bee68STamir Duberstein 			   file, line, bufsize, fmt);
907a79e7daSTamir Duberstein 		return;
917a79e7daSTamir Duberstein 	}
927a79e7daSTamir Duberstein 
937a79e7daSTamir Duberstein 	if (memchr_inv(test_buffer + bufsize, FILL_CHAR, BUF_SIZE + PAD_SIZE - bufsize)) {
94*034bee68STamir Duberstein 		KUNIT_FAIL(kunittest,
95*034bee68STamir Duberstein 			   "%s:%d: vsnprintf(buf, %d, \"%s\", ...) wrote beyond buffer\n",
96*034bee68STamir Duberstein 			   file, line, bufsize, fmt);
977a79e7daSTamir Duberstein 		return;
987a79e7daSTamir Duberstein 	}
997a79e7daSTamir Duberstein 
1007a79e7daSTamir Duberstein 	if (memcmp(test_buffer, expect, written)) {
1017a79e7daSTamir Duberstein 		KUNIT_FAIL(kunittest,
102*034bee68STamir Duberstein 			   "%s:%d: vsnprintf(buf, %d, \"%s\", ...) wrote '%s', expected '%.*s'\n",
103*034bee68STamir Duberstein 			   file, line, bufsize, fmt, test_buffer, written, expect);
1047a79e7daSTamir Duberstein 		return;
1057a79e7daSTamir Duberstein 	}
1067a79e7daSTamir Duberstein }
1077a79e7daSTamir Duberstein 
108*034bee68STamir Duberstein static void __printf(6, 7)
__test(struct kunit * kunittest,const char * file,const int line,const char * expect,int elen,const char * fmt,...)109*034bee68STamir Duberstein __test(struct kunit *kunittest, const char *file, const int line, const char *expect, int elen,
110*034bee68STamir Duberstein 	const char *fmt, ...)
1117a79e7daSTamir Duberstein {
1127a79e7daSTamir Duberstein 	va_list ap;
1137a79e7daSTamir Duberstein 	int rand;
1147a79e7daSTamir Duberstein 	char *p;
1157a79e7daSTamir Duberstein 
1167a79e7daSTamir Duberstein 	if (elen >= BUF_SIZE) {
1177a79e7daSTamir Duberstein 		KUNIT_FAIL(kunittest,
118*034bee68STamir Duberstein 			   "%s:%d: error in test suite: expected length (%d) >= BUF_SIZE (%d). fmt=\"%s\"\n",
119*034bee68STamir Duberstein 			   file, line, elen, BUF_SIZE, fmt);
1207a79e7daSTamir Duberstein 		return;
1217a79e7daSTamir Duberstein 	}
1227a79e7daSTamir Duberstein 
1237a79e7daSTamir Duberstein 	va_start(ap, fmt);
1247a79e7daSTamir Duberstein 
1257a79e7daSTamir Duberstein 	/*
1267a79e7daSTamir Duberstein 	 * Every fmt+args is subjected to four tests: Three where we
1277a79e7daSTamir Duberstein 	 * tell vsnprintf varying buffer sizes (plenty, not quite
1287a79e7daSTamir Duberstein 	 * enough and 0), and then we also test that kvasprintf would
1297a79e7daSTamir Duberstein 	 * be able to print it as expected.
1307a79e7daSTamir Duberstein 	 */
131*034bee68STamir Duberstein 	do_test(kunittest, file, line, BUF_SIZE, expect, elen, fmt, ap);
1327a79e7daSTamir Duberstein 	rand = get_random_u32_inclusive(1, elen + 1);
1337a79e7daSTamir Duberstein 	/* Since elen < BUF_SIZE, we have 1 <= rand <= BUF_SIZE. */
134*034bee68STamir Duberstein 	do_test(kunittest, file, line, rand, expect, elen, fmt, ap);
135*034bee68STamir Duberstein 	do_test(kunittest, file, line, 0, expect, elen, fmt, ap);
1367a79e7daSTamir Duberstein 
1377a79e7daSTamir Duberstein 	p = kvasprintf(GFP_KERNEL, fmt, ap);
1387a79e7daSTamir Duberstein 	if (p) {
1397a79e7daSTamir Duberstein 		total_tests++;
1407a79e7daSTamir Duberstein 		if (memcmp(p, expect, elen+1)) {
1417a79e7daSTamir Duberstein 			KUNIT_FAIL(kunittest,
142*034bee68STamir Duberstein 				   "%s:%d: kvasprintf(..., \"%s\", ...) returned '%s', expected '%s'\n",
143*034bee68STamir Duberstein 				   file, line, fmt, p, expect);
1447a79e7daSTamir Duberstein 		}
1457a79e7daSTamir Duberstein 		kfree(p);
1467a79e7daSTamir Duberstein 	}
1477a79e7daSTamir Duberstein 	va_end(ap);
1487a79e7daSTamir Duberstein }
1497a79e7daSTamir Duberstein 
1507a79e7daSTamir Duberstein #define test(expect, fmt, ...)					\
151*034bee68STamir Duberstein 	__test(kunittest, __FILE__, __LINE__, expect, strlen(expect), fmt, ##__VA_ARGS__)
1527a79e7daSTamir Duberstein 
1537a79e7daSTamir Duberstein static void
test_basic(struct kunit * kunittest)15481a03aa9STamir Duberstein test_basic(struct kunit *kunittest)
1557a79e7daSTamir Duberstein {
1567a79e7daSTamir Duberstein 	/* Work around annoying "warning: zero-length gnu_printf format string". */
1577a79e7daSTamir Duberstein 	char nul = '\0';
1587a79e7daSTamir Duberstein 
1597a79e7daSTamir Duberstein 	test("", &nul);
1607a79e7daSTamir Duberstein 	test("100%", "100%%");
1617a79e7daSTamir Duberstein 	test("xxx%yyy", "xxx%cyyy", '%');
162*034bee68STamir Duberstein 	__test(kunittest, __FILE__, __LINE__, "xxx\0yyy", 7, "xxx%cyyy", '\0');
1637a79e7daSTamir Duberstein }
1647a79e7daSTamir Duberstein 
1657a79e7daSTamir Duberstein static void
test_number(struct kunit * kunittest)16681a03aa9STamir Duberstein test_number(struct kunit *kunittest)
1677a79e7daSTamir Duberstein {
1687a79e7daSTamir Duberstein 	test("0x1234abcd  ", "%#-12x", 0x1234abcd);
1697a79e7daSTamir Duberstein 	test("  0x1234abcd", "%#12x", 0x1234abcd);
1707a79e7daSTamir Duberstein 	test("0|001| 12|+123| 1234|-123|-1234", "%d|%03d|%3d|%+d|% d|%+d|% d", 0, 1, 12, 123, 1234, -123, -1234);
1717a79e7daSTamir Duberstein 	NOWARN(-Wformat, "Intentionally test narrowing conversion specifiers.", {
1727a79e7daSTamir Duberstein 		test("0|1|1|128|255", "%hhu|%hhu|%hhu|%hhu|%hhu", 0, 1, 257, 128, -1);
1737a79e7daSTamir Duberstein 		test("0|1|1|-128|-1", "%hhd|%hhd|%hhd|%hhd|%hhd", 0, 1, 257, 128, -1);
1747a79e7daSTamir Duberstein 		test("2015122420151225", "%ho%ho%#ho", 1037, 5282, -11627);
1757a79e7daSTamir Duberstein 	})
1767a79e7daSTamir Duberstein 	/*
1777a79e7daSTamir Duberstein 	 * POSIX/C99: »The result of converting zero with an explicit
1787a79e7daSTamir Duberstein 	 * precision of zero shall be no characters.« Hence the output
1797a79e7daSTamir Duberstein 	 * from the below test should really be "00|0||| ". However,
1807a79e7daSTamir Duberstein 	 * the kernel's printf also produces a single 0 in that
1817a79e7daSTamir Duberstein 	 * case. This test case simply documents the current
1827a79e7daSTamir Duberstein 	 * behaviour.
1837a79e7daSTamir Duberstein 	 */
1847a79e7daSTamir Duberstein 	test("00|0|0|0|0", "%.2d|%.1d|%.0d|%.*d|%1.0d", 0, 0, 0, 0, 0, 0);
1857a79e7daSTamir Duberstein }
1867a79e7daSTamir Duberstein 
1877a79e7daSTamir Duberstein static void
test_string(struct kunit * kunittest)18881a03aa9STamir Duberstein test_string(struct kunit *kunittest)
1897a79e7daSTamir Duberstein {
1907a79e7daSTamir Duberstein 	test("", "%s%.0s", "", "123");
1917a79e7daSTamir Duberstein 	test("ABCD|abc|123", "%s|%.3s|%.*s", "ABCD", "abcdef", 3, "123456");
1927a79e7daSTamir Duberstein 	test("1  |  2|3  |  4|5  ", "%-3s|%3s|%-*s|%*s|%*s", "1", "2", 3, "3", 3, "4", -3, "5");
1937a79e7daSTamir Duberstein 	test("1234      ", "%-10.4s", "123456");
1947a79e7daSTamir Duberstein 	test("      1234", "%10.4s", "123456");
1957a79e7daSTamir Duberstein 	/*
1967a79e7daSTamir Duberstein 	 * POSIX and C99 say that a negative precision (which is only
1977a79e7daSTamir Duberstein 	 * possible to pass via a * argument) should be treated as if
1987a79e7daSTamir Duberstein 	 * the precision wasn't present, and that if the precision is
1997a79e7daSTamir Duberstein 	 * omitted (as in %.s), the precision should be taken to be
2007a79e7daSTamir Duberstein 	 * 0. However, the kernel's printf behave exactly opposite,
2017a79e7daSTamir Duberstein 	 * treating a negative precision as 0 and treating an omitted
2027a79e7daSTamir Duberstein 	 * precision specifier as if no precision was given.
2037a79e7daSTamir Duberstein 	 *
2047a79e7daSTamir Duberstein 	 * These test cases document the current behaviour; should
2057a79e7daSTamir Duberstein 	 * anyone ever feel the need to follow the standards more
2067a79e7daSTamir Duberstein 	 * closely, this can be revisited.
2077a79e7daSTamir Duberstein 	 */
2087a79e7daSTamir Duberstein 	test("    ", "%4.*s", -5, "123456");
2097a79e7daSTamir Duberstein 	test("123456", "%.s", "123456");
2107a79e7daSTamir Duberstein 	test("a||", "%.s|%.0s|%.*s", "a", "b", 0, "c");
2117a79e7daSTamir Duberstein 	test("a  |   |   ", "%-3.s|%-3.0s|%-3.*s", "a", "b", 0, "c");
2127a79e7daSTamir Duberstein }
2137a79e7daSTamir Duberstein 
2147a79e7daSTamir Duberstein #define PLAIN_BUF_SIZE 64	/* leave some space so we don't oops */
2157a79e7daSTamir Duberstein 
2167a79e7daSTamir Duberstein #if BITS_PER_LONG == 64
2177a79e7daSTamir Duberstein 
2187a79e7daSTamir Duberstein #define PTR_WIDTH 16
2197a79e7daSTamir Duberstein #define PTR ((void *)0xffff0123456789abUL)
2207a79e7daSTamir Duberstein #define PTR_STR "ffff0123456789ab"
2217a79e7daSTamir Duberstein #define PTR_VAL_NO_CRNG "(____ptrval____)"
2227a79e7daSTamir Duberstein #define ZEROS "00000000"	/* hex 32 zero bits */
2237a79e7daSTamir Duberstein #define ONES "ffffffff"		/* hex 32 one bits */
2247a79e7daSTamir Duberstein 
2257a79e7daSTamir Duberstein #else
2267a79e7daSTamir Duberstein 
2277a79e7daSTamir Duberstein #define PTR_WIDTH 8
2287a79e7daSTamir Duberstein #define PTR ((void *)0x456789ab)
2297a79e7daSTamir Duberstein #define PTR_STR "456789ab"
2307a79e7daSTamir Duberstein #define PTR_VAL_NO_CRNG "(ptrval)"
2317a79e7daSTamir Duberstein #define ZEROS ""
2327a79e7daSTamir Duberstein #define ONES ""
2337a79e7daSTamir Duberstein 
2347a79e7daSTamir Duberstein #endif	/* BITS_PER_LONG == 64 */
2357a79e7daSTamir Duberstein 
23681a03aa9STamir Duberstein static void
plain_hash_to_buffer(struct kunit * kunittest,const void * p,char * buf,size_t len)23781a03aa9STamir Duberstein plain_hash_to_buffer(struct kunit *kunittest, const void *p, char *buf, size_t len)
2387a79e7daSTamir Duberstein {
23981a03aa9STamir Duberstein 	KUNIT_ASSERT_EQ(kunittest, snprintf(buf, len, "%p", p), PTR_WIDTH);
2407a79e7daSTamir Duberstein 
2417a79e7daSTamir Duberstein 	if (strncmp(buf, PTR_VAL_NO_CRNG, PTR_WIDTH) == 0) {
24281a03aa9STamir Duberstein 		kunit_skip(kunittest,
2437a79e7daSTamir Duberstein 			   "crng possibly not yet initialized. plain 'p' buffer contains \"%s\"\n",
2447a79e7daSTamir Duberstein 			   PTR_VAL_NO_CRNG);
2457a79e7daSTamir Duberstein 	}
2467a79e7daSTamir Duberstein }
2477a79e7daSTamir Duberstein 
2487a79e7daSTamir Duberstein static void
hash_pointer(struct kunit * kunittest)24981a03aa9STamir Duberstein hash_pointer(struct kunit *kunittest)
2507a79e7daSTamir Duberstein {
25181a03aa9STamir Duberstein 	if (no_hash_pointers)
25281a03aa9STamir Duberstein 		kunit_skip(kunittest, "hash pointers disabled");
25381a03aa9STamir Duberstein 
2547a79e7daSTamir Duberstein 	char buf[PLAIN_BUF_SIZE];
25581a03aa9STamir Duberstein 
25681a03aa9STamir Duberstein 	plain_hash_to_buffer(kunittest, PTR, buf, PLAIN_BUF_SIZE);
2577a79e7daSTamir Duberstein 
2587a79e7daSTamir Duberstein 	/*
25981a03aa9STamir Duberstein 	 * The hash of %p is unpredictable, therefore test() cannot be used.
26081a03aa9STamir Duberstein 	 *
26181a03aa9STamir Duberstein 	 * Instead verify that the first 32 bits are zeros on a 64-bit system
26281a03aa9STamir Duberstein 	 * and that the non-hashed value is not printed.
2637a79e7daSTamir Duberstein 	 */
26481a03aa9STamir Duberstein 
26581a03aa9STamir Duberstein 	KUNIT_EXPECT_MEMEQ(kunittest, buf, ZEROS, strlen(ZEROS));
26681a03aa9STamir Duberstein 	KUNIT_EXPECT_MEMNEQ(kunittest, buf, PTR_STR, PTR_WIDTH);
26781a03aa9STamir Duberstein }
26881a03aa9STamir Duberstein 
26981a03aa9STamir Duberstein static void
test_hashed(struct kunit * kunittest,const char * fmt,const void * p)27081a03aa9STamir Duberstein test_hashed(struct kunit *kunittest, const char *fmt, const void *p)
27181a03aa9STamir Duberstein {
27281a03aa9STamir Duberstein 	char buf[PLAIN_BUF_SIZE];
27381a03aa9STamir Duberstein 
27481a03aa9STamir Duberstein 	plain_hash_to_buffer(kunittest, p, buf, PLAIN_BUF_SIZE);
2757a79e7daSTamir Duberstein 
2767a79e7daSTamir Duberstein 	test(buf, fmt, p);
2777a79e7daSTamir Duberstein }
2787a79e7daSTamir Duberstein 
2797a79e7daSTamir Duberstein /*
2807a79e7daSTamir Duberstein  * NULL pointers aren't hashed.
2817a79e7daSTamir Duberstein  */
2827a79e7daSTamir Duberstein static void
null_pointer(struct kunit * kunittest)28381a03aa9STamir Duberstein null_pointer(struct kunit *kunittest)
2847a79e7daSTamir Duberstein {
2857a79e7daSTamir Duberstein 	test(ZEROS "00000000", "%p", NULL);
2867a79e7daSTamir Duberstein 	test(ZEROS "00000000", "%px", NULL);
2877a79e7daSTamir Duberstein 	test("(null)", "%pE", NULL);
2887a79e7daSTamir Duberstein }
2897a79e7daSTamir Duberstein 
2907a79e7daSTamir Duberstein /*
2917a79e7daSTamir Duberstein  * Error pointers aren't hashed.
2927a79e7daSTamir Duberstein  */
2937a79e7daSTamir Duberstein static void
error_pointer(struct kunit * kunittest)29481a03aa9STamir Duberstein error_pointer(struct kunit *kunittest)
2957a79e7daSTamir Duberstein {
2967a79e7daSTamir Duberstein 	test(ONES "fffffff5", "%p", ERR_PTR(-11));
2977a79e7daSTamir Duberstein 	test(ONES "fffffff5", "%px", ERR_PTR(-11));
2987a79e7daSTamir Duberstein 	test("(efault)", "%pE", ERR_PTR(-11));
2997a79e7daSTamir Duberstein }
3007a79e7daSTamir Duberstein 
3017a79e7daSTamir Duberstein #define PTR_INVALID ((void *)0x000000ab)
3027a79e7daSTamir Duberstein 
3037a79e7daSTamir Duberstein static void
invalid_pointer(struct kunit * kunittest)30481a03aa9STamir Duberstein invalid_pointer(struct kunit *kunittest)
3057a79e7daSTamir Duberstein {
30681a03aa9STamir Duberstein 	test_hashed(kunittest, "%p", PTR_INVALID);
3077a79e7daSTamir Duberstein 	test(ZEROS "000000ab", "%px", PTR_INVALID);
3087a79e7daSTamir Duberstein 	test("(efault)", "%pE", PTR_INVALID);
3097a79e7daSTamir Duberstein }
3107a79e7daSTamir Duberstein 
3117a79e7daSTamir Duberstein static void
symbol_ptr(struct kunit * kunittest)31281a03aa9STamir Duberstein symbol_ptr(struct kunit *kunittest)
3137a79e7daSTamir Duberstein {
3147a79e7daSTamir Duberstein }
3157a79e7daSTamir Duberstein 
3167a79e7daSTamir Duberstein static void
kernel_ptr(struct kunit * kunittest)31781a03aa9STamir Duberstein kernel_ptr(struct kunit *kunittest)
3187a79e7daSTamir Duberstein {
3197a79e7daSTamir Duberstein 	/* We can't test this without access to kptr_restrict. */
3207a79e7daSTamir Duberstein }
3217a79e7daSTamir Duberstein 
3227a79e7daSTamir Duberstein static void
struct_resource(struct kunit * kunittest)32381a03aa9STamir Duberstein struct_resource(struct kunit *kunittest)
3247a79e7daSTamir Duberstein {
3257a79e7daSTamir Duberstein 	struct resource test_resource = {
3267a79e7daSTamir Duberstein 		.start = 0xc0ffee00,
3277a79e7daSTamir Duberstein 		.end = 0xc0ffee00,
3287a79e7daSTamir Duberstein 		.flags = IORESOURCE_MEM,
3297a79e7daSTamir Duberstein 	};
3307a79e7daSTamir Duberstein 
3317a79e7daSTamir Duberstein 	test("[mem 0xc0ffee00 flags 0x200]",
3327a79e7daSTamir Duberstein 	     "%pr", &test_resource);
3337a79e7daSTamir Duberstein 
3347a79e7daSTamir Duberstein 	test_resource = (struct resource) {
3357a79e7daSTamir Duberstein 		.start = 0xc0ffee,
3367a79e7daSTamir Duberstein 		.end = 0xba5eba11,
3377a79e7daSTamir Duberstein 		.flags = IORESOURCE_MEM,
3387a79e7daSTamir Duberstein 	};
3397a79e7daSTamir Duberstein 	test("[mem 0x00c0ffee-0xba5eba11 flags 0x200]",
3407a79e7daSTamir Duberstein 	     "%pr", &test_resource);
3417a79e7daSTamir Duberstein 
3427a79e7daSTamir Duberstein 	test_resource = (struct resource) {
3437a79e7daSTamir Duberstein 		.start = 0xba5eba11,
3447a79e7daSTamir Duberstein 		.end = 0xc0ffee,
3457a79e7daSTamir Duberstein 		.flags = IORESOURCE_MEM,
3467a79e7daSTamir Duberstein 	};
3477a79e7daSTamir Duberstein 	test("[mem 0xba5eba11-0x00c0ffee flags 0x200]",
3487a79e7daSTamir Duberstein 	     "%pr", &test_resource);
3497a79e7daSTamir Duberstein 
3507a79e7daSTamir Duberstein 	test_resource = (struct resource) {
3517a79e7daSTamir Duberstein 		.start = 0xba5eba11,
3527a79e7daSTamir Duberstein 		.end = 0xba5eca11,
3537a79e7daSTamir Duberstein 		.flags = IORESOURCE_MEM,
3547a79e7daSTamir Duberstein 	};
3557a79e7daSTamir Duberstein 
3567a79e7daSTamir Duberstein 	test("[mem 0xba5eba11-0xba5eca11 flags 0x200]",
3577a79e7daSTamir Duberstein 	     "%pr", &test_resource);
3587a79e7daSTamir Duberstein 
3597a79e7daSTamir Duberstein 	test_resource = (struct resource) {
3607a79e7daSTamir Duberstein 		.start = 0xba11,
3617a79e7daSTamir Duberstein 		.end = 0xca10,
3627a79e7daSTamir Duberstein 		.flags = IORESOURCE_IO |
3637a79e7daSTamir Duberstein 			 IORESOURCE_DISABLED |
3647a79e7daSTamir Duberstein 			 IORESOURCE_UNSET,
3657a79e7daSTamir Duberstein 	};
3667a79e7daSTamir Duberstein 
3677a79e7daSTamir Duberstein 	test("[io  size 0x1000 disabled]",
3687a79e7daSTamir Duberstein 	     "%pR", &test_resource);
3697a79e7daSTamir Duberstein }
3707a79e7daSTamir Duberstein 
3717a79e7daSTamir Duberstein static void
struct_range(struct kunit * kunittest)37281a03aa9STamir Duberstein struct_range(struct kunit *kunittest)
3737a79e7daSTamir Duberstein {
3747a79e7daSTamir Duberstein 	struct range test_range = DEFINE_RANGE(0xc0ffee00ba5eba11,
3757a79e7daSTamir Duberstein 					       0xc0ffee00ba5eba11);
3767a79e7daSTamir Duberstein 	test("[range 0xc0ffee00ba5eba11]", "%pra", &test_range);
3777a79e7daSTamir Duberstein 
3787a79e7daSTamir Duberstein 	test_range = DEFINE_RANGE(0xc0ffee, 0xba5eba11);
3797a79e7daSTamir Duberstein 	test("[range 0x0000000000c0ffee-0x00000000ba5eba11]",
3807a79e7daSTamir Duberstein 	     "%pra", &test_range);
3817a79e7daSTamir Duberstein 
3827a79e7daSTamir Duberstein 	test_range = DEFINE_RANGE(0xba5eba11, 0xc0ffee);
3837a79e7daSTamir Duberstein 	test("[range 0x00000000ba5eba11-0x0000000000c0ffee]",
3847a79e7daSTamir Duberstein 	     "%pra", &test_range);
3857a79e7daSTamir Duberstein }
3867a79e7daSTamir Duberstein 
3877a79e7daSTamir Duberstein static void
addr(struct kunit * kunittest)38881a03aa9STamir Duberstein addr(struct kunit *kunittest)
3897a79e7daSTamir Duberstein {
3907a79e7daSTamir Duberstein }
3917a79e7daSTamir Duberstein 
3927a79e7daSTamir Duberstein static void
escaped_str(struct kunit * kunittest)39381a03aa9STamir Duberstein escaped_str(struct kunit *kunittest)
3947a79e7daSTamir Duberstein {
3957a79e7daSTamir Duberstein }
3967a79e7daSTamir Duberstein 
3977a79e7daSTamir Duberstein static void
hex_string(struct kunit * kunittest)39881a03aa9STamir Duberstein hex_string(struct kunit *kunittest)
3997a79e7daSTamir Duberstein {
4007a79e7daSTamir Duberstein 	const char buf[3] = {0xc0, 0xff, 0xee};
4017a79e7daSTamir Duberstein 
4027a79e7daSTamir Duberstein 	test("c0 ff ee|c0:ff:ee|c0-ff-ee|c0ffee",
4037a79e7daSTamir Duberstein 	     "%3ph|%3phC|%3phD|%3phN", buf, buf, buf, buf);
4047a79e7daSTamir Duberstein 	test("c0 ff ee|c0:ff:ee|c0-ff-ee|c0ffee",
4057a79e7daSTamir Duberstein 	     "%*ph|%*phC|%*phD|%*phN", 3, buf, 3, buf, 3, buf, 3, buf);
4067a79e7daSTamir Duberstein }
4077a79e7daSTamir Duberstein 
4087a79e7daSTamir Duberstein static void
mac(struct kunit * kunittest)40981a03aa9STamir Duberstein mac(struct kunit *kunittest)
4107a79e7daSTamir Duberstein {
4117a79e7daSTamir Duberstein 	const u8 addr[6] = {0x2d, 0x48, 0xd6, 0xfc, 0x7a, 0x05};
4127a79e7daSTamir Duberstein 
4137a79e7daSTamir Duberstein 	test("2d:48:d6:fc:7a:05", "%pM", addr);
4147a79e7daSTamir Duberstein 	test("05:7a:fc:d6:48:2d", "%pMR", addr);
4157a79e7daSTamir Duberstein 	test("2d-48-d6-fc-7a-05", "%pMF", addr);
4167a79e7daSTamir Duberstein 	test("2d48d6fc7a05", "%pm", addr);
4177a79e7daSTamir Duberstein 	test("057afcd6482d", "%pmR", addr);
4187a79e7daSTamir Duberstein }
4197a79e7daSTamir Duberstein 
4207a79e7daSTamir Duberstein static void
ip4(struct kunit * kunittest)42181a03aa9STamir Duberstein ip4(struct kunit *kunittest)
4227a79e7daSTamir Duberstein {
4237a79e7daSTamir Duberstein 	struct sockaddr_in sa;
4247a79e7daSTamir Duberstein 
4257a79e7daSTamir Duberstein 	sa.sin_family = AF_INET;
4267a79e7daSTamir Duberstein 	sa.sin_port = cpu_to_be16(12345);
4277a79e7daSTamir Duberstein 	sa.sin_addr.s_addr = cpu_to_be32(0x7f000001);
4287a79e7daSTamir Duberstein 
4297a79e7daSTamir Duberstein 	test("127.000.000.001|127.0.0.1", "%pi4|%pI4", &sa.sin_addr, &sa.sin_addr);
4307a79e7daSTamir Duberstein 	test("127.000.000.001|127.0.0.1", "%piS|%pIS", &sa, &sa);
4317a79e7daSTamir Duberstein 	sa.sin_addr.s_addr = cpu_to_be32(0x01020304);
4327a79e7daSTamir Duberstein 	test("001.002.003.004:12345|1.2.3.4:12345", "%piSp|%pISp", &sa, &sa);
4337a79e7daSTamir Duberstein }
4347a79e7daSTamir Duberstein 
4357a79e7daSTamir Duberstein static void
ip6(struct kunit * kunittest)43681a03aa9STamir Duberstein ip6(struct kunit *kunittest)
4377a79e7daSTamir Duberstein {
4387a79e7daSTamir Duberstein }
4397a79e7daSTamir Duberstein 
4407a79e7daSTamir Duberstein static void
uuid(struct kunit * kunittest)44181a03aa9STamir Duberstein uuid(struct kunit *kunittest)
4427a79e7daSTamir Duberstein {
4437a79e7daSTamir Duberstein 	const char uuid[16] = {0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7,
4447a79e7daSTamir Duberstein 			       0x8, 0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf};
4457a79e7daSTamir Duberstein 
4467a79e7daSTamir Duberstein 	test("00010203-0405-0607-0809-0a0b0c0d0e0f", "%pUb", uuid);
4477a79e7daSTamir Duberstein 	test("00010203-0405-0607-0809-0A0B0C0D0E0F", "%pUB", uuid);
4487a79e7daSTamir Duberstein 	test("03020100-0504-0706-0809-0a0b0c0d0e0f", "%pUl", uuid);
4497a79e7daSTamir Duberstein 	test("03020100-0504-0706-0809-0A0B0C0D0E0F", "%pUL", uuid);
4507a79e7daSTamir Duberstein }
4517a79e7daSTamir Duberstein 
4527a79e7daSTamir Duberstein static struct dentry test_dentry[4] = {
4537a79e7daSTamir Duberstein 	{ .d_parent = &test_dentry[0],
4547a79e7daSTamir Duberstein 	  .d_name = QSTR_INIT(test_dentry[0].d_iname, 3),
4557a79e7daSTamir Duberstein 	  .d_iname = "foo" },
4567a79e7daSTamir Duberstein 	{ .d_parent = &test_dentry[0],
4577a79e7daSTamir Duberstein 	  .d_name = QSTR_INIT(test_dentry[1].d_iname, 5),
4587a79e7daSTamir Duberstein 	  .d_iname = "bravo" },
4597a79e7daSTamir Duberstein 	{ .d_parent = &test_dentry[1],
4607a79e7daSTamir Duberstein 	  .d_name = QSTR_INIT(test_dentry[2].d_iname, 4),
4617a79e7daSTamir Duberstein 	  .d_iname = "alfa" },
4627a79e7daSTamir Duberstein 	{ .d_parent = &test_dentry[2],
4637a79e7daSTamir Duberstein 	  .d_name = QSTR_INIT(test_dentry[3].d_iname, 5),
4647a79e7daSTamir Duberstein 	  .d_iname = "romeo" },
4657a79e7daSTamir Duberstein };
4667a79e7daSTamir Duberstein 
4677a79e7daSTamir Duberstein static void
dentry(struct kunit * kunittest)46881a03aa9STamir Duberstein dentry(struct kunit *kunittest)
4697a79e7daSTamir Duberstein {
4707a79e7daSTamir Duberstein 	test("foo", "%pd", &test_dentry[0]);
4717a79e7daSTamir Duberstein 	test("foo", "%pd2", &test_dentry[0]);
4727a79e7daSTamir Duberstein 
4737a79e7daSTamir Duberstein 	test("(null)", "%pd", NULL);
4747a79e7daSTamir Duberstein 	test("(efault)", "%pd", PTR_INVALID);
4757a79e7daSTamir Duberstein 	test("(null)", "%pD", NULL);
4767a79e7daSTamir Duberstein 	test("(efault)", "%pD", PTR_INVALID);
4777a79e7daSTamir Duberstein 
4787a79e7daSTamir Duberstein 	test("romeo", "%pd", &test_dentry[3]);
4797a79e7daSTamir Duberstein 	test("alfa/romeo", "%pd2", &test_dentry[3]);
4807a79e7daSTamir Duberstein 	test("bravo/alfa/romeo", "%pd3", &test_dentry[3]);
4817a79e7daSTamir Duberstein 	test("/bravo/alfa/romeo", "%pd4", &test_dentry[3]);
4827a79e7daSTamir Duberstein 	test("/bravo/alfa", "%pd4", &test_dentry[2]);
4837a79e7daSTamir Duberstein 
4847a79e7daSTamir Duberstein 	test("bravo/alfa  |bravo/alfa  ", "%-12pd2|%*pd2", &test_dentry[2], -12, &test_dentry[2]);
4857a79e7daSTamir Duberstein 	test("  bravo/alfa|  bravo/alfa", "%12pd2|%*pd2", &test_dentry[2], 12, &test_dentry[2]);
4867a79e7daSTamir Duberstein }
4877a79e7daSTamir Duberstein 
4887a79e7daSTamir Duberstein static void
struct_va_format(struct kunit * kunittest)48981a03aa9STamir Duberstein struct_va_format(struct kunit *kunittest)
4907a79e7daSTamir Duberstein {
4917a79e7daSTamir Duberstein }
4927a79e7daSTamir Duberstein 
4937a79e7daSTamir Duberstein static void
time_and_date(struct kunit * kunittest)49481a03aa9STamir Duberstein time_and_date(struct kunit *kunittest)
4957a79e7daSTamir Duberstein {
4967a79e7daSTamir Duberstein 	/* 1543210543 */
4977a79e7daSTamir Duberstein 	const struct rtc_time tm = {
4987a79e7daSTamir Duberstein 		.tm_sec = 43,
4997a79e7daSTamir Duberstein 		.tm_min = 35,
5007a79e7daSTamir Duberstein 		.tm_hour = 5,
5017a79e7daSTamir Duberstein 		.tm_mday = 26,
5027a79e7daSTamir Duberstein 		.tm_mon = 10,
5037a79e7daSTamir Duberstein 		.tm_year = 118,
5047a79e7daSTamir Duberstein 	};
5057a79e7daSTamir Duberstein 	/* 2019-01-04T15:32:23 */
5067a79e7daSTamir Duberstein 	time64_t t = 1546615943;
5077a79e7daSTamir Duberstein 
5087a79e7daSTamir Duberstein 	test("(%pt?)", "%pt", &tm);
5097a79e7daSTamir Duberstein 	test("2018-11-26T05:35:43", "%ptR", &tm);
5107a79e7daSTamir Duberstein 	test("0118-10-26T05:35:43", "%ptRr", &tm);
5117a79e7daSTamir Duberstein 	test("05:35:43|2018-11-26", "%ptRt|%ptRd", &tm, &tm);
5127a79e7daSTamir Duberstein 	test("05:35:43|0118-10-26", "%ptRtr|%ptRdr", &tm, &tm);
5137a79e7daSTamir Duberstein 	test("05:35:43|2018-11-26", "%ptRttr|%ptRdtr", &tm, &tm);
5147a79e7daSTamir Duberstein 	test("05:35:43 tr|2018-11-26 tr", "%ptRt tr|%ptRd tr", &tm, &tm);
5157a79e7daSTamir Duberstein 
5167a79e7daSTamir Duberstein 	test("2019-01-04T15:32:23", "%ptT", &t);
5177a79e7daSTamir Duberstein 	test("0119-00-04T15:32:23", "%ptTr", &t);
5187a79e7daSTamir Duberstein 	test("15:32:23|2019-01-04", "%ptTt|%ptTd", &t, &t);
5197a79e7daSTamir Duberstein 	test("15:32:23|0119-00-04", "%ptTtr|%ptTdr", &t, &t);
5207a79e7daSTamir Duberstein 
5217a79e7daSTamir Duberstein 	test("2019-01-04 15:32:23", "%ptTs", &t);
5227a79e7daSTamir Duberstein 	test("0119-00-04 15:32:23", "%ptTsr", &t);
5237a79e7daSTamir Duberstein 	test("15:32:23|2019-01-04", "%ptTts|%ptTds", &t, &t);
5247a79e7daSTamir Duberstein 	test("15:32:23|0119-00-04", "%ptTtrs|%ptTdrs", &t, &t);
5257a79e7daSTamir Duberstein }
5267a79e7daSTamir Duberstein 
5277a79e7daSTamir Duberstein static void
struct_clk(struct kunit * kunittest)52881a03aa9STamir Duberstein struct_clk(struct kunit *kunittest)
5297a79e7daSTamir Duberstein {
5307a79e7daSTamir Duberstein }
5317a79e7daSTamir Duberstein 
5327a79e7daSTamir Duberstein static void
large_bitmap(struct kunit * kunittest)53381a03aa9STamir Duberstein large_bitmap(struct kunit *kunittest)
5347a79e7daSTamir Duberstein {
5357a79e7daSTamir Duberstein 	const int nbits = 1 << 16;
5367a79e7daSTamir Duberstein 	unsigned long *bits = bitmap_zalloc(nbits, GFP_KERNEL);
5377a79e7daSTamir Duberstein 	if (!bits)
5387a79e7daSTamir Duberstein 		return;
5397a79e7daSTamir Duberstein 
5407a79e7daSTamir Duberstein 	bitmap_set(bits, 1, 20);
5417a79e7daSTamir Duberstein 	bitmap_set(bits, 60000, 15);
5427a79e7daSTamir Duberstein 	test("1-20,60000-60014", "%*pbl", nbits, bits);
5437a79e7daSTamir Duberstein 	bitmap_free(bits);
5447a79e7daSTamir Duberstein }
5457a79e7daSTamir Duberstein 
5467a79e7daSTamir Duberstein static void
bitmap(struct kunit * kunittest)54781a03aa9STamir Duberstein bitmap(struct kunit *kunittest)
5487a79e7daSTamir Duberstein {
5497a79e7daSTamir Duberstein 	DECLARE_BITMAP(bits, 20);
5507a79e7daSTamir Duberstein 	const int primes[] = {2,3,5,7,11,13,17,19};
5517a79e7daSTamir Duberstein 	int i;
5527a79e7daSTamir Duberstein 
5537a79e7daSTamir Duberstein 	bitmap_zero(bits, 20);
5547a79e7daSTamir Duberstein 	test("00000|00000", "%20pb|%*pb", bits, 20, bits);
5557a79e7daSTamir Duberstein 	test("|", "%20pbl|%*pbl", bits, 20, bits);
5567a79e7daSTamir Duberstein 
5577a79e7daSTamir Duberstein 	for (i = 0; i < ARRAY_SIZE(primes); ++i)
5587a79e7daSTamir Duberstein 		set_bit(primes[i], bits);
5597a79e7daSTamir Duberstein 	test("a28ac|a28ac", "%20pb|%*pb", bits, 20, bits);
5607a79e7daSTamir Duberstein 	test("2-3,5,7,11,13,17,19|2-3,5,7,11,13,17,19", "%20pbl|%*pbl", bits, 20, bits);
5617a79e7daSTamir Duberstein 
5627a79e7daSTamir Duberstein 	bitmap_fill(bits, 20);
5637a79e7daSTamir Duberstein 	test("fffff|fffff", "%20pb|%*pb", bits, 20, bits);
5647a79e7daSTamir Duberstein 	test("0-19|0-19", "%20pbl|%*pbl", bits, 20, bits);
5657a79e7daSTamir Duberstein 
56681a03aa9STamir Duberstein 	large_bitmap(kunittest);
5677a79e7daSTamir Duberstein }
5687a79e7daSTamir Duberstein 
5697a79e7daSTamir Duberstein static void
netdev_features(struct kunit * kunittest)57081a03aa9STamir Duberstein netdev_features(struct kunit *kunittest)
5717a79e7daSTamir Duberstein {
5727a79e7daSTamir Duberstein }
5737a79e7daSTamir Duberstein 
5747a79e7daSTamir Duberstein struct page_flags_test {
5757a79e7daSTamir Duberstein 	int width;
5767a79e7daSTamir Duberstein 	int shift;
5777a79e7daSTamir Duberstein 	int mask;
5787a79e7daSTamir Duberstein 	const char *fmt;
5797a79e7daSTamir Duberstein 	const char *name;
5807a79e7daSTamir Duberstein };
5817a79e7daSTamir Duberstein 
5827a79e7daSTamir Duberstein static const struct page_flags_test pft[] = {
5837a79e7daSTamir Duberstein 	{SECTIONS_WIDTH, SECTIONS_PGSHIFT, SECTIONS_MASK,
5847a79e7daSTamir Duberstein 	 "%d", "section"},
5857a79e7daSTamir Duberstein 	{NODES_WIDTH, NODES_PGSHIFT, NODES_MASK,
5867a79e7daSTamir Duberstein 	 "%d", "node"},
5877a79e7daSTamir Duberstein 	{ZONES_WIDTH, ZONES_PGSHIFT, ZONES_MASK,
5887a79e7daSTamir Duberstein 	 "%d", "zone"},
5897a79e7daSTamir Duberstein 	{LAST_CPUPID_WIDTH, LAST_CPUPID_PGSHIFT, LAST_CPUPID_MASK,
5907a79e7daSTamir Duberstein 	 "%#x", "lastcpupid"},
5917a79e7daSTamir Duberstein 	{KASAN_TAG_WIDTH, KASAN_TAG_PGSHIFT, KASAN_TAG_MASK,
5927a79e7daSTamir Duberstein 	 "%#x", "kasantag"},
5937a79e7daSTamir Duberstein };
5947a79e7daSTamir Duberstein 
5957a79e7daSTamir Duberstein static void
page_flags_test(struct kunit * kunittest,int section,int node,int zone,int last_cpupid,int kasan_tag,unsigned long flags,const char * name,char * cmp_buf)59681a03aa9STamir Duberstein page_flags_test(struct kunit *kunittest, int section, int node, int zone,
59781a03aa9STamir Duberstein 		int last_cpupid, int kasan_tag, unsigned long flags, const char *name,
5987a79e7daSTamir Duberstein 		char *cmp_buf)
5997a79e7daSTamir Duberstein {
6007a79e7daSTamir Duberstein 	unsigned long values[] = {section, node, zone, last_cpupid, kasan_tag};
6017a79e7daSTamir Duberstein 	unsigned long size;
6027a79e7daSTamir Duberstein 	bool append = false;
6037a79e7daSTamir Duberstein 	int i;
6047a79e7daSTamir Duberstein 
6057a79e7daSTamir Duberstein 	for (i = 0; i < ARRAY_SIZE(values); i++)
6067a79e7daSTamir Duberstein 		flags |= (values[i] & pft[i].mask) << pft[i].shift;
6077a79e7daSTamir Duberstein 
6087a79e7daSTamir Duberstein 	size = scnprintf(cmp_buf, BUF_SIZE, "%#lx(", flags);
6097a79e7daSTamir Duberstein 	if (flags & PAGEFLAGS_MASK) {
6107a79e7daSTamir Duberstein 		size += scnprintf(cmp_buf + size, BUF_SIZE - size, "%s", name);
6117a79e7daSTamir Duberstein 		append = true;
6127a79e7daSTamir Duberstein 	}
6137a79e7daSTamir Duberstein 
6147a79e7daSTamir Duberstein 	for (i = 0; i < ARRAY_SIZE(pft); i++) {
6157a79e7daSTamir Duberstein 		if (!pft[i].width)
6167a79e7daSTamir Duberstein 			continue;
6177a79e7daSTamir Duberstein 
6187a79e7daSTamir Duberstein 		if (append)
6197a79e7daSTamir Duberstein 			size += scnprintf(cmp_buf + size, BUF_SIZE - size, "|");
6207a79e7daSTamir Duberstein 
6217a79e7daSTamir Duberstein 		size += scnprintf(cmp_buf + size, BUF_SIZE - size, "%s=",
6227a79e7daSTamir Duberstein 				pft[i].name);
6237a79e7daSTamir Duberstein 		size += scnprintf(cmp_buf + size, BUF_SIZE - size, pft[i].fmt,
6247a79e7daSTamir Duberstein 				values[i] & pft[i].mask);
6257a79e7daSTamir Duberstein 		append = true;
6267a79e7daSTamir Duberstein 	}
6277a79e7daSTamir Duberstein 
6287a79e7daSTamir Duberstein 	snprintf(cmp_buf + size, BUF_SIZE - size, ")");
6297a79e7daSTamir Duberstein 
6307a79e7daSTamir Duberstein 	test(cmp_buf, "%pGp", &flags);
6317a79e7daSTamir Duberstein }
6327a79e7daSTamir Duberstein 
6337a79e7daSTamir Duberstein static void
flags(struct kunit * kunittest)63481a03aa9STamir Duberstein flags(struct kunit *kunittest)
6357a79e7daSTamir Duberstein {
6367a79e7daSTamir Duberstein 	unsigned long flags;
6377a79e7daSTamir Duberstein 	char *cmp_buffer;
6387a79e7daSTamir Duberstein 	gfp_t gfp;
6397a79e7daSTamir Duberstein 
64081a03aa9STamir Duberstein 	cmp_buffer = kunit_kmalloc(kunittest, BUF_SIZE, GFP_KERNEL);
64181a03aa9STamir Duberstein 	KUNIT_ASSERT_NOT_NULL(kunittest, cmp_buffer);
6427a79e7daSTamir Duberstein 
6437a79e7daSTamir Duberstein 	flags = 0;
64481a03aa9STamir Duberstein 	page_flags_test(kunittest, 0, 0, 0, 0, 0, flags, "", cmp_buffer);
6457a79e7daSTamir Duberstein 
6467a79e7daSTamir Duberstein 	flags = 1UL << NR_PAGEFLAGS;
64781a03aa9STamir Duberstein 	page_flags_test(kunittest, 0, 0, 0, 0, 0, flags, "", cmp_buffer);
6487a79e7daSTamir Duberstein 
6497a79e7daSTamir Duberstein 	flags |= 1UL << PG_uptodate | 1UL << PG_dirty | 1UL << PG_lru
6507a79e7daSTamir Duberstein 		| 1UL << PG_active | 1UL << PG_swapbacked;
65181a03aa9STamir Duberstein 	page_flags_test(kunittest, 1, 1, 1, 0x1fffff, 1, flags,
6527a79e7daSTamir Duberstein 			"uptodate|dirty|lru|active|swapbacked",
6537a79e7daSTamir Duberstein 			cmp_buffer);
6547a79e7daSTamir Duberstein 
6557a79e7daSTamir Duberstein 	flags = VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC;
6567a79e7daSTamir Duberstein 	test("read|exec|mayread|maywrite|mayexec", "%pGv", &flags);
6577a79e7daSTamir Duberstein 
6587a79e7daSTamir Duberstein 	gfp = GFP_TRANSHUGE;
6597a79e7daSTamir Duberstein 	test("GFP_TRANSHUGE", "%pGg", &gfp);
6607a79e7daSTamir Duberstein 
6617a79e7daSTamir Duberstein 	gfp = GFP_ATOMIC|__GFP_DMA;
6627a79e7daSTamir Duberstein 	test("GFP_ATOMIC|GFP_DMA", "%pGg", &gfp);
6637a79e7daSTamir Duberstein 
6647a79e7daSTamir Duberstein 	gfp = __GFP_HIGH;
6657a79e7daSTamir Duberstein 	test("__GFP_HIGH", "%pGg", &gfp);
6667a79e7daSTamir Duberstein 
6677a79e7daSTamir Duberstein 	/* Any flags not translated by the table should remain numeric */
6687a79e7daSTamir Duberstein 	gfp = ~__GFP_BITS_MASK;
6697a79e7daSTamir Duberstein 	snprintf(cmp_buffer, BUF_SIZE, "%#lx", (unsigned long) gfp);
6707a79e7daSTamir Duberstein 	test(cmp_buffer, "%pGg", &gfp);
6717a79e7daSTamir Duberstein 
6727a79e7daSTamir Duberstein 	snprintf(cmp_buffer, BUF_SIZE, "__GFP_HIGH|%#lx",
6737a79e7daSTamir Duberstein 							(unsigned long) gfp);
6747a79e7daSTamir Duberstein 	gfp |= __GFP_HIGH;
6757a79e7daSTamir Duberstein 	test(cmp_buffer, "%pGg", &gfp);
6767a79e7daSTamir Duberstein }
6777a79e7daSTamir Duberstein 
fwnode_pointer(struct kunit * kunittest)67881a03aa9STamir Duberstein static void fwnode_pointer(struct kunit *kunittest)
6797a79e7daSTamir Duberstein {
6807a79e7daSTamir Duberstein 	const struct software_node first = { .name = "first" };
6817a79e7daSTamir Duberstein 	const struct software_node second = { .name = "second", .parent = &first };
6827a79e7daSTamir Duberstein 	const struct software_node third = { .name = "third", .parent = &second };
6837a79e7daSTamir Duberstein 	const struct software_node *group[] = { &first, &second, &third, NULL };
6847a79e7daSTamir Duberstein 	const char * const full_name_second = "first/second";
6857a79e7daSTamir Duberstein 	const char * const full_name_third = "first/second/third";
6867a79e7daSTamir Duberstein 	const char * const second_name = "second";
6877a79e7daSTamir Duberstein 	const char * const third_name = "third";
6887a79e7daSTamir Duberstein 	int rval;
6897a79e7daSTamir Duberstein 
6907a79e7daSTamir Duberstein 	rval = software_node_register_node_group(group);
6917a79e7daSTamir Duberstein 	if (rval) {
69281a03aa9STamir Duberstein 		kunit_skip(kunittest, "cannot register softnodes; rval %d\n", rval);
6937a79e7daSTamir Duberstein 	}
6947a79e7daSTamir Duberstein 
6957a79e7daSTamir Duberstein 	test(full_name_second, "%pfw", software_node_fwnode(&second));
6967a79e7daSTamir Duberstein 	test(full_name_third, "%pfw", software_node_fwnode(&third));
6977a79e7daSTamir Duberstein 	test(full_name_third, "%pfwf", software_node_fwnode(&third));
6987a79e7daSTamir Duberstein 	test(second_name, "%pfwP", software_node_fwnode(&second));
6997a79e7daSTamir Duberstein 	test(third_name, "%pfwP", software_node_fwnode(&third));
7007a79e7daSTamir Duberstein 
7017a79e7daSTamir Duberstein 	software_node_unregister_node_group(group);
7027a79e7daSTamir Duberstein }
7037a79e7daSTamir Duberstein 
fourcc_pointer(struct kunit * kunittest)70481a03aa9STamir Duberstein static void fourcc_pointer(struct kunit *kunittest)
7057a79e7daSTamir Duberstein {
7067a79e7daSTamir Duberstein 	struct {
7077a79e7daSTamir Duberstein 		u32 code;
7087a79e7daSTamir Duberstein 		char *str;
7097a79e7daSTamir Duberstein 	} const try[] = {
7107a79e7daSTamir Duberstein 		{ 0x3231564e, "NV12 little-endian (0x3231564e)", },
7117a79e7daSTamir Duberstein 		{ 0xb231564e, "NV12 big-endian (0xb231564e)", },
7127a79e7daSTamir Duberstein 		{ 0x10111213, ".... little-endian (0x10111213)", },
7137a79e7daSTamir Duberstein 		{ 0x20303159, "Y10  little-endian (0x20303159)", },
7147a79e7daSTamir Duberstein 	};
7157a79e7daSTamir Duberstein 	unsigned int i;
7167a79e7daSTamir Duberstein 
7177a79e7daSTamir Duberstein 	for (i = 0; i < ARRAY_SIZE(try); i++)
7187a79e7daSTamir Duberstein 		test(try[i].str, "%p4cc", &try[i].code);
7197a79e7daSTamir Duberstein }
7207a79e7daSTamir Duberstein 
7217a79e7daSTamir Duberstein static void
errptr(struct kunit * kunittest)72281a03aa9STamir Duberstein errptr(struct kunit *kunittest)
7237a79e7daSTamir Duberstein {
7247a79e7daSTamir Duberstein 	test("-1234", "%pe", ERR_PTR(-1234));
7257a79e7daSTamir Duberstein 
7267a79e7daSTamir Duberstein 	/* Check that %pe with a non-ERR_PTR gets treated as ordinary %p. */
7277a79e7daSTamir Duberstein 	BUILD_BUG_ON(IS_ERR(PTR));
72881a03aa9STamir Duberstein 	test_hashed(kunittest, "%pe", PTR);
7297a79e7daSTamir Duberstein 
7307a79e7daSTamir Duberstein #ifdef CONFIG_SYMBOLIC_ERRNAME
7317a79e7daSTamir Duberstein 	test("(-ENOTSOCK)", "(%pe)", ERR_PTR(-ENOTSOCK));
7327a79e7daSTamir Duberstein 	test("(-EAGAIN)", "(%pe)", ERR_PTR(-EAGAIN));
7337a79e7daSTamir Duberstein 	BUILD_BUG_ON(EAGAIN != EWOULDBLOCK);
7347a79e7daSTamir Duberstein 	test("(-EAGAIN)", "(%pe)", ERR_PTR(-EWOULDBLOCK));
7357a79e7daSTamir Duberstein 	test("[-EIO    ]", "[%-8pe]", ERR_PTR(-EIO));
7367a79e7daSTamir Duberstein 	test("[    -EIO]", "[%8pe]", ERR_PTR(-EIO));
7377a79e7daSTamir Duberstein 	test("-EPROBE_DEFER", "%pe", ERR_PTR(-EPROBE_DEFER));
7387a79e7daSTamir Duberstein #endif
7397a79e7daSTamir Duberstein }
7407a79e7daSTamir Duberstein 
printf_suite_init(struct kunit_suite * suite)7417a79e7daSTamir Duberstein static int printf_suite_init(struct kunit_suite *suite)
7427a79e7daSTamir Duberstein {
7437a79e7daSTamir Duberstein 	total_tests = 0;
74481a03aa9STamir Duberstein 
74581a03aa9STamir Duberstein 	alloced_buffer = kmalloc(BUF_SIZE + 2*PAD_SIZE, GFP_KERNEL);
74681a03aa9STamir Duberstein 	if (!alloced_buffer)
74781a03aa9STamir Duberstein 		return -ENOMEM;
74881a03aa9STamir Duberstein 	test_buffer = alloced_buffer + PAD_SIZE;
74981a03aa9STamir Duberstein 
7507a79e7daSTamir Duberstein 	return 0;
7517a79e7daSTamir Duberstein }
7527a79e7daSTamir Duberstein 
printf_suite_exit(struct kunit_suite * suite)7537a79e7daSTamir Duberstein static void printf_suite_exit(struct kunit_suite *suite)
7547a79e7daSTamir Duberstein {
75581a03aa9STamir Duberstein 	kfree(alloced_buffer);
75681a03aa9STamir Duberstein 
7577a79e7daSTamir Duberstein 	kunit_info(suite, "ran %u tests\n", total_tests);
7587a79e7daSTamir Duberstein }
7597a79e7daSTamir Duberstein 
7607a79e7daSTamir Duberstein static struct kunit_case printf_test_cases[] = {
76181a03aa9STamir Duberstein 	KUNIT_CASE(test_basic),
76281a03aa9STamir Duberstein 	KUNIT_CASE(test_number),
76381a03aa9STamir Duberstein 	KUNIT_CASE(test_string),
76481a03aa9STamir Duberstein 	KUNIT_CASE(hash_pointer),
76581a03aa9STamir Duberstein 	KUNIT_CASE(null_pointer),
76681a03aa9STamir Duberstein 	KUNIT_CASE(error_pointer),
76781a03aa9STamir Duberstein 	KUNIT_CASE(invalid_pointer),
76881a03aa9STamir Duberstein 	KUNIT_CASE(symbol_ptr),
76981a03aa9STamir Duberstein 	KUNIT_CASE(kernel_ptr),
77081a03aa9STamir Duberstein 	KUNIT_CASE(struct_resource),
77181a03aa9STamir Duberstein 	KUNIT_CASE(struct_range),
77281a03aa9STamir Duberstein 	KUNIT_CASE(addr),
77381a03aa9STamir Duberstein 	KUNIT_CASE(escaped_str),
77481a03aa9STamir Duberstein 	KUNIT_CASE(hex_string),
77581a03aa9STamir Duberstein 	KUNIT_CASE(mac),
77681a03aa9STamir Duberstein 	KUNIT_CASE(ip4),
77781a03aa9STamir Duberstein 	KUNIT_CASE(ip6),
77881a03aa9STamir Duberstein 	KUNIT_CASE(uuid),
77981a03aa9STamir Duberstein 	KUNIT_CASE(dentry),
78081a03aa9STamir Duberstein 	KUNIT_CASE(struct_va_format),
78181a03aa9STamir Duberstein 	KUNIT_CASE(time_and_date),
78281a03aa9STamir Duberstein 	KUNIT_CASE(struct_clk),
78381a03aa9STamir Duberstein 	KUNIT_CASE(bitmap),
78481a03aa9STamir Duberstein 	KUNIT_CASE(netdev_features),
78581a03aa9STamir Duberstein 	KUNIT_CASE(flags),
78681a03aa9STamir Duberstein 	KUNIT_CASE(errptr),
78781a03aa9STamir Duberstein 	KUNIT_CASE(fwnode_pointer),
78881a03aa9STamir Duberstein 	KUNIT_CASE(fourcc_pointer),
7897a79e7daSTamir Duberstein 	{}
7907a79e7daSTamir Duberstein };
7917a79e7daSTamir Duberstein 
7927a79e7daSTamir Duberstein static struct kunit_suite printf_test_suite = {
7937a79e7daSTamir Duberstein 	.name = "printf",
7947a79e7daSTamir Duberstein 	.suite_init = printf_suite_init,
7957a79e7daSTamir Duberstein 	.suite_exit = printf_suite_exit,
7967a79e7daSTamir Duberstein 	.test_cases = printf_test_cases,
7977a79e7daSTamir Duberstein };
7987a79e7daSTamir Duberstein 
7997a79e7daSTamir Duberstein kunit_test_suite(printf_test_suite);
8007a79e7daSTamir Duberstein 
8017a79e7daSTamir Duberstein MODULE_AUTHOR("Rasmus Villemoes <[email protected]>");
8027a79e7daSTamir Duberstein MODULE_DESCRIPTION("Test cases for printf facility");
8037a79e7daSTamir Duberstein MODULE_LICENSE("GPL");
804