diff options
Diffstat (limited to 'lib/subunit/c/tests/test_child.c')
-rw-r--r-- | lib/subunit/c/tests/test_child.c | 192 |
1 files changed, 192 insertions, 0 deletions
diff --git a/lib/subunit/c/tests/test_child.c b/lib/subunit/c/tests/test_child.c new file mode 100644 index 0000000000..6399eeb645 --- /dev/null +++ b/lib/subunit/c/tests/test_child.c @@ -0,0 +1,192 @@ +/** + * + * subunit C bindings. + * Copyright (C) 2006 Robert Collins <robertc@robertcollins.net> + * + * Licensed under either the Apache License, Version 2.0 or the BSD 3-clause + * license at the users choice. A copy of both licenses are available in the + * project source as Apache-2.0 and BSD. You may not use this file except in + * compliance with one of these two licences. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under these licenses is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the license you chose for the specific language governing permissions + * and limitations under that license. + **/ + +#include <stdlib.h> +#include <unistd.h> +#include <string.h> +#include <check.h> + +#include "subunit/child.h" + +/** + * Helper function to capture stdout, run some call, and check what + * was written. + * @expected the expected stdout content + * @function the function to call. + **/ +static void +test_stdout_function(char const * expected, + void (*function)(void)) +{ + /* test that the start function emits a correct test: line. */ + int bytecount; + int old_stdout; + int new_stdout[2]; + char buffer[100]; + /* we need a socketpair to capture stdout in */ + fail_if(pipe(new_stdout), "Failed to create a socketpair."); + /* backup stdout so we can replace it */ + old_stdout = dup(1); + if (old_stdout == -1) { + close(new_stdout[0]); + close(new_stdout[1]); + fail("Failed to backup stdout before replacing."); + } + /* redirect stdout so we can analyse it */ + if (dup2(new_stdout[1], 1) != 1) { + close(old_stdout); + close(new_stdout[0]); + close(new_stdout[1]); + fail("Failed to redirect stdout"); + } + /* yes this can block. Its a test case with < 100 bytes of output. + * DEAL. + */ + function(); + /* restore stdout now */ + if (dup2(old_stdout, 1) != 1) { + close(old_stdout); + close(new_stdout[0]); + close(new_stdout[1]); + fail("Failed to restore stdout"); + } + /* and we dont need the write side any more */ + if (close(new_stdout[1])) { + close(new_stdout[0]); + fail("Failed to close write side of socketpair."); + } + /* get the output */ + bytecount = read(new_stdout[0], buffer, 100); + if (0 > bytecount) { + close(new_stdout[0]); + fail("Failed to read captured output."); + } + buffer[bytecount]='\0'; + /* and we dont need the read side any more */ + fail_if(close(new_stdout[0]), "Failed to close write side of socketpair."); + /* compare with expected outcome */ + fail_if(strcmp(expected, buffer), "Did not get expected output [%s], got [%s]", expected, buffer); +} + + +static void +call_test_start(void) +{ + subunit_test_start("test case"); +} + + +START_TEST (test_start) +{ + test_stdout_function("test: test case\n", call_test_start); +} +END_TEST + + +static void +call_test_pass(void) +{ + subunit_test_pass("test case"); +} + + +START_TEST (test_pass) +{ + test_stdout_function("success: test case\n", call_test_pass); +} +END_TEST + + +static void +call_test_fail(void) +{ + subunit_test_fail("test case", "Multiple lines\n of error\n"); +} + + +START_TEST (test_fail) +{ + test_stdout_function("failure: test case [\n" + "Multiple lines\n" + " of error\n" + "]\n", + call_test_fail); +} +END_TEST + + +static void +call_test_error(void) +{ + subunit_test_error("test case", "Multiple lines\n of output\n"); +} + + +START_TEST (test_error) +{ + test_stdout_function("error: test case [\n" + "Multiple lines\n" + " of output\n" + "]\n", + call_test_error); +} +END_TEST + + +static void +call_test_skip(void) +{ + subunit_test_skip("test case", "Multiple lines\n of output\n"); +} + + +START_TEST (test_skip) +{ + test_stdout_function("skip: test case [\n" + "Multiple lines\n" + " of output\n" + "]\n", + call_test_skip); +} +END_TEST + +static Suite * +child_suite(void) +{ + Suite *s = suite_create("subunit_child"); + TCase *tc_core = tcase_create("Core"); + suite_add_tcase (s, tc_core); + tcase_add_test (tc_core, test_start); + tcase_add_test (tc_core, test_pass); + tcase_add_test (tc_core, test_fail); + tcase_add_test (tc_core, test_error); + tcase_add_test (tc_core, test_skip); + return s; +} + + +int +main(void) +{ + int nf; + Suite *s = child_suite(); + SRunner *sr = srunner_create(s); + srunner_run_all(sr, CK_NORMAL); + nf = srunner_ntests_failed(sr); + srunner_free(sr); + return (nf == 0) ? EXIT_SUCCESS : EXIT_FAILURE; +} |