xref: /linux/lib/kunit/assert_test.c (revision a1ff5a7d78a036d6c2178ee5acd6ba4946243800)
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  * KUnit test for the assertion formatting functions.
4  * Author: Ivan Orlov <ivan.orlov0322@gmail.com>
5  */
6 #include <kunit/test.h>
7 #include "string-stream.h"
8 
9 #define TEST_PTR_EXPECTED_BUF_SIZE 32
10 #define HEXDUMP_TEST_BUF_LEN 5
11 #define ASSERT_TEST_EXPECT_CONTAIN(test, str, substr) KUNIT_EXPECT_TRUE(test, strstr(str, substr))
12 #define ASSERT_TEST_EXPECT_NCONTAIN(test, str, substr) KUNIT_EXPECT_FALSE(test, strstr(str, substr))
13 
kunit_test_is_literal(struct kunit * test)14 static void kunit_test_is_literal(struct kunit *test)
15 {
16 	KUNIT_EXPECT_TRUE(test, is_literal("5", 5));
17 	KUNIT_EXPECT_TRUE(test, is_literal("0", 0));
18 	KUNIT_EXPECT_TRUE(test, is_literal("1234567890", 1234567890));
19 	KUNIT_EXPECT_TRUE(test, is_literal("-1234567890", -1234567890));
20 	KUNIT_EXPECT_FALSE(test, is_literal("05", 5));
21 	KUNIT_EXPECT_FALSE(test, is_literal("", 0));
22 	KUNIT_EXPECT_FALSE(test, is_literal("-0", 0));
23 	KUNIT_EXPECT_FALSE(test, is_literal("12#45", 1245));
24 }
25 
kunit_test_is_str_literal(struct kunit * test)26 static void kunit_test_is_str_literal(struct kunit *test)
27 {
28 	KUNIT_EXPECT_TRUE(test, is_str_literal("\"Hello, World!\"", "Hello, World!"));
29 	KUNIT_EXPECT_TRUE(test, is_str_literal("\"\"", ""));
30 	KUNIT_EXPECT_TRUE(test, is_str_literal("\"\"\"", "\""));
31 	KUNIT_EXPECT_FALSE(test, is_str_literal("", ""));
32 	KUNIT_EXPECT_FALSE(test, is_str_literal("\"", "\""));
33 	KUNIT_EXPECT_FALSE(test, is_str_literal("\"Abacaba", "Abacaba"));
34 	KUNIT_EXPECT_FALSE(test, is_str_literal("Abacaba\"", "Abacaba"));
35 	KUNIT_EXPECT_FALSE(test, is_str_literal("\"Abacaba\"", "\"Abacaba\""));
36 }
37 
38 KUNIT_DEFINE_ACTION_WRAPPER(kfree_wrapper, kfree, const void *);
39 
40 /* this function is used to get a "char *" string from the string stream and defer its cleanup  */
get_str_from_stream(struct kunit * test,struct string_stream * stream)41 static char *get_str_from_stream(struct kunit *test, struct string_stream *stream)
42 {
43 	char *str = string_stream_get_string(stream);
44 
45 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, str);
46 	kunit_add_action(test, kfree_wrapper, (void *)str);
47 
48 	return str;
49 }
50 
kunit_test_assert_prologue(struct kunit * test)51 static void kunit_test_assert_prologue(struct kunit *test)
52 {
53 	struct string_stream *stream;
54 	char *str;
55 	const struct kunit_loc location = {
56 		.file = "testfile.c",
57 		.line = 1337,
58 	};
59 
60 	stream = kunit_alloc_string_stream(test, GFP_KERNEL);
61 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, stream);
62 
63 	/* Test an expectation fail prologue */
64 	kunit_assert_prologue(&location, KUNIT_EXPECTATION, stream);
65 	str = get_str_from_stream(test, stream);
66 	ASSERT_TEST_EXPECT_CONTAIN(test, str, "EXPECTATION");
67 	ASSERT_TEST_EXPECT_CONTAIN(test, str, "testfile.c");
68 	ASSERT_TEST_EXPECT_CONTAIN(test, str, "1337");
69 
70 	/* Test an assertion fail prologue */
71 	string_stream_clear(stream);
72 	kunit_assert_prologue(&location, KUNIT_ASSERTION, stream);
73 	str = get_str_from_stream(test, stream);
74 	ASSERT_TEST_EXPECT_CONTAIN(test, str, "ASSERTION");
75 	ASSERT_TEST_EXPECT_CONTAIN(test, str, "testfile.c");
76 	ASSERT_TEST_EXPECT_CONTAIN(test, str, "1337");
77 }
78 
79 /*
80  * This function accepts an arbitrary count of parameters and generates a va_format struct,
81  * which can be used to validate kunit_assert_print_msg function
82  */
verify_assert_print_msg(struct kunit * test,struct string_stream * stream,char * expected,const char * format,...)83 static void verify_assert_print_msg(struct kunit *test,
84 				    struct string_stream *stream,
85 				    char *expected, const char *format, ...)
86 {
87 	va_list list;
88 	const struct va_format vformat = {
89 		.fmt = format,
90 		.va = &list,
91 	};
92 
93 	va_start(list, format);
94 	string_stream_clear(stream);
95 	kunit_assert_print_msg(&vformat, stream);
96 	KUNIT_EXPECT_STREQ(test, get_str_from_stream(test, stream), expected);
97 }
98 
kunit_test_assert_print_msg(struct kunit * test)99 static void kunit_test_assert_print_msg(struct kunit *test)
100 {
101 	struct string_stream *stream;
102 
103 	stream = kunit_alloc_string_stream(test, GFP_KERNEL);
104 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, stream);
105 
106 	verify_assert_print_msg(test, stream, "\nTest", "Test");
107 	verify_assert_print_msg(test, stream, "\nAbacaba -123 234", "%s %d %u",
108 				"Abacaba", -123, 234U);
109 	verify_assert_print_msg(test, stream, "", NULL);
110 }
111 
112 /*
113  * Further code contains the tests for different assert format functions.
114  * This helper function accepts the assert format function, executes it and
115  * validates the result string from the stream by checking that all of the
116  * substrings exist in the output.
117  */
validate_assert(assert_format_t format_func,struct kunit * test,const struct kunit_assert * assert,struct string_stream * stream,int num_checks,...)118 static void validate_assert(assert_format_t format_func, struct kunit *test,
119 			    const struct kunit_assert *assert,
120 			    struct string_stream *stream, int num_checks, ...)
121 {
122 	size_t i;
123 	va_list checks;
124 	char *cur_substr_exp;
125 	struct va_format message = { NULL, NULL };
126 
127 	va_start(checks, num_checks);
128 	string_stream_clear(stream);
129 	format_func(assert, &message, stream);
130 
131 	for (i = 0; i < num_checks; i++) {
132 		cur_substr_exp = va_arg(checks, char *);
133 		ASSERT_TEST_EXPECT_CONTAIN(test, get_str_from_stream(test, stream), cur_substr_exp);
134 	}
135 }
136 
kunit_test_unary_assert_format(struct kunit * test)137 static void kunit_test_unary_assert_format(struct kunit *test)
138 {
139 	struct string_stream *stream;
140 	struct kunit_assert assert = {};
141 	struct kunit_unary_assert un_assert = {
142 		.assert = assert,
143 		.condition = "expr",
144 		.expected_true = true,
145 	};
146 
147 	stream = kunit_alloc_string_stream(test, GFP_KERNEL);
148 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, stream);
149 
150 	validate_assert(kunit_unary_assert_format, test, &un_assert.assert,
151 			stream, 2, "true", "is false");
152 
153 	un_assert.expected_true = false;
154 	validate_assert(kunit_unary_assert_format, test, &un_assert.assert,
155 			stream, 2, "false", "is true");
156 }
157 
kunit_test_ptr_not_err_assert_format(struct kunit * test)158 static void kunit_test_ptr_not_err_assert_format(struct kunit *test)
159 {
160 	struct string_stream *stream;
161 	struct kunit_assert assert = {};
162 	struct kunit_ptr_not_err_assert not_err_assert = {
163 		.assert = assert,
164 		.text = "expr",
165 		.value = NULL,
166 	};
167 
168 	stream = kunit_alloc_string_stream(test, GFP_KERNEL);
169 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, stream);
170 
171 	/* Value is NULL. The corresponding message should be printed out */
172 	validate_assert(kunit_ptr_not_err_assert_format, test,
173 			&not_err_assert.assert,
174 			stream, 1, "null");
175 
176 	/* Value is not NULL, but looks like an error pointer. Error should be printed out */
177 	not_err_assert.value = (void *)-12;
178 	validate_assert(kunit_ptr_not_err_assert_format, test,
179 			&not_err_assert.assert, stream, 2,
180 			"error", "-12");
181 }
182 
kunit_test_binary_assert_format(struct kunit * test)183 static void kunit_test_binary_assert_format(struct kunit *test)
184 {
185 	struct string_stream *stream;
186 	struct kunit_assert assert = {};
187 	struct kunit_binary_assert_text text = {
188 		.left_text = "1 + 2",
189 		.operation = "==",
190 		.right_text = "2",
191 	};
192 	const struct kunit_binary_assert binary_assert = {
193 		.assert = assert,
194 		.text = &text,
195 		.left_value = 3,
196 		.right_value = 2,
197 	};
198 
199 	stream = kunit_alloc_string_stream(test, GFP_KERNEL);
200 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, stream);
201 
202 	/*
203 	 * Printed values should depend on the input we provide: the left text, right text, left
204 	 * value and the right value.
205 	 */
206 	validate_assert(kunit_binary_assert_format, test, &binary_assert.assert,
207 			stream, 4, "1 + 2", "2", "3", "==");
208 
209 	text.right_text = "4 - 2";
210 	validate_assert(kunit_binary_assert_format, test, &binary_assert.assert,
211 			stream, 3, "==", "1 + 2", "4 - 2");
212 
213 	text.left_text = "3";
214 	validate_assert(kunit_binary_assert_format, test, &binary_assert.assert,
215 			stream, 4, "3", "4 - 2", "2", "==");
216 
217 	text.right_text = "2";
218 	validate_assert(kunit_binary_assert_format, test, &binary_assert.assert,
219 			stream, 3, "3", "2", "==");
220 }
221 
kunit_test_binary_ptr_assert_format(struct kunit * test)222 static void kunit_test_binary_ptr_assert_format(struct kunit *test)
223 {
224 	struct string_stream *stream;
225 	struct kunit_assert assert = {};
226 	char *addr_var_a, *addr_var_b;
227 	static const void *var_a = (void *)0xDEADBEEF;
228 	static const void *var_b = (void *)0xBADDCAFE;
229 	struct kunit_binary_assert_text text = {
230 		.left_text = "var_a",
231 		.operation = "==",
232 		.right_text = "var_b",
233 	};
234 	struct kunit_binary_ptr_assert binary_ptr_assert = {
235 		.assert = assert,
236 		.text = &text,
237 		.left_value = var_a,
238 		.right_value = var_b,
239 	};
240 
241 	addr_var_a = kunit_kzalloc(test, TEST_PTR_EXPECTED_BUF_SIZE, GFP_KERNEL);
242 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, addr_var_a);
243 	addr_var_b = kunit_kzalloc(test, TEST_PTR_EXPECTED_BUF_SIZE, GFP_KERNEL);
244 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, addr_var_b);
245 	/*
246 	 * Print the addresses to the buffers first.
247 	 * This is necessary as we may have different count of leading zeros in the pointer
248 	 * on different architectures.
249 	 */
250 	snprintf(addr_var_a, TEST_PTR_EXPECTED_BUF_SIZE, "%px", var_a);
251 	snprintf(addr_var_b, TEST_PTR_EXPECTED_BUF_SIZE, "%px", var_b);
252 
253 	stream = kunit_alloc_string_stream(test, GFP_KERNEL);
254 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, stream);
255 	validate_assert(kunit_binary_ptr_assert_format, test, &binary_ptr_assert.assert,
256 			stream, 3, addr_var_a, addr_var_b, "==");
257 }
258 
kunit_test_binary_str_assert_format(struct kunit * test)259 static void kunit_test_binary_str_assert_format(struct kunit *test)
260 {
261 	struct string_stream *stream;
262 	struct kunit_assert assert = {};
263 	static const char *var_a = "abacaba";
264 	static const char *var_b = "kernel";
265 	struct kunit_binary_assert_text text = {
266 		.left_text = "var_a",
267 		.operation = "==",
268 		.right_text = "var_b",
269 	};
270 	struct kunit_binary_str_assert binary_str_assert = {
271 		.assert = assert,
272 		.text = &text,
273 		.left_value = var_a,
274 		.right_value = var_b,
275 	};
276 
277 	stream = kunit_alloc_string_stream(test, GFP_KERNEL);
278 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, stream);
279 
280 	validate_assert(kunit_binary_str_assert_format, test,
281 			&binary_str_assert.assert,
282 			stream, 5, "var_a", "var_b", "\"abacaba\"",
283 			"\"kernel\"", "==");
284 
285 	text.left_text = "\"abacaba\"";
286 	validate_assert(kunit_binary_str_assert_format, test, &binary_str_assert.assert,
287 			stream, 4, "\"abacaba\"", "var_b", "\"kernel\"", "==");
288 
289 	text.right_text = "\"kernel\"";
290 	validate_assert(kunit_binary_str_assert_format, test, &binary_str_assert.assert,
291 			stream, 3, "\"abacaba\"", "\"kernel\"", "==");
292 }
293 
294 static const u8 hex_testbuf1[] = { 0x26, 0x74, 0x6b, 0x9c, 0x55,
295 				   0x45, 0x9d, 0x47, 0xd6, 0x47,
296 				   0x2,  0x89, 0x8c, 0x81, 0x94,
297 				   0x12, 0xfe, 0x01 };
298 static const u8 hex_testbuf2[] = { 0x26, 0x74, 0x6b, 0x9c, 0x55,
299 				   0x45, 0x9d, 0x47, 0x21, 0x47,
300 				   0xcd, 0x89, 0x24, 0x50, 0x94,
301 				   0x12, 0xba, 0x01 };
kunit_test_assert_hexdump(struct kunit * test)302 static void kunit_test_assert_hexdump(struct kunit *test)
303 {
304 	struct string_stream *stream;
305 	char *str;
306 	size_t i;
307 	char buf[HEXDUMP_TEST_BUF_LEN];
308 
309 	stream = kunit_alloc_string_stream(test, GFP_KERNEL);
310 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, stream);
311 	/* Check that we are getting output like <xx> for non-matching numbers. */
312 	kunit_assert_hexdump(stream, hex_testbuf1, hex_testbuf2, sizeof(hex_testbuf1));
313 	str = get_str_from_stream(test, stream);
314 	for (i = 0; i < sizeof(hex_testbuf1); i++) {
315 		snprintf(buf, HEXDUMP_TEST_BUF_LEN, "<%02x>", hex_testbuf1[i]);
316 		if (hex_testbuf1[i] != hex_testbuf2[i])
317 			ASSERT_TEST_EXPECT_CONTAIN(test, str, buf);
318 	}
319 	/* We shouldn't get any <xx> numbers when comparing the buffer with itself. */
320 	string_stream_clear(stream);
321 	kunit_assert_hexdump(stream, hex_testbuf1, hex_testbuf1, sizeof(hex_testbuf1));
322 	str = get_str_from_stream(test, stream);
323 	ASSERT_TEST_EXPECT_NCONTAIN(test, str, "<");
324 	ASSERT_TEST_EXPECT_NCONTAIN(test, str, ">");
325 }
326 
kunit_test_mem_assert_format(struct kunit * test)327 static void kunit_test_mem_assert_format(struct kunit *test)
328 {
329 	struct string_stream *stream;
330 	struct string_stream *expected_stream;
331 	struct kunit_assert assert = {};
332 	static const struct kunit_binary_assert_text text = {
333 		.left_text = "hex_testbuf1",
334 		.operation = "==",
335 		.right_text = "hex_testbuf2",
336 	};
337 	struct kunit_mem_assert mem_assert = {
338 		.assert = assert,
339 		.text = &text,
340 		.left_value = NULL,
341 		.right_value = hex_testbuf2,
342 		.size = sizeof(hex_testbuf1),
343 	};
344 
345 	expected_stream = kunit_alloc_string_stream(test, GFP_KERNEL);
346 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, expected_stream);
347 	stream = kunit_alloc_string_stream(test, GFP_KERNEL);
348 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, stream);
349 
350 	/* The left value is NULL */
351 	validate_assert(kunit_mem_assert_format, test, &mem_assert.assert,
352 			stream, 2, "hex_testbuf1", "is not null");
353 
354 	/* The right value is NULL, the left value is not NULL */
355 	mem_assert.left_value = hex_testbuf1;
356 	mem_assert.right_value = NULL;
357 	validate_assert(kunit_mem_assert_format, test, &mem_assert.assert,
358 			stream, 2, "hex_testbuf2", "is not null");
359 
360 	/* Both arguments are not null */
361 	mem_assert.left_value = hex_testbuf1;
362 	mem_assert.right_value = hex_testbuf2;
363 
364 	validate_assert(kunit_mem_assert_format, test, &mem_assert.assert,
365 			stream, 3, "hex_testbuf1", "hex_testbuf2", "==");
366 }
367 
368 static struct kunit_case assert_test_cases[] = {
369 	KUNIT_CASE(kunit_test_is_literal),
370 	KUNIT_CASE(kunit_test_is_str_literal),
371 	KUNIT_CASE(kunit_test_assert_prologue),
372 	KUNIT_CASE(kunit_test_assert_print_msg),
373 	KUNIT_CASE(kunit_test_unary_assert_format),
374 	KUNIT_CASE(kunit_test_ptr_not_err_assert_format),
375 	KUNIT_CASE(kunit_test_binary_assert_format),
376 	KUNIT_CASE(kunit_test_binary_ptr_assert_format),
377 	KUNIT_CASE(kunit_test_binary_str_assert_format),
378 	KUNIT_CASE(kunit_test_assert_hexdump),
379 	KUNIT_CASE(kunit_test_mem_assert_format),
380 	{}
381 };
382 
383 static struct kunit_suite assert_test_suite = {
384 	.name = "kunit-assert",
385 	.test_cases = assert_test_cases,
386 };
387 
388 kunit_test_suites(&assert_test_suite);
389