Mercurial > hg > th-libs
changeset 282:f0cb48b34463
Implement selectable tests.
author | Matti Hamalainen <ccr@tnsp.org> |
---|---|
date | Mon, 22 Feb 2016 13:14:48 +0200 |
parents | 0c70dcfb6796 |
children | 2b76cc316205 |
files | tests.c |
diffstat | 1 files changed, 159 insertions(+), 94 deletions(-) [+] |
line wrap: on
line diff
--- a/tests.c Mon Feb 22 12:01:29 2016 +0200 +++ b/tests.c Mon Feb 22 13:14:48 2016 +0200 @@ -5,11 +5,13 @@ #include "th_crypto.h" #define SET_BUF_SIZE 128 +#define SET_MAX_TESTS 64 char *test_str_header = NULL, *test_str_res = NULL; -int tests_failed, tests_passed, tests_total, tests_set; +int tests_failed, tests_passed, tests_total, tests_sets, tests_nenabled; +int tests_enabled[SET_MAX_TESTS]; char buf1[SET_BUF_SIZE+2], buf2[SET_BUF_SIZE+2]; @@ -19,6 +21,7 @@ { { 0, '?', "help", "Show this help", OPT_NONE }, { 1, 'v', "verbose", "Be more verbose", OPT_NONE }, + { 2, 't', "tests", "Perform tests -t <set>[,<set2>..]", OPT_ARGREQ }, }; static const int arg_nopts = sizeof(arg_opts) / sizeof(arg_opts[0]); @@ -44,6 +47,40 @@ th_verbosityLevel++; break; + case 2: + { + BOOL ret = TRUE; + char *pos, *pstr, *next; + pos = pstr = th_strdup(optArg); + memset(tests_enabled, 0, sizeof(tests_enabled)); + + do { + next = strchr(pos, ','); + if (next != NULL) + *next = 0; + + char *tmp = th_strdup_trim(pos, TH_TRIM_BOTH); + if (tmp != NULL) + { + int val = atoi(tmp); + if (val > 0 && val <= SET_MAX_TESTS) + tests_enabled[val] = 1; + else + { + THERR("Invalid test number #%d, out of range [%d .. %d]\n", val, 1, SET_MAX_TESTS); + ret = FALSE; + } + th_free(tmp); + } + + if (next != NULL) + pos = next + 1; + } while (next != NULL); + th_free(pstr); + return ret; + } + break; + default: THERR("Unknown option '%s'.\n", currArg); return FALSE; @@ -131,7 +168,7 @@ test_result_msg(ret1 == ret2, "retval mismatch %d != %d", ret1, ret2); test_result_msg(strcmp(buf1, buf2) == 0, "result mismatch '%s' != '%s'", buf1, buf2); - + test_result_msg((unsigned char) buf1[len] == SET_SENTINEL_BYTE, "buffer #1 overflow, sentinel 0x%02x", buf1[len]); test_result_msg((unsigned char) buf2[len] == SET_SENTINEL_BYTE, "buffer #2 overflow, sentinel 0x%02x", buf2[len]); @@ -152,74 +189,29 @@ va_copy(tmp, ap); test_snprintf_do(2, fmt, tmp, "2"); va_copy(tmp, ap); test_snprintf_do(16, fmt, tmp, "16"); va_copy(tmp, ap); test_snprintf_do(SET_BUF_SIZE, fmt, tmp, "SET_BUF_SIZE"); - va_end(ap); + va_end(ap); THPRINT(2, "----------------------------------------------\n"); } -void tests_header(const char *str) +BOOL test_set_start(const char *str) { - THPRINT(1, - "======================================================\n" - " Set #%d : %s tests\n" - "======================================================\n", - ++tests_set, - str); + if (tests_enabled[tests_sets++]) + { + tests_nenabled++; + THPRINT(1, + "======================================================\n" + " Set #%d : %s tests\n" + "======================================================\n", + tests_sets, str); + + return TRUE; + } + else + return FALSE; } -int main(int argc, char *argv[]) -{ - // - // Initialization - // - th_init("th-test", "th-libs unit tests", "0.0.1", NULL, NULL); - th_verbosityLevel = 0; - - if (sizeof(char) != sizeof(unsigned char)) - { - THERR("sizeof(char) != sizeof(unsigned char)???\n"); - return -1; - } - - tests_failed = tests_passed = tests_total = tests_set = 0; - - // - // Parse command line arguments - // - if (!th_args_process(argc, argv, arg_opts, arg_nopts, - arg_handle_opt, NULL, 0)) - return 0; - - - // - // Test series #1 - // - tests_header("printf() function family"); - int i_vals[] = { 2, 612342, -2, -612342, 0x1fff, 0x8000000, }; - char *i_fmts[] = { "%d", "%x", "%05d", "%5d", "%-5d", "%05x", "%5x", "", }; - size_t i1, i2; - - for (i1 = 0; i1 < sizeof(i_vals) / sizeof(i_vals[0]); i1++) - for (i2 = 0; i2 < sizeof(i_fmts) / sizeof(i_fmts[0]); i2++) - test_snprintf(i_fmts[i2], i_vals); - - char *s_vals[] = { "", "asdf", "xxx yyy zzz ppp fff", NULL, "X", "abcde", }; - char *s_fmts[] = { "%s", "%2s", "%-2s", "%5s", "%-5s", "%16s", "%-16s", "%1s", "%-1s", }; - - for (i1 = 0; i1 < sizeof(s_vals) / sizeof(s_vals[0]); i1++) - for (i2 = 0; i2 < sizeof(s_fmts) / sizeof(s_fmts[0]); i2++) - test_snprintf(s_fmts[i2], s_vals); - - test_snprintf("a%cBC", 'x'); - test_snprintf("%c", 'x'); - test_snprintf("", 'x'); - - // - // String matching functions - // - tests_header("String matching"); - #define TEST2(fun, str1, str2, ret) do { \ test_start(# fun "('%s', '%s')", str1, str2); \ test_result(( fun (str1, str2) == 0) == ret); \ @@ -235,50 +227,123 @@ test_result(( fun (str1, str2, len) == 0) == ret); \ } while (0) - TEST2(th_strcasecmp, "aSdFq", "asdfq", TRUE); - TEST2(th_strcasecmp, "aSdFq", "asFfq", FALSE); - TEST2(th_strcasecmp, "abcde", "abcde", TRUE); - TEST2(th_strcasecmp, "öäå", "öäå", TRUE); - TEST2(th_strcasecmp, "aöäå", "aöäå", TRUE); + + +int main(int argc, char *argv[]) +{ + size_t i1, i2; + + // + // Initialization + // + th_init("th-test", "th-libs unit tests", "0.0.1", NULL, NULL); + th_verbosityLevel = 0; + + if (sizeof(char) != sizeof(unsigned char)) + { + THERR("sizeof(char) != sizeof(unsigned char)???\n"); + return -1; + } + + tests_failed = tests_passed = tests_total = tests_sets = tests_nenabled = 0; + for (i1 = 0; i1 < SET_MAX_TESTS; i1++) + tests_enabled[i1] = 1; + + // + // Parse command line arguments + // + if (!th_args_process(argc, argv, arg_opts, arg_nopts, + arg_handle_opt, NULL, 0)) + return 0; + + + // + // Test series #1 + // + if (test_set_start("printf() function family #1")) + { + int i_vals[] = { 2, 612342, -2, -612342, 0x1fff, 0x8000000, }; + char *i_fmts[] = { "%d", "%x", "%05d", "%5d", "%-5d", "%05x", "%5x", "", }; + + for (i1 = 0; i1 < sizeof(i_vals) / sizeof(i_vals[0]); i1++) + for (i2 = 0; i2 < sizeof(i_fmts) / sizeof(i_fmts[0]); i2++) + test_snprintf(i_fmts[i2], i_vals); + } + + if (test_set_start("printf() function family #2")) + { + char *s_vals[] = { "", "asdf", "xxx yyy zzz ppp fff", NULL, "X", "abcde", }; + char *s_fmts[] = { "%s", "%2s", "%-2s", "%5s", "%-5s", "%16s", "%-16s", "%1s", "%-1s", }; - TEST3(th_strncasecmp, "aSdFq", "asFfq", 4, FALSE); - TEST3(th_strncasecmp, "aSdFq", "asFfq", 2, TRUE); - TEST3(th_strncasecmp, "aSdFq", "asDfq", 3, TRUE); - TEST3(th_strncasecmp, "aSdFq", "asDfq", 2, TRUE); - TEST3(th_strncasecmp, "aSdFq", "asDfq", 0, TRUE); - TEST3(th_strncasecmp, "aSdFq", "QsDfq", 0, TRUE); - TEST3(th_strncasecmp, "aSdFq", "QsDfq", 1, FALSE); + for (i1 = 0; i1 < sizeof(s_vals) / sizeof(s_vals[0]); i1++) + for (i2 = 0; i2 < sizeof(s_fmts) / sizeof(s_fmts[0]); i2++) + test_snprintf(s_fmts[i2], s_vals); + + test_snprintf("a%cBC", 'x'); + test_snprintf("%c", 'x'); + test_snprintf("", 'x'); + } + + // + // String matching functions + // + if (test_set_start("String matching #1")) + { + TEST2(th_strcasecmp, "aSdFq", "asdfq", TRUE); + TEST2(th_strcasecmp, "aSdFq", "asFfq", FALSE); + TEST2(th_strcasecmp, "abcde", "abcde", TRUE); + TEST2(th_strcasecmp, "öäå", "öäå", TRUE); + TEST2(th_strcasecmp, "aöäå", "aöäå", TRUE); + } - TEST2B(th_strmatch, "abba ABBAkukka lol", "*lol", TRUE); - TEST2B(th_strmatch, "abba ABBAkukka lol", "*lo*", TRUE); - TEST2B(th_strmatch, "abba ABBAkukka lol", "*lo", FALSE); - TEST2B(th_strmatch, "abba ABBAkukka lol", "abba", FALSE); - TEST2B(th_strmatch, "abba ABBAkukka lol", "abba*", TRUE); - TEST2B(th_strmatch, "abba ABBAkukka lol", "abbak*", FALSE); - TEST2B(th_strcasematch, "abba ABBAkukka lol", "abbak*", FALSE); - TEST2B(th_strcasematch, "abba ABBAkukka lol", "*abbak*", TRUE); - TEST2B(th_strcasematch, "abba ABBAkukka lol", "*abbak?", FALSE); - TEST2B(th_strcasematch, "abba ABBAkukka lol", "?bba?abba*", TRUE); - TEST2B(th_strmatch, "abba ABBAöökukka lol", "*abbaö?", FALSE); + if (test_set_start("String matching #2")) + { + TEST3(th_strncasecmp, "aSdFq", "asFfq", 4, FALSE); + TEST3(th_strncasecmp, "aSdFq", "asFfq", 2, TRUE); + TEST3(th_strncasecmp, "aSdFq", "asDfq", 3, TRUE); + TEST3(th_strncasecmp, "aSdFq", "asDfq", 2, TRUE); + TEST3(th_strncasecmp, "aSdFq", "asDfq", 0, TRUE); + TEST3(th_strncasecmp, "aSdFq", "QsDfq", 0, TRUE); + TEST3(th_strncasecmp, "aSdFq", "QsDfq", 1, FALSE); + } + + if (test_set_start("String matching #3")) + { + TEST2B(th_strmatch, "abba ABBAkukka lol", "*lol", TRUE); + TEST2B(th_strmatch, "abba ABBAkukka lol", "*lo*", TRUE); + TEST2B(th_strmatch, "abba ABBAkukka lol", "*lo", FALSE); + TEST2B(th_strmatch, "abba ABBAkukka lol", "abba", FALSE); + TEST2B(th_strmatch, "abba ABBAkukka lol", "abba*", TRUE); + TEST2B(th_strmatch, "abba ABBAkukka lol", "abbak*", FALSE); + TEST2B(th_strmatch, "abba ABBAöökukka lol", "*abbaö?", FALSE); + } + + if (test_set_start("String matching #4")) + { + TEST2B(th_strcasematch, "abba ABBAkukka lol", "abbak*", FALSE); + TEST2B(th_strcasematch, "abba ABBAkukka lol", "*abbak*", TRUE); + TEST2B(th_strcasematch, "abba ABBAkukka lol", "*abbak?", FALSE); + TEST2B(th_strcasematch, "abba ABBAkukka lol", "?bba?abba*", TRUE); + } // Tests that test for things that do not work correctly yet // Unicode / multibyte UTF-8 causes problems here - tests_header("Invalid"); - TEST2(th_strcasecmp, "ÖÄÅ", "öäå", FALSE); // SHOULD match - TEST3(th_strncasecmp, "Aäöå", "aöå", 2, TRUE); // should NOT match - - TEST2B(th_strmatch, "öriÖRI! lol", "?ri?RI!*", FALSE); // should match - + if (test_set_start("Invalid")) + { + TEST2(th_strcasecmp, "ÖÄÅ", "öäå", FALSE); // SHOULD match + TEST3(th_strncasecmp, "Aäöå", "aöå", 2, TRUE); // should NOT match + TEST2B(th_strmatch, "öriÖRI! lol", "?ri?RI!*", FALSE); // should match + } // // Print summary and exit // THPRINT(1, "======================================================\n"); - + THPRINT(0, - "%d tests failed, %d passed (%d main tests), %d test sets.\n", - tests_failed, tests_passed, tests_total, tests_set); + "%d tests failed, %d passed (%d main tests), %d test sets of %d sets total.\n", + tests_failed, tests_passed, tests_total, tests_nenabled, tests_sets); return 0; }