mirror of
https://github.com/samba-team/samba.git
synced 2025-06-23 11:17:06 +03:00
235 lines
5.3 KiB
C
235 lines
5.3 KiB
C
/**
|
|
*
|
|
* 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 <stdio.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();
|
|
/* flush writes on FILE object to file descriptor */
|
|
fflush(stdout);
|
|
/* 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 void
|
|
call_test_progress_pop(void)
|
|
{
|
|
subunit_progress(SUBUNIT_PROGRESS_POP, 0);
|
|
}
|
|
|
|
static void
|
|
call_test_progress_set(void)
|
|
{
|
|
subunit_progress(SUBUNIT_PROGRESS_SET, 5);
|
|
}
|
|
|
|
static void
|
|
call_test_progress_push(void)
|
|
{
|
|
subunit_progress(SUBUNIT_PROGRESS_PUSH, 0);
|
|
}
|
|
|
|
static void
|
|
call_test_progress_cur(void)
|
|
{
|
|
subunit_progress(SUBUNIT_PROGRESS_CUR, -6);
|
|
}
|
|
|
|
START_TEST (test_progress)
|
|
{
|
|
test_stdout_function("progress: pop\n",
|
|
call_test_progress_pop);
|
|
test_stdout_function("progress: push\n",
|
|
call_test_progress_push);
|
|
test_stdout_function("progress: 5\n",
|
|
call_test_progress_set);
|
|
test_stdout_function("progress: -6\n",
|
|
call_test_progress_cur);
|
|
}
|
|
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);
|
|
tcase_add_test (tc_core, test_progress);
|
|
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;
|
|
}
|