Fixed old comments and added new ones.
2 Copyright (C) 2011 Markus Kauppila <markus.kauppila@gmail.com>
4 This software is provided 'as-is', without any express or implied
5 warranty. In no event will the authors be held liable for any damages
6 arising from the use of this software.
8 Permission is granted to anyone to use this software for any purpose,
9 including commercial applications, and to alter it and redistribute it
10 freely, subject to the following restrictions:
12 1. The origin of this software must not be misrepresented; you must not
13 claim that you wrote the original software. If you use this software
14 in a product, an acknowledgment in the product documentation would be
15 appreciated but is not required.
16 2. Altered source versions must be plainly marked as such, and must not be
17 misrepresented as being the original software.
18 3. This notice may not be removed or altered from any source distribution.
26 #include <sys/types.h>
30 //!< Function pointer to a test case function
31 typedef void (*TestCase)(void *arg);
32 //!< Function pointer to a test case init function
33 typedef void (*TestCaseInit)(void);
34 //!< Function pointer to a test case quit function
35 typedef int (*TestCaseQuit)(void);
37 //!< Flag for executing tests in-process
38 static int execute_inproc = 0;
41 * Returns the name for the dynamic library
42 * which implements the test suite.
44 * (in the future: scans the test/ directory and
45 * returns the names of the dynamic libraries
46 * implementing the test suites)
48 * \return Name of the dummy test suite
52 #if defined(linux) || defined( __linux)
53 char *libName = "tests/libtest.so";
55 char *libName = "tests/libtest.dylib";
62 * Loads test suite which is implemented as dynamic library.
64 * \param testSuiteName Name of the test suite which will be loaded
66 * \return Pointer to loaded test suite, or NULL if library could not be loaded
69 LoadTestSuite(char *testSuiteName)
71 void *library = SDL_LoadObject(testSuiteName);
73 fprintf(stderr, "Loading %s failed\n", testSuiteName);
74 fprintf(stderr, "%s\n", SDL_GetError());
81 * Loads the test case references from the given test suite.
83 * \param library Previously loaded dynamic library AKA test suite
84 * \return Pointer to array of TestCaseReferences or NULL if function failed
87 QueryTestCases(void *library)
89 TestCaseReference **(*suite)(void);
91 suite = (TestCaseReference **(*)(void)) SDL_LoadFunction(library, "QueryTestSuite");
93 fprintf(stderr, "Loading QueryTestCaseReferences() failed.\n");
94 fprintf(stderr, "%s\n", SDL_GetError());
97 TestCaseReference **tests = suite();
99 fprintf(stderr, "Failed to load test references.\n");
100 fprintf(stderr, "%s\n", SDL_GetError());
108 * Loads test case from a test suite
110 * \param suite a test suite
111 * \param testName Name of the test that is going to be loaded
113 * \return Function Pointer (TestCase) to loaded test case, NULL if function failed
116 LoadTestCase(void *suite, char *testName)
118 TestCase test = (TestCase) SDL_LoadFunction(suite, testName);
120 fprintf(stderr, "Loading test failed, tests == NULL\n");
121 fprintf(stderr, "%s\n", SDL_GetError());
128 * Loads function that initialises the test case from the
131 * \param suite Used test suite
133 * \return Function pointer (TestCaseInit) which points to loaded init function. NULL if function fails.
136 LoadTestCaseInit(void *suite) {
137 TestCaseInit testCaseInit = (TestCaseInit) SDL_LoadFunction(suite, "_TestCaseInit");
138 if(testCaseInit == NULL) {
139 fprintf(stderr, "Loading TestCaseInit function failed, testCaseInit == NULL\n");
140 fprintf(stderr, "%s\n", SDL_GetError());
147 * Loads function that deinitialises the executed test case from the
150 * \param suite Used test suite
152 * \return Function pointer (TestCaseInit) which points to loaded init function. NULL if function fails.
155 LoadTestCaseQuit(void *suite) {
156 TestCaseQuit testCaseQuit = (TestCaseQuit) SDL_LoadFunction(suite, "_TestCaseQuit");
157 if(testCaseQuit == NULL) {
158 fprintf(stderr, "Loading TestCaseQuit function failed, testCaseQuit == NULL\n");
159 fprintf(stderr, "%s\n", SDL_GetError());
166 * If using out-of-proc execution of tests. This function
167 * will handle the return value of the child process
168 * and interprets it to the runner. Also prints warnings
169 * if child was aborted by a signela.
171 * \param stat_lock information about the exited child process
173 * \return 0 if test case succeeded, 1 otherwise
176 HandleTestReturnValue(int stat_lock)
178 //! \todo rename to: HandleChildProcessReturnValue?
179 int returnValue = -1;
181 if(WIFEXITED(stat_lock)) {
182 returnValue = WEXITSTATUS(stat_lock);
183 } else if(WIFSIGNALED(stat_lock)) {
184 int signal = WTERMSIG(stat_lock);
185 fprintf(stderr, "FAILURE: test was aborted due to signal no %d\n", signal);
193 * Prints usage information
196 printf("Usage: ./runner [--in-proc] [--help]\n");
197 printf("Options:\n");
198 printf(" --in-proc Executes tests in-process\n");
199 printf(" --help Print this help\n");
203 * Parse command line arguments
205 * \param argc Count of command line arguments
206 * \param argv Array of commond lines arguments
209 ParseOptions(int argc, char *argv[])
213 for (i = 1; i < argc; ++i) {
214 const char *arg = argv[i];
215 if(SDL_strcmp(arg, "--in-proc") == 0) {
218 else if(SDL_strcmp(arg, "--help") == 0 || SDL_strcmp(arg, "-h") == 0) {
222 printf("runner: unknown command '%s'\n", arg);
230 * Entry point for test runner
232 * \param argc Count of command line arguments
233 * \param argv Array of commond lines arguments
236 main(int argc, char *argv[])
238 ParseOptions(argc, argv);
240 // print: Testing against SDL version fuu (rev: bar) if verbose == true
242 int failureCount = 0, passCount = 0;
244 const Uint32 startTicks = SDL_GetTicks();
246 char *testSuiteName = ScanForTestSuites();
247 void *suite = LoadTestSuite(testSuiteName);
248 TestCaseReference **tests = QueryTestCases(suite);
250 TestCaseReference *reference = NULL;
253 for(reference = tests[counter]; reference; reference = tests[++counter]) {
254 if(reference->enabled == TEST_DISABLED) {
255 printf("Test %s (in %s) disabled. Omitting...\n", reference->name, testSuiteName);
257 char *testname = reference->name;
259 printf("Running %s (in %s):\n", testname, testSuiteName);
261 TestCaseInit testCaseInit = LoadTestCaseInit(suite);
262 TestCaseQuit testCaseQuit = LoadTestCaseQuit(suite);
263 TestCase test = (TestCase) LoadTestCase(suite, testname);
271 retVal = testCaseQuit();
273 int childpid = fork();
279 return testCaseQuit();
282 int child = wait(&stat_lock);
284 retVal = HandleTestReturnValue(stat_lock);
291 printf("%s (in %s): FAILED -> No asserts\n", testname, testSuiteName);
293 printf("%s (in %s): FAILED\n", testname, testSuiteName);
297 printf("%s (in %s): ok\n", testname, testSuiteName);
304 SDL_UnloadObject(suite);
306 const Uint32 endTicks = SDL_GetTicks();
308 printf("Ran %d tests in %0.5f seconds.\n", (passCount + failureCount), (endTicks-startTicks)/1000.0f);
310 printf("%d tests passed\n", passCount);
311 printf("%d tests failed\n", failureCount);