diff options
Diffstat (limited to 'ptunit/src/ptunit.c')
-rw-r--r-- | ptunit/src/ptunit.c | 345 |
1 files changed, 345 insertions, 0 deletions
diff --git a/ptunit/src/ptunit.c b/ptunit/src/ptunit.c new file mode 100644 index 0000000000000..e4a5b5a72731a --- /dev/null +++ b/ptunit/src/ptunit.c @@ -0,0 +1,345 @@ +/* + * Copyright (c) 2013-2018, Intel Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * * Neither the name of Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include "ptunit.h" + +#include <stdlib.h> +#include <stdio.h> +#include <inttypes.h> +#include <string.h> + + +struct ptunit_srcloc ptunit_mk_srcloc(const char *file, uint32_t line) +{ + struct ptunit_srcloc srcloc; + + srcloc.file = file; + srcloc.line = line; + + return srcloc; +} + +struct ptunit_result ptunit_mk_failed_signed_int(const char *expr, + const char *cmp, + struct ptunit_srcloc where, + int64_t actual, + int64_t expected) +{ + struct ptunit_result result; + + result.type = ptur_failed_signed_int; + result.failed.where = where; + result.failed.variant.signed_int.expr = expr; + result.failed.variant.signed_int.cmp = cmp; + result.failed.variant.signed_int.expected = expected; + result.failed.variant.signed_int.actual = actual; + + return result; +} + +struct ptunit_result ptunit_mk_failed_unsigned_int(const char *expr, + const char *cmp, + struct ptunit_srcloc where, + uint64_t actual, + uint64_t expected) +{ + struct ptunit_result result; + + result.type = ptur_failed_unsigned_int; + result.failed.where = where; + result.failed.variant.unsigned_int.expr = expr; + result.failed.variant.unsigned_int.cmp = cmp; + result.failed.variant.unsigned_int.expected = expected; + result.failed.variant.unsigned_int.actual = actual; + + return result; +} + +struct ptunit_result ptunit_mk_failed_pointer(const char *expr, + const char *cmp, + struct ptunit_srcloc where, + const void *actual, + const void *expected) +{ + struct ptunit_result result; + + result.type = ptur_failed_pointer; + result.failed.where = where; + result.failed.variant.pointer.expr = expr; + result.failed.variant.pointer.cmp = cmp; + result.failed.variant.pointer.expected = expected; + result.failed.variant.pointer.actual = actual; + + return result; +} + +static char *dupstr(const char *str) +{ + char *dup; + size_t len; + + if (!str) + str = "(null)"; + + len = strlen(str); + dup = malloc(len + 1); + if (!dup) + return NULL; + + strncpy(dup, str, len); + dup[len] = 0; + + return dup; +} + +struct ptunit_result ptunit_mk_failed_str(const char *expr, + const char *cmp, + struct ptunit_srcloc where, + const char *actual, + const char *expected) +{ + struct ptunit_result result; + + result.type = ptur_failed_str; + result.failed.where = where; + result.failed.variant.str.expr = expr; + result.failed.variant.str.cmp = cmp; + result.failed.variant.str.expected = dupstr(expected); + result.failed.variant.str.actual = dupstr(actual); + + return result; +} + +struct ptunit_result ptunit_mk_passed(void) +{ + struct ptunit_result result; + + memset(&result, 0, sizeof(result)); + result.type = ptur_passed; + + return result; +} + +struct ptunit_result ptunit_mk_skipped(void) +{ + struct ptunit_result result; + + memset(&result, 0, sizeof(result)); + result.type = ptur_skipped; + + return result; +} + +struct ptunit_test ptunit_mk_test(const char *name, const char *args) +{ + struct ptunit_test test; + + test.name = name; + test.args = args; + test.result = ptunit_mk_skipped(); + + return test; +} + +void ptunit_fini_test(struct ptunit_test *test) +{ + if (!test) + return; + + switch (test->result.type) { + case ptur_skipped: + case ptur_passed: + case ptur_failed_signed_int: + case ptur_failed_unsigned_int: + case ptur_failed_pointer: + break; + + case ptur_failed_str: + free(test->result.failed.variant.str.expected); + free(test->result.failed.variant.str.actual); + break; + } +} + +struct ptunit_suite ptunit_mk_suite(int argc, char **argv) +{ + struct ptunit_suite suite; + + memset(&suite, 0, sizeof(suite)); + + if (argc && argv) + suite.name = argv[0]; + return suite; +} + +static void ptunit_print_test(const struct ptunit_test *test) +{ + fprintf(stderr, "%s", test->name); + + if (test->args) + fprintf(stderr, "(%s)", test->args); + + fprintf(stderr, ": "); +} + +static const char *basename(const char *file) +{ + const char *base; + + if (!file) + return NULL; + + for (base = file + strlen(file); base != file; base -= 1) { + char ch; + + ch = base[-1]; + if ((ch == '/') || (ch == '\\')) + break; + } + + return base; +} + +static void ptunit_print_srcloc(const struct ptunit_test *test) +{ + const char *file; + + switch (test->result.type) { + case ptur_passed: + case ptur_skipped: + fprintf(stderr, "n/a: "); + break; + + case ptur_failed_signed_int: + case ptur_failed_unsigned_int: + case ptur_failed_pointer: + case ptur_failed_str: + file = basename(test->result.failed.where.file); + if (!file) + file = "<unknown>"; + + fprintf(stderr, "%s:%" PRIu32 ": ", file, + test->result.failed.where.line); + break; + } +} + +static void ptunit_report_test(const struct ptunit_test *test) +{ + switch (test->result.type) { + case ptur_skipped: + case ptur_passed: + return; + + case ptur_failed_signed_int: + ptunit_print_test(test); + ptunit_print_srcloc(test); + fprintf(stderr, "%s [%" PRId64 "%s%" PRId64 "] failed.\n", + test->result.failed.variant.signed_int.expr, + test->result.failed.variant.signed_int.actual, + test->result.failed.variant.signed_int.cmp, + test->result.failed.variant.signed_int.expected); + return; + + case ptur_failed_unsigned_int: + ptunit_print_test(test); + ptunit_print_srcloc(test); + fprintf(stderr, "%s [0x%" PRIx64 "%s0x%" PRIx64 "] failed.\n", + test->result.failed.variant.unsigned_int.expr, + test->result.failed.variant.unsigned_int.actual, + test->result.failed.variant.unsigned_int.cmp, + test->result.failed.variant.unsigned_int.expected); + return; + + case ptur_failed_pointer: + ptunit_print_test(test); + ptunit_print_srcloc(test); + fprintf(stderr, "%s [%p%s%p] failed.\n", + test->result.failed.variant.pointer.expr, + test->result.failed.variant.pointer.actual, + test->result.failed.variant.pointer.cmp, + test->result.failed.variant.pointer.expected); + return; + + case ptur_failed_str: + ptunit_print_test(test); + ptunit_print_srcloc(test); + fprintf(stderr, "%s [%s%s%s] failed.\n", + test->result.failed.variant.str.expr, + test->result.failed.variant.str.actual, + test->result.failed.variant.str.cmp, + test->result.failed.variant.str.expected); + return; + } + + ptunit_print_test(test); + fprintf(stderr, "bad result type: 0x%" PRIx32 ".\n", test->result.type); +} + +void ptunit_log_test(struct ptunit_suite *suite, + const struct ptunit_test *test) +{ + if (!test) + return; + + if (suite) { + suite->nr_tests += 1; + + if (test->result.type == ptur_skipped) + suite->nr_skips += 1; + else if (test->result.type != ptur_passed) + suite->nr_fails += 1; + } + + ptunit_report_test(test); +} + +int ptunit_report(const struct ptunit_suite *suite) +{ + if (!suite) + return -1; + + if (suite->name) + fprintf(stdout, "%s: ", suite->name); + + fprintf(stdout, + "tests: %" PRIu32 ", passes: %" PRIu32 ", fails: %" PRIu32, + suite->nr_tests, + suite->nr_tests - (suite->nr_fails + suite->nr_skips), + suite->nr_fails); + + if (suite->nr_skips) + fprintf(stdout, " (skipped: %" PRIu32 ")", suite->nr_skips); + + fprintf(stdout, "\n"); + + if (INT32_MAX < suite->nr_fails) + return INT32_MAX; + + return (int) suite->nr_fails; +} |