diff options
| author | jsmall-nvidia <jsmall@nvidia.com> | 2018-09-13 14:02:33 -0400 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2018-09-13 14:02:33 -0400 |
| commit | 929745d75f0607ab5b2218083ca4ccb493eb6032 (patch) | |
| tree | 32ceddda261aaba108607b89aeb89ebafd424e00 /tools | |
| parent | f60135cec62c91a9d7923397fe8796d2b3eaa5cb (diff) | |
Feature/memory arena improvements (#633)
* First pass at MemoryArena.
* First pass at RandomGenerator.
* Extract TestContext into external source file.
* Fix warning on printf.
* Use enum classes for Test enums.
OutputMode -> TestOutputMode.
* First pass at FreeList unit test.
* Auto registering tests.
Improvements to RandomGenerator.
* Remove the need for unitTest headers - cos can use registering.
* Added unitTest for MemoryArena.
* Do unit tests.
* Fix typo.
* Fix problem limiting errors from TestContext.
* Refactor of MemoryArena
* Removed the ability to rewind (to improve memory usage/simplify)
* Better memory usage - around oversized blocks
+ Will keep allocating from a normal block if more than 1/3 memory left, or an oversided block is allocated
* Better unitTest coverage for MemoryArena.
* Fixes based on code review
* Remove e prefix from enum class types for TestContext
* Added extra checking for allocations sizes
* Fixed some typos
* Added std::is_pod test to allocateAndCopyArray
* Add include for is_pod needed for linux build.
Diffstat (limited to 'tools')
| -rw-r--r-- | tools/slang-test/main.cpp | 169 | ||||
| -rw-r--r-- | tools/slang-test/test-context.cpp | 75 | ||||
| -rw-r--r-- | tools/slang-test/test-context.h | 31 | ||||
| -rw-r--r-- | tools/slang-test/unit-test-memory-arena.cpp | 49 |
4 files changed, 171 insertions, 153 deletions
diff --git a/tools/slang-test/main.cpp b/tools/slang-test/main.cpp index b57dc6d9c..a4b903e25 100644 --- a/tools/slang-test/main.cpp +++ b/tools/slang-test/main.cpp @@ -99,7 +99,7 @@ struct Options bool dumpOutputOnFailure = false; // kind of output to generate - TestOutputMode outputMode = TestOutputMode::eDefault; + TestOutputMode outputMode = TestOutputMode::Default; // Only run tests that match one of the given categories Dictionary<TestCategory*, TestCategory*> includeCategories; @@ -212,21 +212,21 @@ Result parseOptions(int* argc, char** argv) } else if( strcmp(arg, "-appveyor") == 0 ) { - g_options.outputMode = TestOutputMode::eAppVeyor; + g_options.outputMode = TestOutputMode::AppVeyor; g_options.dumpOutputOnFailure = true; } else if( strcmp(arg, "-travis") == 0 ) { - g_options.outputMode = TestOutputMode::eTravis; + g_options.outputMode = TestOutputMode::Travis; g_options.dumpOutputOnFailure = true; } else if (strcmp(arg, "-xunit") == 0) { - g_options.outputMode = TestOutputMode::eXUnit; + g_options.outputMode = TestOutputMode::XUnit; } else if (strcmp(arg, "-xunit2") == 0) { - g_options.outputMode = TestOutputMode::eXUnit2; + g_options.outputMode = TestOutputMode::XUnit2; } else if( strcmp(arg, "-category") == 0 ) { @@ -484,7 +484,7 @@ TestResult gatherTestOptions( if(!category) { - return TestResult::eFail; + return TestResult::Fail; } testOptions.categories.Add(category); @@ -499,7 +499,7 @@ TestResult gatherTestOptions( break; case 0: case '\r': case '\n': - return TestResult::eFail; + return TestResult::Fail; } break; @@ -516,7 +516,7 @@ TestResult gatherTestOptions( cursor++; else { - return TestResult::eFail; + return TestResult::Fail; } // Next scan for a sub-command name @@ -533,7 +533,7 @@ TestResult gatherTestOptions( break; case 0: case '\r': case '\n': - return TestResult::eFail; + return TestResult::Fail; } break; @@ -546,7 +546,7 @@ TestResult gatherTestOptions( cursor++; else { - return TestResult::eFail; + return TestResult::Fail; } // Now scan for arguments. For now we just assume that @@ -562,7 +562,7 @@ TestResult gatherTestOptions( case 0: case '\r': case '\n': skipToEndOfLine(&cursor); testList->tests.Add(testOptions); - return TestResult::ePass; + return TestResult::Pass; default: break; @@ -603,7 +603,7 @@ TestResult gatherTestsForFile( } catch (Slang::IOException) { - return TestResult::eFail; + return TestResult::Fail; } @@ -619,12 +619,12 @@ TestResult gatherTestsForFile( // Look for a pattern that matches what we want if(match(&cursor, "//TEST_IGNORE_FILE")) { - return TestResult::eIgnored; + return TestResult::Ignored; } else if(match(&cursor, "//TEST")) { - if(gatherTestOptions(&cursor, testList) != TestResult::ePass) - return TestResult::eFail; + if(gatherTestOptions(&cursor, testList) != TestResult::Pass) + return TestResult::Fail; } else { @@ -632,7 +632,7 @@ TestResult gatherTestsForFile( } } - return TestResult::ePass; + return TestResult::Pass; } OSError spawnAndWait(TestContext* context, const String& testPath, OSProcessSpawner& spawner) @@ -642,14 +642,14 @@ OSError spawnAndWait(TestContext* context, const String& testPath, OSProcessSpaw if(context->m_isVerbose) { String commandLine = spawner.getCommandLine(); - context->messageFormat(TestMessageType::eInfo, "%s\n", commandLine.begin()); + context->messageFormat(TestMessageType::Info, "%s\n", commandLine.begin()); } OSError err = spawner.spawnAndWaitForCompletion(); if (err != kOSError_None) { // fprintf(stderr, "failed to run test '%S'\n", testPath.ToWString()); - context->messageFormat(TestMessageType::eRunError, "failed to run test '%S'", testPath.ToWString().begin()); + context->messageFormat(TestMessageType::RunError, "failed to run test '%S'", testPath.ToWString().begin()); } return err; } @@ -731,7 +731,7 @@ TestResult runSimpleTest(TestContext* context, TestInput& input) if (spawnAndWait(context, outputStem, spawner) != kOSError_None) { - return TestResult::eFail; + return TestResult::Fail; } String actualOutput = getOutput(spawner); @@ -753,19 +753,19 @@ TestResult runSimpleTest(TestContext* context, TestInput& input) expectedOutput = "result code = 0\nstandard error = {\n}\nstandard output = {\n}\n"; } - TestResult result = TestResult::ePass; + TestResult result = TestResult::Pass; // Otherwise we compare to the expected output if (actualOutput != expectedOutput) { context->dumpOutputDifference(expectedOutput, actualOutput); - result = TestResult::eFail; + result = TestResult::Fail; } // If the test failed, then we write the actual output to a file // so that we can easily diff it from the command line and // diagnose the problem. - if (result == TestResult::eFail) + if (result == TestResult::Fail) { String actualOutputPath = outputStem + ".actual"; Slang::File::WriteAllText(actualOutputPath, actualOutput); @@ -793,7 +793,7 @@ TestResult runReflectionTest(TestContext* context, TestInput& input) if (spawnAndWait(context, outputStem, spawner) != kOSError_None) { - return TestResult::eFail; + return TestResult::Fail; } String actualOutput = getOutput(spawner); @@ -815,18 +815,18 @@ TestResult runReflectionTest(TestContext* context, TestInput& input) expectedOutput = "result code = 0\nstandard error = {\n}\nstandard output = {\n}\n"; } - TestResult result = TestResult::ePass; + TestResult result = TestResult::Pass; // Otherwise we compare to the expected output if (actualOutput != expectedOutput) { - result = TestResult::eFail; + result = TestResult::Fail; } // If the test failed, then we write the actual output to a file // so that we can easily diff it from the command line and // diagnose the problem. - if (result == TestResult::eFail) + if (result == TestResult::Fail) { String actualOutputPath = outputStem + ".actual"; Slang::File::WriteAllText(actualOutputPath, actualOutput); @@ -878,24 +878,24 @@ TestResult runEvalTest(TestContext* context, TestInput& input) if (spawnAndWait(context, outputStem, spawner) != kOSError_None) { - return TestResult::eFail; + return TestResult::Fail; } String actualOutput = getOutput(spawner); String expectedOutput = getExpectedOutput(outputStem); - TestResult result = TestResult::ePass; + TestResult result = TestResult::Pass; // Otherwise we compare to the expected output if (actualOutput != expectedOutput) { - result = TestResult::eFail; + result = TestResult::Fail; } // If the test failed, then we write the actual output to a file // so that we can easily diff it from the command line and // diagnose the problem. - if (result == TestResult::eFail) + if (result == TestResult::Fail) { String actualOutputPath = outputStem + ".actual"; Slang::File::WriteAllText(actualOutputPath, actualOutput); @@ -934,7 +934,7 @@ TestResult runCrossCompilerTest(TestContext* context, TestInput& input) if (spawnAndWait(context, outputStem, expectedSpawner) != kOSError_None) { - return TestResult::eFail; + return TestResult::Fail; } String expectedOutput = getOutput(expectedSpawner); @@ -945,27 +945,27 @@ TestResult runCrossCompilerTest(TestContext* context, TestInput& input) } catch (Slang::IOException) { - return TestResult::eFail; + return TestResult::Fail; } if (spawnAndWait(context, outputStem, actualSpawner) != kOSError_None) { - return TestResult::eFail; + return TestResult::Fail; } String actualOutput = getOutput(actualSpawner); - TestResult result = TestResult::ePass; + TestResult result = TestResult::Pass; // Otherwise we compare to the expected output if (actualOutput != expectedOutput) { - result = TestResult::eFail; + result = TestResult::Fail; } // If the test failed, then we write the actual output to a file // so that we can easily diff it from the command line and // diagnose the problem. - if (result == TestResult::eFail) + if (result == TestResult::Fail) { String actualOutputPath = outputStem + ".actual"; Slang::File::WriteAllText(actualOutputPath, actualOutput); @@ -999,7 +999,7 @@ TestResult generateHLSLBaseline(TestContext* context, TestInput& input) if (spawnAndWait(context, outputStem, spawner) != kOSError_None) { - return TestResult::eFail; + return TestResult::Fail; } String expectedOutput = getOutput(spawner); @@ -1010,9 +1010,9 @@ TestResult generateHLSLBaseline(TestContext* context, TestInput& input) } catch (Slang::IOException) { - return TestResult::eFail; + return TestResult::Fail; } - return TestResult::ePass; + return TestResult::Pass; } TestResult runHLSLComparisonTest(TestContext* context, TestInput& input) @@ -1047,7 +1047,7 @@ TestResult runHLSLComparisonTest(TestContext* context, TestInput& input) if (spawnAndWait(context, outputStem, spawner) != kOSError_None) { - return TestResult::eFail; + return TestResult::Fail; } // We ignore output to stdout, and only worry about what the compiler @@ -1079,26 +1079,26 @@ TestResult runHLSLComparisonTest(TestContext* context, TestInput& input) { } - TestResult result = TestResult::ePass; + TestResult result = TestResult::Pass; // If no expected output file was found, then we // expect everything to be empty if (expectedOutput.Length() == 0) { - if (resultCode != 0) result = TestResult::eFail; - if (standardError.Length() != 0) result = TestResult::eFail; - if (standardOutput.Length() != 0) result = TestResult::eFail; + if (resultCode != 0) result = TestResult::Fail; + if (standardError.Length() != 0) result = TestResult::Fail; + if (standardOutput.Length() != 0) result = TestResult::Fail; } // Otherwise we compare to the expected output else if (actualOutput != expectedOutput) { - result = TestResult::eFail; + result = TestResult::Fail; } // If the test failed, then we write the actual output to a file // so that we can easily diff it from the command line and // diagnose the problem. - if (result == TestResult::eFail) + if (result == TestResult::Fail) { String actualOutputPath = outputStem + ".actual"; Slang::File::WriteAllText(actualOutputPath, actualOutput); @@ -1147,7 +1147,7 @@ TestResult doGLSLComparisonTestRun(TestContext* context, if (spawnAndWait(context, outputStem, spawner) != kOSError_None) { - return TestResult::eFail; + return TestResult::Fail; } OSProcessSpawner::ResultCode resultCode = spawner.getResultCode(); @@ -1170,7 +1170,7 @@ TestResult doGLSLComparisonTestRun(TestContext* context, *outOutput = output; - return TestResult::ePass; + return TestResult::Pass; } TestResult runGLSLComparisonTest(TestContext* context, TestInput& input) @@ -1187,17 +1187,17 @@ TestResult runGLSLComparisonTest(TestContext* context, TestInput& input) Slang::File::WriteAllText(outputStem + ".expected", expectedOutput); Slang::File::WriteAllText(outputStem + ".actual", actualOutput); - if( hlslResult == TestResult::eFail ) return TestResult::eFail; - if( slangResult == TestResult::eFail ) return TestResult::eFail; + if( hlslResult == TestResult::Fail ) return TestResult::Fail; + if( slangResult == TestResult::Fail ) return TestResult::Fail; if (actualOutput != expectedOutput) { context->dumpOutputDifference(expectedOutput, actualOutput); - return TestResult::eFail; + return TestResult::Fail; } - return TestResult::ePass; + return TestResult::Pass; } @@ -1210,7 +1210,7 @@ TestResult runComputeComparisonImpl(TestContext* context, TestInput& input, cons const String referenceOutput = findExpectedPath(input, ".expected.txt"); if (referenceOutput.Length() <= 0) { - return TestResult::eFail; + return TestResult::Fail; } OSProcessSpawner spawner; @@ -1234,7 +1234,7 @@ TestResult runComputeComparisonImpl(TestContext* context, TestInput& input, cons if (spawnAndWait(context, outputStem, spawner) != kOSError_None) { printf("error spawning render-test\n"); - return TestResult::eFail; + return TestResult::Fail; } auto actualOutput = getOutput(spawner); @@ -1246,7 +1246,7 @@ TestResult runComputeComparisonImpl(TestContext* context, TestInput& input, cons String actualOutputPath = outputStem + ".actual"; Slang::File::WriteAllText(actualOutputPath, actualOutput); - return TestResult::eFail; + return TestResult::Fail; } // check against reference output @@ -1254,24 +1254,24 @@ TestResult runComputeComparisonImpl(TestContext* context, TestInput& input, cons { printf("render-test not producing expected outputs.\n"); printf("render-test output:\n%s\n", actualOutput.Buffer()); - return TestResult::eFail; + return TestResult::Fail; } if (!File::Exists(referenceOutput)) { printf("referenceOutput %s not found.\n", referenceOutput.Buffer()); - return TestResult::eFail; + return TestResult::Fail; } auto actualOutputContent = File::ReadAllText(actualOutputFile); auto actualProgramOutput = Split(actualOutputContent, '\n'); auto referenceProgramOutput = Split(File::ReadAllText(referenceOutput), '\n'); auto printOutput = [&]() { - context->messageFormat(TestMessageType::eTestFailure, "output mismatch! actual output: {\n%s\n}, \n%s\n", actualOutputContent.Buffer(), actualOutput.Buffer()); + context->messageFormat(TestMessageType::TestFailure, "output mismatch! actual output: {\n%s\n}, \n%s\n", actualOutputContent.Buffer(), actualOutput.Buffer()); }; if (actualProgramOutput.Count() < referenceProgramOutput.Count()) { printOutput(); - return TestResult::eFail; + return TestResult::Fail; } for (int i = 0; i < (int)referenceProgramOutput.Count(); i++) { @@ -1285,13 +1285,13 @@ TestResult runComputeComparisonImpl(TestContext* context, TestInput& input, cons if (actual != uval) { printOutput(); - return TestResult::eFail; + return TestResult::Fail; } else - return TestResult::ePass; + return TestResult::Pass; } } - return TestResult::ePass; + return TestResult::Pass; } TestResult runSlangComputeComparisonTest(TestContext* context, TestInput& input) @@ -1337,7 +1337,7 @@ TestResult doRenderComparisonTestRun(TestContext* context, TestInput& input, cha if (spawnAndWait(context, outputStem, spawner) != kOSError_None) { - return TestResult::eFail; + return TestResult::Fail; } OSProcessSpawner::ResultCode resultCode = spawner.getResultCode(); @@ -1360,7 +1360,7 @@ TestResult doRenderComparisonTestRun(TestContext* context, TestInput& input, cha *outOutput = output; - return TestResult::ePass; + return TestResult::Pass; } TestResult doImageComparison(TestContext* context, String const& filePath) @@ -1382,19 +1382,19 @@ TestResult doImageComparison(TestContext* context, String const& filePath) if(!expectedData) { - context->messageFormat(TestMessageType::eRunError, "Unable to load image ;%s'", expectedPath.Buffer()); - return TestResult::eFail; + context->messageFormat(TestMessageType::RunError, "Unable to load image ;%s'", expectedPath.Buffer()); + return TestResult::Fail; } if(!actualData) { - context->messageFormat(TestMessageType::eRunError, "Unable to load image '%s'", actualPath.Buffer()); - return TestResult::eFail; + context->messageFormat(TestMessageType::RunError, "Unable to load image '%s'", actualPath.Buffer()); + return TestResult::Fail; } if(expectedX != actualX || expectedY != actualY || expectedN != actualN) { - context->messageFormat(TestMessageType::eTestFailure, "Images are different sizes '%s' '%s'", actualPath.Buffer(), expectedPath.Buffer()); - return TestResult::eFail; + context->messageFormat(TestMessageType::TestFailure, "Images are different sizes '%s' '%s'", actualPath.Buffer(), expectedPath.Buffer()); + return TestResult::Fail; } unsigned char* expectedCursor = expectedData; @@ -1434,7 +1434,7 @@ TestResult doImageComparison(TestContext* context, String const& filePath) // cases where vertex shader results lead to rendering that is off // by one pixel... - context->messageFormat(TestMessageType::eTestFailure, "image compare failure at (%d,%d) channel %d. expected %d got %d (absolute error: %d, relative error: %f)\n", + context->messageFormat(TestMessageType::TestFailure, "image compare failure at (%d,%d) channel %d. expected %d got %d (absolute error: %d, relative error: %f)\n", x, y, n, expectedVal, actualVal, @@ -1442,12 +1442,12 @@ TestResult doImageComparison(TestContext* context, String const& filePath) relativeDiff); // There was a difference we couldn't excuse! - return TestResult::eFail; + return TestResult::Fail; } } } - return TestResult::ePass; + return TestResult::Pass; } TestResult runHLSLRenderComparisonTestImpl( @@ -1468,23 +1468,23 @@ TestResult runHLSLRenderComparisonTestImpl( Slang::File::WriteAllText(outputStem + ".expected", expectedOutput); Slang::File::WriteAllText(outputStem + ".actual", actualOutput); - if( hlslResult == TestResult::eFail ) return TestResult::eFail; - if( slangResult == TestResult::eFail ) return TestResult::eFail; + if( hlslResult == TestResult::Fail ) return TestResult::Fail; + if( slangResult == TestResult::Fail ) return TestResult::Fail; if (actualOutput != expectedOutput) { context->dumpOutputDifference(expectedOutput, actualOutput); - return TestResult::eFail; + return TestResult::Fail; } // Next do an image comparison on the expected output images! TestResult imageCompareResult = doImageComparison(context, outputStem); - if(imageCompareResult != TestResult::ePass) + if(imageCompareResult != TestResult::Pass) return imageCompareResult; - return TestResult::ePass; + return TestResult::Pass; } TestResult runHLSLRenderComparisonTest(TestContext* context, TestInput& input) @@ -1504,7 +1504,7 @@ TestResult runHLSLAndGLSLRenderComparisonTest(TestContext* context, TestInput& i TestResult skipTest(TestContext* /* context */, TestInput& /*input*/) { - return TestResult::eIgnored; + return TestResult::Ignored; } @@ -1610,7 +1610,7 @@ TestResult runTest( // If this test can be ignored if (canIgnoreTestWithDisabledRenderer(testOptions)) { - return TestResult::eIgnored; + return TestResult::Ignored; } // based on command name, dispatch to an appropriate callback @@ -1673,7 +1673,7 @@ TestResult runTest( // No actual test runner found! - return TestResult::eFail; + return TestResult::Fail; } bool testCategoryMatches( @@ -1732,7 +1732,7 @@ void runTestsOnFile( // Gather a list of tests to run FileTestList testList; - if( gatherTestsForFile(filePath, &testList) == TestResult::eIgnored ) + if( gatherTestsForFile(filePath, &testList) == TestResult::Ignored ) { // Test was explicitly ignored return; @@ -1741,7 +1741,7 @@ void runTestsOnFile( // Note cases where a test file exists, but we found nothing to run if( testList.tests.Count() == 0 ) { - context->addTest(filePath, TestResult::eIgnored); + context->addTest(filePath, TestResult::Ignored); return; } @@ -1933,7 +1933,7 @@ int main( // Exclude rendering tests when building under AppVeyor. // // TODO: this is very ad hoc, and we should do something cleaner. - if( g_options.outputMode == TestOutputMode::eAppVeyor ) + if( g_options.outputMode == TestOutputMode::AppVeyor ) { g_options.excludeCategories.Add(renderTestCategory, renderTestCategory); g_options.excludeCategories.Add(vulkanTestCategory, vulkanTestCategory); @@ -1972,7 +1972,6 @@ int main( // TODO: add more directories to this list // TODO: allow for a command-line argument to select a particular directory runTestsInDirectory(&context, "tests/"); - } context.outputSummary(); diff --git a/tools/slang-test/test-context.cpp b/tools/slang-test/test-context.cpp index f77262001..822a5953c 100644 --- a/tools/slang-test/test-context.cpp +++ b/tools/slang-test/test-context.cpp @@ -77,7 +77,7 @@ TestContext::TestContext(TestOutputMode outputMode) : m_failedTestCount = 0; m_ignoredTestCount = 0; - m_maxTestResults = 10; + m_maxFailTestResults = 10; m_inTest = false; m_dumpOutputOnFailure = false; @@ -88,8 +88,8 @@ bool TestContext::canWriteStdError() const { switch (m_outputMode) { - case TestOutputMode::eXUnit: - case TestOutputMode::eXUnit2: + case TestOutputMode::XUnit: + case TestOutputMode::XUnit2: { return false; } @@ -103,6 +103,8 @@ void TestContext::startTest(const String& testName) m_inTest = true; m_numCurrentResults = 0; + m_numFailResults = 0; + m_currentInfo = TestInfo(); m_currentInfo.name = testName; m_currentMessage.Clear(); @@ -133,19 +135,22 @@ void TestContext::addResultWithLocation(TestResult result, const char* testText, m_numCurrentResults++; m_currentInfo.testResult = combine(m_currentInfo.testResult, result); - if (result != TestResult::eFail) + if (result != TestResult::Fail) { // We don't need to output the result if it return; } - if (m_maxTestResults > 0) + m_numFailResults++; + + if (m_maxFailTestResults > 0) { - if (m_numCurrentResults > m_maxTestResults) + if (m_numFailResults > m_maxFailTestResults) { - if (m_numCurrentResults == m_maxTestResults + 1) + if (m_numFailResults == m_maxFailTestResults + 1) { - message(TestMessageType::eInfo, "..."); + // It's a failure, but to show that there are more than are going to be shown, just show '...' + message(TestMessageType::TestFailure, "..."); } return; } @@ -154,17 +159,17 @@ void TestContext::addResultWithLocation(TestResult result, const char* testText, StringBuilder buf; buf << testText << " - " << file << " (" << line << ")"; - message(TestMessageType::eTestFailure, buf); + message(TestMessageType::TestFailure, buf); } void TestContext::addResultWithLocation(bool testSucceeded, const char* testText, const char* file, int line) { - addResultWithLocation(testSucceeded ? TestResult::ePass : TestResult::eFail, testText, file, line); + addResultWithLocation(testSucceeded ? TestResult::Pass : TestResult::Fail, testText, file, line); } TestResult TestContext::addTest(const String& testName, bool isPass) { - const TestResult res = isPass ? TestResult::ePass : TestResult::eFail; + const TestResult res = isPass ? TestResult::Pass : TestResult::Fail; addTest(testName, res); return res; } @@ -188,7 +193,7 @@ void TestContext::dumpOutputDifference(const String& expectedOutput, const Strin } // Add to the m_currentInfo - message(TestMessageType::eTestFailure, builder); + message(TestMessageType::TestFailure, builder); } void TestContext::_addResult(const TestInfo& info) @@ -197,15 +202,15 @@ void TestContext::_addResult(const TestInfo& info) switch (info.testResult) { - case TestResult::eFail: + case TestResult::Fail: m_failedTestCount++; break; - case TestResult::ePass: + case TestResult::Pass: m_passedTestCount++; break; - case TestResult::eIgnored: + case TestResult::Ignored: m_ignoredTestCount++; break; @@ -224,9 +229,9 @@ void TestContext::_addResult(const TestInfo& info) char const* resultString = "UNEXPECTED"; switch (info.testResult) { - case TestResult::eFail: resultString = "FAILED"; break; - case TestResult::ePass: resultString = "passed"; break; - case TestResult::eIgnored: resultString = "ignored"; break; + case TestResult::Fail: resultString = "FAILED"; break; + case TestResult::Pass: resultString = "passed"; break; + case TestResult::Ignored: resultString = "ignored"; break; default: assert(!"unexpected"); break; @@ -234,20 +239,20 @@ void TestContext::_addResult(const TestInfo& info) printf("%s test: '%S'\n", resultString, info.name.ToWString().begin()); break; } - case TestOutputMode::eXUnit2: - case TestOutputMode::eXUnit: + case TestOutputMode::XUnit2: + case TestOutputMode::XUnit: { // Don't output anything -> we'll output all in one go at the end break; } - case TestOutputMode::eAppVeyor: + case TestOutputMode::AppVeyor: { char const* resultString = "None"; switch (info.testResult) { - case TestResult::eFail: resultString = "Failed"; break; - case TestResult::ePass: resultString = "Passed"; break; - case TestResult::eIgnored: resultString = "Ignored"; break; + case TestResult::Fail: resultString = "Failed"; break; + case TestResult::Pass: resultString = "Passed"; break; + case TestResult::Ignored: resultString = "Ignored"; break; default: assert(!"unexpected"); break; @@ -269,7 +274,7 @@ void TestContext::_addResult(const TestInfo& info) if (err != kOSError_None) { - messageFormat(TestMessageType::eInfo, "failed to add appveyor test results for '%S'\n", info.name.ToWString().begin()); + messageFormat(TestMessageType::Info, "failed to add appveyor test results for '%S'\n", info.name.ToWString().begin()); #if 0 fprintf(stderr, "[%d] TEST RESULT: %s {%d} {%s} {%s}\n", err, spawner.commandLine_.Buffer(), @@ -297,7 +302,7 @@ void TestContext::addTest(const String& testName, TestResult testResult) void TestContext::message(TestMessageType type, const String& message) { - if (type == TestMessageType::eInfo) + if (type == TestMessageType::Info) { if (m_isVerbose && canWriteStdError()) { @@ -310,7 +315,7 @@ void TestContext::message(TestMessageType type, const String& message) if (canWriteStdError()) { - if (type == TestMessageType::eRunError || type == TestMessageType::eTestFailure) + if (type == TestMessageType::RunError || type == TestMessageType::TestFailure) { fprintf(stderr, "error: "); fputs(message.Buffer(), stderr); @@ -383,7 +388,7 @@ void TestContext::outputSummary() printf("---\n"); for (const auto& testInfo : m_testInfos) { - if (testInfo.testResult == TestResult::eFail) + if (testInfo.testResult == TestResult::Fail) { printf("%s\n", testInfo.name.Buffer()); } @@ -392,7 +397,7 @@ void TestContext::outputSummary() } break; } - case TestOutputMode::eXUnit: + case TestOutputMode::XUnit: { // xUnit 1.0 format @@ -402,11 +407,11 @@ void TestContext::outputSummary() for (const auto& testInfo : m_testInfos) { - const int numFailed = (testInfo.testResult == TestResult::eFail); - const int numIgnored = (testInfo.testResult == TestResult::eIgnored); + const int numFailed = (testInfo.testResult == TestResult::Fail); + const int numIgnored = (testInfo.testResult == TestResult::Ignored); //int numPassed = (testInfo.testResult == TestResult::ePass); - if (testInfo.testResult == TestResult::ePass) + if (testInfo.testResult == TestResult::Pass) { printf(" <testcase name=\"%s\" status=\"run\"/>\n", testInfo.name.Buffer()); } @@ -415,7 +420,7 @@ void TestContext::outputSummary() printf(" <testcase name=\"%s\" status=\"run\">\n", testInfo.name.Buffer()); switch (testInfo.testResult) { - case TestResult::eFail: + case TestResult::Fail: { StringBuilder buf; appendXmlEncode(testInfo.message, buf); @@ -425,7 +430,7 @@ void TestContext::outputSummary() printf(" </error>\n"); break; } - case TestResult::eIgnored: + case TestResult::Ignored: { printf(" <skip>Ignored</skip>\n"); break; @@ -440,7 +445,7 @@ void TestContext::outputSummary() printf("</testSuites>\n"); break; } - case TestOutputMode::eXUnit2: + case TestOutputMode::XUnit2: { // https://xunit.github.io/docs/format-xml-v2 assert("Not currently supported"); diff --git a/tools/slang-test/test-context.h b/tools/slang-test/test-context.h index 22042a4e6..853bd3015 100644 --- a/tools/slang-test/test-context.h +++ b/tools/slang-test/test-context.h @@ -27,25 +27,27 @@ struct TestRegister enum class TestOutputMode { - eDefault = 0, ///< Default mode is to write test results to the console - eAppVeyor, ///< For AppVeyor continuous integration - eTravis, ///< We currently don't specialize for Travis, but maybe we should. - eXUnit, ///< xUnit original format https://nose.readthedocs.io/en/latest/plugins/xunit.html - eXUnit2, ///< https://xunit.github.io/docs/format-xml-v2 + Default = 0, ///< Default mode is to write test results to the console + AppVeyor, ///< For AppVeyor continuous integration + Travis, ///< We currently don't specialize for Travis, but maybe we should. + XUnit, ///< xUnit original format https://nose.readthedocs.io/en/latest/plugins/xunit.html + XUnit2, ///< https://xunit.github.io/docs/format-xml-v2 }; enum class TestResult { - eIgnored, - ePass, - eFail, + // NOTE! Must keep in order such that combine is meaningful. That is larger values are higher precident - and a series of tests that has lots of passes + // and a fail, is still a fail overall. + Ignored, + Pass, + Fail, }; enum class TestMessageType { - eInfo, ///< General info (may not be shown depending on verbosity setting) - eTestFailure, ///< Describes how a test failure took place - eRunError, ///< Describes an error that caused a test not to actually correctly run + Info, ///< General info (may not be shown depending on verbosity setting) + TestFailure, ///< Describes how a test failure took place + RunError, ///< Describes an error that caused a test not to actually correctly run }; class TestContext @@ -54,7 +56,7 @@ class TestContext struct TestInfo { - TestResult testResult = TestResult::eIgnored; + TestResult testResult = TestResult::Ignored; Slang::String name; Slang::String message; ///< Message that is specific for the testResult }; @@ -118,9 +120,9 @@ class TestContext int m_failedTestCount; int m_ignoredTestCount; - int m_maxTestResults; ///< Maximum amount of results per test. If 0 it's infinite. + int m_maxFailTestResults; ///< Maximum amount of results per test. If 0 it's infinite. - TestOutputMode m_outputMode = TestOutputMode::eDefault; + TestOutputMode m_outputMode = TestOutputMode::Default; bool m_dumpOutputOnFailure; bool m_isVerbose; @@ -130,6 +132,7 @@ protected: Slang::StringBuilder m_currentMessage; TestInfo m_currentInfo; int m_numCurrentResults; + int m_numFailResults; bool m_inTest; diff --git a/tools/slang-test/unit-test-memory-arena.cpp b/tools/slang-test/unit-test-memory-arena.cpp index 69eed520a..20a7e047d 100644 --- a/tools/slang-test/unit-test-memory-arena.cpp +++ b/tools/slang-test/unit-test-memory-arena.cpp @@ -123,15 +123,23 @@ static void memoryArenaUnitTest() blocks.Add(arena.allocate(blockSize * 2)); blocks.Add(arena.allocate(100)); - while (blocks.Count()) + arena.deallocateAll(); + blocks.Add(arena.allocate(100)); + blocks.Add(arena.allocate(blockSize * 2)); + + arena.reset(); + { - arena.deallocateLast(blocks.Last()); - blocks.RemoveLast(); + uint32_t data[] = { 1, 2, 3 }; + + const uint32_t* copy = arena.allocateAndCopyArray(data, SLANG_COUNT_OF(data)); + + SLANG_CHECK(::memcmp(copy, data, sizeof(data)) == 0); } } { - + int count = 0; const size_t blockSize = 1024; for (TestMode mode = TestMode(0); int(mode) < int(TestMode::eCount); mode = TestMode(int(mode) + 1)) @@ -143,32 +151,30 @@ static void memoryArenaUnitTest() List<Block> blocks; - for (int i = 0; i < 1000; i++) + for (int i = 0; i < 10000; i++) { - int var = randGen.nextInt32() & 0x3ff; + count++; + + const int var = randGen.nextInt32() & 0x3ff; if (var < 3 && blocks.Count() > 0) { - if (var == 0) - { - // Do a single dealloc - arena.deallocateLast(blocks.Last().m_data); - blocks.RemoveLast(); - } - else if (var == 1) + if (var == 1) { // Deallocate everything arena.deallocateAll(); blocks.Clear(); + } + else if (var == 2) + { + arena.reset(); + blocks.Clear(); } else { - // Do a multiple dealloc - int index = randGen.nextInt32UpTo(int(blocks.Count())); + size_t usedMemory = arena.calcTotalMemoryUsed(); + size_t allocatedMemory = arena.calcTotalMemoryAllocated(); - // Deallocate all afterwards - arena.deallocateAllFrom(blocks[index].m_data); - - blocks.SetSize(index); + SLANG_CHECK(allocatedMemory >= usedMemory); } } else @@ -180,6 +186,11 @@ static void memoryArenaUnitTest() { sizeInBytes += blockSize; } + else if ((randGen.nextInt32() & 0xff) < 2) + { + // Let's try for a block that's awkwardly sized + sizeInBytes = blockSize / 3 + 10; + } const uint8_t value = uint8_t(randGen.nextInt32()); |
