Linux Audio

Check our new training course

Loading...
Note: File does not exist in v5.14.15.
  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
 14static 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
 26static 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
 38KUNIT_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  */
 41static 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
 51static 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 */
 83static 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
 99static 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 */
118static 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
137static 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
158static 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
183static 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
222static 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
259static 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
294static 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 };
298static 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 };
302static 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
327static 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
368static 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
383static struct kunit_suite assert_test_suite = {
384	.name = "kunit-assert",
385	.test_cases = assert_test_cases,
386};
387
388kunit_test_suites(&assert_test_suite);