comparison tests.c @ 282:f0cb48b34463

Implement selectable tests.
author Matti Hamalainen <ccr@tnsp.org>
date Mon, 22 Feb 2016 13:14:48 +0200
parents 56b0de9f9d44
children 89c7696acb82
comparison
equal deleted inserted replaced
281:0c70dcfb6796 282:f0cb48b34463
3 #include "th_util.h" 3 #include "th_util.h"
4 #include "th_string.h" 4 #include "th_string.h"
5 #include "th_crypto.h" 5 #include "th_crypto.h"
6 6
7 #define SET_BUF_SIZE 128 7 #define SET_BUF_SIZE 128
8 #define SET_MAX_TESTS 64
8 9
9 char *test_str_header = NULL, 10 char *test_str_header = NULL,
10 *test_str_res = NULL; 11 *test_str_res = NULL;
11 12
12 int tests_failed, tests_passed, tests_total, tests_set; 13 int tests_failed, tests_passed, tests_total, tests_sets, tests_nenabled;
14 int tests_enabled[SET_MAX_TESTS];
13 15
14 char buf1[SET_BUF_SIZE+2], buf2[SET_BUF_SIZE+2]; 16 char buf1[SET_BUF_SIZE+2], buf2[SET_BUF_SIZE+2];
15 17
16 18
17 // Define option arguments 19 // Define option arguments
18 static const th_optarg_t arg_opts[] = 20 static const th_optarg_t arg_opts[] =
19 { 21 {
20 { 0, '?', "help", "Show this help", OPT_NONE }, 22 { 0, '?', "help", "Show this help", OPT_NONE },
21 { 1, 'v', "verbose", "Be more verbose", OPT_NONE }, 23 { 1, 'v', "verbose", "Be more verbose", OPT_NONE },
24 { 2, 't', "tests", "Perform tests -t <set>[,<set2>..]", OPT_ARGREQ },
22 }; 25 };
23 26
24 static const int arg_nopts = sizeof(arg_opts) / sizeof(arg_opts[0]); 27 static const int arg_nopts = sizeof(arg_opts) / sizeof(arg_opts[0]);
25 28
26 29
40 exit(0); 43 exit(0);
41 break; 44 break;
42 45
43 case 1: 46 case 1:
44 th_verbosityLevel++; 47 th_verbosityLevel++;
48 break;
49
50 case 2:
51 {
52 BOOL ret = TRUE;
53 char *pos, *pstr, *next;
54 pos = pstr = th_strdup(optArg);
55 memset(tests_enabled, 0, sizeof(tests_enabled));
56
57 do {
58 next = strchr(pos, ',');
59 if (next != NULL)
60 *next = 0;
61
62 char *tmp = th_strdup_trim(pos, TH_TRIM_BOTH);
63 if (tmp != NULL)
64 {
65 int val = atoi(tmp);
66 if (val > 0 && val <= SET_MAX_TESTS)
67 tests_enabled[val] = 1;
68 else
69 {
70 THERR("Invalid test number #%d, out of range [%d .. %d]\n", val, 1, SET_MAX_TESTS);
71 ret = FALSE;
72 }
73 th_free(tmp);
74 }
75
76 if (next != NULL)
77 pos = next + 1;
78 } while (next != NULL);
79 th_free(pstr);
80 return ret;
81 }
45 break; 82 break;
46 83
47 default: 84 default:
48 THERR("Unknown option '%s'.\n", currArg); 85 THERR("Unknown option '%s'.\n", currArg);
49 return FALSE; 86 return FALSE;
129 ret1 = th_vsnprintf(buf1, len, fmt, ap); 166 ret1 = th_vsnprintf(buf1, len, fmt, ap);
130 ret2 = vsnprintf(buf2, len, fmt, tmp); 167 ret2 = vsnprintf(buf2, len, fmt, tmp);
131 168
132 test_result_msg(ret1 == ret2, "retval mismatch %d != %d", ret1, ret2); 169 test_result_msg(ret1 == ret2, "retval mismatch %d != %d", ret1, ret2);
133 test_result_msg(strcmp(buf1, buf2) == 0, "result mismatch '%s' != '%s'", buf1, buf2); 170 test_result_msg(strcmp(buf1, buf2) == 0, "result mismatch '%s' != '%s'", buf1, buf2);
134 171
135 test_result_msg((unsigned char) buf1[len] == SET_SENTINEL_BYTE, "buffer #1 overflow, sentinel 0x%02x", buf1[len]); 172 test_result_msg((unsigned char) buf1[len] == SET_SENTINEL_BYTE, "buffer #1 overflow, sentinel 0x%02x", buf1[len]);
136 test_result_msg((unsigned char) buf2[len] == SET_SENTINEL_BYTE, "buffer #2 overflow, sentinel 0x%02x", buf2[len]); 173 test_result_msg((unsigned char) buf2[len] == SET_SENTINEL_BYTE, "buffer #2 overflow, sentinel 0x%02x", buf2[len]);
137 174
138 // Test th_strdup_vprintf() 175 // Test th_strdup_vprintf()
139 test_start("th_strdup_vprintf('%s')", fmt); 176 test_start("th_strdup_vprintf('%s')", fmt);
150 va_copy(tmp, ap); test_snprintf_do(0, fmt, tmp, "0"); 187 va_copy(tmp, ap); test_snprintf_do(0, fmt, tmp, "0");
151 va_copy(tmp, ap); test_snprintf_do(1, fmt, tmp, "1"); 188 va_copy(tmp, ap); test_snprintf_do(1, fmt, tmp, "1");
152 va_copy(tmp, ap); test_snprintf_do(2, fmt, tmp, "2"); 189 va_copy(tmp, ap); test_snprintf_do(2, fmt, tmp, "2");
153 va_copy(tmp, ap); test_snprintf_do(16, fmt, tmp, "16"); 190 va_copy(tmp, ap); test_snprintf_do(16, fmt, tmp, "16");
154 va_copy(tmp, ap); test_snprintf_do(SET_BUF_SIZE, fmt, tmp, "SET_BUF_SIZE"); 191 va_copy(tmp, ap); test_snprintf_do(SET_BUF_SIZE, fmt, tmp, "SET_BUF_SIZE");
155 va_end(ap); 192 va_end(ap);
156 THPRINT(2, "----------------------------------------------\n"); 193 THPRINT(2, "----------------------------------------------\n");
157 } 194 }
158 195
159 196
160 void tests_header(const char *str) 197 BOOL test_set_start(const char *str)
161 { 198 {
162 THPRINT(1, 199 if (tests_enabled[tests_sets++])
163 "======================================================\n" 200 {
164 " Set #%d : %s tests\n" 201 tests_nenabled++;
165 "======================================================\n", 202 THPRINT(1,
166 ++tests_set, 203 "======================================================\n"
167 str); 204 " Set #%d : %s tests\n"
168 } 205 "======================================================\n",
169 206 tests_sets, str);
170 207
171 int main(int argc, char *argv[]) 208 return TRUE;
172 { 209 }
173 // 210 else
174 // Initialization 211 return FALSE;
175 // 212 }
176 th_init("th-test", "th-libs unit tests", "0.0.1", NULL, NULL); 213
177 th_verbosityLevel = 0;
178
179 if (sizeof(char) != sizeof(unsigned char))
180 {
181 THERR("sizeof(char) != sizeof(unsigned char)???\n");
182 return -1;
183 }
184
185 tests_failed = tests_passed = tests_total = tests_set = 0;
186
187 //
188 // Parse command line arguments
189 //
190 if (!th_args_process(argc, argv, arg_opts, arg_nopts,
191 arg_handle_opt, NULL, 0))
192 return 0;
193
194
195 //
196 // Test series #1
197 //
198 tests_header("printf() function family");
199 int i_vals[] = { 2, 612342, -2, -612342, 0x1fff, 0x8000000, };
200 char *i_fmts[] = { "%d", "%x", "%05d", "%5d", "%-5d", "%05x", "%5x", "", };
201 size_t i1, i2;
202
203 for (i1 = 0; i1 < sizeof(i_vals) / sizeof(i_vals[0]); i1++)
204 for (i2 = 0; i2 < sizeof(i_fmts) / sizeof(i_fmts[0]); i2++)
205 test_snprintf(i_fmts[i2], i_vals);
206
207 char *s_vals[] = { "", "asdf", "xxx yyy zzz ppp fff", NULL, "X", "abcde", };
208 char *s_fmts[] = { "%s", "%2s", "%-2s", "%5s", "%-5s", "%16s", "%-16s", "%1s", "%-1s", };
209
210 for (i1 = 0; i1 < sizeof(s_vals) / sizeof(s_vals[0]); i1++)
211 for (i2 = 0; i2 < sizeof(s_fmts) / sizeof(s_fmts[0]); i2++)
212 test_snprintf(s_fmts[i2], s_vals);
213
214 test_snprintf("a%cBC", 'x');
215 test_snprintf("%c", 'x');
216 test_snprintf("", 'x');
217
218 //
219 // String matching functions
220 //
221 tests_header("String matching");
222 214
223 #define TEST2(fun, str1, str2, ret) do { \ 215 #define TEST2(fun, str1, str2, ret) do { \
224 test_start(# fun "('%s', '%s')", str1, str2); \ 216 test_start(# fun "('%s', '%s')", str1, str2); \
225 test_result(( fun (str1, str2) == 0) == ret); \ 217 test_result(( fun (str1, str2) == 0) == ret); \
226 } while (0) 218 } while (0)
233 #define TEST3(fun, str1, str2, len, ret) do { \ 225 #define TEST3(fun, str1, str2, len, ret) do { \
234 test_start(# fun "('%s', '%s', %d)", str1, str2, len); \ 226 test_start(# fun "('%s', '%s', %d)", str1, str2, len); \
235 test_result(( fun (str1, str2, len) == 0) == ret); \ 227 test_result(( fun (str1, str2, len) == 0) == ret); \
236 } while (0) 228 } while (0)
237 229
238 TEST2(th_strcasecmp, "aSdFq", "asdfq", TRUE); 230
239 TEST2(th_strcasecmp, "aSdFq", "asFfq", FALSE); 231
240 TEST2(th_strcasecmp, "abcde", "abcde", TRUE); 232 int main(int argc, char *argv[])
241 TEST2(th_strcasecmp, "öäå", "öäå", TRUE); 233 {
242 TEST2(th_strcasecmp, "aöäå", "aöäå", TRUE); 234 size_t i1, i2;
243 235
244 TEST3(th_strncasecmp, "aSdFq", "asFfq", 4, FALSE); 236 //
245 TEST3(th_strncasecmp, "aSdFq", "asFfq", 2, TRUE); 237 // Initialization
246 TEST3(th_strncasecmp, "aSdFq", "asDfq", 3, TRUE); 238 //
247 TEST3(th_strncasecmp, "aSdFq", "asDfq", 2, TRUE); 239 th_init("th-test", "th-libs unit tests", "0.0.1", NULL, NULL);
248 TEST3(th_strncasecmp, "aSdFq", "asDfq", 0, TRUE); 240 th_verbosityLevel = 0;
249 TEST3(th_strncasecmp, "aSdFq", "QsDfq", 0, TRUE); 241
250 TEST3(th_strncasecmp, "aSdFq", "QsDfq", 1, FALSE); 242 if (sizeof(char) != sizeof(unsigned char))
251 243 {
252 TEST2B(th_strmatch, "abba ABBAkukka lol", "*lol", TRUE); 244 THERR("sizeof(char) != sizeof(unsigned char)???\n");
253 TEST2B(th_strmatch, "abba ABBAkukka lol", "*lo*", TRUE); 245 return -1;
254 TEST2B(th_strmatch, "abba ABBAkukka lol", "*lo", FALSE); 246 }
255 TEST2B(th_strmatch, "abba ABBAkukka lol", "abba", FALSE); 247
256 TEST2B(th_strmatch, "abba ABBAkukka lol", "abba*", TRUE); 248 tests_failed = tests_passed = tests_total = tests_sets = tests_nenabled = 0;
257 TEST2B(th_strmatch, "abba ABBAkukka lol", "abbak*", FALSE); 249 for (i1 = 0; i1 < SET_MAX_TESTS; i1++)
258 TEST2B(th_strcasematch, "abba ABBAkukka lol", "abbak*", FALSE); 250 tests_enabled[i1] = 1;
259 TEST2B(th_strcasematch, "abba ABBAkukka lol", "*abbak*", TRUE); 251
260 TEST2B(th_strcasematch, "abba ABBAkukka lol", "*abbak?", FALSE); 252 //
261 TEST2B(th_strcasematch, "abba ABBAkukka lol", "?bba?abba*", TRUE); 253 // Parse command line arguments
262 TEST2B(th_strmatch, "abba ABBAöökukka lol", "*abbaö?", FALSE); 254 //
255 if (!th_args_process(argc, argv, arg_opts, arg_nopts,
256 arg_handle_opt, NULL, 0))
257 return 0;
258
259
260 //
261 // Test series #1
262 //
263 if (test_set_start("printf() function family #1"))
264 {
265 int i_vals[] = { 2, 612342, -2, -612342, 0x1fff, 0x8000000, };
266 char *i_fmts[] = { "%d", "%x", "%05d", "%5d", "%-5d", "%05x", "%5x", "", };
267
268 for (i1 = 0; i1 < sizeof(i_vals) / sizeof(i_vals[0]); i1++)
269 for (i2 = 0; i2 < sizeof(i_fmts) / sizeof(i_fmts[0]); i2++)
270 test_snprintf(i_fmts[i2], i_vals);
271 }
272
273 if (test_set_start("printf() function family #2"))
274 {
275 char *s_vals[] = { "", "asdf", "xxx yyy zzz ppp fff", NULL, "X", "abcde", };
276 char *s_fmts[] = { "%s", "%2s", "%-2s", "%5s", "%-5s", "%16s", "%-16s", "%1s", "%-1s", };
277
278 for (i1 = 0; i1 < sizeof(s_vals) / sizeof(s_vals[0]); i1++)
279 for (i2 = 0; i2 < sizeof(s_fmts) / sizeof(s_fmts[0]); i2++)
280 test_snprintf(s_fmts[i2], s_vals);
281
282 test_snprintf("a%cBC", 'x');
283 test_snprintf("%c", 'x');
284 test_snprintf("", 'x');
285 }
286
287 //
288 // String matching functions
289 //
290 if (test_set_start("String matching #1"))
291 {
292 TEST2(th_strcasecmp, "aSdFq", "asdfq", TRUE);
293 TEST2(th_strcasecmp, "aSdFq", "asFfq", FALSE);
294 TEST2(th_strcasecmp, "abcde", "abcde", TRUE);
295 TEST2(th_strcasecmp, "öäå", "öäå", TRUE);
296 TEST2(th_strcasecmp, "aöäå", "aöäå", TRUE);
297 }
298
299 if (test_set_start("String matching #2"))
300 {
301 TEST3(th_strncasecmp, "aSdFq", "asFfq", 4, FALSE);
302 TEST3(th_strncasecmp, "aSdFq", "asFfq", 2, TRUE);
303 TEST3(th_strncasecmp, "aSdFq", "asDfq", 3, TRUE);
304 TEST3(th_strncasecmp, "aSdFq", "asDfq", 2, TRUE);
305 TEST3(th_strncasecmp, "aSdFq", "asDfq", 0, TRUE);
306 TEST3(th_strncasecmp, "aSdFq", "QsDfq", 0, TRUE);
307 TEST3(th_strncasecmp, "aSdFq", "QsDfq", 1, FALSE);
308 }
309
310 if (test_set_start("String matching #3"))
311 {
312 TEST2B(th_strmatch, "abba ABBAkukka lol", "*lol", TRUE);
313 TEST2B(th_strmatch, "abba ABBAkukka lol", "*lo*", TRUE);
314 TEST2B(th_strmatch, "abba ABBAkukka lol", "*lo", FALSE);
315 TEST2B(th_strmatch, "abba ABBAkukka lol", "abba", FALSE);
316 TEST2B(th_strmatch, "abba ABBAkukka lol", "abba*", TRUE);
317 TEST2B(th_strmatch, "abba ABBAkukka lol", "abbak*", FALSE);
318 TEST2B(th_strmatch, "abba ABBAöökukka lol", "*abbaö?", FALSE);
319 }
320
321 if (test_set_start("String matching #4"))
322 {
323 TEST2B(th_strcasematch, "abba ABBAkukka lol", "abbak*", FALSE);
324 TEST2B(th_strcasematch, "abba ABBAkukka lol", "*abbak*", TRUE);
325 TEST2B(th_strcasematch, "abba ABBAkukka lol", "*abbak?", FALSE);
326 TEST2B(th_strcasematch, "abba ABBAkukka lol", "?bba?abba*", TRUE);
327 }
263 328
264 // Tests that test for things that do not work correctly yet 329 // Tests that test for things that do not work correctly yet
265 // Unicode / multibyte UTF-8 causes problems here 330 // Unicode / multibyte UTF-8 causes problems here
266 tests_header("Invalid"); 331 if (test_set_start("Invalid"))
267 TEST2(th_strcasecmp, "ÖÄÅ", "öäå", FALSE); // SHOULD match 332 {
268 TEST3(th_strncasecmp, "Aäöå", "aöå", 2, TRUE); // should NOT match 333 TEST2(th_strcasecmp, "ÖÄÅ", "öäå", FALSE); // SHOULD match
269 334 TEST3(th_strncasecmp, "Aäöå", "aöå", 2, TRUE); // should NOT match
270 TEST2B(th_strmatch, "öriÖRI! lol", "?ri?RI!*", FALSE); // should match 335 TEST2B(th_strmatch, "öriÖRI! lol", "?ri?RI!*", FALSE); // should match
271 336 }
272 337
273 // 338 //
274 // Print summary and exit 339 // Print summary and exit
275 // 340 //
276 THPRINT(1, 341 THPRINT(1,
277 "======================================================\n"); 342 "======================================================\n");
278 343
279 THPRINT(0, 344 THPRINT(0,
280 "%d tests failed, %d passed (%d main tests), %d test sets.\n", 345 "%d tests failed, %d passed (%d main tests), %d test sets of %d sets total.\n",
281 tests_failed, tests_passed, tests_total, tests_set); 346 tests_failed, tests_passed, tests_total, tests_nenabled, tests_sets);
282 347
283 return 0; 348 return 0;
284 } 349 }