diff options
Diffstat (limited to 't/unit-tests/clar/test/selftest.c')
| -rw-r--r-- | t/unit-tests/clar/test/selftest.c | 173 |
1 files changed, 127 insertions, 46 deletions
diff --git a/t/unit-tests/clar/test/selftest.c b/t/unit-tests/clar/test/selftest.c index abd585f4e4..eed83e4512 100644 --- a/t/unit-tests/clar/test/selftest.c +++ b/t/unit-tests/clar/test/selftest.c @@ -59,38 +59,34 @@ static char *read_file(const char *path) return content; } -static void run(const char *expected_output_file, int expected_error_code, ...) +static char *execute(const char *suite, int expected_error_code, const char **args, size_t nargs) { SECURITY_ATTRIBUTES security_attributes = { 0 }; PROCESS_INFORMATION process_info = { 0 }; STARTUPINFO startup_info = { 0 }; + char binary_path[4096] = { 0 }; char cmdline[4096] = { 0 }; - char *expected_output = NULL; char *output = NULL; HANDLE stdout_write; HANDLE stdout_read; DWORD exit_code; - va_list ap; + size_t i; + + snprintf(binary_path, sizeof(binary_path), "%s/%s_suite.exe", + selftest_suite_directory, suite); /* * Assemble command line arguments. In theory we'd have to properly * quote them. In practice none of our tests actually care. */ - va_start(ap, expected_error_code); - snprintf(cmdline, sizeof(cmdline), "selftest"); - while (1) { + snprintf(cmdline, sizeof(cmdline), suite); + for (i = 0; i < nargs; i++) { size_t cmdline_len = strlen(cmdline); - const char *arg; - - arg = va_arg(ap, const char *); - if (!arg) - break; - + const char *arg = args[i]; cl_assert(cmdline_len + strlen(arg) < sizeof(cmdline)); snprintf(cmdline + cmdline_len, sizeof(cmdline) - cmdline_len, " %s", arg); } - va_end(ap); /* * Create a pipe that we will use to read data from the child process. @@ -110,17 +106,39 @@ static void run(const char *expected_output_file, int expected_error_code, ...) startup_info.hStdError = stdout_write; startup_info.hStdOutput = stdout_write; startup_info.dwFlags |= STARTF_USESTDHANDLES; - cl_assert_equal_b(1, CreateProcess(selftest_binary_path, cmdline, NULL, NULL, TRUE, + cl_assert_equal_b(1, CreateProcess(binary_path, cmdline, NULL, NULL, TRUE, 0, NULL, NULL, &startup_info, &process_info)); cl_assert_equal_b(1, CloseHandle(stdout_write)); output = read_full(stdout_read, 1); cl_assert_equal_b(1, CloseHandle(stdout_read)); cl_assert_equal_b(1, GetExitCodeProcess(process_info.hProcess, &exit_code)); + cl_assert_equal_i(exit_code, expected_error_code); + + return output; +} + +static void assert_output(const char *suite, const char *expected_output_file, int expected_error_code, ...) +{ + char *expected_output = NULL; + char *output = NULL; + const char *args[16]; + va_list ap; + size_t i; + + va_start(ap, expected_error_code); + for (i = 0; ; i++) { + const char *arg = va_arg(ap, const char *); + if (!arg) + break; + cl_assert(i < sizeof(args) / sizeof(*args)); + args[i] = arg; + } + va_end(ap); + output = execute(suite, expected_error_code, args, i); expected_output = read_file(cl_fixture(expected_output_file)); cl_assert_equal_s(output, expected_output); - cl_assert_equal_i(exit_code, expected_error_code); free(expected_output); free(output); @@ -180,29 +198,25 @@ static char *read_file(const char *path) return data; } -static void run(const char *expected_output_file, int expected_error_code, ...) +static char *execute(const char *suite, int expected_error_code, const char **args, size_t nargs) { - const char *argv[16]; int pipe_fds[2]; - va_list ap; pid_t pid; - int i; - - va_start(ap, expected_error_code); - argv[0] = "selftest"; - for (i = 1; ; i++) { - cl_assert(i < sizeof(argv) / sizeof(*argv)); - - argv[i] = va_arg(ap, const char *); - if (!argv[i]) - break; - } - va_end(ap); cl_must_pass(pipe(pipe_fds)); pid = fork(); if (!pid) { + const char *final_args[17] = { NULL }; + char binary_path[4096]; + size_t len = 0; + size_t i; + + cl_assert(nargs < sizeof(final_args) / sizeof(*final_args)); + final_args[0] = suite; + for (i = 0; i < nargs; i++) + final_args[i + 1] = args[i]; + if (dup2(pipe_fds[1], STDOUT_FILENO) < 0 || dup2(pipe_fds[1], STDERR_FILENO) < 0 || close(0) < 0 || @@ -210,11 +224,29 @@ static void run(const char *expected_output_file, int expected_error_code, ...) close(pipe_fds[1]) < 0) exit(1); - execv(selftest_binary_path, (char **) argv); + cl_assert(len + strlen(selftest_suite_directory) < sizeof(binary_path)); + strcpy(binary_path, selftest_suite_directory); + len += strlen(selftest_suite_directory); + + cl_assert(len + 1 < sizeof(binary_path)); + binary_path[len] = '/'; + len += 1; + + cl_assert(len + strlen(suite) < sizeof(binary_path)); + strcpy(binary_path + len, suite); + len += strlen(suite); + + cl_assert(len + strlen("_suite") < sizeof(binary_path)); + strcpy(binary_path + len, "_suite"); + len += strlen("_suite"); + + binary_path[len] = '\0'; + + execv(binary_path, (char **) final_args); exit(1); } else if (pid > 0) { pid_t waited_pid; - char *expected_output, *output; + char *output; int stat; cl_must_pass(close(pipe_fds[1])); @@ -226,56 +258,78 @@ static void run(const char *expected_output_file, int expected_error_code, ...) cl_assert(WIFEXITED(stat)); cl_assert_equal_i(WEXITSTATUS(stat), expected_error_code); - expected_output = read_file(cl_fixture(expected_output_file)); - cl_assert_equal_s(output, expected_output); - - free(expected_output); - free(output); + return output; } else { cl_fail("Fork failed."); } + + return NULL; +} + +static void assert_output(const char *suite, const char *expected_output_file, int expected_error_code, ...) +{ + char *expected_output, *output; + const char *args[16]; + va_list ap; + size_t i; + + va_start(ap, expected_error_code); + for (i = 0; ; i++) { + cl_assert(i < sizeof(args) / sizeof(*args)); + args[i] = va_arg(ap, const char *); + if (!args[i]) + break; + } + va_end(ap); + + output = execute(suite, expected_error_code, args, i); + expected_output = read_file(cl_fixture(expected_output_file)); + cl_assert_equal_s(output, expected_output); + + free(expected_output); + free(output); } #endif void test_selftest__help(void) { - cl_invoke(run("help", 1, "-h", NULL)); + cl_invoke(assert_output("combined", "help", 1, "-h", NULL)); } void test_selftest__without_arguments(void) { - cl_invoke(run("without_arguments", 10, NULL)); + cl_invoke(assert_output("combined", "without_arguments", 9, NULL)); } void test_selftest__specific_test(void) { - cl_invoke(run("specific_test", 1, "-sselftest::suite::bool", NULL)); + cl_invoke(assert_output("combined", "specific_test", 1, "-scombined::bool", NULL)); } void test_selftest__stop_on_failure(void) { - cl_invoke(run("stop_on_failure", 1, "-Q", NULL)); + cl_invoke(assert_output("combined", "stop_on_failure", 1, "-Q", NULL)); } void test_selftest__quiet(void) { - cl_invoke(run("quiet", 10, "-q", NULL)); + cl_invoke(assert_output("combined", "quiet", 9, "-q", NULL)); } void test_selftest__tap(void) { - cl_invoke(run("tap", 10, "-t", NULL)); + cl_invoke(assert_output("combined", "tap", 9, "-t", NULL)); } void test_selftest__suite_names(void) { - cl_invoke(run("suite_names", 0, "-l", NULL)); + cl_invoke(assert_output("combined", "suite_names", 0, "-l", NULL)); } void test_selftest__summary_without_filename(void) { struct stat st; - cl_invoke(run("summary_without_filename", 10, "-r", NULL)); + cl_invoke(assert_output("combined", "summary_without_filename", 9, "-r", NULL)); /* The summary contains timestamps, so we cannot verify its contents. */ cl_must_pass(stat("summary.xml", &st)); } @@ -283,7 +337,34 @@ void test_selftest__summary_without_filename(void) void test_selftest__summary_with_filename(void) { struct stat st; - cl_invoke(run("summary_with_filename", 10, "-rdifferent.xml", NULL)); + cl_invoke(assert_output("combined", "summary_with_filename", 9, "-rdifferent.xml", NULL)); /* The summary contains timestamps, so we cannot verify its contents. */ cl_must_pass(stat("different.xml", &st)); } + +void test_selftest__pointer_equal(void) +{ + const char *args[] = { + "-spointer::equal", + "-t" + }; + char *output = execute("pointer", 0, args, 2); + cl_assert_equal_s(output, + "TAP version 13\n" + "# start of suite 1: pointer\n" + "ok 1 - pointer::equal\n" + "1..1\n" + ); + free(output); +} + +void test_selftest__pointer_unequal(void) +{ + const char *args[] = { + "-spointer::unequal", + }; + char *output = execute("pointer", 1, args, 1); + cl_assert(output); + cl_assert(strstr(output, "Pointer mismatch: ")); + free(output); +} |
