Merge commit '3a7f96fd99528968c39b5be81db067ca018d432b' into dev

This commit is contained in:
SimoneN64
2024-09-18 20:42:08 +02:00
641 changed files with 31269 additions and 30646 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -27,14 +27,14 @@
*/
#include <SDL3/SDL_test.h>
int SDLTest_Crc32Init(SDLTest_Crc32Context *crcContext)
bool SDLTest_Crc32Init(SDLTest_Crc32Context *crcContext)
{
int i, j;
CrcUint32 c;
/* Sanity check context pointer */
if (!crcContext) {
return -1;
return SDL_InvalidParamError("crcContext");
}
/*
@@ -61,35 +61,35 @@ int SDLTest_Crc32Init(SDLTest_Crc32Context *crcContext)
}
#endif
return 0;
return true;
}
/* Complete CRC32 calculation on a memory block */
int SDLTest_Crc32Calc(SDLTest_Crc32Context *crcContext, CrcUint8 *inBuf, CrcUint32 inLen, CrcUint32 *crc32)
bool SDLTest_Crc32Calc(SDLTest_Crc32Context *crcContext, CrcUint8 *inBuf, CrcUint32 inLen, CrcUint32 *crc32)
{
if (SDLTest_Crc32CalcStart(crcContext, crc32)) {
return -1;
if (!SDLTest_Crc32CalcStart(crcContext, crc32)) {
return false;
}
if (SDLTest_Crc32CalcBuffer(crcContext, inBuf, inLen, crc32)) {
return -1;
if (!SDLTest_Crc32CalcBuffer(crcContext, inBuf, inLen, crc32)) {
return false;
}
if (SDLTest_Crc32CalcEnd(crcContext, crc32)) {
return -1;
if (!SDLTest_Crc32CalcEnd(crcContext, crc32)) {
return false;
}
return 0;
return true;
}
/* Start crc calculation */
int SDLTest_Crc32CalcStart(SDLTest_Crc32Context *crcContext, CrcUint32 *crc32)
bool SDLTest_Crc32CalcStart(SDLTest_Crc32Context *crcContext, CrcUint32 *crc32)
{
/* Sanity check pointers */
if (!crcContext) {
*crc32 = 0;
return -1;
return SDL_InvalidParamError("crcContext");
}
/*
@@ -97,17 +97,17 @@ int SDLTest_Crc32CalcStart(SDLTest_Crc32Context *crcContext, CrcUint32 *crc32)
*/
*crc32 = 0xffffffff;
return 0;
return true;
}
/* Finish crc calculation */
int SDLTest_Crc32CalcEnd(SDLTest_Crc32Context *crcContext, CrcUint32 *crc32)
bool SDLTest_Crc32CalcEnd(SDLTest_Crc32Context *crcContext, CrcUint32 *crc32)
{
/* Sanity check pointers */
if (!crcContext) {
*crc32 = 0;
return -1;
return SDL_InvalidParamError("crcContext");
}
/*
@@ -115,23 +115,23 @@ int SDLTest_Crc32CalcEnd(SDLTest_Crc32Context *crcContext, CrcUint32 *crc32)
*/
*crc32 = (~(*crc32));
return 0;
return true;
}
/* Include memory block in crc */
int SDLTest_Crc32CalcBuffer(SDLTest_Crc32Context *crcContext, CrcUint8 *inBuf, CrcUint32 inLen, CrcUint32 *crc32)
bool SDLTest_Crc32CalcBuffer(SDLTest_Crc32Context *crcContext, CrcUint8 *inBuf, CrcUint32 inLen, CrcUint32 *crc32)
{
CrcUint8 *p;
register CrcUint32 crc;
if (!crcContext) {
*crc32 = 0;
return -1;
return SDL_InvalidParamError("crcContext");
}
if (!inBuf) {
return -1;
return SDL_InvalidParamError("inBuf");
}
/*
@@ -147,14 +147,14 @@ int SDLTest_Crc32CalcBuffer(SDLTest_Crc32Context *crcContext, CrcUint8 *inBuf, C
}
*crc32 = crc;
return 0;
return true;
}
int SDLTest_Crc32Done(SDLTest_Crc32Context *crcContext)
bool SDLTest_Crc32Done(SDLTest_Crc32Context *crcContext)
{
if (!crcContext) {
return -1;
return SDL_InvalidParamError("crcContext");
}
return 0;
return true;
}

View File

@@ -3142,13 +3142,13 @@ static struct SDLTest_CharTextureCache *SDLTest_CharTextureCacheList;
int FONT_CHARACTER_SIZE = 8;
SDL_bool SDLTest_DrawCharacter(SDL_Renderer *renderer, float x, float y, Uint32 c)
bool SDLTest_DrawCharacter(SDL_Renderer *renderer, float x, float y, Uint32 c)
{
const Uint32 charWidth = FONT_CHARACTER_SIZE;
const Uint32 charHeight = FONT_CHARACTER_SIZE;
SDL_FRect srect;
SDL_FRect drect;
SDL_bool result;
bool result;
Uint32 ix, iy;
const unsigned char *charpos;
Uint32 *curpos;
@@ -3205,7 +3205,7 @@ SDL_bool SDLTest_DrawCharacter(SDL_Renderer *renderer, float x, float y, Uint32
*/
character = SDL_CreateSurface(charWidth, charHeight, SDL_PIXELFORMAT_RGBA8888);
if (!character) {
return SDL_FALSE;
return false;
}
charpos = SDLTest_FontData + ci * 8;
@@ -3237,7 +3237,7 @@ SDL_bool SDLTest_DrawCharacter(SDL_Renderer *renderer, float x, float y, Uint32
* Check pointer
*/
if (cache->charTextureCache[ci] == NULL) {
return SDL_FALSE;
return false;
}
SDL_SetTextureScaleMode(cache->charTextureCache[ci], SDL_SCALEMODE_NEAREST);
@@ -3246,7 +3246,7 @@ SDL_bool SDLTest_DrawCharacter(SDL_Renderer *renderer, float x, float y, Uint32
/*
* Set color
*/
result = SDL_TRUE;
result = true;
result &= SDL_GetRenderDrawColor(renderer, &r, &g, &b, &a);
result &= SDL_SetTextureColorMod(cache->charTextureCache[ci], r, g, b);
result &= SDL_SetTextureAlphaMod(cache->charTextureCache[ci], a);
@@ -3267,8 +3267,8 @@ static Uint32 UTF8_getch(const char *src, size_t srclen, int *inc)
const Uint8 *p = (const Uint8 *)src;
size_t left = 0;
size_t save_srclen = srclen;
SDL_bool overlong = SDL_FALSE;
SDL_bool underflow = SDL_FALSE;
bool overlong = false;
bool underflow = false;
Uint32 ch = UNKNOWN_UNICODE;
if (srclen == 0) {
@@ -3277,7 +3277,7 @@ static Uint32 UTF8_getch(const char *src, size_t srclen, int *inc)
if (p[0] >= 0xFC) {
if ((p[0] & 0xFE) == 0xFC) {
if (p[0] == 0xFC && (p[1] & 0xFC) == 0x80) {
overlong = SDL_TRUE;
overlong = true;
}
ch = (Uint32)(p[0] & 0x01);
left = 5;
@@ -3285,7 +3285,7 @@ static Uint32 UTF8_getch(const char *src, size_t srclen, int *inc)
} else if (p[0] >= 0xF8) {
if ((p[0] & 0xFC) == 0xF8) {
if (p[0] == 0xF8 && (p[1] & 0xF8) == 0x80) {
overlong = SDL_TRUE;
overlong = true;
}
ch = (Uint32)(p[0] & 0x03);
left = 4;
@@ -3293,7 +3293,7 @@ static Uint32 UTF8_getch(const char *src, size_t srclen, int *inc)
} else if (p[0] >= 0xF0) {
if ((p[0] & 0xF8) == 0xF0) {
if (p[0] == 0xF0 && (p[1] & 0xF0) == 0x80) {
overlong = SDL_TRUE;
overlong = true;
}
ch = (Uint32)(p[0] & 0x07);
left = 3;
@@ -3301,7 +3301,7 @@ static Uint32 UTF8_getch(const char *src, size_t srclen, int *inc)
} else if (p[0] >= 0xE0) {
if ((p[0] & 0xF0) == 0xE0) {
if (p[0] == 0xE0 && (p[1] & 0xE0) == 0x80) {
overlong = SDL_TRUE;
overlong = true;
}
ch = (Uint32)(p[0] & 0x0F);
left = 2;
@@ -3309,7 +3309,7 @@ static Uint32 UTF8_getch(const char *src, size_t srclen, int *inc)
} else if (p[0] >= 0xC0) {
if ((p[0] & 0xE0) == 0xC0) {
if ((p[0] & 0xDE) == 0xC0) {
overlong = SDL_TRUE;
overlong = true;
}
ch = (Uint32)(p[0] & 0x1F);
left = 1;
@@ -3332,7 +3332,7 @@ static Uint32 UTF8_getch(const char *src, size_t srclen, int *inc)
--left;
}
if (left > 0) {
underflow = SDL_TRUE;
underflow = true;
}
if (overlong || underflow ||
@@ -3348,10 +3348,10 @@ static Uint32 UTF8_getch(const char *src, size_t srclen, int *inc)
#define UTF8_IsTrailingByte(c) ((c) >= 0x80 && (c) <= 0xBF)
SDL_bool SDLTest_DrawString(SDL_Renderer *renderer, float x, float y, const char *s)
bool SDLTest_DrawString(SDL_Renderer *renderer, float x, float y, const char *s)
{
const Uint32 charWidth = FONT_CHARACTER_SIZE;
SDL_bool result = SDL_TRUE;
bool result = true;
float curx = x;
float cury = y;
size_t len = SDL_strlen(s);
@@ -3417,12 +3417,12 @@ void SDLTest_TextWindowAddText(SDLTest_TextWindow *textwin, const char *fmt, ...
void SDLTest_TextWindowAddTextWithLength(SDLTest_TextWindow *textwin, const char *text, size_t len)
{
size_t existing;
SDL_bool newline = SDL_FALSE;
bool newline = false;
char *line;
if (len > 0 && text[len - 1] == '\n') {
--len;
newline = SDL_TRUE;
newline = true;
}
if (textwin->lines[textwin->current]) {

View File

@@ -170,7 +170,7 @@ Sint32 SDLTest_RandomIntegerInRange(Sint32 min, Sint32 max)
*
* \returns Returns a random boundary value for the domain or 0 in case of error
*/
static Uint64 SDLTest_GenerateUnsignedBoundaryValues(const Uint64 maxValue, Uint64 boundary1, Uint64 boundary2, SDL_bool validDomain)
static Uint64 SDLTest_GenerateUnsignedBoundaryValues(const Uint64 maxValue, Uint64 boundary1, Uint64 boundary2, bool validDomain)
{
Uint64 b1, b2;
Uint64 delta;
@@ -187,7 +187,7 @@ static Uint64 SDLTest_GenerateUnsignedBoundaryValues(const Uint64 maxValue, Uint
}
index = 0;
if (validDomain == SDL_TRUE) {
if (validDomain == true) {
if (b1 == b2) {
return b1;
}
@@ -231,7 +231,7 @@ static Uint64 SDLTest_GenerateUnsignedBoundaryValues(const Uint64 maxValue, Uint
return tempBuf[SDLTest_RandomUint8() % index];
}
Uint8 SDLTest_RandomUint8BoundaryValue(Uint8 boundary1, Uint8 boundary2, SDL_bool validDomain)
Uint8 SDLTest_RandomUint8BoundaryValue(Uint8 boundary1, Uint8 boundary2, bool validDomain)
{
/* max value for Uint8 */
const Uint64 maxValue = UCHAR_MAX;
@@ -240,7 +240,7 @@ Uint8 SDLTest_RandomUint8BoundaryValue(Uint8 boundary1, Uint8 boundary2, SDL_boo
validDomain);
}
Uint16 SDLTest_RandomUint16BoundaryValue(Uint16 boundary1, Uint16 boundary2, SDL_bool validDomain)
Uint16 SDLTest_RandomUint16BoundaryValue(Uint16 boundary1, Uint16 boundary2, bool validDomain)
{
/* max value for Uint16 */
const Uint64 maxValue = USHRT_MAX;
@@ -249,7 +249,7 @@ Uint16 SDLTest_RandomUint16BoundaryValue(Uint16 boundary1, Uint16 boundary2, SDL
validDomain);
}
Uint32 SDLTest_RandomUint32BoundaryValue(Uint32 boundary1, Uint32 boundary2, SDL_bool validDomain)
Uint32 SDLTest_RandomUint32BoundaryValue(Uint32 boundary1, Uint32 boundary2, bool validDomain)
{
/* max value for Uint32 */
#if ((ULONG_MAX) == (UINT_MAX))
@@ -262,7 +262,7 @@ Uint32 SDLTest_RandomUint32BoundaryValue(Uint32 boundary1, Uint32 boundary2, SDL
validDomain);
}
Uint64 SDLTest_RandomUint64BoundaryValue(Uint64 boundary1, Uint64 boundary2, SDL_bool validDomain)
Uint64 SDLTest_RandomUint64BoundaryValue(Uint64 boundary1, Uint64 boundary2, bool validDomain)
{
/* max value for Uint64 */
const Uint64 maxValue = UINT64_MAX;
@@ -296,7 +296,7 @@ Uint64 SDLTest_RandomUint64BoundaryValue(Uint64 boundary1, Uint64 boundary2, SDL
*
* \returns Returns a random boundary value for the domain or 0 in case of error
*/
static Sint64 SDLTest_GenerateSignedBoundaryValues(const Sint64 minValue, const Sint64 maxValue, Sint64 boundary1, Sint64 boundary2, SDL_bool validDomain)
static Sint64 SDLTest_GenerateSignedBoundaryValues(const Sint64 minValue, const Sint64 maxValue, Sint64 boundary1, Sint64 boundary2, bool validDomain)
{
Sint64 b1, b2;
Sint64 delta;
@@ -313,7 +313,7 @@ static Sint64 SDLTest_GenerateSignedBoundaryValues(const Sint64 minValue, const
}
index = 0;
if (validDomain == SDL_TRUE) {
if (validDomain == true) {
if (b1 == b2) {
return b1;
}
@@ -357,7 +357,7 @@ static Sint64 SDLTest_GenerateSignedBoundaryValues(const Sint64 minValue, const
return tempBuf[SDLTest_RandomUint8() % index];
}
Sint8 SDLTest_RandomSint8BoundaryValue(Sint8 boundary1, Sint8 boundary2, SDL_bool validDomain)
Sint8 SDLTest_RandomSint8BoundaryValue(Sint8 boundary1, Sint8 boundary2, bool validDomain)
{
/* min & max values for Sint8 */
const Sint64 maxValue = SCHAR_MAX;
@@ -367,7 +367,7 @@ Sint8 SDLTest_RandomSint8BoundaryValue(Sint8 boundary1, Sint8 boundary2, SDL_boo
validDomain);
}
Sint16 SDLTest_RandomSint16BoundaryValue(Sint16 boundary1, Sint16 boundary2, SDL_bool validDomain)
Sint16 SDLTest_RandomSint16BoundaryValue(Sint16 boundary1, Sint16 boundary2, bool validDomain)
{
/* min & max values for Sint16 */
const Sint64 maxValue = SHRT_MAX;
@@ -377,7 +377,7 @@ Sint16 SDLTest_RandomSint16BoundaryValue(Sint16 boundary1, Sint16 boundary2, SDL
validDomain);
}
Sint32 SDLTest_RandomSint32BoundaryValue(Sint32 boundary1, Sint32 boundary2, SDL_bool validDomain)
Sint32 SDLTest_RandomSint32BoundaryValue(Sint32 boundary1, Sint32 boundary2, bool validDomain)
{
/* min & max values for Sint32 */
#if ((ULONG_MAX) == (UINT_MAX))
@@ -392,7 +392,7 @@ Sint32 SDLTest_RandomSint32BoundaryValue(Sint32 boundary1, Sint32 boundary2, SDL
validDomain);
}
Sint64 SDLTest_RandomSint64BoundaryValue(Sint64 boundary1, Sint64 boundary2, SDL_bool validDomain)
Sint64 SDLTest_RandomSint64BoundaryValue(Sint64 boundary1, Sint64 boundary2, bool validDomain)
{
/* min & max values for Sint64 */
const Sint64 maxValue = INT64_MAX;

View File

@@ -47,38 +47,48 @@
/* Final result message format */
#define SDLTEST_FINAL_RESULT_FORMAT COLOR_YELLOW ">>> %s '%s':" COLOR_END " %s\n"
struct SDLTest_TestSuiteRunner {
struct
{
SDLTest_TestSuiteReference **testSuites;
char *runSeed;
Uint64 execKey;
char *filter;
int testIterations;
bool randomOrder;
} user;
SDLTest_ArgumentParser argparser;
};
/* ! Timeout for single test case execution */
static Uint32 SDLTest_TestCaseTimeout = 3600;
/**
* Generates a random run seed string for the harness. The generated seed
* will contain alphanumeric characters (0-9A-Z).
*
* Note: The returned string needs to be deallocated by the caller.
*
* \param length The length of the seed string to generate
*
* \returns The generated seed string
*/
char *SDLTest_GenerateRunSeed(const int length)
static const char *common_harness_usage[] = {
"[--iterations #]",
"[--execKey #]",
"[--seed string]",
"[--filter suite_name|test_name]",
"[--random-order]",
NULL
};
char *SDLTest_GenerateRunSeed(char *buffer, int length)
{
char *seed = NULL;
Uint64 randomContext = SDL_GetPerformanceCounter();
int counter;
if (!buffer) {
SDLTest_LogError("Input buffer must not be NULL.");
return NULL;
}
/* Sanity check input */
if (length <= 0) {
SDLTest_LogError("The length of the harness seed must be >0.");
return NULL;
}
/* Allocate output buffer */
seed = (char *)SDL_malloc((length + 1) * sizeof(char));
if (!seed) {
SDLTest_LogError("SDL_malloc for run seed output buffer failed.");
return NULL;
}
/* Generate a random string of alphanumeric characters */
for (counter = 0; counter < length; counter++) {
char ch;
@@ -88,11 +98,11 @@ char *SDLTest_GenerateRunSeed(const int length)
} else {
ch = (char)('A' + v - 10);
}
seed[counter] = ch;
buffer[counter] = ch;
}
seed[length] = '\0';
buffer[length] = '\0';
return seed;
return buffer;
}
/**
@@ -168,14 +178,12 @@ static Uint64 SDLTest_GenerateExecKey(const char *runSeed, const char *suiteName
/**
* Set timeout handler for test.
*
* Note: SDL_Init(SDL_INIT_TIMER) will be called if it wasn't done so before.
*
* \param timeout Timeout interval in seconds.
* \param callback Function that will be called after timeout has elapsed.
*
* \return Timer id or -1 on failure.
*/
static SDL_TimerID SDLTest_SetTestTimeout(int timeout, void(SDLCALL *callback)(void))
static SDL_TimerID SDLTest_SetTestTimeout(int timeout, SDL_TimerCallback callback)
{
Uint32 timeoutInMilliseconds;
SDL_TimerID timerID;
@@ -190,17 +198,9 @@ static SDL_TimerID SDLTest_SetTestTimeout(int timeout, void(SDLCALL *callback)(v
return 0;
}
/* Init SDL timer if not initialized before */
if (!SDL_WasInit(SDL_INIT_TIMER)) {
if (!SDL_InitSubSystem(SDL_INIT_TIMER)) {
SDLTest_LogError("Failed to init timer subsystem: %s", SDL_GetError());
return 0;
}
}
/* Set timer */
timeoutInMilliseconds = timeout * 1000;
timerID = SDL_AddTimer(timeoutInMilliseconds, (SDL_TimerCallback)callback, 0x0);
timerID = SDL_AddTimer(timeoutInMilliseconds, callback, 0x0);
if (timerID == 0) {
SDLTest_LogError("Creation of SDL timer failed: %s", SDL_GetError());
return 0;
@@ -212,13 +212,11 @@ static SDL_TimerID SDLTest_SetTestTimeout(int timeout, void(SDLCALL *callback)(v
/**
* Timeout handler. Aborts test run and exits harness process.
*/
#ifdef __WATCOMC__
#pragma aux SDLTest_BailOut aborts;
#endif
static SDL_NORETURN void SDLCALL SDLTest_BailOut(void)
static Uint32 SDLCALL SDLTest_BailOut(void *userdata, SDL_TimerID timerID, Uint32 interval)
{
SDLTest_LogError("TestCaseTimeout timer expired. Aborting test run.");
exit(TEST_ABORTED); /* bail out from the test */
return 0;
}
/**
@@ -231,19 +229,20 @@ static SDL_NORETURN void SDLCALL SDLTest_BailOut(void)
*
* \returns Test case result.
*/
static int SDLTest_RunTest(SDLTest_TestSuiteReference *testSuite, const SDLTest_TestCaseReference *testCase, Uint64 execKey, SDL_bool forceTestRun)
static int SDLTest_RunTest(SDLTest_TestSuiteReference *testSuite, const SDLTest_TestCaseReference *testCase, Uint64 execKey, bool forceTestRun)
{
SDL_TimerID timer = 0;
int testCaseResult = 0;
int testResult = 0;
int fuzzerCount;
void *data = NULL;
if (!testSuite || !testCase || !testSuite->name || !testCase->name) {
SDLTest_LogError("Setup failure: testSuite or testCase references NULL");
return TEST_RESULT_SETUP_FAILURE;
}
if (!testCase->enabled && forceTestRun == SDL_FALSE) {
if (!testCase->enabled && forceTestRun == false) {
SDLTest_Log(SDLTEST_FINAL_RESULT_FORMAT, "Test", testCase->name, "Skipped (Disabled)");
return TEST_RESULT_SKIPPED;
}
@@ -259,7 +258,7 @@ static int SDLTest_RunTest(SDLTest_TestSuiteReference *testSuite, const SDLTest_
/* Maybe run suite initializer function */
if (testSuite->testSetUp) {
testSuite->testSetUp(0x0);
testSuite->testSetUp(&data);
if (SDLTest_AssertSummaryToTestResult() == TEST_RESULT_FAILED) {
SDLTest_LogError(SDLTEST_FINAL_RESULT_FORMAT, "Suite Setup", testSuite->name, COLOR_RED "Failed" COLOR_END);
return TEST_RESULT_SETUP_FAILURE;
@@ -267,7 +266,7 @@ static int SDLTest_RunTest(SDLTest_TestSuiteReference *testSuite, const SDLTest_
}
/* Run test case function */
testCaseResult = testCase->testCase(0x0);
testCaseResult = testCase->testCase(data);
/* Convert test execution result into harness result */
if (testCaseResult == TEST_SKIPPED) {
@@ -286,7 +285,7 @@ static int SDLTest_RunTest(SDLTest_TestSuiteReference *testSuite, const SDLTest_
/* Maybe run suite cleanup function (ignore failed asserts) */
if (testSuite->testTearDown) {
testSuite->testTearDown(0x0);
testSuite->testTearDown(data);
}
/* Cancel timeout timer */
@@ -360,16 +359,11 @@ static float GetClock(void)
* The filter string is matched to the suite name (full comparison) to select a single suite,
* or if no suite matches, it is matched to the test names (full comparison) to select a single test.
*
* \param testSuites Suites containing the test case.
* \param userRunSeed Custom run seed provided by user, or NULL to autogenerate one.
* \param userExecKey Custom execution key provided by user, or 0 to autogenerate one.
* \param filter Filter specification. NULL disables. Case sensitive.
* \param testIterations Number of iterations to run each test case.
* \param randomOrder allow to run suites and tests in random order when there is no filter
* \param runner The runner to execute.
*
* \returns Test run result; 0 when all tests passed, 1 if any tests failed.
*/
int SDLTest_RunSuites(SDLTest_TestSuiteReference *testSuites[], const char *userRunSeed, Uint64 userExecKey, const char *filter, int testIterations, SDL_bool randomOrder)
int SDLTest_ExecuteTestSuiteRunner(SDLTest_TestSuiteRunner *runner)
{
int totalNumberOfTests = 0;
int failedNumberOfTests = 0;
@@ -393,7 +387,7 @@ int SDLTest_RunSuites(SDLTest_TestSuiteReference *testSuites[], const char *user
const char *suiteFilterName = NULL;
int testFilter = 0;
const char *testFilterName = NULL;
SDL_bool forceTestRun = SDL_FALSE;
bool forceTestRun = false;
int testResult = 0;
int runResult = 0;
int totalTestFailedCount = 0;
@@ -410,22 +404,19 @@ int SDLTest_RunSuites(SDLTest_TestSuiteReference *testSuites[], const char *user
int *arraySuites = NULL;
/* Sanitize test iterations */
if (testIterations < 1) {
testIterations = 1;
if (runner->user.testIterations < 1) {
runner->user.testIterations = 1;
}
/* Generate run see if we don't have one already */
if (!userRunSeed || userRunSeed[0] == '\0') {
char *tmp = SDLTest_GenerateRunSeed(16);
if (!tmp) {
if (!runner->user.runSeed || runner->user.runSeed[0] == '\0') {
runSeed = SDLTest_GenerateRunSeed(generatedSeed, 16);
if (!runSeed) {
SDLTest_LogError("Generating a random seed failed");
return 2;
}
SDL_memcpy(generatedSeed, tmp, 16 + 1);
SDL_free(tmp);
runSeed = generatedSeed;
} else {
runSeed = userRunSeed;
runSeed = runner->user.runSeed;
}
/* Reset per-run counters */
@@ -441,8 +432,8 @@ int SDLTest_RunSuites(SDLTest_TestSuiteReference *testSuites[], const char *user
/* Count the total number of tests */
suiteCounter = 0;
while (testSuites[suiteCounter]) {
testSuite = testSuites[suiteCounter];
while (runner->user.testSuites[suiteCounter]) {
testSuite = runner->user.testSuites[suiteCounter];
suiteCounter++;
testCounter = 0;
while (testSuite->testCases[testCounter]) {
@@ -464,13 +455,13 @@ int SDLTest_RunSuites(SDLTest_TestSuiteReference *testSuites[], const char *user
}
/* Initialize filtering */
if (filter && filter[0] != '\0') {
if (runner->user.filter && runner->user.filter[0] != '\0') {
/* Loop over all suites to check if we have a filter match */
suiteCounter = 0;
while (testSuites[suiteCounter] && suiteFilter == 0) {
testSuite = testSuites[suiteCounter];
while (runner->user.testSuites[suiteCounter] && suiteFilter == 0) {
testSuite = runner->user.testSuites[suiteCounter];
suiteCounter++;
if (testSuite->name && SDL_strcasecmp(filter, testSuite->name) == 0) {
if (testSuite->name && SDL_strcasecmp(runner->user.filter, testSuite->name) == 0) {
/* Matched a suite name */
suiteFilter = 1;
suiteFilterName = testSuite->name;
@@ -483,7 +474,7 @@ int SDLTest_RunSuites(SDLTest_TestSuiteReference *testSuites[], const char *user
while (testSuite->testCases[testCounter] && testFilter == 0) {
testCase = testSuite->testCases[testCounter];
testCounter++;
if (testCase->name && SDL_strcasecmp(filter, testCase->name) == 0) {
if (testCase->name && SDL_strcasecmp(runner->user.filter, testCase->name) == 0) {
/* Matched a test name */
suiteFilter = 1;
suiteFilterName = testSuite->name;
@@ -496,9 +487,9 @@ int SDLTest_RunSuites(SDLTest_TestSuiteReference *testSuites[], const char *user
}
if (suiteFilter == 0 && testFilter == 0) {
SDLTest_LogError("Filter '%s' did not match any test suite/case.", filter);
for (suiteCounter = 0; testSuites[suiteCounter]; ++suiteCounter) {
testSuite = testSuites[suiteCounter];
SDLTest_LogError("Filter '%s' did not match any test suite/case.", runner->user.filter);
for (suiteCounter = 0; runner->user.testSuites[suiteCounter]; ++suiteCounter) {
testSuite = runner->user.testSuites[suiteCounter];
if (testSuite->name) {
SDLTest_Log("Test suite: %s", testSuite->name);
}
@@ -514,11 +505,11 @@ int SDLTest_RunSuites(SDLTest_TestSuiteReference *testSuites[], const char *user
return 2;
}
randomOrder = SDL_FALSE;
runner->user.randomOrder = false;
}
/* Number of test suites */
while (testSuites[nbSuites]) {
while (runner->user.testSuites[nbSuites]) {
nbSuites++;
}
@@ -532,11 +523,11 @@ int SDLTest_RunSuites(SDLTest_TestSuiteReference *testSuites[], const char *user
/* Mix the list of suites to run them in random order */
{
/* Exclude last test "subsystemsTestSuite" which is said to interfer with other tests */
/* Exclude last test "subsystemsTestSuite" which is said to interfere with other tests */
nbSuites--;
if (userExecKey != 0) {
execKey = userExecKey;
if (runner->user.execKey != 0) {
execKey = runner->user.execKey;
} else {
/* dummy values to have random numbers working */
execKey = SDLTest_GenerateExecKey(runSeed, "random testSuites", "initialisation", 1);
@@ -559,7 +550,7 @@ int SDLTest_RunSuites(SDLTest_TestSuiteReference *testSuites[], const char *user
* If some random value were used at initialization before the tests start, the --seed wouldn't do the same with or without randomOrder.
*/
/* Swap */
if (randomOrder) {
if (runner->user.randomOrder) {
tmp = arraySuites[b];
arraySuites[b] = arraySuites[a];
arraySuites[a] = tmp;
@@ -573,7 +564,7 @@ int SDLTest_RunSuites(SDLTest_TestSuiteReference *testSuites[], const char *user
/* Loop over all suites */
for (i = 0; i < nbSuites; i++) {
suiteCounter = arraySuites[i];
testSuite = testSuites[suiteCounter];
testSuite = runner->user.testSuites[suiteCounter];
currentSuiteName = (testSuite->name ? testSuite->name : SDLTEST_INVALID_NAME_FORMAT);
suiteCounter++;
@@ -610,7 +601,7 @@ int SDLTest_RunSuites(SDLTest_TestSuiteReference *testSuites[], const char *user
b = SDLTest_RandomIntegerInRange(0, nbTestCases - 1);
/* Swap */
/* See previous note */
if (randomOrder) {
if (runner->user.randomOrder) {
tmp = arrayTestCases[b];
arrayTestCases[b] = arrayTestCases[a];
arrayTestCases[a] = tmp;
@@ -649,7 +640,7 @@ int SDLTest_RunSuites(SDLTest_TestSuiteReference *testSuites[], const char *user
/* Override 'disabled' flag if we specified a test filter (i.e. force run for debugging) */
if (testFilter == 1 && !testCase->enabled) {
SDLTest_Log("Force run of disabled test since test filter was set");
forceTestRun = SDL_TRUE;
forceTestRun = true;
}
/* Take time - test start */
@@ -667,11 +658,11 @@ int SDLTest_RunSuites(SDLTest_TestSuiteReference *testSuites[], const char *user
/* Loop over all iterations */
iterationCounter = 0;
while (iterationCounter < testIterations) {
while (iterationCounter < runner->user.testIterations) {
iterationCounter++;
if (userExecKey != 0) {
execKey = userExecKey;
if (runner->user.execKey != 0) {
execKey = runner->user.execKey;
} else {
execKey = SDLTest_GenerateExecKey(runSeed, testSuite->name, testCase->name, iterationCounter);
}
@@ -698,10 +689,10 @@ int SDLTest_RunSuites(SDLTest_TestSuiteReference *testSuites[], const char *user
runtime = 0.0f;
}
if (testIterations > 1) {
if (runner->user.testIterations > 1) {
/* Log test runtime */
SDLTest_Log("Runtime of %i iterations: %.1f sec", testIterations, runtime);
SDLTest_Log("Average Test runtime: %.5f sec", runtime / (float)testIterations);
SDLTest_Log("Runtime of %i iterations: %.1f sec", runner->user.testIterations, runtime);
SDLTest_Log("Average Test runtime: %.5f sec", runtime / (float)runner->user.testIterations);
} else {
/* Log test runtime */
SDLTest_Log("Total Test runtime: %.1f sec", runtime);
@@ -788,3 +779,83 @@ int SDLTest_RunSuites(SDLTest_TestSuiteReference *testSuites[], const char *user
SDLTest_Log("Exit code: %d", runResult);
return runResult;
}
static int SDLCALL SDLTest_TestSuiteCommonArg(void *data, char **argv, int index)
{
SDLTest_TestSuiteRunner *runner = data;
if (SDL_strcasecmp(argv[index], "--iterations") == 0) {
if (argv[index + 1]) {
runner->user.testIterations = SDL_atoi(argv[index + 1]);
if (runner->user.testIterations < 1) {
runner->user.testIterations = 1;
}
return 2;
}
}
else if (SDL_strcasecmp(argv[index], "--execKey") == 0) {
if (argv[index + 1]) {
(void)SDL_sscanf(argv[index + 1], "%" SDL_PRIu64, &runner->user.execKey);
return 2;
}
}
else if (SDL_strcasecmp(argv[index], "--seed") == 0) {
if (argv[index + 1]) {
runner->user.runSeed = SDL_strdup(argv[index + 1]);
return 2;
}
}
else if (SDL_strcasecmp(argv[index], "--filter") == 0) {
if (argv[index + 1]) {
runner->user.filter = SDL_strdup(argv[index + 1]);
return 2;
}
}
else if (SDL_strcasecmp(argv[index], "--random-order") == 0) {
runner->user.randomOrder = true;
return 1;
}
return 0;
}
SDLTest_TestSuiteRunner *SDLTest_CreateTestSuiteRunner(SDLTest_CommonState *state, SDLTest_TestSuiteReference *testSuites[])
{
SDLTest_TestSuiteRunner *runner;
SDLTest_ArgumentParser *argparser;
if (!state) {
SDLTest_LogError("SDL Test Suites require a common state");
return NULL;
}
runner = SDL_calloc(1, sizeof(SDLTest_TestSuiteRunner));
if (!runner) {
SDLTest_LogError("Failed to allocate memory for test suite runner");
return NULL;
}
runner->user.testSuites = testSuites;
runner->argparser.parse_arguments = SDLTest_TestSuiteCommonArg;
runner->argparser.usage = common_harness_usage;
runner->argparser.data = runner;
/* Find last argument description and append our description */
argparser = state->argparser;
for (;;) {
if (argparser->next == NULL) {
argparser->next = &runner->argparser;
break;
}
argparser = argparser->next;
}
return runner;
}
void SDLTest_DestroyTestSuiteRunner(SDLTest_TestSuiteRunner *runner) {
SDL_free(runner->user.filter);
SDL_free(runner->user.runSeed);
SDL_free(runner);
}

View File

@@ -109,3 +109,103 @@ void SDLTest_LogError(SDL_PRINTF_FORMAT_STRING const char *fmt, ...)
/* Log with timestamp and newline */
SDL_LogMessage(SDL_LOG_CATEGORY_TEST, SDL_LOG_PRIORITY_ERROR, "%s: %s", SDLTest_TimestampToString(time(0)), logMessage);
}
static char nibble_to_char(Uint8 nibble)
{
if (nibble < 0xa) {
return '0' + nibble;
} else {
return 'a' + nibble - 10;
}
}
void SDLTest_LogEscapedString(const char *prefix, const void *buffer, size_t size)
{
const Uint8 *data = buffer;
char logMessage[SDLTEST_MAX_LOGMESSAGE_LENGTH];
if (data) {
size_t i;
size_t pos = 0;
#define NEED_X_CHARS(N) \
if (pos + (N) > sizeof(logMessage) - 2) { \
break; \
}
logMessage[pos++] = '"';
for (i = 0; i < size; i++) {
Uint8 c = data[i];
size_t pos_start = pos;
switch (c) {
case '\0':
NEED_X_CHARS(2);
logMessage[pos++] = '\\';
logMessage[pos++] = '0';
break;
case '"':
NEED_X_CHARS(2);
logMessage[pos++] = '\\';
logMessage[pos++] = '"';
break;
case '\n':
NEED_X_CHARS(2);
logMessage[pos++] = '\\';
logMessage[pos++] = 'n';
break;
case '\r':
NEED_X_CHARS(2);
logMessage[pos++] = '\\';
logMessage[pos++] = 'r';
break;
case '\t':
NEED_X_CHARS(2);
logMessage[pos++] = '\\';
logMessage[pos++] = 't';
break;
case '\f':
NEED_X_CHARS(2);
logMessage[pos++] = '\\';
logMessage[pos++] = 'f';
break;
case '\b':
NEED_X_CHARS(2);
logMessage[pos++] = '\\';
logMessage[pos++] = 'b';
break;
case '\\':
NEED_X_CHARS(2);
logMessage[pos++] = '\\';
logMessage[pos++] = '\\';
break;
default:
if (SDL_isprint(c)) {
NEED_X_CHARS(1);
logMessage[pos++] = c;
} else {
NEED_X_CHARS(4);
logMessage[pos++] = '\\';
logMessage[pos++] = 'x';
logMessage[pos++] = nibble_to_char(c >> 4);
logMessage[pos++] = nibble_to_char(c & 0xf);
}
break;
}
if (pos == pos_start) {
break;
}
}
if (i < size) {
logMessage[sizeof(logMessage) - 4] = '.';
logMessage[sizeof(logMessage) - 3] = '.';
logMessage[sizeof(logMessage) - 2] = '.';
logMessage[sizeof(logMessage) - 1] = '\0';
} else {
logMessage[pos++] = '"';
logMessage[pos] = '\0';
}
} else {
SDL_strlcpy(logMessage, "(nil)", sizeof(logMessage));
}
SDLTest_Log("%s%s", prefix, logMessage);
}

View File

@@ -25,7 +25,7 @@
#include <libunwind.h>
#ifndef unw_get_proc_name_by_ip
#define SDLTEST_UNWIND_NO_PROC_NAME_BY_IP
static SDL_bool s_unwind_symbol_names = SDL_TRUE;
static bool s_unwind_symbol_names = true;
#endif
#endif
@@ -73,17 +73,17 @@ static SDL_realloc_func SDL_realloc_orig = NULL;
static SDL_free_func SDL_free_orig = NULL;
static int s_previous_allocations = 0;
static SDL_tracked_allocation *s_tracked_allocations[256];
static SDL_bool s_randfill_allocations = SDL_FALSE;
static bool s_randfill_allocations = false;
static SDL_AtomicInt s_lock;
#define LOCK_ALLOCATOR() \
do { \
if (SDL_AtomicCompareAndSwap(&s_lock, 0, 1)) { \
if (SDL_CompareAndSwapAtomicInt(&s_lock, 0, 1)) { \
break; \
} \
SDL_CPUPauseInstruction(); \
} while (SDL_TRUE)
#define UNLOCK_ALLOCATOR() do { SDL_AtomicSet(&s_lock, 0); } while (0)
} while (true)
#define UNLOCK_ALLOCATOR() do { SDL_SetAtomicInt(&s_lock, 0); } while (0)
static unsigned int get_allocation_bucket(void *mem)
{
@@ -116,7 +116,7 @@ static size_t SDL_GetTrackedAllocationSize(void *mem)
return entry ? entry->size : SIZE_MAX;
}
static SDL_bool SDL_IsAllocationTracked(void *mem)
static bool SDL_IsAllocationTracked(void *mem)
{
return SDL_GetTrackedAllocation(mem) != NULL;
}
@@ -299,12 +299,12 @@ void SDLTest_TrackAllocations(void)
#ifdef SDLTEST_UNWIND_NO_PROC_NAME_BY_IP
do {
/* Don't use SDL_GetHint: SDL_malloc is off limits. */
const char *env_trackmem = SDL_getenv("SDL_TRACKMEM_SYMBOL_NAMES");
const char *env_trackmem = SDL_getenv_unsafe("SDL_TRACKMEM_SYMBOL_NAMES");
if (env_trackmem) {
if (SDL_strcasecmp(env_trackmem, "1") == 0 || SDL_strcasecmp(env_trackmem, "yes") == 0 || SDL_strcasecmp(env_trackmem, "true") == 0) {
s_unwind_symbol_names = SDL_TRUE;
s_unwind_symbol_names = true;
} else if (SDL_strcasecmp(env_trackmem, "0") == 0 || SDL_strcasecmp(env_trackmem, "no") == 0 || SDL_strcasecmp(env_trackmem, "false") == 0) {
s_unwind_symbol_names = SDL_FALSE;
s_unwind_symbol_names = false;
}
}
} while (0);
@@ -348,7 +348,7 @@ void SDLTest_RandFillAllocations(void)
{
SDLTest_TrackAllocations();
s_randfill_allocations = SDL_TRUE;
s_randfill_allocations = true;
}
void SDLTest_LogAllocations(void)