src/test/SDL_test_harness.c
author Andreas Schiffler
Sat, 01 Dec 2012 14:48:30 -0800
changeset 6718 918ba414168b
parent 6717 2acd95060548
child 6721 53b71f45a53a
permissions -rw-r--r--
Update assert API in test lib; add to and harness; add test lib to VS2010 and VS2012 solution; fix VS2012 solution; fix compiler warning
     1 /*
     2   Simple DirectMedia Layer
     3   Copyright (C) 1997-2012 Sam Lantinga <slouken@libsdl.org>
     4 
     5   This software is provided 'as-is', without any express or implied
     6   warranty.  In no event will the authors be held liable for any damages
     7   arising from the use of this software.
     8 
     9   Permission is granted to anyone to use this software for any purpose,
    10   including commercial applications, and to alter it and redistribute it
    11   freely, subject to the following restrictions:
    12 
    13   1. The origin of this software must not be misrepresented; you must not
    14      claim that you wrote the original software. If you use this software
    15      in a product, an acknowledgment in the product documentation would be
    16      appreciated but is not required.
    17   2. Altered source versions must be plainly marked as such, and must not be
    18      misrepresented as being the original software.
    19   3. This notice may not be removed or altered from any source distribution.
    20 */
    21 
    22 #include "SDL_config.h"
    23 
    24 #include "SDL_test.h"
    25 
    26 #include <stdio.h>
    27 #include <string.h>
    28 
    29 // TODO: port over remaining harness
    30 
    31 /**
    32  * Generates a random run seed string for the harness. The generated seed
    33  * will contain alphanumeric characters (0-9A-Z).
    34  *
    35  * Note: The returned string needs to be deallocated by the caller.
    36  *
    37  * \param length The length of the seed string to generate
    38  *
    39  * \returns The generated seed string
    40  */
    41 char *
    42 SDLTest_GenerateRunSeed(const int length)
    43 {
    44 	char *seed = NULL;
    45 	SDLTest_RandomContext randomContext;
    46 	int counter;
    47 
    48 	// Sanity check input
    49 	if (length <= 0) {
    50 		SDLTest_LogError("The length of the harness seed must be >0.");
    51 		return NULL;
    52 	}
    53 
    54 	// Allocate output buffer
    55 	seed = (char *)SDL_malloc((length + 1) * sizeof(char));
    56 	if (seed == NULL) {
    57 		SDLTest_LogError("SDL_malloc for run seed output buffer failed.");
    58 		return NULL;
    59 	}
    60 
    61 	// Generate a random string of alphanumeric characters
    62 	SDLTest_RandomInitTime(&randomContext);
    63 	for (counter = 0; counter < length - 1; ++counter) {
    64 		unsigned int number = SDLTest_Random(&randomContext);
    65 		char ch = (char) (number % (91 - 48)) + 48;
    66 		if (ch >= 58 && ch <= 64) {
    67 			ch = 65;
    68 		}
    69 		seed[counter] = ch;
    70 	}
    71 	seed[counter] = '\0';
    72 
    73 	return seed;
    74 }
    75 
    76 /**
    77  * Generates an execution key for the fuzzer.
    78  *
    79  * \param runSeed		The run seed to use
    80  * \param suiteName		The name of the test suite
    81  * \param testName		The name of the test
    82  * \param iteration		The iteration count
    83  *
    84  * \returns The generated execution key to initialize the fuzzer with.
    85  *
    86  */
    87 Uint64
    88 SDLTest_GenerateExecKey(char *runSeed, char *suiteName, char *testName, int iteration)
    89 {
    90 	SDLTest_Md5Context md5Context;
    91 	Uint64 *keys;
    92 	char iterationString[16];
    93 	Uint32 runSeedLength;
    94 	Uint32 suiteNameLength;
    95 	Uint32 testNameLength;
    96 	Uint32 iterationStringLength;
    97 	Uint32 entireStringLength;
    98 	char *buffer;
    99 
   100 	if (runSeed == NULL || strlen(runSeed)==0) {
   101 		SDLTest_LogError("Invalid runSeed string.");
   102 		return -1;
   103 	}
   104 
   105 	if (suiteName == NULL || strlen(suiteName)==0) {
   106 		SDLTest_LogError("Invalid suiteName string.");
   107 		return -1;
   108 	}
   109 
   110 	if (testName == NULL || strlen(testName)==0) {
   111 		SDLTest_LogError("Invalid testName string.");
   112 		return -1;
   113 	}
   114 
   115 	if (iteration <= 0) {
   116 		SDLTest_LogError("Invalid iteration count.");
   117 		return -1;
   118 	}
   119 
   120 	// Convert iteration number into a string
   121 	memset(iterationString, 0, sizeof(iterationString));
   122 	SDL_snprintf(iterationString, sizeof(iterationString) - 1, "%d", iteration);
   123 
   124 	// Combine the parameters into single string
   125 	runSeedLength = strlen(runSeed);
   126 	suiteNameLength = strlen(suiteName);
   127 	testNameLength = strlen(testName);
   128 	iterationStringLength = strlen(iterationString);
   129 	entireStringLength  = runSeedLength + suiteNameLength + testNameLength + iterationStringLength + 1;
   130 	buffer = (char *)SDL_malloc(entireStringLength);
   131 	if (buffer == NULL) {
   132 		SDLTest_LogError("SDL_malloc failed to allocate buffer for execKey generation.");
   133 		return 0;
   134 	}
   135 	SDL_snprintf(buffer, entireStringLength, "%s%s%s%d", runSeed, suiteName, testName, iteration);
   136 
   137 	// Hash string and use half of the digest as 64bit exec key
   138 	SDLTest_Md5Init(&md5Context);
   139 	SDLTest_Md5Update(&md5Context, (unsigned char *)buffer, entireStringLength);
   140 	SDLTest_Md5Final(&md5Context);
   141 	SDL_free(buffer);
   142 	keys = (Uint64 *)md5Context.digest;
   143 
   144 	return keys[0];
   145 }
   146 
   147 /**
   148  * \brief Set timeout handler for test.
   149  *
   150  * Note: SDL_Init(SDL_INIT_TIMER) will be called if it wasn't done so before.
   151  *
   152  * \param timeout Timeout interval in seconds.
   153  * \param callback Function that will be called after timeout has elapsed.
   154  * 
   155  * \return Timer id or -1 on failure.
   156  */
   157 SDL_TimerID
   158 SetTestTimeout(int timeout, void (*callback)())
   159 {
   160 	Uint32 timeoutInMilliseconds;
   161 	SDL_TimerID timerID;
   162 
   163 	if (callback == NULL) {
   164 		SDLTest_LogError("Timeout callback can't be NULL");
   165 		return -1;
   166 	}
   167 
   168 	if (timeout < 0) {
   169 		SDLTest_LogError("Timeout value must be bigger than zero.");
   170 		return -1;
   171 	}
   172 
   173 	/* Init SDL timer if not initialized before */
   174 	if (SDL_WasInit(SDL_INIT_TIMER) == 0) {
   175 		if (SDL_InitSubSystem(SDL_INIT_TIMER)) {
   176 			SDLTest_LogError("Failed to init timer subsystem: %s", SDL_GetError());
   177 			return -1;
   178 		}
   179 	}
   180 
   181 	/* Set timer */
   182 	timeoutInMilliseconds = timeout * 1000;
   183 	timerID = SDL_AddTimer(timeoutInMilliseconds, (SDL_TimerCallback)callback, 0x0);
   184 	if (timerID == 0) {
   185 		SDLTest_LogError("Creation of SDL timer failed: %s", SDL_GetError());
   186 		return -1;
   187 	}
   188 
   189 	return timerID;
   190 }