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