xref: /linux/lib/string_kunit.c (revision 4b911a9690d72641879ea6d13cce1de31d346d79)
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * Test cases for string functions.
4  */
5 
6 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
7 
8 #include <kunit/test.h>
9 #include <linux/module.h>
10 #include <linux/printk.h>
11 #include <linux/slab.h>
12 #include <linux/string.h>
13 
14 static void test_memset16(struct kunit *test)
15 {
16 	unsigned i, j, k;
17 	u16 v, *p;
18 
19 	p = kunit_kzalloc(test, 256 * 2 * 2, GFP_KERNEL);
20 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, p);
21 
22 	for (i = 0; i < 256; i++) {
23 		for (j = 0; j < 256; j++) {
24 			memset(p, 0xa1, 256 * 2 * sizeof(v));
25 			memset16(p + i, 0xb1b2, j);
26 			for (k = 0; k < 512; k++) {
27 				v = p[k];
28 				if (k < i) {
29 					KUNIT_ASSERT_EQ_MSG(test, v, 0xa1a1,
30 						"i:%d j:%d k:%d", i, j, k);
31 				} else if (k < i + j) {
32 					KUNIT_ASSERT_EQ_MSG(test, v, 0xb1b2,
33 						"i:%d j:%d k:%d", i, j, k);
34 				} else {
35 					KUNIT_ASSERT_EQ_MSG(test, v, 0xa1a1,
36 						"i:%d j:%d k:%d", i, j, k);
37 				}
38 			}
39 		}
40 	}
41 }
42 
43 static void test_memset32(struct kunit *test)
44 {
45 	unsigned i, j, k;
46 	u32 v, *p;
47 
48 	p = kunit_kzalloc(test, 256 * 2 * 4, GFP_KERNEL);
49 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, p);
50 
51 	for (i = 0; i < 256; i++) {
52 		for (j = 0; j < 256; j++) {
53 			memset(p, 0xa1, 256 * 2 * sizeof(v));
54 			memset32(p + i, 0xb1b2b3b4, j);
55 			for (k = 0; k < 512; k++) {
56 				v = p[k];
57 				if (k < i) {
58 					KUNIT_ASSERT_EQ_MSG(test, v, 0xa1a1a1a1,
59 						"i:%d j:%d k:%d", i, j, k);
60 				} else if (k < i + j) {
61 					KUNIT_ASSERT_EQ_MSG(test, v, 0xb1b2b3b4,
62 						"i:%d j:%d k:%d", i, j, k);
63 				} else {
64 					KUNIT_ASSERT_EQ_MSG(test, v, 0xa1a1a1a1,
65 						"i:%d j:%d k:%d", i, j, k);
66 				}
67 			}
68 		}
69 	}
70 }
71 
72 static void test_memset64(struct kunit *test)
73 {
74 	unsigned i, j, k;
75 	u64 v, *p;
76 
77 	p = kunit_kzalloc(test, 256 * 2 * 8, GFP_KERNEL);
78 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, p);
79 
80 	for (i = 0; i < 256; i++) {
81 		for (j = 0; j < 256; j++) {
82 			memset(p, 0xa1, 256 * 2 * sizeof(v));
83 			memset64(p + i, 0xb1b2b3b4b5b6b7b8ULL, j);
84 			for (k = 0; k < 512; k++) {
85 				v = p[k];
86 				if (k < i) {
87 					KUNIT_ASSERT_EQ_MSG(test, v, 0xa1a1a1a1a1a1a1a1ULL,
88 						"i:%d j:%d k:%d", i, j, k);
89 				} else if (k < i + j) {
90 					KUNIT_ASSERT_EQ_MSG(test, v, 0xb1b2b3b4b5b6b7b8ULL,
91 						"i:%d j:%d k:%d", i, j, k);
92 				} else {
93 					KUNIT_ASSERT_EQ_MSG(test, v, 0xa1a1a1a1a1a1a1a1ULL,
94 						"i:%d j:%d k:%d", i, j, k);
95 				}
96 			}
97 		}
98 	}
99 }
100 
101 static void test_strchr(struct kunit *test)
102 {
103 	const char *test_string = "abcdefghijkl";
104 	const char *empty_string = "";
105 	char *result;
106 	int i;
107 
108 	for (i = 0; i < strlen(test_string) + 1; i++) {
109 		result = strchr(test_string, test_string[i]);
110 		KUNIT_ASSERT_EQ_MSG(test, result - test_string, i,
111 				    "char:%c", 'a' + i);
112 	}
113 
114 	result = strchr(empty_string, '\0');
115 	KUNIT_ASSERT_PTR_EQ(test, result, empty_string);
116 
117 	result = strchr(empty_string, 'a');
118 	KUNIT_ASSERT_NULL(test, result);
119 
120 	result = strchr(test_string, 'z');
121 	KUNIT_ASSERT_NULL(test, result);
122 }
123 
124 static void test_strnchr(struct kunit *test)
125 {
126 	const char *test_string = "abcdefghijkl";
127 	const char *empty_string = "";
128 	char *result;
129 	int i, j;
130 
131 	for (i = 0; i < strlen(test_string) + 1; i++) {
132 		for (j = 0; j < strlen(test_string) + 2; j++) {
133 			result = strnchr(test_string, j, test_string[i]);
134 			if (j <= i) {
135 				KUNIT_ASSERT_NULL_MSG(test, result,
136 					"char:%c i:%d j:%d", 'a' + i, i, j);
137 			} else {
138 				KUNIT_ASSERT_EQ_MSG(test, result - test_string, i,
139 					"char:%c i:%d j:%d", 'a' + i, i, j);
140 			}
141 		}
142 	}
143 
144 	result = strnchr(empty_string, 0, '\0');
145 	KUNIT_ASSERT_NULL(test, result);
146 
147 	result = strnchr(empty_string, 1, '\0');
148 	KUNIT_ASSERT_PTR_EQ(test, result, empty_string);
149 
150 	result = strnchr(empty_string, 1, 'a');
151 	KUNIT_ASSERT_NULL(test, result);
152 
153 	result = strnchr(NULL, 0, '\0');
154 	KUNIT_ASSERT_NULL(test, result);
155 }
156 
157 static void test_strspn(struct kunit *test)
158 {
159 	static const struct strspn_test {
160 		const char str[16];
161 		const char accept[16];
162 		const char reject[16];
163 		unsigned a;
164 		unsigned r;
165 	} tests[] = {
166 		{ "foobar", "", "", 0, 6 },
167 		{ "abba", "abc", "ABBA", 4, 4 },
168 		{ "abba", "a", "b", 1, 1 },
169 		{ "", "abc", "abc", 0, 0},
170 	};
171 	const struct strspn_test *s = tests;
172 	size_t i;
173 
174 	for (i = 0; i < ARRAY_SIZE(tests); ++i, ++s) {
175 		KUNIT_ASSERT_EQ_MSG(test, s->a, strspn(s->str, s->accept),
176 			"i:%zu", i);
177 		KUNIT_ASSERT_EQ_MSG(test, s->r, strcspn(s->str, s->reject),
178 			"i:%zu", i);
179 	}
180 }
181 
182 static struct kunit_case string_test_cases[] = {
183 	KUNIT_CASE(test_memset16),
184 	KUNIT_CASE(test_memset32),
185 	KUNIT_CASE(test_memset64),
186 	KUNIT_CASE(test_strchr),
187 	KUNIT_CASE(test_strnchr),
188 	KUNIT_CASE(test_strspn),
189 	{}
190 };
191 
192 static struct kunit_suite string_test_suite = {
193 	.name = "string",
194 	.test_cases = string_test_cases,
195 };
196 
197 kunit_test_suites(&string_test_suite);
198 
199 MODULE_LICENSE("GPL v2");
200