brintos

brintos / linux-shallow public Read only

0
0
Text · 12.5 KiB · 4a59677 Raw
389 lines · c
1// SPDX-License-Identifier: GPL-2.0-or-later2/*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 3210#define HEXDUMP_TEST_BUF_LEN 511#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 function82 */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 and115 * validates the result string from the stream by checking that all of the116 * 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, left204	 * 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 pointer248	 * 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);389