/* Prints summary of all suites/tests contained in the given reference */ void SDLTest_LogTestSuiteSummary(SDLTest_TestSuiteReference *testSuites) { int suiteCounter; int testCounter; SDLTest_TestSuiteReference *testSuite; SDLTest_TestCaseReference *testCase; /* Loop over all suites */ suiteCounter = 0; while(&testSuites[suiteCounter]) { testSuite=&testSuites[suiteCounter]; suiteCounter++; SDLTest_Log("Test Suite %i - %s\n", suiteCounter, (testSuite->name) ? testSuite->name : SDLTest_InvalidNameFormat); /* Loop over all test cases */ testCounter = 0; while(testSuite->testCases[testCounter]) { testCase=(SDLTest_TestCaseReference *)testSuite->testCases[testCounter]; testCounter++; SDLTest_Log(" Test Case %i - %s: %s", testCounter, (testCase->name) ? testCase->name : SDLTest_InvalidNameFormat, (testCase->description) ? testCase->description : SDLTest_InvalidNameFormat); } } }
static void SDLTest_LogTestSuiteSummary(SDLTest_TestSuiteReference *testSuites) { int suiteCounter; int testCounter; SDLTest_TestSuiteReference *testSuite; SDLTest_TestCaseReference *testCase; /* Loop over all suites */ suiteCounter = 0; while(&testSuites[suiteCounter]) { testSuite=&testSuites[suiteCounter]; suiteCounter++; SDLTest_Log("Test Suite %i - %s\n", suiteCounter, (testSuite->name) ? testSuite->name : SDLTEST_INVALID_NAME_FORMAT); /* Loop over all test cases */ testCounter = 0; while(testSuite->testCases[testCounter]) { testCase=(SDLTest_TestCaseReference *)testSuite->testCases[testCounter]; testCounter++; SDLTest_Log(" Test Case %i - %s: %s", testCounter, (testCase->name) ? testCase->name : SDLTEST_INVALID_NAME_FORMAT, (testCase->description) ? testCase->description : SDLTEST_INVALID_NAME_FORMAT); } } }
/** * \brief Locks and unlocks open audio device. * * \sa https://wiki.libsdl.org/SDL_LockAudioDevice * \sa https://wiki.libsdl.org/SDL_UnlockAudioDevice */ int audio_lockUnlockOpenAudioDevice() { int i; int count; char *device; SDL_AudioDeviceID id; SDL_AudioSpec desired, obtained; /* Get number of devices. */ count = SDL_GetNumAudioDevices(0); SDLTest_AssertPass("Call to SDL_GetNumAudioDevices(0)"); if (count > 0) { for (i = 0; i < count; i++) { /* Get device name */ device = (char *)SDL_GetAudioDeviceName(i, 0); SDLTest_AssertPass("SDL_GetAudioDeviceName(%i,0)", i); SDLTest_AssertCheck(device != NULL, "Validate device name is not NULL; got: %s", (device != NULL) ? device : "NULL"); if (device == NULL) return TEST_ABORTED; /* Set standard desired spec */ desired.freq=22050; desired.format=AUDIO_S16SYS; desired.channels=2; desired.samples=4096; desired.callback=_audio_testCallback; desired.userdata=NULL; /* Open device */ id = SDL_OpenAudioDevice((const char *)device, 0, &desired, &obtained, SDL_AUDIO_ALLOW_ANY_CHANGE); SDLTest_AssertPass("SDL_OpenAudioDevice('%s',...)", device); SDLTest_AssertCheck(id > 1, "Validate device ID; expected: >=2, got: %i", id); if (id > 1) { /* Lock to protect callback */ SDL_LockAudioDevice(id); SDLTest_AssertPass("SDL_LockAudioDevice(%i)", id); /* Simulate callback processing */ SDL_Delay(10); SDLTest_Log("Simulate callback processing - delay"); /* Unlock again */ SDL_UnlockAudioDevice(id); SDLTest_AssertPass("SDL_UnlockAudioDevice(%i)", id); /* Close device again */ SDL_CloseAudioDevice(id); SDLTest_AssertPass("Call to SDL_CloseAudioDevice()"); } } } else { SDLTest_Log("No devices to test with"); } return TEST_COMPLETED; }
/** * @brief Call to SDL_GetWindowWMInfo */ int syswm_getWindowWMInfo(void *arg) { SDL_bool result; SDL_Window *window; SDL_SysWMinfo info; window = SDL_CreateWindow("", 0, 0, 0, 0, SDL_WINDOW_HIDDEN); SDLTest_AssertPass("Call to SDL_CreateWindow()"); SDLTest_AssertCheck(window != NULL, "Check that value returned from SDL_CreateWindow is not NULL"); if (window == NULL) { return TEST_ABORTED; } /* Initialize info structure with SDL version info */ SDL_VERSION(&info.version); /* Make call */ result = SDL_GetWindowWMInfo(window, &info); SDLTest_AssertPass("Call to SDL_GetWindowWMInfo"); SDLTest_Log((result == SDL_TRUE) ? "Got window information" : "Couldn't get window information"); SDL_DestroyWindow(window); SDLTest_AssertPass("Call to SDL_DestroyWindow()"); return TEST_COMPLETED; }
/* * Assert that logs but does not break execution flow on failures (i.e. for test cases). */ int SDLTest_AssertCheck(int assertCondition, const char *assertDescription, ...) { va_list list; char logMessage[SDLTEST_MAX_LOGMESSAGE_LENGTH]; /* Print assert description into a buffer */ SDL_memset(logMessage, 0, SDLTEST_MAX_LOGMESSAGE_LENGTH); va_start(list, assertDescription); SDL_vsnprintf(logMessage, SDLTEST_MAX_LOGMESSAGE_LENGTH - 1, assertDescription, list); va_end(list); /* Log pass or fail message */ if (assertCondition == ASSERT_FAIL) { SDLTest_AssertsFailed++; SDLTest_LogError(SDLTest_AssertCheckFormat, logMessage, "Failed"); } else { SDLTest_AssertsPassed++; SDLTest_Log(SDLTest_AssertCheckFormat, logMessage, "Passed"); } return assertCondition; }
/** * \brief Opens, checks current connected status, and closes a device. * * \sa https://wiki.libsdl.org/SDL_AudioDeviceConnected */ int audio_openCloseAudioDeviceConnected() { int result = -1; int i; int count; char *device; SDL_AudioDeviceID id; SDL_AudioSpec desired, obtained; /* Get number of devices. */ count = SDL_GetNumAudioDevices(0); SDLTest_AssertPass("Call to SDL_GetNumAudioDevices(0)"); if (count > 0) { for (i = 0; i < count; i++) { /* Get device name */ device = (char *)SDL_GetAudioDeviceName(i, 0); SDLTest_AssertPass("SDL_GetAudioDeviceName(%i,0)", i); SDLTest_AssertCheck(device != NULL, "Validate device name is not NULL; got: %s", (device != NULL) ? device : "NULL"); if (device == NULL) return TEST_ABORTED; /* Set standard desired spec */ desired.freq=22050; desired.format=AUDIO_S16SYS; desired.channels=2; desired.samples=4096; desired.callback=_audio_testCallback; desired.userdata=NULL; /* Open device */ id = SDL_OpenAudioDevice((const char *)device, 0, &desired, &obtained, SDL_AUDIO_ALLOW_ANY_CHANGE); SDLTest_AssertPass("SDL_OpenAudioDevice('%s',...)", device); SDLTest_AssertCheck(id > 1, "Validate device ID; expected: >1, got: %i", id); if (id > 1) { /* TODO: enable test code when function is available in SDL2 */ #ifdef AUDIODEVICECONNECTED_DEFINED /* Get connected status */ result = SDL_AudioDeviceConnected(id); SDLTest_AssertPass("Call to SDL_AudioDeviceConnected()"); #endif SDLTest_AssertCheck(result == 1, "Verify returned value; expected: 1; got: %i", result); /* Close device again */ SDL_CloseAudioDevice(id); SDLTest_AssertPass("Call to SDL_CloseAudioDevice()"); } } } else { SDLTest_Log("No devices to test with"); } return TEST_COMPLETED; }
/* * Logs summary of all assertions (total, pass, fail) since last reset * as INFO (failed==0) or ERROR (failed > 0). */ void SDLTest_LogAssertSummary() { Uint32 totalAsserts = SDLTest_AssertsPassed + SDLTest_AssertsFailed; if (SDLTest_AssertsFailed == 0) { SDLTest_Log(SDLTEST_ASSERT_SUMMARY_FORMAT, totalAsserts, SDLTest_AssertsPassed, SDLTest_AssertsFailed); } else { SDLTest_LogError(SDLTEST_ASSERT_SUMMARY_FORMAT, totalAsserts, SDLTest_AssertsPassed, SDLTest_AssertsFailed); } }
/* * Logs summary of all assertions (total, pass, fail) since last reset * as INFO (failed==0) or ERROR (failed > 0). */ void SDLTest_LogAssertSummary() { Uint32 totalAsserts = SDLTest_AssertsPassed + SDLTest_AssertsFailed; if (SDLTest_AssertsFailed == 0) { SDLTest_Log(SDLTest_AssertSummaryFormat, totalAsserts, SDLTest_AssertsPassed, SDLTest_AssertsFailed); } else { SDLTest_LogError(SDLTest_AssertSummaryFormat, totalAsserts, SDLTest_AssertsPassed, SDLTest_AssertsFailed); } }
/** * \brief Opens, checks current audio status, and closes a device. * * \sa https://wiki.libsdl.org/SDL_GetAudioStatus */ int audio_openCloseAndGetAudioStatus() { SDL_AudioStatus result; int i; int count; char *device; SDL_AudioDeviceID id; SDL_AudioSpec desired, obtained; /* Get number of devices. */ count = SDL_GetNumAudioDevices(0); SDLTest_AssertPass("Call to SDL_GetNumAudioDevices(0)"); if (count > 0) { for (i = 0; i < count; i++) { /* Get device name */ device = (char *)SDL_GetAudioDeviceName(i, 0); SDLTest_AssertPass("SDL_GetAudioDeviceName(%i,0)", i); SDLTest_AssertCheck(device != NULL, "Validate device name is not NULL; got: %s", (device != NULL) ? device : "NULL"); if (device == NULL) return TEST_ABORTED; /* Set standard desired spec */ desired.freq=22050; desired.format=AUDIO_S16SYS; desired.channels=2; desired.samples=4096; desired.callback=_audio_testCallback; desired.userdata=NULL; /* Open device */ id = SDL_OpenAudioDevice((const char *)device, 0, &desired, &obtained, SDL_AUDIO_ALLOW_ANY_CHANGE); SDLTest_AssertPass("SDL_OpenAudioDevice('%s',...)", device); SDLTest_AssertCheck(id > 1, "Validate device ID; expected: >=2, got: %i", id); if (id > 1) { /* Check device audio status */ result = SDL_GetAudioDeviceStatus(id); SDLTest_AssertPass("Call to SDL_GetAudioDeviceStatus()"); SDLTest_AssertCheck(result == SDL_AUDIO_STOPPED || result == SDL_AUDIO_PLAYING || result == SDL_AUDIO_PAUSED, "Verify returned value; expected: STOPPED (%i) | PLAYING (%i) | PAUSED (%i), got: %i", SDL_AUDIO_STOPPED, SDL_AUDIO_PLAYING, SDL_AUDIO_PAUSED, result); /* Close device again */ SDL_CloseAudioDevice(id); SDLTest_AssertPass("Call to SDL_CloseAudioDevice()"); } } } else { SDLTest_Log("No devices to test with"); } return TEST_COMPLETED; }
/** * \brief Enumerate and name available audio devices (output and capture). * * \sa https://wiki.libsdl.org/SDL_GetNumAudioDevices * \sa https://wiki.libsdl.org/SDL_GetAudioDeviceName */ int audio_enumerateAndNameAudioDevices() { int t, tt; int i, n, nn; const char *name, *nameAgain; /* Iterate over types: t=0 output device, t=1 input/capture device */ for (t=0; t<2; t++) { /* Get number of devices. */ n = SDL_GetNumAudioDevices(t); SDLTest_AssertPass("Call to SDL_GetNumAudioDevices(%i)", t); SDLTest_Log("Number of %s devices < 0, reported as %i", (t) ? "capture" : "output", n); SDLTest_AssertCheck(n >= 0, "Validate result is >= 0, got: %i", n); /* Variation of non-zero type */ if (t==1) { tt = t + SDLTest_RandomIntegerInRange(1,10); nn = SDL_GetNumAudioDevices(tt); SDLTest_AssertCheck(n==nn, "Verify result from SDL_GetNumAudioDevices(%i), expected same number of audio devices %i, got %i", tt, n, nn); nn = SDL_GetNumAudioDevices(-tt); SDLTest_AssertCheck(n==nn, "Verify result from SDL_GetNumAudioDevices(%i), expected same number of audio devices %i, got %i", -tt, n, nn); } /* List devices. */ if (n>0) { for (i=0; i<n; i++) { name = SDL_GetAudioDeviceName(i, t); SDLTest_AssertPass("Call to SDL_GetAudioDeviceName(%i, %i)", i, t); SDLTest_AssertCheck(name != NULL, "Verify result from SDL_GetAudioDeviceName(%i, %i) is not NULL", i, t); if (name != NULL) { SDLTest_AssertCheck(name[0] != '\0', "verify result from SDL_GetAudioDeviceName(%i, %i) is not empty, got: '%s'", i, t, name); if (t==1) { /* Also try non-zero type */ tt = t + SDLTest_RandomIntegerInRange(1,10); nameAgain = SDL_GetAudioDeviceName(i, tt); SDLTest_AssertCheck(nameAgain != NULL, "Verify result from SDL_GetAudioDeviceName(%i, %i) is not NULL", i, tt); if (nameAgain != NULL) { SDLTest_AssertCheck(nameAgain[0] != '\0', "Verify result from SDL_GetAudioDeviceName(%i, %i) is not empty, got: '%s'", i, tt, nameAgain); SDLTest_AssertCheck(SDL_strcmp(name, nameAgain)==0, "Verify SDL_GetAudioDeviceName(%i, %i) and SDL_GetAudioDeviceName(%i %i) return the same string", i, t, i, tt); } } } } } } return TEST_COMPLETED; }
/* * Explicitly passing Assert that logs (i.e. for test cases). */ void SDLTest_AssertPass(const char *assertDescription, ...) { va_list list; char logMessage[SDLTEST_MAX_LOGMESSAGE_LENGTH]; /* Print assert description into a buffer */ SDL_memset(logMessage, 0, SDLTEST_MAX_LOGMESSAGE_LENGTH); va_start(list, assertDescription); SDL_vsnprintf(logMessage, SDLTEST_MAX_LOGMESSAGE_LENGTH - 1, assertDescription, list); va_end(list); /* Log pass message */ SDLTest_AssertsPassed++; SDLTest_Log(SDLTest_AssertCheckFormat, logMessage, "Pass"); }
/** * \brief Execute a test using the given execution key. * * \param testSuite Suite containing the test case. * \param testCase Case to execute. * \param execKey Execution key for the fuzzer. * * \returns Test case result. */ int SDLTest_RunTest(SDLTest_TestSuiteReference *testSuite, SDLTest_TestCaseReference *testCase, Uint64 execKey) { SDL_TimerID timer = 0; int testCaseResult = 0; int testResult = 0; int fuzzerCount; if (testSuite==NULL || testCase==NULL || testSuite->name==NULL || testCase->name==NULL) { SDLTest_LogError("Setup failure: testSuite or testCase references NULL"); return TEST_RESULT_SETUP_FAILURE; } if (!testCase->enabled) { SDLTest_Log((char *)SDLTest_FinalResultFormat, "Test", testCase->name, "Skipped (Disabled)"); return TEST_RESULT_SKIPPED; } /* Initialize fuzzer */ SDLTest_FuzzerInit(execKey); /* Reset assert tracker */ SDLTest_ResetAssertSummary(); /* Set timeout timer */ timer = SDLTest_SetTestTimeout(SDLTest_TestCaseTimeout, SDLTest_BailOut); /* Maybe run suite initalizer function */ if (testSuite->testSetUp) { testSuite->testSetUp(0x0); if (SDLTest_AssertSummaryToTestResult() == TEST_RESULT_FAILED) { SDLTest_LogError((char *)SDLTest_FinalResultFormat, "Suite Setup", testSuite->name, "Failed"); return TEST_RESULT_SETUP_FAILURE; } } /* Run test case function */ testCaseResult = testCase->testCase(0x0); /* Convert test execution result into harness result */ if (testCaseResult == TEST_SKIPPED) { /* Test was programatically skipped */ testResult = TEST_RESULT_SKIPPED; } else if (testCaseResult == TEST_STARTED) { /* Test did not return a TEST_COMPLETED value; assume it failed */ testResult = TEST_RESULT_FAILED; } else if (testCaseResult == TEST_ABORTED) { /* Test was aborted early; assume it failed */ testResult = TEST_RESULT_FAILED; } else { /* Perform failure analysis based on asserts */ testResult = SDLTest_AssertSummaryToTestResult(); } /* Maybe run suite cleanup function (ignore failed asserts) */ if (testSuite->testTearDown) { testSuite->testTearDown(0x0); } /* Cancel timeout timer */ if (timer) { SDL_RemoveTimer(timer); } /* Report on asserts and fuzzer usage */ fuzzerCount = SDLTest_GetFuzzerInvocationCount(); if (fuzzerCount > 0) { SDLTest_Log("Fuzzer invocations: %d", fuzzerCount); } /* Final log based on test execution result */ if (testCaseResult == TEST_SKIPPED) { /* Test was programatically skipped */ SDLTest_Log((char *)SDLTest_FinalResultFormat, "Test", testCase->name, "Skipped (Programmatically)"); } else if (testCaseResult == TEST_STARTED) { /* Test did not return a TEST_COMPLETED value; assume it failed */ SDLTest_LogError((char *)SDLTest_FinalResultFormat, "Test", testCase->name, "Failed (test started, but did not return TEST_COMPLETED)"); } else if (testCaseResult == TEST_ABORTED) { /* Test was aborted early; assume it failed */ SDLTest_LogError((char *)SDLTest_FinalResultFormat, "Test", testCase->name, "Failed (Aborted)"); } else { SDLTest_LogAssertSummary(); } return testResult; }
/** * \brief Execute a test suite using the given run seed and execution key. * * 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. * * \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) { int totalNumberOfTests = 0; int failedNumberOfTests = 0; int suiteCounter; int testCounter; int iterationCounter; SDLTest_TestSuiteReference *testSuite; const SDLTest_TestCaseReference *testCase; const char *runSeed = NULL; char *currentSuiteName; char *currentTestName; Uint64 execKey; float runStartSeconds; float suiteStartSeconds; float testStartSeconds; float runEndSeconds; float suiteEndSeconds; float testEndSeconds; float runtime; int suiteFilter = 0; char *suiteFilterName = NULL; int testFilter = 0; char *testFilterName = NULL; SDL_bool forceTestRun = SDL_FALSE; int testResult = 0; int runResult = 0; Uint32 totalTestFailedCount = 0; Uint32 totalTestPassedCount = 0; Uint32 totalTestSkippedCount = 0; Uint32 testFailedCount = 0; Uint32 testPassedCount = 0; Uint32 testSkippedCount = 0; Uint32 countSum = 0; const SDLTest_TestCaseReference **failedTests; /* Sanitize test iterations */ if (testIterations < 1) { testIterations = 1; } /* Generate run see if we don't have one already */ if (userRunSeed == NULL || userRunSeed[0] == '\0') { runSeed = SDLTest_GenerateRunSeed(16); if (runSeed == NULL) { SDLTest_LogError("Generating a random seed failed"); return 2; } } else { runSeed = userRunSeed; } /* Reset per-run counters */ totalTestFailedCount = 0; totalTestPassedCount = 0; totalTestSkippedCount = 0; /* Take time - run start */ runStartSeconds = GetClock(); /* Log run with fuzzer parameters */ SDLTest_Log("::::: Test Run /w seed '%s' started\n", runSeed); /* Count the total number of tests */ suiteCounter = 0; while (testSuites[suiteCounter]) { testSuite=(SDLTest_TestSuiteReference *)testSuites[suiteCounter]; suiteCounter++; testCounter = 0; while (testSuite->testCases[testCounter]) { testCounter++; totalNumberOfTests++; } } /* Pre-allocate an array for tracking failed tests (potentially all test cases) */ failedTests = (const SDLTest_TestCaseReference **)SDL_malloc(totalNumberOfTests * sizeof(SDLTest_TestCaseReference *)); if (failedTests == NULL) { SDLTest_LogError("Unable to allocate cache for failed tests"); SDL_Error(SDL_ENOMEM); return -1; } /* Initialize filtering */ if (filter != NULL && filter[0] != '\0') { /* Loop over all suites to check if we have a filter match */ suiteCounter = 0; while (testSuites[suiteCounter] && suiteFilter == 0) { testSuite=(SDLTest_TestSuiteReference *)testSuites[suiteCounter]; suiteCounter++; if (testSuite->name != NULL && SDL_strcmp(filter, testSuite->name) == 0) { /* Matched a suite name */ suiteFilter = 1; suiteFilterName = testSuite->name; SDLTest_Log("Filtering: running only suite '%s'", suiteFilterName); break; } /* Within each suite, loop over all test cases to check if we have a filter match */ testCounter = 0; while (testSuite->testCases[testCounter] && testFilter == 0) { testCase = testSuite->testCases[testCounter]; testCounter++; if (testCase->name != NULL && SDL_strcmp(filter, testCase->name) == 0) { /* Matched a test name */ suiteFilter = 1; suiteFilterName = testSuite->name; testFilter = 1; testFilterName = testCase->name; SDLTest_Log("Filtering: running only test '%s' in suite '%s'", testFilterName, suiteFilterName); break; } } } if (suiteFilter == 0 && testFilter == 0) { SDLTest_LogError("Filter '%s' did not match any test suite/case.", filter); SDLTest_Log("Exit code: 2"); SDL_free((void *) failedTests); return 2; } } /* Loop over all suites */ suiteCounter = 0; while(testSuites[suiteCounter]) { testSuite=(SDLTest_TestSuiteReference *)testSuites[suiteCounter]; currentSuiteName = (char *)((testSuite->name) ? testSuite->name : SDLTEST_INVALID_NAME_FORMAT); suiteCounter++; /* Filter suite if flag set and we have a name */ if (suiteFilter == 1 && suiteFilterName != NULL && testSuite->name != NULL && SDL_strcmp(suiteFilterName, testSuite->name) != 0) { /* Skip suite */ SDLTest_Log("===== Test Suite %i: '%s' skipped\n", suiteCounter, currentSuiteName); } else { /* Reset per-suite counters */ testFailedCount = 0; testPassedCount = 0; testSkippedCount = 0; /* Take time - suite start */ suiteStartSeconds = GetClock(); /* Log suite started */ SDLTest_Log("===== Test Suite %i: '%s' started\n", suiteCounter, currentSuiteName); /* Loop over all test cases */ testCounter = 0; while(testSuite->testCases[testCounter]) { testCase = testSuite->testCases[testCounter]; currentTestName = (char *)((testCase->name) ? testCase->name : SDLTEST_INVALID_NAME_FORMAT); testCounter++; /* Filter tests if flag set and we have a name */ if (testFilter == 1 && testFilterName != NULL && testCase->name != NULL && SDL_strcmp(testFilterName, testCase->name) != 0) { /* Skip test */ SDLTest_Log("===== Test Case %i.%i: '%s' skipped\n", suiteCounter, testCounter, currentTestName); } else { /* 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; } /* Take time - test start */ testStartSeconds = GetClock(); /* Log test started */ SDLTest_Log("----- Test Case %i.%i: '%s' started", suiteCounter, testCounter, currentTestName); if (testCase->description != NULL && testCase->description[0] != '\0') { SDLTest_Log("Test Description: '%s'", (testCase->description) ? testCase->description : SDLTEST_INVALID_NAME_FORMAT); } /* Loop over all iterations */ iterationCounter = 0; while(iterationCounter < testIterations) { iterationCounter++; if (userExecKey != 0) { execKey = userExecKey; } else { execKey = SDLTest_GenerateExecKey(runSeed, testSuite->name, testCase->name, iterationCounter); } SDLTest_Log("Test Iteration %i: execKey %" SDL_PRIu64, iterationCounter, execKey); testResult = SDLTest_RunTest(testSuite, testCase, execKey, forceTestRun); if (testResult == TEST_RESULT_PASSED) { testPassedCount++; totalTestPassedCount++; } else if (testResult == TEST_RESULT_SKIPPED) { testSkippedCount++; totalTestSkippedCount++; } else { testFailedCount++; totalTestFailedCount++; } } /* Take time - test end */ testEndSeconds = GetClock(); runtime = testEndSeconds - testStartSeconds; if (runtime < 0.0f) runtime = 0.0f; if (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); } else { /* Log test runtime */ SDLTest_Log("Total Test runtime: %.1f sec", runtime); } /* Log final test result */ switch (testResult) { case TEST_RESULT_PASSED: SDLTest_Log(SDLTEST_FINAL_RESULT_FORMAT, "Test", currentTestName, "Passed"); break; case TEST_RESULT_FAILED: SDLTest_LogError(SDLTEST_FINAL_RESULT_FORMAT, "Test", currentTestName, "Failed"); break; case TEST_RESULT_NO_ASSERT: SDLTest_LogError(SDLTEST_FINAL_RESULT_FORMAT,"Test", currentTestName, "No Asserts"); break; } /* Collect failed test case references for repro-step display */ if (testResult == TEST_RESULT_FAILED) { failedTests[failedNumberOfTests] = testCase; failedNumberOfTests++; } } } /* Take time - suite end */ suiteEndSeconds = GetClock(); runtime = suiteEndSeconds - suiteStartSeconds; if (runtime < 0.0f) runtime = 0.0f; /* Log suite runtime */ SDLTest_Log("Total Suite runtime: %.1f sec", runtime); /* Log summary and final Suite result */ countSum = testPassedCount + testFailedCount + testSkippedCount; if (testFailedCount == 0) { SDLTest_Log(SDLTEST_LOG_SUMMARY_FORMAT, "Suite", countSum, testPassedCount, testFailedCount, testSkippedCount); SDLTest_Log(SDLTEST_FINAL_RESULT_FORMAT, "Suite", currentSuiteName, "Passed"); } else { SDLTest_LogError(SDLTEST_LOG_SUMMARY_FORMAT, "Suite", countSum, testPassedCount, testFailedCount, testSkippedCount); SDLTest_LogError(SDLTEST_FINAL_RESULT_FORMAT, "Suite", currentSuiteName, "Failed"); } } } /* Take time - run end */ runEndSeconds = GetClock(); runtime = runEndSeconds - runStartSeconds; if (runtime < 0.0f) runtime = 0.0f; /* Log total runtime */ SDLTest_Log("Total Run runtime: %.1f sec", runtime); /* Log summary and final run result */ countSum = totalTestPassedCount + totalTestFailedCount + totalTestSkippedCount; if (totalTestFailedCount == 0) { runResult = 0; SDLTest_Log(SDLTEST_LOG_SUMMARY_FORMAT, "Run", countSum, totalTestPassedCount, totalTestFailedCount, totalTestSkippedCount); SDLTest_Log(SDLTEST_FINAL_RESULT_FORMAT, "Run /w seed", runSeed, "Passed"); } else { runResult = 1; SDLTest_LogError(SDLTEST_LOG_SUMMARY_FORMAT, "Run", countSum, totalTestPassedCount, totalTestFailedCount, totalTestSkippedCount); SDLTest_LogError(SDLTEST_FINAL_RESULT_FORMAT, "Run /w seed", runSeed, "Failed"); } /* Print repro steps for failed tests */ if (failedNumberOfTests > 0) { SDLTest_Log("Harness input to repro failures:"); for (testCounter = 0; testCounter < failedNumberOfTests; testCounter++) { SDLTest_Log(" --seed %s --filter %s", runSeed, failedTests[testCounter]->name); } } SDL_free((void *) failedTests); SDLTest_Log("Exit code: %d", runResult); return runResult; }
/** * \brief Pause and unpause audio * * \sa https://wiki.libsdl.org/SDL_PauseAudio */ int audio_pauseUnpauseAudio() { int result; int i, iMax, j, k, l; int totalDelay; int pause_on; int originalCounter; const char* audioDriver; SDL_AudioSpec desired; /* Stop SDL audio subsystem */ SDL_QuitSubSystem( SDL_INIT_AUDIO ); SDLTest_AssertPass("Call to SDL_QuitSubSystem(SDL_INIT_AUDIO)"); /* Loop over all available audio drivers */ iMax = SDL_GetNumAudioDrivers(); SDLTest_AssertPass("Call to SDL_GetNumAudioDrivers()"); SDLTest_AssertCheck(iMax > 0, "Validate number of audio drivers; expected: >0 got: %d", iMax); for (i = 0; i < iMax; i++) { audioDriver = SDL_GetAudioDriver(i); SDLTest_AssertPass("Call to SDL_GetAudioDriver(%d)", i); SDLTest_AssertCheck(audioDriver != NULL, "Audio driver name is not NULL"); SDLTest_AssertCheck(audioDriver[0] != '\0', "Audio driver name is not empty; got: %s", audioDriver); /* Change specs */ for (j = 0; j < 2; j++) { /* Call Init */ result = SDL_AudioInit(audioDriver); SDLTest_AssertPass("Call to SDL_AudioInit('%s')", audioDriver); SDLTest_AssertCheck(result == 0, "Validate result value; expected: 0 got: %d", result); /* Set spec */ SDL_memset(&desired, 0, sizeof(desired)); switch (j) { case 0: /* Set standard desired spec */ desired.freq = 22050; desired.format = AUDIO_S16SYS; desired.channels = 2; desired.samples = 4096; desired.callback = _audio_testCallback; desired.userdata = NULL; case 1: /* Set custom desired spec */ desired.freq = 48000; desired.format = AUDIO_F32SYS; desired.channels = 2; desired.samples = 2048; desired.callback = _audio_testCallback; desired.userdata = NULL; break; } /* Call Open */ result = SDL_OpenAudio(&desired, NULL); SDLTest_AssertPass("Call to SDL_OpenAudio(desired_spec_%d, NULL)", j); SDLTest_AssertCheck(result == 0, "Verify return value; expected: 0 got: %d", result); /* Start and stop audio multiple times */ for (l=0; l<3; l++) { SDLTest_Log("Pause/Unpause iteration: %d", l+1); /* Reset callback counters */ _audio_testCallbackCounter = 0; _audio_testCallbackLength = 0; /* Un-pause audio to start playing (maybe multiple times) */ pause_on = 0; for (k=0; k <= j; k++) { SDL_PauseAudio(pause_on); SDLTest_AssertPass("Call to SDL_PauseAudio(%d), call %d", pause_on, k+1); } /* Wait for callback */ totalDelay = 0; do { SDL_Delay(10); totalDelay += 10; } while (_audio_testCallbackCounter == 0 && totalDelay < 1000); SDLTest_AssertCheck(_audio_testCallbackCounter > 0, "Verify callback counter; expected: >0 got: %d", _audio_testCallbackCounter); SDLTest_AssertCheck(_audio_testCallbackLength > 0, "Verify callback length; expected: >0 got: %d", _audio_testCallbackLength); /* Pause audio to stop playing (maybe multiple times) */ for (k=0; k <= j; k++) { pause_on = (k==0) ? 1 : SDLTest_RandomIntegerInRange(99, 9999); SDL_PauseAudio(pause_on); SDLTest_AssertPass("Call to SDL_PauseAudio(%d), call %d", pause_on, k+1); } /* Ensure callback is not called again */ originalCounter = _audio_testCallbackCounter; SDL_Delay(totalDelay + 10); SDLTest_AssertCheck(originalCounter == _audio_testCallbackCounter, "Verify callback counter; expected: %d, got: %d", originalCounter, _audio_testCallbackCounter); } /* Call Close */ SDL_CloseAudio(); SDLTest_AssertPass("Call to SDL_CloseAudio()"); /* Call Quit */ SDL_AudioQuit(); SDLTest_AssertPass("Call to SDL_AudioQuit()"); } /* spec loop */ } /* driver loop */ /* Restart audio again */ _audioSetUp(NULL); return TEST_COMPLETED; }
/** * @brief Call to SDL_GetPixelFormatName * * @sa http://wiki.libsdl.org/moin.fcg/SDL_GetPixelFormatName */ int pixels_getPixelFormatName(void *arg) { const char *unknownFormat = "SDL_PIXELFORMAT_UNKNOWN"; const char *error; int i; Uint32 format; char* result; /* Blank/undefined format */ format = 0; SDLTest_Log("RGB Format: %s (%u)", unknownFormat, format); /* Get name of format */ result = (char *)SDL_GetPixelFormatName(format); SDLTest_AssertPass("Call to SDL_GetPixelFormatName()"); SDLTest_AssertCheck(result != NULL, "Verify result is not NULL"); if (result != NULL) { SDLTest_AssertCheck(result[0] != '\0', "Verify result is non-empty"); SDLTest_AssertCheck(SDL_strcmp(result, unknownFormat) == 0, "Verify result text; expected: %s, got %s", unknownFormat, result); } /* RGB formats */ for (i = 0; i < _numRGBPixelFormats; i++) { format = _RGBPixelFormats[i]; SDLTest_Log("RGB Format: %s (%u)", _RGBPixelFormatsVerbose[i], format); /* Get name of format */ result = (char *)SDL_GetPixelFormatName(format); SDLTest_AssertPass("Call to SDL_GetPixelFormatName()"); SDLTest_AssertCheck(result != NULL, "Verify result is not NULL"); if (result != NULL) { SDLTest_AssertCheck(result[0] != '\0', "Verify result is non-empty"); SDLTest_AssertCheck(SDL_strcmp(result, _RGBPixelFormatsVerbose[i]) == 0, "Verify result text; expected: %s, got %s", _RGBPixelFormatsVerbose[i], result); } } /* Non-RGB formats */ for (i = 0; i < _numNonRGBPixelFormats; i++) { format = _nonRGBPixelFormats[i]; SDLTest_Log("non-RGB Format: %s (%u)", _nonRGBPixelFormatsVerbose[i], format); /* Get name of format */ result = (char *)SDL_GetPixelFormatName(format); SDLTest_AssertPass("Call to SDL_GetPixelFormatName()"); SDLTest_AssertCheck(result != NULL, "Verify result is not NULL"); if (result != NULL) { SDLTest_AssertCheck(result[0] != '\0', "Verify result is non-empty"); SDLTest_AssertCheck(SDL_strcmp(result, _nonRGBPixelFormatsVerbose[i]) == 0, "Verify result text; expected: %s, got %s", _nonRGBPixelFormatsVerbose[i], result); } } /* Negative cases */ /* Invalid Formats */ SDL_ClearError(); SDLTest_AssertPass("Call to SDL_ClearError()"); for (i = 0; i < _numInvalidPixelFormats; i++) { format = _invalidPixelFormats[i]; result = (char *)SDL_GetPixelFormatName(format); SDLTest_AssertPass("Call to SDL_GetPixelFormatName(%u)", format); SDLTest_AssertCheck(result != NULL, "Verify result is not NULL"); if (result != NULL) { SDLTest_AssertCheck(result[0] != '\0', "Verify result is non-empty; got: %s", result); SDLTest_AssertCheck(SDL_strcmp(result, _invalidPixelFormatsVerbose[i]) == 0, "Validate name is UNKNOWN, expected: '%s', got: '%s'", _invalidPixelFormatsVerbose[i], result); } error = SDL_GetError(); SDLTest_AssertPass("Call to SDL_GetError()"); SDLTest_AssertCheck(error != NULL && error[0] != '\0', "Validate that error message is empty"); } return TEST_COMPLETED; }
/** * \brief Checkes calls with invalid input to SDL_BuildAudioCVT * * \sa https://wiki.libsdl.org/SDL_BuildAudioCVT */ int audio_buildAudioCVTNegative() { const char *expectedError = "Parameter 'cvt' is invalid"; const char *error; int result; SDL_AudioCVT cvt; SDL_AudioSpec spec1; SDL_AudioSpec spec2; int i; char message[256]; /* Valid format */ spec1.format = AUDIO_S8; spec1.channels = 1; spec1.freq = 22050; spec2.format = AUDIO_S16LSB; spec2.channels = 2; spec2.freq = 44100; SDL_ClearError(); SDLTest_AssertPass("Call to SDL_ClearError()"); /* NULL input for CVT buffer */ result = SDL_BuildAudioCVT((SDL_AudioCVT *)NULL, spec1.format, spec1.channels, spec1.freq, spec2.format, spec2.channels, spec2.freq); SDLTest_AssertPass("Call to SDL_BuildAudioCVT(NULL,...)"); SDLTest_AssertCheck(result == -1, "Verify result value; expected: -1, got: %i", result); error = SDL_GetError(); SDLTest_AssertPass("Call to SDL_GetError()"); SDLTest_AssertCheck(error != NULL, "Validate that error message was not NULL"); if (error != NULL) { SDLTest_AssertCheck(SDL_strcmp(error, expectedError) == 0, "Validate error message, expected: '%s', got: '%s'", expectedError, error); } /* Invalid conversions */ for (i = 1; i < 64; i++) { /* Valid format to start with */ spec1.format = AUDIO_S8; spec1.channels = 1; spec1.freq = 22050; spec2.format = AUDIO_S16LSB; spec2.channels = 2; spec2.freq = 44100; SDL_ClearError(); SDLTest_AssertPass("Call to SDL_ClearError()"); /* Set various invalid format inputs */ SDL_strlcpy(message, "Invalid: ", 256); if (i & 1) { SDL_strlcat(message, " spec1.format", 256); spec1.format = 0; } if (i & 2) { SDL_strlcat(message, " spec1.channels", 256); spec1.channels = 0; } if (i & 4) { SDL_strlcat(message, " spec1.freq", 256); spec1.freq = 0; } if (i & 8) { SDL_strlcat(message, " spec2.format", 256); spec2.format = 0; } if (i & 16) { SDL_strlcat(message, " spec2.channels", 256); spec2.channels = 0; } if (i & 32) { SDL_strlcat(message, " spec2.freq", 256); spec2.freq = 0; } SDLTest_Log("%s", message); result = SDL_BuildAudioCVT(&cvt, spec1.format, spec1.channels, spec1.freq, spec2.format, spec2.channels, spec2.freq); SDLTest_AssertPass("Call to SDL_BuildAudioCVT(spec1 ==> spec2)"); SDLTest_AssertCheck(result == -1, "Verify result value; expected: -1, got: %i", result); error = SDL_GetError(); SDLTest_AssertPass("Call to SDL_GetError()"); SDLTest_AssertCheck(error != NULL && error[0] != '\0', "Validate that error message was not NULL or empty"); } SDL_ClearError(); SDLTest_AssertPass("Call to SDL_ClearError()"); return TEST_COMPLETED; }
/** * \brief Convert audio using various conversion structures * * \sa https://wiki.libsdl.org/SDL_BuildAudioCVT * \sa https://wiki.libsdl.org/SDL_ConvertAudio */ int audio_convertAudio() { int result; SDL_AudioCVT cvt; SDL_AudioSpec spec1; SDL_AudioSpec spec2; int c; char message[128]; int i, ii, j, jj, k, kk, l, ll; /* Iterate over bitmask that determines which parameters are modified in the conversion */ for (c = 1; c < 8; c++) { SDL_strlcpy(message, "Changing:", 128); if (c & 1) { SDL_strlcat(message, " Format", 128); } if (c & 2) { SDL_strlcat(message, " Channels", 128); } if (c & 4) { SDL_strlcat(message, " Frequencies", 128); } SDLTest_Log("%s", message); /* All source conversions with random conversion targets */ for (i = 0; i < _numAudioFormats; i++) { for (j = 0; j < _numAudioChannels; j++) { for (k = 0; k < _numAudioFrequencies; k++) { spec1.format = _audioFormats[i]; spec1.channels = _audioChannels[j]; spec1.freq = _audioFrequencies[k]; /* Ensure we have a different target format */ do { if (c & 1) { ii = SDLTest_RandomIntegerInRange(0, _numAudioFormats - 1); } else { ii = 1; } if (c & 2) { jj = SDLTest_RandomIntegerInRange(0, _numAudioChannels - 1); } else { jj= j; } if (c & 4) { kk = SDLTest_RandomIntegerInRange(0, _numAudioFrequencies - 1); } else { kk = k; } } while ((i == ii) && (j == jj) && (k == kk)); spec2.format = _audioFormats[ii]; spec2.channels = _audioChannels[jj]; spec2.freq = _audioFrequencies[kk]; result = SDL_BuildAudioCVT(&cvt, spec1.format, spec1.channels, spec1.freq, spec2.format, spec2.channels, spec2.freq); SDLTest_AssertPass("Call to SDL_BuildAudioCVT(format[%i]=%s(%i),channels[%i]=%i,freq[%i]=%i ==> format[%i]=%s(%i),channels[%i]=%i,freq[%i]=%i)", i, _audioFormatsVerbose[i], spec1.format, j, spec1.channels, k, spec1.freq, ii, _audioFormatsVerbose[ii], spec2.format, jj, spec2.channels, kk, spec2.freq); SDLTest_AssertCheck(result == 1, "Verify result value; expected: 1, got: %i", result); if (result != 1) { SDLTest_LogError("%s", SDL_GetError()); } else { SDLTest_AssertCheck(cvt.len_mult > 0, "Verify that cvt.len_mult value; expected: >0, got: %i", cvt.len_mult); if (cvt.len_mult < 1) return TEST_ABORTED; /* Create some random data to convert */ l = 64; ll = l * cvt.len_mult; SDLTest_Log("Creating dummy sample buffer of %i length (%i bytes)", l, ll); cvt.len = l; cvt.buf = (Uint8 *)SDL_malloc(ll); SDLTest_AssertCheck(cvt.buf != NULL, "Check data buffer to convert is not NULL"); if (cvt.buf == NULL) return TEST_ABORTED; /* Convert the data */ result = SDL_ConvertAudio(&cvt); SDLTest_AssertPass("Call to SDL_ConvertAudio()"); SDLTest_AssertCheck(result == 0, "Verify result value; expected: 0; got: %i", result); SDLTest_AssertCheck(cvt.buf != NULL, "Verify conversion buffer is not NULL"); SDLTest_AssertCheck(cvt.len_ratio > 0.0, "Verify conversion length ratio; expected: >0; got: %f", cvt.len_ratio); /* Free converted buffer */ SDL_free(cvt.buf); cvt.buf = NULL; } } } } } return TEST_COMPLETED; }
/** * \brief Execute a test suite using the given run seend and execution key. * * 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. * * \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) { int suiteCounter; int testCounter; int iterationCounter; SDLTest_TestSuiteReference *testSuite; SDLTest_TestCaseReference *testCase; const char *runSeed = NULL; char *currentSuiteName; char *currentTestName; Uint64 execKey; float runStartSeconds; float suiteStartSeconds; float testStartSeconds; float runEndSeconds; float suiteEndSeconds; float testEndSeconds; float runtime; int suiteFilter = 0; char *suiteFilterName = NULL; int testFilter = 0; char *testFilterName = NULL; int testResult = 0; int runResult = 0; Uint32 totalTestFailedCount = 0; Uint32 totalTestPassedCount = 0; Uint32 totalTestSkippedCount = 0; Uint32 testFailedCount = 0; Uint32 testPassedCount = 0; Uint32 testSkippedCount = 0; Uint32 countSum = 0; char *logFormat = (char *)SDLTest_LogSummaryFormat; /* Sanitize test iterations */ if (testIterations < 1) { testIterations = 1; } /* Generate run see if we don't have one already */ if (userRunSeed == NULL || userRunSeed[0] == '\0') { runSeed = SDLTest_GenerateRunSeed(16); if (runSeed == NULL) { SDLTest_LogError("Generating a random seed failed"); return 2; } } else { runSeed = userRunSeed; } /* Reset per-run counters */ totalTestFailedCount = 0; totalTestPassedCount = 0; totalTestSkippedCount = 0; /* Take time - run start */ runStartSeconds = GetClock(); /* Log run with fuzzer parameters */ SDLTest_Log("::::: Test Run /w seed '%s' started\n", runSeed); /* Initialize filtering */ if (filter != NULL && filter[0] != '\0') { /* Loop over all suites to check if we have a filter match */ suiteCounter = 0; while (testSuites[suiteCounter] && suiteFilter == 0) { testSuite=(SDLTest_TestSuiteReference *)testSuites[suiteCounter]; suiteCounter++; if (testSuite->name != NULL && SDL_strcmp(filter, testSuite->name) == 0) { /* Matched a suite name */ suiteFilter = 1; suiteFilterName = testSuite->name; SDLTest_Log("Filtering: running only suite '%s'", suiteFilterName); break; } /* Within each suite, loop over all test cases to check if we have a filter match */ testCounter = 0; while (testSuite->testCases[testCounter] && testFilter == 0) { testCase=(SDLTest_TestCaseReference *)testSuite->testCases[testCounter]; testCounter++; if (testCase->name != NULL && SDL_strcmp(filter, testCase->name) == 0) { /* Matched a test name */ suiteFilter = 1; suiteFilterName = testSuite->name; testFilter = 1; testFilterName = testCase->name; SDLTest_Log("Filtering: running only test '%s' in suite '%s'", testFilterName, suiteFilterName); break; } } } if (suiteFilter == 0 && testFilter == 0) { SDLTest_LogError("Filter '%s' did not match any test suite/case.", filter); SDLTest_Log("Exit code: 2"); return 2; } } /* Loop over all suites */ suiteCounter = 0; while(testSuites[suiteCounter]) { testSuite=(SDLTest_TestSuiteReference *)testSuites[suiteCounter]; currentSuiteName = (char *)((testSuite->name) ? testSuite->name : SDLTest_InvalidNameFormat); suiteCounter++; /* Filter suite if flag set and we have a name */ if (suiteFilter == 1 && suiteFilterName != NULL && testSuite->name != NULL && SDL_strcmp(suiteFilterName, testSuite->name) != 0) { /* Skip suite */ SDLTest_Log("===== Test Suite %i: '%s' skipped\n", suiteCounter, currentSuiteName); } else { /* Reset per-suite counters */ testFailedCount = 0; testPassedCount = 0; testSkippedCount = 0; /* Take time - suite start */ suiteStartSeconds = GetClock(); /* Log suite started */ SDLTest_Log("===== Test Suite %i: '%s' started\n", suiteCounter, currentSuiteName); /* Loop over all test cases */ testCounter = 0; while(testSuite->testCases[testCounter]) { testCase=(SDLTest_TestCaseReference *)testSuite->testCases[testCounter]; currentTestName = (char *)((testCase->name) ? testCase->name : SDLTest_InvalidNameFormat); testCounter++; /* Filter tests if flag set and we have a name */ if (testFilter == 1 && testFilterName != NULL && testCase->name != NULL && SDL_strcmp(testFilterName, testCase->name) != 0) { /* Skip test */ SDLTest_Log("===== Test Case %i.%i: '%s' skipped\n", suiteCounter, testCounter, currentTestName); } else { /* 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"); testCase->enabled = 1; } /* Take time - test start */ testStartSeconds = GetClock(); /* Log test started */ SDLTest_Log("----- Test Case %i.%i: '%s' started", suiteCounter, testCounter, currentTestName); if (testCase->description != NULL && testCase->description[0] != '\0') { SDLTest_Log("Test Description: '%s'", (testCase->description) ? testCase->description : SDLTest_InvalidNameFormat); } /* Loop over all iterations */ iterationCounter = 0; while(iterationCounter < testIterations) { iterationCounter++; if (userExecKey != 0) { execKey = userExecKey; } else { execKey = SDLTest_GenerateExecKey((char *)runSeed, testSuite->name, testCase->name, iterationCounter); } SDLTest_Log("Test Iteration %i: execKey %llu", iterationCounter, execKey); testResult = SDLTest_RunTest(testSuite, testCase, execKey); if (testResult == TEST_RESULT_PASSED) { testPassedCount++; totalTestPassedCount++; } else if (testResult == TEST_RESULT_SKIPPED) { testSkippedCount++; totalTestSkippedCount++; } else { testFailedCount++; totalTestFailedCount++; } } /* Take time - test end */ testEndSeconds = GetClock(); runtime = testEndSeconds - testStartSeconds; if (runtime < 0.0f) runtime = 0.0f; if (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); } else { /* Log test runtime */ SDLTest_Log("Total Test runtime: %.1f sec", runtime); } /* Log final test result */ switch (testResult) { case TEST_RESULT_PASSED: SDLTest_Log((char *)SDLTest_FinalResultFormat, "Test", currentTestName, "Passed"); break; case TEST_RESULT_FAILED: SDLTest_LogError((char *)SDLTest_FinalResultFormat, "Test", currentTestName, "Failed"); break; case TEST_RESULT_NO_ASSERT: SDLTest_LogError((char *)SDLTest_FinalResultFormat,"Test", currentTestName, "No Asserts"); break; } } } /* Take time - suite end */ suiteEndSeconds = GetClock(); runtime = suiteEndSeconds - suiteStartSeconds; if (runtime < 0.0f) runtime = 0.0f; /* Log suite runtime */ SDLTest_Log("Total Suite runtime: %.1f sec", runtime); /* Log summary and final Suite result */ countSum = testPassedCount + testFailedCount + testSkippedCount; if (testFailedCount == 0) { SDLTest_Log(logFormat, "Suite", countSum, testPassedCount, testFailedCount, testSkippedCount); SDLTest_Log((char *)SDLTest_FinalResultFormat, "Suite", currentSuiteName, "Passed"); } else { SDLTest_LogError(logFormat, "Suite", countSum, testPassedCount, testFailedCount, testSkippedCount); SDLTest_LogError((char *)SDLTest_FinalResultFormat, "Suite", currentSuiteName, "Failed"); } } } /* Take time - run end */ runEndSeconds = GetClock(); runtime = runEndSeconds - runStartSeconds; if (runtime < 0.0f) runtime = 0.0f; /* Log total runtime */ SDLTest_Log("Total Run runtime: %.1f sec", runtime); /* Log summary and final run result */ countSum = totalTestPassedCount + totalTestFailedCount + totalTestSkippedCount; if (totalTestFailedCount == 0) { runResult = 0; SDLTest_Log(logFormat, "Run", countSum, totalTestPassedCount, totalTestFailedCount, totalTestSkippedCount); SDLTest_Log((char *)SDLTest_FinalResultFormat, "Run /w seed", runSeed, "Passed"); } else { runResult = 1; SDLTest_LogError(logFormat, "Run", countSum, totalTestPassedCount, totalTestFailedCount, totalTestSkippedCount); SDLTest_LogError((char *)SDLTest_FinalResultFormat, "Run /w seed", runSeed, "Failed"); } SDLTest_Log("Exit code: %d", runResult); return runResult; }
/** * @brief Call to SDL_getenv and SDL_setenv */ int stdlib_getsetenv(void *arg) { const int nameLen = 16; char name[17]; int counter; int result; char * value1; char * value2; char * expected; int overwrite; char * text; /* Create a random name. This tests SDL_getenv, since we need to */ /* make sure the variable is not set yet (it shouldn't). */ do { for(counter = 0; counter < nameLen; counter++) { name[counter] = (char)SDLTest_RandomIntegerInRange(65, 90); } name[nameLen] = '\0'; text = SDL_getenv(name); SDLTest_AssertPass("Call to SDL_getenv('%s')", name); if (text != NULL) { SDLTest_Log("Expected: NULL, Got: '%s' (%i)", text, (int) SDL_strlen(text)); } } while (text != NULL); /* Create random values to set */ value1 = SDLTest_RandomAsciiStringOfSize(10); value2 = SDLTest_RandomAsciiStringOfSize(10); /* Set value 1 without overwrite */ overwrite = 0; expected = value1; result = SDL_setenv(name, value1, overwrite); SDLTest_AssertPass("Call to SDL_setenv('%s','%s', %i)", name, value1, overwrite); SDLTest_AssertCheck(result == 0, "Check result, expected: 0, got: %i", result); /* Check value */ text = SDL_getenv(name); SDLTest_AssertPass("Call to SDL_getenv('%s')", name); SDLTest_AssertCheck(text != NULL, "Verify returned text is not NULL"); if (text != NULL) { SDLTest_AssertCheck( SDL_strcmp(text, expected) == 0, "Verify returned text, expected: %s, got: %s", expected, text); } /* Set value 2 with overwrite */ overwrite = 1; expected = value2; result = SDL_setenv(name, value2, overwrite); SDLTest_AssertPass("Call to SDL_setenv('%s','%s', %i)", name, value2, overwrite); SDLTest_AssertCheck(result == 0, "Check result, expected: 0, got: %i", result); /* Check value */ text = SDL_getenv(name); SDLTest_AssertPass("Call to SDL_getenv('%s')", name); SDLTest_AssertCheck(text != NULL, "Verify returned text is not NULL"); if (text != NULL) { SDLTest_AssertCheck( SDL_strcmp(text, expected) == 0, "Verify returned text, expected: %s, got: %s", expected, text); } /* Set value 1 without overwrite */ overwrite = 0; expected = value2; result = SDL_setenv(name, value1, overwrite); SDLTest_AssertPass("Call to SDL_setenv('%s','%s', %i)", name, value1, overwrite); SDLTest_AssertCheck(result == 0, "Check result, expected: 0, got: %i", result); /* Check value */ text = SDL_getenv(name); SDLTest_AssertPass("Call to SDL_getenv('%s')", name); SDLTest_AssertCheck(text != NULL, "Verify returned text is not NULL"); if (text != NULL) { SDLTest_AssertCheck( SDL_strcmp(text, expected) == 0, "Verify returned text, expected: %s, got: %s", expected, text); } /* Set value 1 without overwrite */ overwrite = 1; expected = value1; result = SDL_setenv(name, value1, overwrite); SDLTest_AssertPass("Call to SDL_setenv('%s','%s', %i)", name, value1, overwrite); SDLTest_AssertCheck(result == 0, "Check result, expected: 0, got: %i", result); /* Check value */ text = SDL_getenv(name); SDLTest_AssertPass("Call to SDL_getenv('%s')", name); SDLTest_AssertCheck(text != NULL, "Verify returned text is not NULL"); if (text != NULL) { SDLTest_AssertCheck( SDL_strcmp(text, expected) == 0, "Verify returned text, expected: %s, got: %s", expected, text); } /* Negative cases */ for (overwrite=0; overwrite <= 1; overwrite++) { result = SDL_setenv(NULL, value1, overwrite); SDLTest_AssertPass("Call to SDL_setenv(NULL,'%s', %i)", value1, overwrite); SDLTest_AssertCheck(result == -1, "Check result, expected: -1, got: %i", result); result = SDL_setenv("", value1, overwrite); SDLTest_AssertPass("Call to SDL_setenv('','%s', %i)", value1, overwrite); SDLTest_AssertCheck(result == -1, "Check result, expected: -1, got: %i", result); result = SDL_setenv("=", value1, overwrite); SDLTest_AssertPass("Call to SDL_setenv('=','%s', %i)", value1, overwrite); SDLTest_AssertCheck(result == -1, "Check result, expected: -1, got: %i", result); result = SDL_setenv(name, NULL, overwrite); SDLTest_AssertPass("Call to SDL_setenv('%s', NULL, %i)", name, overwrite); SDLTest_AssertCheck(result == -1, "Check result, expected: -1, got: %i", result); } /* Clean up */ SDL_free(value1); SDL_free(value2); return TEST_COMPLETED; }
int SDLVisualTest_ParseHarnessArgs(char** argv, SDLVisualTest_HarnessState* state) { int i; SDLTest_Log("Parsing commandline arguments.."); if(!argv) { SDLTest_LogError("argv is NULL"); return 0; } if(!state) { SDLTest_LogError("state is NULL"); return 0; } /* initialize the state object */ state->sutargs[0] = '\0'; state->sutapp[0] = '\0'; state->output_dir[0] = '\0'; state->verify_dir[0] = '\0'; state->timeout = DEFAULT_SUT_TIMEOUT; SDL_memset(&state->sut_config, 0, sizeof(SDLVisualTest_SUTConfig)); SDL_memset(&state->action_queue, 0, sizeof(SDLVisualTest_ActionQueue)); state->variator_type = SDL_VARIATOR_RANDOM; state->num_variations = -1; state->no_launch = SDL_FALSE; /* parse config file if passed */ for(i = 0; argv[i]; i++) { if(StrCaseCmpIgnoreHyphen("config", argv[i]) == 0) { if(!argv[i + 1]) { SDLTest_Log("Arguments parsing error: invalid argument for config."); return 0; } if(!ParseConfig(argv[i + 1], state)) { SDLTest_LogError("ParseConfig() failed"); return 0; } } } /* parse the arguments */ for(i = 0; argv[i];) { int consumed = ParseArg(argv, i, state); if(consumed == -1 || consumed == 0) { SDLTest_LogError("ParseArg() failed"); return 0; } i += consumed; } if(state->variator_type == SDL_VARIATOR_RANDOM && state->num_variations == -1) state->num_variations = 1; /* check to see if required options have been passed */ if(!state->sutapp[0]) { SDLTest_LogError("sutapp must be passed."); return 0; } if(!state->sutargs[0] && !state->sut_config.options) { SDLTest_LogError("Either sutargs or parameter-config must be passed."); return 0; } if(!state->output_dir[0]) { SDL_strlcpy(state->output_dir, "./output", MAX_PATH_LEN); } if(!state->verify_dir[0]) { SDL_strlcpy(state->verify_dir, "./verify", MAX_PATH_LEN); } return 1; }
/* parser an argument, updates the state object and returns the number of arguments processed; returns -1 on failure */ static int ParseArg(char** argv, int index, SDLVisualTest_HarnessState* state) { if(!argv || !argv[index] || !state) return 0; if(StrCaseCmpIgnoreHyphen("sutapp", argv[index]) == 0) { index++; if(!argv[index]) { SDLTest_LogError("Arguments parsing error: Invalid argument for sutapp."); return -1; } SDL_strlcpy(state->sutapp, argv[index], MAX_PATH_LEN); SDLTest_Log("SUT Application: %s", state->sutapp); return 2; } else if(StrCaseCmpIgnoreHyphen("output-dir", argv[index]) == 0) { index++; if(!argv[index]) { SDLTest_LogError("Arguments parsing error: Invalid argument for output-dir."); return -1; } SDL_strlcpy(state->output_dir, argv[index], MAX_PATH_LEN); SDLTest_Log("Screenshot Output Directory: %s", state->output_dir); return 2; } else if(StrCaseCmpIgnoreHyphen("verify-dir", argv[index]) == 0) { index++; if(!argv[index]) { SDLTest_LogError("Arguments parsing error: Invalid argument for verify-dir."); return -1; } SDL_strlcpy(state->verify_dir, argv[index], MAX_PATH_LEN); SDLTest_Log("Screenshot Verification Directory: %s", state->verify_dir); return 2; } else if(StrCaseCmpIgnoreHyphen("sutargs", argv[index]) == 0) { index++; if(!argv[index]) { SDLTest_LogError("Arguments parsing error: Invalid argument for sutargs."); return -1; } SDL_strlcpy(state->sutargs, argv[index], MAX_SUT_ARGS_LEN); SDLTest_Log("SUT Arguments: %s", state->sutargs); return 2; } else if(StrCaseCmpIgnoreHyphen("timeout", argv[index]) == 0) { int hr, min, sec; index++; if(!argv[index] || SDL_sscanf(argv[index], "%d:%d:%d", &hr, &min, &sec) != 3) { SDLTest_LogError("Arguments parsing error: Invalid argument for timeout."); return -1; } state->timeout = (((hr * 60) + min) * 60 + sec) * 1000; SDLTest_Log("Maximum Timeout for each SUT run: %d milliseconds", state->timeout); return 2; } else if(StrCaseCmpIgnoreHyphen("parameter-config", argv[index]) == 0) { index++; if(!argv[index]) { SDLTest_LogError("Arguments parsing error: Invalid argument for parameter-config."); return -1; } SDLTest_Log("SUT Parameters file: %s", argv[index]); SDLVisualTest_FreeSUTConfig(&state->sut_config); if(!SDLVisualTest_ParseSUTConfig(argv[index], &state->sut_config)) { SDLTest_LogError("Failed to parse SUT parameters file"); return -1; } return 2; } else if(StrCaseCmpIgnoreHyphen("variator", argv[index]) == 0) { index++; if(!argv[index]) { SDLTest_LogError("Arguments parsing error: Invalid argument for variator."); return -1; } SDLTest_Log("Variator: %s", argv[index]); if(SDL_strcasecmp("exhaustive", argv[index]) == 0) state->variator_type = SDL_VARIATOR_EXHAUSTIVE; else if(SDL_strcasecmp("random", argv[index]) == 0) state->variator_type = SDL_VARIATOR_RANDOM; else { SDLTest_LogError("Arguments parsing error: Invalid variator name."); return -1; } return 2; } else if(StrCaseCmpIgnoreHyphen("num-variations", argv[index]) == 0) { index++; if(!argv[index]) { SDLTest_LogError("Arguments parsing error: Invalid argument for num-variations."); return -1; } state->num_variations = SDL_atoi(argv[index]); SDLTest_Log("Number of variations to run: %d", state->num_variations); if(state->num_variations <= 0) { SDLTest_LogError("Arguments parsing error: num-variations must be positive."); return -1; } return 2; } else if(StrCaseCmpIgnoreHyphen("no-launch", argv[index]) == 0) { state->no_launch = SDL_TRUE; SDLTest_Log("SUT will not be launched."); return 1; } else if(StrCaseCmpIgnoreHyphen("action-config", argv[index]) == 0) { index++; if(!argv[index]) { SDLTest_LogError("Arguments parsing error: invalid argument for action-config"); return -1; } SDLTest_Log("Action Config file: %s", argv[index]); SDLVisualTest_EmptyActionQueue(&state->action_queue); if(!SDLVisualTest_ParseActionConfig(argv[index], &state->action_queue)) { SDLTest_LogError("SDLVisualTest_ParseActionConfig() failed"); return -1; } return 2; } else if(StrCaseCmpIgnoreHyphen("config", argv[index]) == 0) { index++; if(!argv[index]) { SDLTest_LogError("Arguments parsing error: invalid argument for config"); return -1; } /* do nothing, this option has already been handled */ return 2; } return 0; }
/** * @brief Tests writing and reading from file using endian aware functions. * * \sa * http://wiki.libsdl.org/moin.cgi/SDL_RWFromFile * http://wiki.libsdl.org/moin.cgi/SDL_RWClose * http://wiki.libsdl.org/moin.cgi/SDL_ReadBE16 * http://wiki.libsdl.org/moin.cgi/SDL_WriteBE16 */ int rwops_testFileWriteReadEndian(void) { SDL_RWops *rw; Sint64 result; int mode; size_t objectsWritten; Uint16 BE16value; Uint32 BE32value; Uint64 BE64value; Uint16 LE16value; Uint32 LE32value; Uint64 LE64value; Uint16 BE16test; Uint32 BE32test; Uint64 BE64test; Uint16 LE16test; Uint32 LE32test; Uint64 LE64test; int cresult; for (mode = 0; mode < 3; mode++) { /* Create test data */ switch (mode) { case 0: SDLTest_Log("All 0 values"); BE16value = 0; BE32value = 0; BE64value = 0; LE16value = 0; LE32value = 0; LE64value = 0; break; case 1: SDLTest_Log("All 1 values"); BE16value = 1; BE32value = 1; BE64value = 1; LE16value = 1; LE32value = 1; LE64value = 1; break; case 2: SDLTest_Log("Random values"); BE16value = SDLTest_RandomUint16(); BE32value = SDLTest_RandomUint32(); BE64value = SDLTest_RandomUint64(); LE16value = SDLTest_RandomUint16(); LE32value = SDLTest_RandomUint32(); LE64value = SDLTest_RandomUint64(); break; } /* Write test. */ rw = SDL_RWFromFile(RWopsWriteTestFilename, "w+"); SDLTest_AssertPass("Call to SDL_RWFromFile(..,\"w+\")"); SDLTest_AssertCheck(rw != NULL, "Verify opening file with SDL_RWFromFile in write mode does not return NULL"); /* Bail out if NULL */ if (rw == NULL) return TEST_ABORTED; /* Write test data */ objectsWritten = SDL_WriteBE16(rw, BE16value); SDLTest_AssertPass("Call to SDL_WriteBE16"); SDLTest_AssertCheck(objectsWritten == 1, "Validate number of objects written, expected: 1, got: %i", objectsWritten); objectsWritten = SDL_WriteBE32(rw, BE32value); SDLTest_AssertPass("Call to SDL_WriteBE32"); SDLTest_AssertCheck(objectsWritten == 1, "Validate number of objects written, expected: 1, got: %i", objectsWritten); objectsWritten = SDL_WriteBE64(rw, BE64value); SDLTest_AssertPass("Call to SDL_WriteBE64"); SDLTest_AssertCheck(objectsWritten == 1, "Validate number of objects written, expected: 1, got: %i", objectsWritten); objectsWritten = SDL_WriteLE16(rw, LE16value); SDLTest_AssertPass("Call to SDL_WriteLE16"); SDLTest_AssertCheck(objectsWritten == 1, "Validate number of objects written, expected: 1, got: %i", objectsWritten); objectsWritten = SDL_WriteLE32(rw, LE32value); SDLTest_AssertPass("Call to SDL_WriteLE32"); SDLTest_AssertCheck(objectsWritten == 1, "Validate number of objects written, expected: 1, got: %i", objectsWritten); objectsWritten = SDL_WriteLE64(rw, LE64value); SDLTest_AssertPass("Call to SDL_WriteLE64"); SDLTest_AssertCheck(objectsWritten == 1, "Validate number of objects written, expected: 1, got: %i", objectsWritten); /* Test seek to start */ result = SDL_RWseek( rw, 0, RW_SEEK_SET ); SDLTest_AssertPass("Call to SDL_RWseek succeeded"); SDLTest_AssertCheck(result == 0, "Verify result from position 0 with SDL_RWseek, expected 0, got %i", result); /* Read test data */ BE16test = SDL_ReadBE16(rw); SDLTest_AssertPass("Call to SDL_ReadBE16"); SDLTest_AssertCheck(BE16test == BE16value, "Validate return value from SDL_ReadBE16, expected: %hu, got: %hu", BE16value, BE16test); BE32test = SDL_ReadBE32(rw); SDLTest_AssertPass("Call to SDL_ReadBE32"); SDLTest_AssertCheck(BE32test == BE32value, "Validate return value from SDL_ReadBE32, expected: %u, got: %u", BE32value, BE32test); BE64test = SDL_ReadBE64(rw); SDLTest_AssertPass("Call to SDL_ReadBE64"); SDLTest_AssertCheck(BE64test == BE64value, "Validate return value from SDL_ReadBE64, expected: %llu, got: %llu", BE64value, BE64test); LE16test = SDL_ReadLE16(rw); SDLTest_AssertPass("Call to SDL_ReadLE16"); SDLTest_AssertCheck(LE16test == LE16value, "Validate return value from SDL_ReadLE16, expected: %hu, got: %hu", LE16value, LE16test); LE32test = SDL_ReadLE32(rw); SDLTest_AssertPass("Call to SDL_ReadLE32"); SDLTest_AssertCheck(LE32test == LE32value, "Validate return value from SDL_ReadLE32, expected: %u, got: %u", LE32value, LE32test); LE64test = SDL_ReadLE64(rw); SDLTest_AssertPass("Call to SDL_ReadLE64"); SDLTest_AssertCheck(LE64test == LE64value, "Validate return value from SDL_ReadLE64, expected: %llu, got: %llu", LE64value, LE64test); /* Close handle */ cresult = SDL_RWclose(rw); SDLTest_AssertPass("Call to SDL_RWclose() succeeded"); SDLTest_AssertCheck(cresult == 0, "Verify result value is 0; got: %d", cresult); } return TEST_COMPLETED; }
/** * @brief Call to SDL_AllocFormat and SDL_FreeFormat * * @sa http://wiki.libsdl.org/moin.fcg/SDL_AllocFormat * @sa http://wiki.libsdl.org/moin.fcg/SDL_FreeFormat */ int pixels_allocFreeFormat(void *arg) { const char *unknownFormat = "SDL_PIXELFORMAT_UNKNOWN"; const char *expectedError = "Parameter 'format' is invalid"; const char *error; int i; Uint32 format; Uint32 masks; SDL_PixelFormat* result; /* Blank/unknown format */ format = 0; SDLTest_Log("RGB Format: %s (%u)", unknownFormat, format); /* Allocate format */ result = SDL_AllocFormat(format); SDLTest_AssertPass("Call to SDL_AllocFormat()"); SDLTest_AssertCheck(result != NULL, "Verify result is not NULL"); if (result != NULL) { SDLTest_AssertCheck(result->format == format, "Verify value of result.format; expected: %u, got %u", format, result->format); SDLTest_AssertCheck(result->BitsPerPixel == 0, "Verify value of result.BitsPerPixel; expected: 0, got %u", result->BitsPerPixel); SDLTest_AssertCheck(result->BytesPerPixel == 0, "Verify value of result.BytesPerPixel; expected: 0, got %u", result->BytesPerPixel); masks = result->Rmask | result->Gmask | result->Bmask | result->Amask; SDLTest_AssertCheck(masks == 0, "Verify value of result.[RGBA]mask combined; expected: 0, got %u", masks); /* Deallocate again */ SDL_FreeFormat(result); SDLTest_AssertPass("Call to SDL_FreeFormat()"); } /* RGB formats */ for (i = 0; i < _numRGBPixelFormats; i++) { format = _RGBPixelFormats[i]; SDLTest_Log("RGB Format: %s (%u)", _RGBPixelFormatsVerbose[i], format); /* Allocate format */ result = SDL_AllocFormat(format); SDLTest_AssertPass("Call to SDL_AllocFormat()"); SDLTest_AssertCheck(result != NULL, "Verify result is not NULL"); if (result != NULL) { SDLTest_AssertCheck(result->format == format, "Verify value of result.format; expected: %u, got %u", format, result->format); SDLTest_AssertCheck(result->BitsPerPixel > 0, "Verify value of result.BitsPerPixel; expected: >0, got %u", result->BitsPerPixel); SDLTest_AssertCheck(result->BytesPerPixel > 0, "Verify value of result.BytesPerPixel; expected: >0, got %u", result->BytesPerPixel); if (result->palette != NULL) { masks = result->Rmask | result->Gmask | result->Bmask | result->Amask; SDLTest_AssertCheck(masks > 0, "Verify value of result.[RGBA]mask combined; expected: >0, got %u", masks); } /* Deallocate again */ SDL_FreeFormat(result); SDLTest_AssertPass("Call to SDL_FreeFormat()"); } } /* Non-RGB formats */ for (i = 0; i < _numNonRGBPixelFormats; i++) { format = _nonRGBPixelFormats[i]; SDLTest_Log("non-RGB Format: %s (%u)", _nonRGBPixelFormatsVerbose[i], format); /* Try to allocate format */ result = SDL_AllocFormat(format); SDLTest_AssertPass("Call to SDL_AllocFormat()"); SDLTest_AssertCheck(result == NULL, "Verify result is NULL"); } /* Negative cases */ /* Invalid Formats */ for (i = 0; i < _numInvalidPixelFormats; i++) { SDL_ClearError(); SDLTest_AssertPass("Call to SDL_ClearError()"); format = _invalidPixelFormats[i]; result = SDL_AllocFormat(format); SDLTest_AssertPass("Call to SDL_AllocFormat(%u)", format); SDLTest_AssertCheck(result == NULL, "Verify result is NULL"); error = SDL_GetError(); SDLTest_AssertPass("Call to SDL_GetError()"); SDLTest_AssertCheck(error != NULL, "Validate that error message was not NULL"); if (error != NULL) { SDLTest_AssertCheck(SDL_strcmp(error, expectedError) == 0, "Validate error message, expected: '%s', got: '%s'", expectedError, error); } } /* Invalid free pointer */ SDL_ClearError(); SDLTest_AssertPass("Call to SDL_ClearError()"); SDL_FreeFormat(NULL); SDLTest_AssertPass("Call to SDL_FreeFormat(NULL)"); error = SDL_GetError(); SDLTest_AssertPass("Call to SDL_GetError()"); SDLTest_AssertCheck(error != NULL, "Validate that error message was not NULL"); if (error != NULL) { SDLTest_AssertCheck(SDL_strcmp(error, expectedError) == 0, "Validate error message, expected: '%s', got: '%s'", expectedError, error); } return TEST_COMPLETED; }