1db6fe4d6SKees Cook // SPDX-License-Identifier: GPL-2.0-only 2db6fe4d6SKees Cook /* 3db6fe4d6SKees Cook * Test cases for string functions. 4db6fe4d6SKees Cook */ 5db6fe4d6SKees Cook 6db6fe4d6SKees Cook #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 7db6fe4d6SKees Cook 8db6fe4d6SKees Cook #include <kunit/test.h> 9db6fe4d6SKees Cook #include <linux/module.h> 10db6fe4d6SKees Cook #include <linux/printk.h> 11db6fe4d6SKees Cook #include <linux/slab.h> 12db6fe4d6SKees Cook #include <linux/string.h> 13db6fe4d6SKees Cook 14db6fe4d6SKees Cook #define STRCMP_LARGE_BUF_LEN 2048 15db6fe4d6SKees Cook #define STRCMP_CHANGE_POINT 1337 16db6fe4d6SKees Cook #define STRCMP_TEST_EXPECT_EQUAL(test, fn, ...) KUNIT_EXPECT_EQ(test, fn(__VA_ARGS__), 0) 17db6fe4d6SKees Cook #define STRCMP_TEST_EXPECT_LOWER(test, fn, ...) KUNIT_EXPECT_LT(test, fn(__VA_ARGS__), 0) 18db6fe4d6SKees Cook #define STRCMP_TEST_EXPECT_GREATER(test, fn, ...) KUNIT_EXPECT_GT(test, fn(__VA_ARGS__), 0) 19db6fe4d6SKees Cook 20db6fe4d6SKees Cook static void string_test_memset16(struct kunit *test) 21db6fe4d6SKees Cook { 22db6fe4d6SKees Cook unsigned i, j, k; 23db6fe4d6SKees Cook u16 v, *p; 24db6fe4d6SKees Cook 25db6fe4d6SKees Cook p = kunit_kzalloc(test, 256 * 2 * 2, GFP_KERNEL); 26db6fe4d6SKees Cook KUNIT_ASSERT_NOT_ERR_OR_NULL(test, p); 27db6fe4d6SKees Cook 28db6fe4d6SKees Cook for (i = 0; i < 256; i++) { 29db6fe4d6SKees Cook for (j = 0; j < 256; j++) { 30db6fe4d6SKees Cook memset(p, 0xa1, 256 * 2 * sizeof(v)); 31db6fe4d6SKees Cook memset16(p + i, 0xb1b2, j); 32db6fe4d6SKees Cook for (k = 0; k < 512; k++) { 33db6fe4d6SKees Cook v = p[k]; 34db6fe4d6SKees Cook if (k < i) { 35db6fe4d6SKees Cook KUNIT_ASSERT_EQ_MSG(test, v, 0xa1a1, 36db6fe4d6SKees Cook "i:%d j:%d k:%d", i, j, k); 37db6fe4d6SKees Cook } else if (k < i + j) { 38db6fe4d6SKees Cook KUNIT_ASSERT_EQ_MSG(test, v, 0xb1b2, 39db6fe4d6SKees Cook "i:%d j:%d k:%d", i, j, k); 40db6fe4d6SKees Cook } else { 41db6fe4d6SKees Cook KUNIT_ASSERT_EQ_MSG(test, v, 0xa1a1, 42db6fe4d6SKees Cook "i:%d j:%d k:%d", i, j, k); 43db6fe4d6SKees Cook } 44db6fe4d6SKees Cook } 45db6fe4d6SKees Cook } 46db6fe4d6SKees Cook } 47db6fe4d6SKees Cook } 48db6fe4d6SKees Cook 49db6fe4d6SKees Cook static void string_test_memset32(struct kunit *test) 50db6fe4d6SKees Cook { 51db6fe4d6SKees Cook unsigned i, j, k; 52db6fe4d6SKees Cook u32 v, *p; 53db6fe4d6SKees Cook 54db6fe4d6SKees Cook p = kunit_kzalloc(test, 256 * 2 * 4, GFP_KERNEL); 55db6fe4d6SKees Cook KUNIT_ASSERT_NOT_ERR_OR_NULL(test, p); 56db6fe4d6SKees Cook 57db6fe4d6SKees Cook for (i = 0; i < 256; i++) { 58db6fe4d6SKees Cook for (j = 0; j < 256; j++) { 59db6fe4d6SKees Cook memset(p, 0xa1, 256 * 2 * sizeof(v)); 60db6fe4d6SKees Cook memset32(p + i, 0xb1b2b3b4, j); 61db6fe4d6SKees Cook for (k = 0; k < 512; k++) { 62db6fe4d6SKees Cook v = p[k]; 63db6fe4d6SKees Cook if (k < i) { 64db6fe4d6SKees Cook KUNIT_ASSERT_EQ_MSG(test, v, 0xa1a1a1a1, 65db6fe4d6SKees Cook "i:%d j:%d k:%d", i, j, k); 66db6fe4d6SKees Cook } else if (k < i + j) { 67db6fe4d6SKees Cook KUNIT_ASSERT_EQ_MSG(test, v, 0xb1b2b3b4, 68db6fe4d6SKees Cook "i:%d j:%d k:%d", i, j, k); 69db6fe4d6SKees Cook } else { 70db6fe4d6SKees Cook KUNIT_ASSERT_EQ_MSG(test, v, 0xa1a1a1a1, 71db6fe4d6SKees Cook "i:%d j:%d k:%d", i, j, k); 72db6fe4d6SKees Cook } 73db6fe4d6SKees Cook } 74db6fe4d6SKees Cook } 75db6fe4d6SKees Cook } 76db6fe4d6SKees Cook } 77db6fe4d6SKees Cook 78db6fe4d6SKees Cook static void string_test_memset64(struct kunit *test) 79db6fe4d6SKees Cook { 80db6fe4d6SKees Cook unsigned i, j, k; 81db6fe4d6SKees Cook u64 v, *p; 82db6fe4d6SKees Cook 83db6fe4d6SKees Cook p = kunit_kzalloc(test, 256 * 2 * 8, GFP_KERNEL); 84db6fe4d6SKees Cook KUNIT_ASSERT_NOT_ERR_OR_NULL(test, p); 85db6fe4d6SKees Cook 86db6fe4d6SKees Cook for (i = 0; i < 256; i++) { 87db6fe4d6SKees Cook for (j = 0; j < 256; j++) { 88db6fe4d6SKees Cook memset(p, 0xa1, 256 * 2 * sizeof(v)); 89db6fe4d6SKees Cook memset64(p + i, 0xb1b2b3b4b5b6b7b8ULL, j); 90db6fe4d6SKees Cook for (k = 0; k < 512; k++) { 91db6fe4d6SKees Cook v = p[k]; 92db6fe4d6SKees Cook if (k < i) { 93db6fe4d6SKees Cook KUNIT_ASSERT_EQ_MSG(test, v, 0xa1a1a1a1a1a1a1a1ULL, 94db6fe4d6SKees Cook "i:%d j:%d k:%d", i, j, k); 95db6fe4d6SKees Cook } else if (k < i + j) { 96db6fe4d6SKees Cook KUNIT_ASSERT_EQ_MSG(test, v, 0xb1b2b3b4b5b6b7b8ULL, 97db6fe4d6SKees Cook "i:%d j:%d k:%d", i, j, k); 98db6fe4d6SKees Cook } else { 99db6fe4d6SKees Cook KUNIT_ASSERT_EQ_MSG(test, v, 0xa1a1a1a1a1a1a1a1ULL, 100db6fe4d6SKees Cook "i:%d j:%d k:%d", i, j, k); 101db6fe4d6SKees Cook } 102db6fe4d6SKees Cook } 103db6fe4d6SKees Cook } 104db6fe4d6SKees Cook } 105db6fe4d6SKees Cook } 106db6fe4d6SKees Cook 107db6fe4d6SKees Cook static void string_test_strchr(struct kunit *test) 108db6fe4d6SKees Cook { 109db6fe4d6SKees Cook const char *test_string = "abcdefghijkl"; 110db6fe4d6SKees Cook const char *empty_string = ""; 111db6fe4d6SKees Cook char *result; 112db6fe4d6SKees Cook int i; 113db6fe4d6SKees Cook 114db6fe4d6SKees Cook for (i = 0; i < strlen(test_string) + 1; i++) { 115db6fe4d6SKees Cook result = strchr(test_string, test_string[i]); 116db6fe4d6SKees Cook KUNIT_ASSERT_EQ_MSG(test, result - test_string, i, 117db6fe4d6SKees Cook "char:%c", 'a' + i); 118db6fe4d6SKees Cook } 119db6fe4d6SKees Cook 120db6fe4d6SKees Cook result = strchr(empty_string, '\0'); 121db6fe4d6SKees Cook KUNIT_ASSERT_PTR_EQ(test, result, empty_string); 122db6fe4d6SKees Cook 123db6fe4d6SKees Cook result = strchr(empty_string, 'a'); 124db6fe4d6SKees Cook KUNIT_ASSERT_NULL(test, result); 125db6fe4d6SKees Cook 126db6fe4d6SKees Cook result = strchr(test_string, 'z'); 127db6fe4d6SKees Cook KUNIT_ASSERT_NULL(test, result); 128db6fe4d6SKees Cook } 129db6fe4d6SKees Cook 130db6fe4d6SKees Cook static void string_test_strnchr(struct kunit *test) 131db6fe4d6SKees Cook { 132db6fe4d6SKees Cook const char *test_string = "abcdefghijkl"; 133db6fe4d6SKees Cook const char *empty_string = ""; 134db6fe4d6SKees Cook char *result; 135db6fe4d6SKees Cook int i, j; 136db6fe4d6SKees Cook 137db6fe4d6SKees Cook for (i = 0; i < strlen(test_string) + 1; i++) { 138db6fe4d6SKees Cook for (j = 0; j < strlen(test_string) + 2; j++) { 139db6fe4d6SKees Cook result = strnchr(test_string, j, test_string[i]); 140db6fe4d6SKees Cook if (j <= i) { 141db6fe4d6SKees Cook KUNIT_ASSERT_NULL_MSG(test, result, 142db6fe4d6SKees Cook "char:%c i:%d j:%d", 'a' + i, i, j); 143db6fe4d6SKees Cook } else { 144db6fe4d6SKees Cook KUNIT_ASSERT_EQ_MSG(test, result - test_string, i, 145db6fe4d6SKees Cook "char:%c i:%d j:%d", 'a' + i, i, j); 146db6fe4d6SKees Cook } 147db6fe4d6SKees Cook } 148db6fe4d6SKees Cook } 149db6fe4d6SKees Cook 150db6fe4d6SKees Cook result = strnchr(empty_string, 0, '\0'); 151db6fe4d6SKees Cook KUNIT_ASSERT_NULL(test, result); 152db6fe4d6SKees Cook 153db6fe4d6SKees Cook result = strnchr(empty_string, 1, '\0'); 154db6fe4d6SKees Cook KUNIT_ASSERT_PTR_EQ(test, result, empty_string); 155db6fe4d6SKees Cook 156db6fe4d6SKees Cook result = strnchr(empty_string, 1, 'a'); 157db6fe4d6SKees Cook KUNIT_ASSERT_NULL(test, result); 158db6fe4d6SKees Cook 159db6fe4d6SKees Cook result = strnchr(NULL, 0, '\0'); 160db6fe4d6SKees Cook KUNIT_ASSERT_NULL(test, result); 161db6fe4d6SKees Cook } 162db6fe4d6SKees Cook 163db6fe4d6SKees Cook static void string_test_strspn(struct kunit *test) 164db6fe4d6SKees Cook { 165db6fe4d6SKees Cook static const struct strspn_test { 166db6fe4d6SKees Cook const char str[16]; 167db6fe4d6SKees Cook const char accept[16]; 168db6fe4d6SKees Cook const char reject[16]; 169db6fe4d6SKees Cook unsigned a; 170db6fe4d6SKees Cook unsigned r; 171db6fe4d6SKees Cook } tests[] = { 172db6fe4d6SKees Cook { "foobar", "", "", 0, 6 }, 173db6fe4d6SKees Cook { "abba", "abc", "ABBA", 4, 4 }, 174db6fe4d6SKees Cook { "abba", "a", "b", 1, 1 }, 175db6fe4d6SKees Cook { "", "abc", "abc", 0, 0}, 176db6fe4d6SKees Cook }; 177db6fe4d6SKees Cook const struct strspn_test *s = tests; 178db6fe4d6SKees Cook size_t i; 179db6fe4d6SKees Cook 180db6fe4d6SKees Cook for (i = 0; i < ARRAY_SIZE(tests); ++i, ++s) { 181db6fe4d6SKees Cook KUNIT_ASSERT_EQ_MSG(test, s->a, strspn(s->str, s->accept), 182db6fe4d6SKees Cook "i:%zu", i); 183db6fe4d6SKees Cook KUNIT_ASSERT_EQ_MSG(test, s->r, strcspn(s->str, s->reject), 184db6fe4d6SKees Cook "i:%zu", i); 185db6fe4d6SKees Cook } 186db6fe4d6SKees Cook } 187db6fe4d6SKees Cook 188db6fe4d6SKees Cook static char strcmp_buffer1[STRCMP_LARGE_BUF_LEN]; 189db6fe4d6SKees Cook static char strcmp_buffer2[STRCMP_LARGE_BUF_LEN]; 190db6fe4d6SKees Cook 191db6fe4d6SKees Cook static void strcmp_fill_buffers(char fill1, char fill2) 192db6fe4d6SKees Cook { 193db6fe4d6SKees Cook memset(strcmp_buffer1, fill1, STRCMP_LARGE_BUF_LEN); 194db6fe4d6SKees Cook memset(strcmp_buffer2, fill2, STRCMP_LARGE_BUF_LEN); 195db6fe4d6SKees Cook strcmp_buffer1[STRCMP_LARGE_BUF_LEN - 1] = 0; 196db6fe4d6SKees Cook strcmp_buffer2[STRCMP_LARGE_BUF_LEN - 1] = 0; 197db6fe4d6SKees Cook } 198db6fe4d6SKees Cook 199db6fe4d6SKees Cook static void string_test_strcmp(struct kunit *test) 200db6fe4d6SKees Cook { 201db6fe4d6SKees Cook /* Equal strings */ 202db6fe4d6SKees Cook STRCMP_TEST_EXPECT_EQUAL(test, strcmp, "Hello, Kernel!", "Hello, Kernel!"); 203db6fe4d6SKees Cook /* First string is lexicographically less than the second */ 204db6fe4d6SKees Cook STRCMP_TEST_EXPECT_LOWER(test, strcmp, "Hello, KUnit!", "Hello, Kernel!"); 205db6fe4d6SKees Cook /* First string is lexicographically larger than the second */ 206db6fe4d6SKees Cook STRCMP_TEST_EXPECT_GREATER(test, strcmp, "Hello, Kernel!", "Hello, KUnit!"); 207db6fe4d6SKees Cook /* Empty string is always lexicographically less than any non-empty string */ 208db6fe4d6SKees Cook STRCMP_TEST_EXPECT_LOWER(test, strcmp, "", "Non-empty string"); 209db6fe4d6SKees Cook /* Two empty strings should be equal */ 210db6fe4d6SKees Cook STRCMP_TEST_EXPECT_EQUAL(test, strcmp, "", ""); 211db6fe4d6SKees Cook /* Compare two strings which have only one char difference */ 212db6fe4d6SKees Cook STRCMP_TEST_EXPECT_LOWER(test, strcmp, "Abacaba", "Abadaba"); 213db6fe4d6SKees Cook /* Compare two strings which have the same prefix*/ 214db6fe4d6SKees Cook STRCMP_TEST_EXPECT_LOWER(test, strcmp, "Just a string", "Just a string and something else"); 215db6fe4d6SKees Cook } 216db6fe4d6SKees Cook 217db6fe4d6SKees Cook static void string_test_strcmp_long_strings(struct kunit *test) 218db6fe4d6SKees Cook { 219db6fe4d6SKees Cook strcmp_fill_buffers('B', 'B'); 220db6fe4d6SKees Cook STRCMP_TEST_EXPECT_EQUAL(test, strcmp, strcmp_buffer1, strcmp_buffer2); 221db6fe4d6SKees Cook 222db6fe4d6SKees Cook strcmp_buffer1[STRCMP_CHANGE_POINT] = 'A'; 223db6fe4d6SKees Cook STRCMP_TEST_EXPECT_LOWER(test, strcmp, strcmp_buffer1, strcmp_buffer2); 224db6fe4d6SKees Cook 225db6fe4d6SKees Cook strcmp_buffer1[STRCMP_CHANGE_POINT] = 'C'; 226db6fe4d6SKees Cook STRCMP_TEST_EXPECT_GREATER(test, strcmp, strcmp_buffer1, strcmp_buffer2); 227db6fe4d6SKees Cook } 228db6fe4d6SKees Cook 229db6fe4d6SKees Cook static void string_test_strncmp(struct kunit *test) 230db6fe4d6SKees Cook { 231db6fe4d6SKees Cook /* Equal strings */ 232db6fe4d6SKees Cook STRCMP_TEST_EXPECT_EQUAL(test, strncmp, "Hello, KUnit!", "Hello, KUnit!", 13); 233db6fe4d6SKees Cook /* First string is lexicographically less than the second */ 234db6fe4d6SKees Cook STRCMP_TEST_EXPECT_LOWER(test, strncmp, "Hello, KUnit!", "Hello, Kernel!", 13); 235db6fe4d6SKees Cook /* Result is always 'equal' when count = 0 */ 236db6fe4d6SKees Cook STRCMP_TEST_EXPECT_EQUAL(test, strncmp, "Hello, Kernel!", "Hello, KUnit!", 0); 237db6fe4d6SKees Cook /* Strings with common prefix are equal if count = length of prefix */ 238db6fe4d6SKees Cook STRCMP_TEST_EXPECT_EQUAL(test, strncmp, "Abacaba", "Abadaba", 3); 239db6fe4d6SKees Cook /* Strings with common prefix are not equal when count = length of prefix + 1 */ 240db6fe4d6SKees Cook STRCMP_TEST_EXPECT_LOWER(test, strncmp, "Abacaba", "Abadaba", 4); 241db6fe4d6SKees Cook /* If one string is a prefix of another, the shorter string is lexicographically smaller */ 242db6fe4d6SKees Cook STRCMP_TEST_EXPECT_LOWER(test, strncmp, "Just a string", "Just a string and something else", 243db6fe4d6SKees Cook strlen("Just a string and something else")); 244db6fe4d6SKees Cook /* 245db6fe4d6SKees Cook * If one string is a prefix of another, and we check first length 246db6fe4d6SKees Cook * of prefix chars, the result is 'equal' 247db6fe4d6SKees Cook */ 248db6fe4d6SKees Cook STRCMP_TEST_EXPECT_EQUAL(test, strncmp, "Just a string", "Just a string and something else", 249db6fe4d6SKees Cook strlen("Just a string")); 250db6fe4d6SKees Cook } 251db6fe4d6SKees Cook 252db6fe4d6SKees Cook static void string_test_strncmp_long_strings(struct kunit *test) 253db6fe4d6SKees Cook { 254db6fe4d6SKees Cook strcmp_fill_buffers('B', 'B'); 255db6fe4d6SKees Cook STRCMP_TEST_EXPECT_EQUAL(test, strncmp, strcmp_buffer1, 256db6fe4d6SKees Cook strcmp_buffer2, STRCMP_LARGE_BUF_LEN); 257db6fe4d6SKees Cook 258db6fe4d6SKees Cook strcmp_buffer1[STRCMP_CHANGE_POINT] = 'A'; 259db6fe4d6SKees Cook STRCMP_TEST_EXPECT_LOWER(test, strncmp, strcmp_buffer1, 260db6fe4d6SKees Cook strcmp_buffer2, STRCMP_LARGE_BUF_LEN); 261db6fe4d6SKees Cook 262db6fe4d6SKees Cook strcmp_buffer1[STRCMP_CHANGE_POINT] = 'C'; 263db6fe4d6SKees Cook STRCMP_TEST_EXPECT_GREATER(test, strncmp, strcmp_buffer1, 264db6fe4d6SKees Cook strcmp_buffer2, STRCMP_LARGE_BUF_LEN); 265db6fe4d6SKees Cook /* the strings are equal up to STRCMP_CHANGE_POINT */ 266db6fe4d6SKees Cook STRCMP_TEST_EXPECT_EQUAL(test, strncmp, strcmp_buffer1, 267db6fe4d6SKees Cook strcmp_buffer2, STRCMP_CHANGE_POINT); 268db6fe4d6SKees Cook STRCMP_TEST_EXPECT_GREATER(test, strncmp, strcmp_buffer1, 269db6fe4d6SKees Cook strcmp_buffer2, STRCMP_CHANGE_POINT + 1); 270db6fe4d6SKees Cook } 271db6fe4d6SKees Cook 272db6fe4d6SKees Cook static void string_test_strcasecmp(struct kunit *test) 273db6fe4d6SKees Cook { 274db6fe4d6SKees Cook /* Same strings in different case should be equal */ 275db6fe4d6SKees Cook STRCMP_TEST_EXPECT_EQUAL(test, strcasecmp, "Hello, Kernel!", "HeLLO, KErNeL!"); 276db6fe4d6SKees Cook /* Empty strings should be equal */ 277db6fe4d6SKees Cook STRCMP_TEST_EXPECT_EQUAL(test, strcasecmp, "", ""); 278db6fe4d6SKees Cook /* Despite ascii code for 'a' is larger than ascii code for 'B', 'a' < 'B' */ 279db6fe4d6SKees Cook STRCMP_TEST_EXPECT_LOWER(test, strcasecmp, "a", "B"); 280db6fe4d6SKees Cook STRCMP_TEST_EXPECT_GREATER(test, strcasecmp, "B", "a"); 281db6fe4d6SKees Cook /* Special symbols and numbers should be processed correctly */ 282db6fe4d6SKees Cook STRCMP_TEST_EXPECT_EQUAL(test, strcasecmp, "-+**.1230ghTTT~^", "-+**.1230Ghttt~^"); 283db6fe4d6SKees Cook } 284db6fe4d6SKees Cook 285db6fe4d6SKees Cook static void string_test_strcasecmp_long_strings(struct kunit *test) 286db6fe4d6SKees Cook { 287db6fe4d6SKees Cook strcmp_fill_buffers('b', 'B'); 288db6fe4d6SKees Cook STRCMP_TEST_EXPECT_EQUAL(test, strcasecmp, strcmp_buffer1, strcmp_buffer2); 289db6fe4d6SKees Cook 290db6fe4d6SKees Cook strcmp_buffer1[STRCMP_CHANGE_POINT] = 'a'; 291db6fe4d6SKees Cook STRCMP_TEST_EXPECT_LOWER(test, strcasecmp, strcmp_buffer1, strcmp_buffer2); 292db6fe4d6SKees Cook 293db6fe4d6SKees Cook strcmp_buffer1[STRCMP_CHANGE_POINT] = 'C'; 294db6fe4d6SKees Cook STRCMP_TEST_EXPECT_GREATER(test, strcasecmp, strcmp_buffer1, strcmp_buffer2); 295db6fe4d6SKees Cook } 296db6fe4d6SKees Cook 297db6fe4d6SKees Cook static void string_test_strncasecmp(struct kunit *test) 298db6fe4d6SKees Cook { 299db6fe4d6SKees Cook /* Same strings in different case should be equal */ 300db6fe4d6SKees Cook STRCMP_TEST_EXPECT_EQUAL(test, strncasecmp, "AbAcAbA", "Abacaba", strlen("Abacaba")); 301db6fe4d6SKees Cook /* strncasecmp should check 'count' chars only */ 302db6fe4d6SKees Cook STRCMP_TEST_EXPECT_EQUAL(test, strncasecmp, "AbaCaBa", "abaCaDa", 5); 303db6fe4d6SKees Cook STRCMP_TEST_EXPECT_LOWER(test, strncasecmp, "a", "B", 1); 304db6fe4d6SKees Cook STRCMP_TEST_EXPECT_GREATER(test, strncasecmp, "B", "a", 1); 305db6fe4d6SKees Cook /* Result is always 'equal' when count = 0 */ 306db6fe4d6SKees Cook STRCMP_TEST_EXPECT_EQUAL(test, strncasecmp, "Abacaba", "Not abacaba", 0); 307db6fe4d6SKees Cook } 308db6fe4d6SKees Cook 309db6fe4d6SKees Cook static void string_test_strncasecmp_long_strings(struct kunit *test) 310db6fe4d6SKees Cook { 311db6fe4d6SKees Cook strcmp_fill_buffers('b', 'B'); 312db6fe4d6SKees Cook STRCMP_TEST_EXPECT_EQUAL(test, strncasecmp, strcmp_buffer1, 313db6fe4d6SKees Cook strcmp_buffer2, STRCMP_LARGE_BUF_LEN); 314db6fe4d6SKees Cook 315db6fe4d6SKees Cook strcmp_buffer1[STRCMP_CHANGE_POINT] = 'a'; 316db6fe4d6SKees Cook STRCMP_TEST_EXPECT_LOWER(test, strncasecmp, strcmp_buffer1, 317db6fe4d6SKees Cook strcmp_buffer2, STRCMP_LARGE_BUF_LEN); 318db6fe4d6SKees Cook 319db6fe4d6SKees Cook strcmp_buffer1[STRCMP_CHANGE_POINT] = 'C'; 320db6fe4d6SKees Cook STRCMP_TEST_EXPECT_GREATER(test, strncasecmp, strcmp_buffer1, 321db6fe4d6SKees Cook strcmp_buffer2, STRCMP_LARGE_BUF_LEN); 322db6fe4d6SKees Cook 323db6fe4d6SKees Cook STRCMP_TEST_EXPECT_EQUAL(test, strncasecmp, strcmp_buffer1, 324db6fe4d6SKees Cook strcmp_buffer2, STRCMP_CHANGE_POINT); 325db6fe4d6SKees Cook STRCMP_TEST_EXPECT_GREATER(test, strncasecmp, strcmp_buffer1, 326db6fe4d6SKees Cook strcmp_buffer2, STRCMP_CHANGE_POINT + 1); 327db6fe4d6SKees Cook } 328db6fe4d6SKees Cook 329db6fe4d6SKees Cook /** 330db6fe4d6SKees Cook * strscpy_check() - Run a specific test case. 331db6fe4d6SKees Cook * @test: KUnit test context pointer 332db6fe4d6SKees Cook * @src: Source string, argument to strscpy_pad() 333db6fe4d6SKees Cook * @count: Size of destination buffer, argument to strscpy_pad() 334db6fe4d6SKees Cook * @expected: Expected return value from call to strscpy_pad() 335db6fe4d6SKees Cook * @chars: Number of characters from the src string expected to be 336db6fe4d6SKees Cook * written to the dst buffer. 337db6fe4d6SKees Cook * @terminator: 1 if there should be a terminating null byte 0 otherwise. 338db6fe4d6SKees Cook * @pad: Number of pad characters expected (in the tail of dst buffer). 339db6fe4d6SKees Cook * (@pad does not include the null terminator byte.) 340db6fe4d6SKees Cook * 341db6fe4d6SKees Cook * Calls strscpy_pad() and verifies the return value and state of the 342db6fe4d6SKees Cook * destination buffer after the call returns. 343db6fe4d6SKees Cook */ 344db6fe4d6SKees Cook static void strscpy_check(struct kunit *test, char *src, int count, 345db6fe4d6SKees Cook int expected, int chars, int terminator, int pad) 346db6fe4d6SKees Cook { 347db6fe4d6SKees Cook int nr_bytes_poison; 348db6fe4d6SKees Cook int max_expected; 349db6fe4d6SKees Cook int max_count; 350db6fe4d6SKees Cook int written; 351db6fe4d6SKees Cook char buf[6]; 352db6fe4d6SKees Cook int index, i; 353db6fe4d6SKees Cook const char POISON = 'z'; 354db6fe4d6SKees Cook 355db6fe4d6SKees Cook KUNIT_ASSERT_TRUE_MSG(test, src != NULL, 356db6fe4d6SKees Cook "null source string not supported"); 357db6fe4d6SKees Cook 358db6fe4d6SKees Cook memset(buf, POISON, sizeof(buf)); 359db6fe4d6SKees Cook /* Future proofing test suite, validate args */ 360db6fe4d6SKees Cook max_count = sizeof(buf) - 2; /* Space for null and to verify overflow */ 361db6fe4d6SKees Cook max_expected = count - 1; /* Space for the null */ 362db6fe4d6SKees Cook 363db6fe4d6SKees Cook KUNIT_ASSERT_LE_MSG(test, count, max_count, 364db6fe4d6SKees Cook "count (%d) is too big (%d) ... aborting", count, max_count); 365db6fe4d6SKees Cook KUNIT_EXPECT_LE_MSG(test, expected, max_expected, 366db6fe4d6SKees Cook "expected (%d) is bigger than can possibly be returned (%d)", 367db6fe4d6SKees Cook expected, max_expected); 368db6fe4d6SKees Cook 369db6fe4d6SKees Cook written = strscpy_pad(buf, src, count); 370db6fe4d6SKees Cook KUNIT_ASSERT_EQ(test, written, expected); 371db6fe4d6SKees Cook 372db6fe4d6SKees Cook if (count && written == -E2BIG) { 373db6fe4d6SKees Cook KUNIT_ASSERT_EQ_MSG(test, 0, strncmp(buf, src, count - 1), 374db6fe4d6SKees Cook "buffer state invalid for -E2BIG"); 375db6fe4d6SKees Cook KUNIT_ASSERT_EQ_MSG(test, buf[count - 1], '\0', 376db6fe4d6SKees Cook "too big string is not null terminated correctly"); 377db6fe4d6SKees Cook } 378db6fe4d6SKees Cook 379db6fe4d6SKees Cook for (i = 0; i < chars; i++) 380db6fe4d6SKees Cook KUNIT_ASSERT_EQ_MSG(test, buf[i], src[i], 381db6fe4d6SKees Cook "buf[i]==%c != src[i]==%c", buf[i], src[i]); 382db6fe4d6SKees Cook 383db6fe4d6SKees Cook if (terminator) 384db6fe4d6SKees Cook KUNIT_ASSERT_EQ_MSG(test, buf[count - 1], '\0', 385db6fe4d6SKees Cook "string is not null terminated correctly"); 386db6fe4d6SKees Cook 387db6fe4d6SKees Cook for (i = 0; i < pad; i++) { 388db6fe4d6SKees Cook index = chars + terminator + i; 389db6fe4d6SKees Cook KUNIT_ASSERT_EQ_MSG(test, buf[index], '\0', 390db6fe4d6SKees Cook "padding missing at index: %d", i); 391db6fe4d6SKees Cook } 392db6fe4d6SKees Cook 393db6fe4d6SKees Cook nr_bytes_poison = sizeof(buf) - chars - terminator - pad; 394db6fe4d6SKees Cook for (i = 0; i < nr_bytes_poison; i++) { 395db6fe4d6SKees Cook index = sizeof(buf) - 1 - i; /* Check from the end back */ 396db6fe4d6SKees Cook KUNIT_ASSERT_EQ_MSG(test, buf[index], POISON, 397db6fe4d6SKees Cook "poison value missing at index: %d", i); 398db6fe4d6SKees Cook } 399db6fe4d6SKees Cook } 400db6fe4d6SKees Cook 401db6fe4d6SKees Cook static void string_test_strscpy(struct kunit *test) 402db6fe4d6SKees Cook { 403db6fe4d6SKees Cook char dest[8]; 404db6fe4d6SKees Cook 405db6fe4d6SKees Cook /* 406db6fe4d6SKees Cook * strscpy_check() uses a destination buffer of size 6 and needs at 407db6fe4d6SKees Cook * least 2 characters spare (one for null and one to check for 408db6fe4d6SKees Cook * overflow). This means we should only call tc() with 409db6fe4d6SKees Cook * strings up to a maximum of 4 characters long and 'count' 410db6fe4d6SKees Cook * should not exceed 4. To test with longer strings increase 411db6fe4d6SKees Cook * the buffer size in tc(). 412db6fe4d6SKees Cook */ 413db6fe4d6SKees Cook 414db6fe4d6SKees Cook /* strscpy_check(test, src, count, expected, chars, terminator, pad) */ 415db6fe4d6SKees Cook strscpy_check(test, "a", 0, -E2BIG, 0, 0, 0); 416db6fe4d6SKees Cook strscpy_check(test, "", 0, -E2BIG, 0, 0, 0); 417db6fe4d6SKees Cook 418db6fe4d6SKees Cook strscpy_check(test, "a", 1, -E2BIG, 0, 1, 0); 419db6fe4d6SKees Cook strscpy_check(test, "", 1, 0, 0, 1, 0); 420db6fe4d6SKees Cook 421db6fe4d6SKees Cook strscpy_check(test, "ab", 2, -E2BIG, 1, 1, 0); 422db6fe4d6SKees Cook strscpy_check(test, "a", 2, 1, 1, 1, 0); 423db6fe4d6SKees Cook strscpy_check(test, "", 2, 0, 0, 1, 1); 424db6fe4d6SKees Cook 425db6fe4d6SKees Cook strscpy_check(test, "abc", 3, -E2BIG, 2, 1, 0); 426db6fe4d6SKees Cook strscpy_check(test, "ab", 3, 2, 2, 1, 0); 427db6fe4d6SKees Cook strscpy_check(test, "a", 3, 1, 1, 1, 1); 428db6fe4d6SKees Cook strscpy_check(test, "", 3, 0, 0, 1, 2); 429db6fe4d6SKees Cook 430db6fe4d6SKees Cook strscpy_check(test, "abcd", 4, -E2BIG, 3, 1, 0); 431db6fe4d6SKees Cook strscpy_check(test, "abc", 4, 3, 3, 1, 0); 432db6fe4d6SKees Cook strscpy_check(test, "ab", 4, 2, 2, 1, 1); 433db6fe4d6SKees Cook strscpy_check(test, "a", 4, 1, 1, 1, 2); 434db6fe4d6SKees Cook strscpy_check(test, "", 4, 0, 0, 1, 3); 435db6fe4d6SKees Cook 436db6fe4d6SKees Cook /* Compile-time-known source strings. */ 437db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, strscpy(dest, "", ARRAY_SIZE(dest)), 0); 438db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, strscpy(dest, "", 3), 0); 439db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, strscpy(dest, "", 1), 0); 440db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, strscpy(dest, "", 0), -E2BIG); 441db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, strscpy(dest, "Fixed", ARRAY_SIZE(dest)), 5); 442db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, strscpy(dest, "Fixed", 3), -E2BIG); 443db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, strscpy(dest, "Fixed", 1), -E2BIG); 444db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, strscpy(dest, "Fixed", 0), -E2BIG); 445db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, strscpy(dest, "This is too long", ARRAY_SIZE(dest)), -E2BIG); 446db6fe4d6SKees Cook } 447db6fe4d6SKees Cook 448db6fe4d6SKees Cook static volatile int unconst; 449db6fe4d6SKees Cook 450db6fe4d6SKees Cook static void string_test_strcat(struct kunit *test) 451db6fe4d6SKees Cook { 452db6fe4d6SKees Cook char dest[8]; 453db6fe4d6SKees Cook 454db6fe4d6SKees Cook /* Destination is terminated. */ 455db6fe4d6SKees Cook memset(dest, 0, sizeof(dest)); 456db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, strlen(dest), 0); 457db6fe4d6SKees Cook /* Empty copy does nothing. */ 458db6fe4d6SKees Cook KUNIT_EXPECT_TRUE(test, strcat(dest, "") == dest); 459db6fe4d6SKees Cook KUNIT_EXPECT_STREQ(test, dest, ""); 460db6fe4d6SKees Cook /* 4 characters copied in, stops at %NUL. */ 461db6fe4d6SKees Cook KUNIT_EXPECT_TRUE(test, strcat(dest, "four\000123") == dest); 462db6fe4d6SKees Cook KUNIT_EXPECT_STREQ(test, dest, "four"); 463db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, dest[5], '\0'); 464db6fe4d6SKees Cook /* 2 more characters copied in okay. */ 465db6fe4d6SKees Cook KUNIT_EXPECT_TRUE(test, strcat(dest, "AB") == dest); 466db6fe4d6SKees Cook KUNIT_EXPECT_STREQ(test, dest, "fourAB"); 467db6fe4d6SKees Cook } 468db6fe4d6SKees Cook 469db6fe4d6SKees Cook static void string_test_strncat(struct kunit *test) 470db6fe4d6SKees Cook { 471db6fe4d6SKees Cook char dest[8]; 472db6fe4d6SKees Cook 473db6fe4d6SKees Cook /* Destination is terminated. */ 474db6fe4d6SKees Cook memset(dest, 0, sizeof(dest)); 475db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, strlen(dest), 0); 476db6fe4d6SKees Cook /* Empty copy of size 0 does nothing. */ 477db6fe4d6SKees Cook KUNIT_EXPECT_TRUE(test, strncat(dest, "", 0 + unconst) == dest); 478db6fe4d6SKees Cook KUNIT_EXPECT_STREQ(test, dest, ""); 479db6fe4d6SKees Cook /* Empty copy of size 1 does nothing too. */ 480db6fe4d6SKees Cook KUNIT_EXPECT_TRUE(test, strncat(dest, "", 1 + unconst) == dest); 481db6fe4d6SKees Cook KUNIT_EXPECT_STREQ(test, dest, ""); 482db6fe4d6SKees Cook /* Copy of max 0 characters should do nothing. */ 483db6fe4d6SKees Cook KUNIT_EXPECT_TRUE(test, strncat(dest, "asdf", 0 + unconst) == dest); 484db6fe4d6SKees Cook KUNIT_EXPECT_STREQ(test, dest, ""); 485db6fe4d6SKees Cook 486db6fe4d6SKees Cook /* 4 characters copied in, even if max is 8. */ 487db6fe4d6SKees Cook KUNIT_EXPECT_TRUE(test, strncat(dest, "four\000123", 8 + unconst) == dest); 488db6fe4d6SKees Cook KUNIT_EXPECT_STREQ(test, dest, "four"); 489db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, dest[5], '\0'); 490db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, dest[6], '\0'); 491db6fe4d6SKees Cook /* 2 characters copied in okay, 2 ignored. */ 492db6fe4d6SKees Cook KUNIT_EXPECT_TRUE(test, strncat(dest, "ABCD", 2 + unconst) == dest); 493db6fe4d6SKees Cook KUNIT_EXPECT_STREQ(test, dest, "fourAB"); 494db6fe4d6SKees Cook } 495db6fe4d6SKees Cook 496db6fe4d6SKees Cook static void string_test_strlcat(struct kunit *test) 497db6fe4d6SKees Cook { 498db6fe4d6SKees Cook char dest[8] = ""; 499db6fe4d6SKees Cook int len = sizeof(dest) + unconst; 500db6fe4d6SKees Cook 501db6fe4d6SKees Cook /* Destination is terminated. */ 502db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, strlen(dest), 0); 503db6fe4d6SKees Cook /* Empty copy is size 0. */ 504db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, strlcat(dest, "", len), 0); 505db6fe4d6SKees Cook KUNIT_EXPECT_STREQ(test, dest, ""); 506db6fe4d6SKees Cook /* Size 1 should keep buffer terminated, report size of source only. */ 507db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, strlcat(dest, "four", 1 + unconst), 4); 508db6fe4d6SKees Cook KUNIT_EXPECT_STREQ(test, dest, ""); 509db6fe4d6SKees Cook 510db6fe4d6SKees Cook /* 4 characters copied in. */ 511db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, strlcat(dest, "four", len), 4); 512db6fe4d6SKees Cook KUNIT_EXPECT_STREQ(test, dest, "four"); 513db6fe4d6SKees Cook /* 2 characters copied in okay, gets to 6 total. */ 514db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, strlcat(dest, "AB", len), 6); 515db6fe4d6SKees Cook KUNIT_EXPECT_STREQ(test, dest, "fourAB"); 516db6fe4d6SKees Cook /* 2 characters ignored if max size (7) reached. */ 517db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, strlcat(dest, "CD", 7 + unconst), 8); 518db6fe4d6SKees Cook KUNIT_EXPECT_STREQ(test, dest, "fourAB"); 519db6fe4d6SKees Cook /* 1 of 2 characters skipped, now at true max size. */ 520db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, strlcat(dest, "EFG", len), 9); 521db6fe4d6SKees Cook KUNIT_EXPECT_STREQ(test, dest, "fourABE"); 522db6fe4d6SKees Cook /* Everything else ignored, now at full size. */ 523db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, strlcat(dest, "1234", len), 11); 524db6fe4d6SKees Cook KUNIT_EXPECT_STREQ(test, dest, "fourABE"); 525db6fe4d6SKees Cook } 526db6fe4d6SKees Cook 527db6fe4d6SKees Cook static void string_test_strtomem(struct kunit *test) 528db6fe4d6SKees Cook { 529db6fe4d6SKees Cook static const char input[sizeof(unsigned long)] = "hi"; 530db6fe4d6SKees Cook static const char truncate[] = "this is too long"; 531db6fe4d6SKees Cook struct { 532db6fe4d6SKees Cook unsigned long canary1; 533db6fe4d6SKees Cook unsigned char output[sizeof(unsigned long)] __nonstring; 534db6fe4d6SKees Cook unsigned long canary2; 535db6fe4d6SKees Cook } wrap; 536db6fe4d6SKees Cook 537db6fe4d6SKees Cook memset(&wrap, 0xFF, sizeof(wrap)); 538db6fe4d6SKees Cook KUNIT_EXPECT_EQ_MSG(test, wrap.canary1, ULONG_MAX, 539db6fe4d6SKees Cook "bad initial canary value"); 540db6fe4d6SKees Cook KUNIT_EXPECT_EQ_MSG(test, wrap.canary2, ULONG_MAX, 541db6fe4d6SKees Cook "bad initial canary value"); 542db6fe4d6SKees Cook 543db6fe4d6SKees Cook /* Check unpadded copy leaves surroundings untouched. */ 544db6fe4d6SKees Cook strtomem(wrap.output, input); 545db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, wrap.canary1, ULONG_MAX); 546db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, wrap.output[0], input[0]); 547db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, wrap.output[1], input[1]); 548db6fe4d6SKees Cook for (size_t i = 2; i < sizeof(wrap.output); i++) 549db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, wrap.output[i], 0xFF); 550db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, wrap.canary2, ULONG_MAX); 551db6fe4d6SKees Cook 552db6fe4d6SKees Cook /* Check truncated copy leaves surroundings untouched. */ 553db6fe4d6SKees Cook memset(&wrap, 0xFF, sizeof(wrap)); 554db6fe4d6SKees Cook strtomem(wrap.output, truncate); 555db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, wrap.canary1, ULONG_MAX); 556db6fe4d6SKees Cook for (size_t i = 0; i < sizeof(wrap.output); i++) 557db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, wrap.output[i], truncate[i]); 558db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, wrap.canary2, ULONG_MAX); 559db6fe4d6SKees Cook 560db6fe4d6SKees Cook /* Check padded copy leaves only string padded. */ 561db6fe4d6SKees Cook memset(&wrap, 0xFF, sizeof(wrap)); 562db6fe4d6SKees Cook strtomem_pad(wrap.output, input, 0xAA); 563db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, wrap.canary1, ULONG_MAX); 564db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, wrap.output[0], input[0]); 565db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, wrap.output[1], input[1]); 566db6fe4d6SKees Cook for (size_t i = 2; i < sizeof(wrap.output); i++) 567db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, wrap.output[i], 0xAA); 568db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, wrap.canary2, ULONG_MAX); 569db6fe4d6SKees Cook 570db6fe4d6SKees Cook /* Check truncated padded copy has no padding. */ 571db6fe4d6SKees Cook memset(&wrap, 0xFF, sizeof(wrap)); 572db6fe4d6SKees Cook strtomem(wrap.output, truncate); 573db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, wrap.canary1, ULONG_MAX); 574db6fe4d6SKees Cook for (size_t i = 0; i < sizeof(wrap.output); i++) 575db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, wrap.output[i], truncate[i]); 576db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, wrap.canary2, ULONG_MAX); 577db6fe4d6SKees Cook } 578db6fe4d6SKees Cook 579db6fe4d6SKees Cook 580db6fe4d6SKees Cook static void string_test_memtostr(struct kunit *test) 581db6fe4d6SKees Cook { 582fc13a78eSLinus Torvalds char nonstring[7] __nonstring = { 'a', 'b', 'c', 'd', 'e', 'f', 'g' }; 583fc13a78eSLinus Torvalds char nonstring_small[3] __nonstring = { 'a', 'b', 'c' }; 584db6fe4d6SKees Cook char dest[sizeof(nonstring) + 1]; 585db6fe4d6SKees Cook 586db6fe4d6SKees Cook /* Copy in a non-NUL-terminated string into exactly right-sized dest. */ 587db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, sizeof(dest), sizeof(nonstring) + 1); 588db6fe4d6SKees Cook memset(dest, 'X', sizeof(dest)); 589db6fe4d6SKees Cook memtostr(dest, nonstring); 590db6fe4d6SKees Cook KUNIT_EXPECT_STREQ(test, dest, "abcdefg"); 591db6fe4d6SKees Cook memset(dest, 'X', sizeof(dest)); 592db6fe4d6SKees Cook memtostr(dest, nonstring_small); 593db6fe4d6SKees Cook KUNIT_EXPECT_STREQ(test, dest, "abc"); 594db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, dest[7], 'X'); 595db6fe4d6SKees Cook 596db6fe4d6SKees Cook memset(dest, 'X', sizeof(dest)); 597db6fe4d6SKees Cook memtostr_pad(dest, nonstring); 598db6fe4d6SKees Cook KUNIT_EXPECT_STREQ(test, dest, "abcdefg"); 599db6fe4d6SKees Cook memset(dest, 'X', sizeof(dest)); 600db6fe4d6SKees Cook memtostr_pad(dest, nonstring_small); 601db6fe4d6SKees Cook KUNIT_EXPECT_STREQ(test, dest, "abc"); 602db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, dest[7], '\0'); 603db6fe4d6SKees Cook } 604db6fe4d6SKees Cook 605*197b3f3cSBartosz Golaszewski static void string_test_strends(struct kunit *test) 606*197b3f3cSBartosz Golaszewski { 607*197b3f3cSBartosz Golaszewski KUNIT_EXPECT_TRUE(test, strends("foo-bar", "bar")); 608*197b3f3cSBartosz Golaszewski KUNIT_EXPECT_TRUE(test, strends("foo-bar", "-bar")); 609*197b3f3cSBartosz Golaszewski KUNIT_EXPECT_TRUE(test, strends("foobar", "foobar")); 610*197b3f3cSBartosz Golaszewski KUNIT_EXPECT_TRUE(test, strends("foobar", "")); 611*197b3f3cSBartosz Golaszewski KUNIT_EXPECT_FALSE(test, strends("bar", "foobar")); 612*197b3f3cSBartosz Golaszewski KUNIT_EXPECT_FALSE(test, strends("", "foo")); 613*197b3f3cSBartosz Golaszewski KUNIT_EXPECT_FALSE(test, strends("foobar", "ba")); 614*197b3f3cSBartosz Golaszewski KUNIT_EXPECT_TRUE(test, strends("", "")); 615*197b3f3cSBartosz Golaszewski } 616*197b3f3cSBartosz Golaszewski 617db6fe4d6SKees Cook static struct kunit_case string_test_cases[] = { 618db6fe4d6SKees Cook KUNIT_CASE(string_test_memset16), 619db6fe4d6SKees Cook KUNIT_CASE(string_test_memset32), 620db6fe4d6SKees Cook KUNIT_CASE(string_test_memset64), 621db6fe4d6SKees Cook KUNIT_CASE(string_test_strchr), 622db6fe4d6SKees Cook KUNIT_CASE(string_test_strnchr), 623db6fe4d6SKees Cook KUNIT_CASE(string_test_strspn), 624db6fe4d6SKees Cook KUNIT_CASE(string_test_strcmp), 625db6fe4d6SKees Cook KUNIT_CASE(string_test_strcmp_long_strings), 626db6fe4d6SKees Cook KUNIT_CASE(string_test_strncmp), 627db6fe4d6SKees Cook KUNIT_CASE(string_test_strncmp_long_strings), 628db6fe4d6SKees Cook KUNIT_CASE(string_test_strcasecmp), 629db6fe4d6SKees Cook KUNIT_CASE(string_test_strcasecmp_long_strings), 630db6fe4d6SKees Cook KUNIT_CASE(string_test_strncasecmp), 631db6fe4d6SKees Cook KUNIT_CASE(string_test_strncasecmp_long_strings), 632db6fe4d6SKees Cook KUNIT_CASE(string_test_strscpy), 633db6fe4d6SKees Cook KUNIT_CASE(string_test_strcat), 634db6fe4d6SKees Cook KUNIT_CASE(string_test_strncat), 635db6fe4d6SKees Cook KUNIT_CASE(string_test_strlcat), 636db6fe4d6SKees Cook KUNIT_CASE(string_test_strtomem), 637db6fe4d6SKees Cook KUNIT_CASE(string_test_memtostr), 638*197b3f3cSBartosz Golaszewski KUNIT_CASE(string_test_strends), 639db6fe4d6SKees Cook {} 640db6fe4d6SKees Cook }; 641db6fe4d6SKees Cook 642db6fe4d6SKees Cook static struct kunit_suite string_test_suite = { 643db6fe4d6SKees Cook .name = "string", 644db6fe4d6SKees Cook .test_cases = string_test_cases, 645db6fe4d6SKees Cook }; 646db6fe4d6SKees Cook 647db6fe4d6SKees Cook kunit_test_suites(&string_test_suite); 648db6fe4d6SKees Cook 649db6fe4d6SKees Cook MODULE_DESCRIPTION("Test cases for string functions"); 650db6fe4d6SKees Cook MODULE_LICENSE("GPL v2"); 651