From 0187c1eac126eaac074a827b21f9927c35100b1d Mon Sep 17 00:00:00 2001 From: Markus Kauppila Date: Mon, 30 May 2011 12:55:40 +0300 Subject: [PATCH] Refactoring the code (runner.c). Adding support for executing tests in-proc. --- test/test-automation/runner.c | 118 ++++++++++++++++---------- test/test-automation/tests/SDL_test.c | 6 +- test/test-automation/tests/SDL_test.h | 3 +- test/test-automation/tests/test.c | 16 ++-- 4 files changed, 87 insertions(+), 56 deletions(-) diff --git a/test/test-automation/runner.c b/test/test-automation/runner.c index 90d727ce9..c96d901c6 100644 --- a/test/test-automation/runner.c +++ b/test/test-automation/runner.c @@ -27,6 +27,9 @@ #include "tests/SDL_test.h" +//!< Function pointer to a test case function +typedef int (*TestCase)(void *arg); + /*! * Loads test suite which is implemented as dynamic library. * @@ -72,44 +75,77 @@ TestCaseReference **QueryTestCases(void *library) { return tests; } -/* +/*! + * Loads test case from a test suite + * + * \param Test suite + * \testName Name of the test that is going to be loaded * + * \return loaded test */ +TestCase LoadTestCase(void *suite, char *testName) { + TestCase test = (int (*)(void *)) SDL_LoadFunction(suite, testName); + if(test == NULL) { + printf("Loading test failed, tests == NULL\n"); + printf("%s\n", SDL_GetError()); + } + + return test; +} + + /*! - * Success or failure of test case is determined by - * it's return value. If test case succeeds, it'll - * return 0, if not it will return a positive integer. + * If using out-of-proc execution of tests. This function + * will handle the return value of the child process + * and interprets it to the runner. Also prints warnings + * if child was aborted by a signela. * - * The function checks the return value and returns value - * based on it. If the test is aborted due to a signal - * function warn about it. + * \param stat_lock information about the exited child process * - * \return 1 if test case succeeded, 0 otherwise + * \return 0 if test case succeeded, 1 otherwise */ int HandleTestReturnValue(int stat_lock) { - if(WIFEXITED(stat_lock)) { - int returnValue = WEXITSTATUS(stat_lock); + //! \todo rename to: HandleChildReturn Value + int returnValue = -1; - if(returnValue == 0) { - return 1; - } + if(WIFEXITED(stat_lock)) { + returnValue = WEXITSTATUS(stat_lock); } else if(WIFSIGNALED(stat_lock)) { int signal = WTERMSIG(stat_lock); printf("FAILURE: test was aborted due to signal nro %d\n", signal); - + returnValue = 1; } else if(WIFSTOPPED(stat_lock)) { } - return 0; + return returnValue; } +//!< Flag for executing tests in-process +int execute_inproc = 0; -int main(int argc, char *argv[]) { +/*! + * Parse command line arguments + */ +void +ParseOptions(int argc, char *argv[]) +{ + int i; + + for (i = 1; i < argc; ++i) { + const char *arg = argv[i]; + if (SDL_strcmp(arg, "--in-proc") == 0) { + execute_inproc = 1; + } + } +} - //! \todo Handle command line arguments +int +main(int argc, char *argv[]) +{ + ParseOptions(argc, argv); - // print: Testing againts SDL version fuu (rev: bar) + // print: Testing againts SDL version fuu (rev: bar) if verbose == true int failureCount = 0, passCount = 0; @@ -131,34 +167,30 @@ int main(int argc, char *argv[]) { printf("Running %s (in %s):\n", testname, libName); - int childpid = fork(); - if(childpid == 0) { - void (*test)(void *arg); - - test = (void (*)(void *)) SDL_LoadFunction(suite, testname); - if(test == NULL) { - printf("Loading test failed, tests == NULL\n"); - printf("%s\n", SDL_GetError()); - } else { - test(0x0); - } - return 0; // exit the child if the test didn't exit + int retVal = 1; + if(execute_inproc) { + TestCase test = (TestCase) LoadTestCase(suite, testname); + retVal = test(0x0); } else { - int stat_lock = -1; - int child = wait(&stat_lock); - - int passed = -1; - - passed = HandleTestReturnValue(stat_lock); - - if(passed) { - passCount++; - printf("%s (in %s): ok\n", testname, libName); + int childpid = fork(); + if(childpid == 0) { + TestCase test = (TestCase) LoadTestCase(suite, testname); + return test(0x0); } else { - failureCount++; - printf("%s (in %s): failed\n", testname, libName); + int stat_lock = -1; + int child = wait(&stat_lock); + + retVal = HandleTestReturnValue(stat_lock); } } + + if(retVal) { + failureCount++; + printf("%s (in %s): FAILED\n", testname, libName); + } else { + passCount++; + printf("%s (in %s): ok\n", testname, libName); + } } printf("\n"); @@ -168,7 +200,7 @@ int main(int argc, char *argv[]) { const Uint32 endTicks = SDL_GetTicks(); - printf("Ran %d tests in %0.3f seconds.\n", (passCount + failureCount), (endTicks-startTicks)/1000.0f); + printf("Ran %d tests in %0.5f seconds.\n", (passCount + failureCount), (endTicks-startTicks)/1000.0f); printf("%d tests passed\n", passCount); printf("%d tests failed\n", failureCount); diff --git a/test/test-automation/tests/SDL_test.c b/test/test-automation/tests/SDL_test.c index dcc3d1d24..32e0fd684 100644 --- a/test/test-automation/tests/SDL_test.c +++ b/test/test-automation/tests/SDL_test.c @@ -23,8 +23,6 @@ #include "SDL_test.h" -#include - /*! \brief return value of test case. Non-zero value means that the test failed */ static int _testReturnValue; @@ -34,10 +32,10 @@ TestCaseInit() _testReturnValue = 0; } -void +int TestCaseQuit() { - exit(_testReturnValue); + return _testReturnValue; } void diff --git a/test/test-automation/tests/SDL_test.h b/test/test-automation/tests/SDL_test.h index 6c5a8f5de..5a06ebbae 100644 --- a/test/test-automation/tests/SDL_test.h +++ b/test/test-automation/tests/SDL_test.h @@ -48,8 +48,9 @@ void TestCaseInit(); /*! \fn TestCaseQuit * Deinitializes and exits the test case * + * \return 0 if test succeeded, otherwise 1 */ -void TestCaseQuit(); +int TestCaseQuit(); void AssertEquals(char *message, Uint32 expected, Uint32 actual); diff --git a/test/test-automation/tests/test.c b/test/test-automation/tests/test.c index d1119551b..3e9ee3626 100644 --- a/test/test-automation/tests/test.c +++ b/test/test-automation/tests/test.c @@ -32,7 +32,7 @@ static const TestCaseReference test1 = (TestCaseReference){ "hello", "description", TEST_ENABLED, 0 }; static const TestCaseReference test2 = - (TestCaseReference){ "hello2", "description", TEST_DISABLED, 0 }; + (TestCaseReference){ "hello2", "description", TEST_ENABLED, 0 }; static const TestCaseReference test3 = (TestCaseReference){ "hello3", "description", TEST_ENABLED, 0 }; @@ -48,7 +48,7 @@ TestCaseReference **QueryTestSuite() { } /* Test case functions */ -void hello(void *arg) +int hello(void *arg) { TestCaseInit(); @@ -57,27 +57,27 @@ void hello(void *arg) printf("Revision is %s\n", revision); AssertEquals("will fail", 3, 5); - TestCaseQuit(); + return TestCaseQuit(); } -void hello2(void *arg) +int hello2(void *arg) { TestCaseInit(); char *msg = "eello"; - msg[0] = 'H'; + //msg[0] = 'H'; - TestCaseQuit(); + return TestCaseQuit(); } -void hello3(void *arg) +int hello3(void *arg) { TestCaseInit(); printf("hello3\n"); AssertEquals("passes", 3, 3); - TestCaseQuit(); + return TestCaseQuit(); } #endif