1 /* SPDX-License-Identifier: GPL-2.0-only */
7 #include <tests/test.h>
11 * Important note: In every particular test, don't use any string-related
12 * functions other than function under test. We are linking against
13 * src/lib/string.c not the standard library. This is important for proper test
17 struct string_pairs_t
{
22 {"He\0llo ", "world"},
27 const char *strings
[] = {
33 /* Used to test atol */
34 struct str_with_l_val_t
{
37 } str_with_l_val
[] = {
44 {"\t\n\r\f\v-42", -42},
47 /* Used to test skip_atoi */
48 struct str_with_u_val_t
{
52 } str_with_u_val
[] = {
59 static void test_strdup(void **state
)
61 char str
[] = "Hello coreboot\n";
62 char *duplicate
= strdup(str
);
64 /* There is a more suitable Cmocka's function 'assert_string_equal()', but it
65 is using strcmp() internally. */
66 assert_int_equal(0, memcmp(str
, duplicate
, __builtin_strlen(str
)));
71 static void test_strconcat(void **state
)
74 size_t str_len
, str2_len
, res_len
;
77 for (i
= 0; i
< ARRAY_SIZE(string_pairs
); i
++) {
78 str_len
= __builtin_strlen(string_pairs
[i
].dst
);
79 str2_len
= __builtin_strlen(string_pairs
[i
].src
);
81 result
= strconcat(string_pairs
[i
].dst
, string_pairs
[i
].src
);
82 res_len
= __builtin_strlen(result
);
84 assert_int_equal(res_len
, str_len
+ str2_len
);
85 assert_int_equal(0, memcmp(string_pairs
[i
].dst
, result
, str_len
));
86 assert_int_equal(0, memcmp(string_pairs
[i
].src
, result
+ str_len
, str2_len
));
92 static void test_strnlen(void **state
)
95 size_t str_len
, limited_len
;
97 for (i
= 0; i
< ARRAY_SIZE(strings
); i
++) {
98 str_len
= __builtin_strlen(strings
[i
]);
99 limited_len
= MIN(n
, str_len
);
100 assert_int_equal(limited_len
, strnlen(strings
[i
], n
));
104 static void test_strlen(void **state
)
108 for (i
= 0; i
< ARRAY_SIZE(strings
); i
++)
109 assert_int_equal(__builtin_strlen(strings
[i
]), strlen(strings
[i
]));
112 static void test_strchr(void **state
)
114 char str
[] = "Abracadabra!\n";
116 assert_ptr_equal(str
, strchr(str
, 'A'));
117 assert_ptr_equal(str
+ 3, strchr(str
, 'a'));
118 assert_ptr_equal(str
+ 12, strchr(str
, '\n'));
120 assert_null(strchr(str
, 'z'));
124 static void test_strrchr(void **state
)
126 char str
[] = "Abracadabra!\n";
128 assert_ptr_equal(str
, strrchr(str
, 'A'));
129 assert_ptr_equal(str
+ 9, strrchr(str
, 'r'));
130 assert_ptr_equal(str
+ 12, strrchr(str
, '\n'));
132 assert_null(strrchr(str
, 'z'));
135 static void test_strncpy(void **state
)
139 char src
[] = "Hello";
140 char dst
[sizeof(src
) + 5];
141 size_t src_len
= __builtin_strlen(src
);
142 size_t dst_len
= sizeof(dst
);
146 /* Needed for ensuring that characters behind the limit
147 are not overwritten */
148 memset(dst
, 'x', dst_len
);
150 strncpy(dst
, src
, n1
);
152 assert_int_equal(0, memcmp(dst
, src
, n1
));
154 for (i
= n1
; i
< dst_len
; i
++)
155 assert_true(dst
[i
] == 'x');
159 memset(dst
, 'x', dst_len
);
161 strncpy(dst
, src
, n2
);
163 assert_int_equal(0, memcmp(dst
, src
, src_len
));
165 for (i
= src_len
; i
< n2
; i
++)
166 assert_true(dst
[i
] == '\0');
168 for (i
= n2
; i
< dst_len
; i
++)
169 assert_true(dst
[i
] == 'x');
172 static void test_strcpy(void **state
)
174 char src
[] = "Hello coreboot\n";
175 char dst
[sizeof(src
)];
177 /* Make sure that strcpy() sets '\0' by initializing a whole
178 dst array to fixed, non-'\0' value */
179 memset(dst
, 'x', sizeof(dst
));
183 assert_int_equal(0, memcmp(dst
, src
, __builtin_strlen(src
) + 1));
186 static void test_strcmp(void **state
)
188 char str
[] = "Banana";
189 char str2
[] = "Banana";
190 char str3
[] = "Bananas";
192 assert_true(strcmp(str
, str3
) < 0);
193 assert_int_equal(0, strcmp(str
, str2
));
194 assert_true(strcmp(str3
, str2
) > 0);
197 static void test_strncmp(void **state
)
199 char str
[] = "Banana";
200 char str2
[] = "Bananas";
202 size_t str2_len
= __builtin_strlen(str2
);
204 assert_true(strncmp(str
, str2
, str2_len
) < 0);
205 assert_int_equal(0, strncmp(str
, str2
, str2_len
- 1));
208 static void test_skip_atoi(void **state
)
213 for (i
= 0; i
< ARRAY_SIZE(str_with_u_val
); i
++) {
214 ptr
= str_with_u_val
[i
].str
;
216 assert_true(str_with_u_val
[i
].value
== skip_atoi(&ptr
));
217 assert_int_equal(str_with_u_val
[i
].offset
, ptr
- copy
);
221 static void test_strspn(void **state
)
223 char str
[] = "4213401234";
224 char str2
[] = "01234";
225 char str3
[] = "1234";
227 assert_int_equal(5, strspn(str
, str3
));
228 assert_int_equal(0, strspn(str2
, str3
));
231 static void test_strcspn(void **state
)
233 char str
[] = "12340000";
234 char str2
[] = "00001234";
235 char str3
[] = "1234";
237 assert_int_equal(0, strcspn(str
, str3
));
238 assert_int_equal(4, strcspn(str2
, str3
));
241 /* Please bear in mind that `atol()` uses `strspn()` internally, so the result
242 of `test_atol` is dependent on the result of `test_strspn`. */
243 static void test_atol(void **state
)
247 for (i
= 0; i
< ARRAY_SIZE(str_with_l_val
); i
++)
248 assert_int_equal(str_with_l_val
[i
].value
, atol(str_with_l_val
[i
].str
));
253 const struct CMUnitTest tests
[] = {
254 cmocka_unit_test(test_strdup
),
255 cmocka_unit_test(test_strconcat
),
256 cmocka_unit_test(test_strnlen
),
257 cmocka_unit_test(test_strlen
),
258 cmocka_unit_test(test_strchr
),
259 cmocka_unit_test(test_strrchr
),
260 cmocka_unit_test(test_strncpy
),
261 cmocka_unit_test(test_strcpy
),
262 cmocka_unit_test(test_strcmp
),
263 cmocka_unit_test(test_strncmp
),
264 cmocka_unit_test(test_skip_atoi
),
265 cmocka_unit_test(test_strspn
),
266 cmocka_unit_test(test_strcspn
),
267 cmocka_unit_test(test_atol
),
270 return cb_run_group_tests(tests
, NULL
, NULL
);