From dc493d492d4d9c090dab410a0cb80eca490c32aa Mon Sep 17 00:00:00 2001 From: jsmall-nvidia Date: Wed, 14 Aug 2019 12:57:33 -0400 Subject: Small improvements around C/C++ testing (#1017) * * Simplify some of test code around CPPCompiler * Test using 'callable' with pass-through * Small cpu doc improvements * Improvements to Clang output parsing. * Remove temporary file (base filename) . * Improve handling of external errors - handle severity. * On error dumping out to 'actual' file for runCPPCompilerCompile. * Small fixes. Set the source language type correctly for pass thru. * Remove warning for test for clang backend c --- tools/slang-test/slang-test-main.cpp | 240 +++++++++++++++++------------------ tools/slang-test/test-context.cpp | 7 + tools/slang-test/test-context.h | 1 + 3 files changed, 126 insertions(+), 122 deletions(-) (limited to 'tools') diff --git a/tools/slang-test/slang-test-main.cpp b/tools/slang-test/slang-test-main.cpp index 8137733ee..99a139e3c 100644 --- a/tools/slang-test/slang-test-main.cpp +++ b/tools/slang-test/slang-test-main.cpp @@ -1326,11 +1326,18 @@ static String _calcSummary(const CPPCompiler::Output& inOutput) return builder; } -static TestResult runCPPCompilerCompile(TestContext* context, TestInput& input) +static String _calcModulePath(const TestInput& input) { - CPPCompilerSet* compilerSet = context->getCPPCompilerSet(); - CPPCompiler* compiler = compilerSet ? compilerSet->getDefaultCompiler() : nullptr; + // Make the module name the same as the source file + auto filePath = input.filePath; + String directory = Path::getParentDirectory(input.outputStem); + String moduleName = Path::getFileNameWithoutExt(filePath); + return Path::combine(directory, moduleName); +} +static TestResult runCPPCompilerCompile(TestContext* context, TestInput& input) +{ + CPPCompiler* compiler = context->getDefaultCPPCompiler(); if (!compiler) { return TestResult::Ignored; @@ -1344,7 +1351,6 @@ static TestResult runCPPCompilerCompile(TestContext* context, TestInput& input) _initSlangCompiler(context, cmdLine); cmdLine.addArg(input.filePath); - for (auto arg : input.testOptions->args) { cmdLine.addArg(arg); @@ -1352,29 +1358,26 @@ static TestResult runCPPCompilerCompile(TestContext* context, TestInput& input) ExecuteResult exeRes; TEST_RETURN_ON_DONE(spawnAndWait(context, outputStem, input.spawnType, cmdLine, exeRes)); - if (context->isCollectingRequirements()) { return TestResult::Pass; } + // Dump out what happened + { + String actualOutputPath = outputStem + ".actual"; + Slang::File::writeAllText(actualOutputPath, getOutput(exeRes)); + } + if (exeRes.resultCode != 0) { return TestResult::Fail; } - String actualOutput = exeRes.standardOutput; + String modulePath = _calcModulePath(input); - // Make the module name the same as the source file - auto filePath = input.filePath; - String directory = Path::getParentDirectory(input.outputStem); - String moduleName = Path::getFileNameWithoutExt(filePath); - String ext = Path::getFileExt(filePath); - String modulePath = Path::combine(directory, moduleName); - - UnownedStringSlice targetExt = UnownedStringSlice::fromLiteral("c"); - // Find the target + UnownedStringSlice targetExt = UnownedStringSlice::fromLiteral("c"); Index index = cmdLine.findArgIndex(UnownedStringSlice::fromLiteral("-target")); if (index >= 0 && index + 1 < cmdLine.getArgCount()) { @@ -1389,6 +1392,8 @@ static TestResult runCPPCompilerCompile(TestContext* context, TestInput& input) options.includePaths.add("tests/cross-compile"); + String actualOutput = exeRes.standardOutput; + // Create a filename to write this out to String cppSource = modulePath + "." + targetExt; Slang::File::writeAllText(cppSource, actualOutput); @@ -1420,11 +1425,9 @@ static TestResult runCPPCompilerCompile(TestContext* context, TestInput& input) return TestResult::Pass; } -static TestResult runCPPCompilerExecute(TestContext* context, TestInput& input) +static TestResult runCPPCompilerSharedLibrary(TestContext* context, TestInput& input) { - CPPCompilerSet* compilerSet = context->getCPPCompilerSet(); - CPPCompiler* compiler = compilerSet ? compilerSet->getDefaultCompiler() : nullptr; - + CPPCompiler* compiler = context->getDefaultCPPCompiler(); if (!compiler) { return TestResult::Ignored; @@ -1436,101 +1439,110 @@ static TestResult runCPPCompilerExecute(TestContext* context, TestInput& input) return TestResult::Pass; } - auto filePath = input.filePath; auto outputStem = input.outputStem; + auto filePath = input.filePath; String actualOutputPath = outputStem + ".actual"; File::remove(actualOutputPath); // Make the module name the same as the source file - String directory = Path::getParentDirectory(input.outputStem); - String moduleName = Path::getFileNameWithoutExt(filePath); + String modulePath = _calcModulePath(input); String ext = Path::getFileExt(filePath); - String modulePath = Path::combine(directory, moduleName); // Remove the binary.. - { - StringBuilder moduleExePath; - moduleExePath << modulePath; - moduleExePath << ProcessUtil::getExecutableSuffix(); - File::remove(moduleExePath); - } + String sharedLibraryPath = SharedLibrary::calcPlatformPath(modulePath.getUnownedSlice()); + File::remove(sharedLibraryPath); // Set up the compilation options CPPCompiler::CompileOptions options; options.sourceType = (ext == "c") ? CPPCompiler::SourceType::C : CPPCompiler::SourceType::CPP; + // Build a shared library + options.targetType = CPPCompiler::TargetType::SharedLibrary; + // Compile this source options.sourceFiles.add(filePath); options.modulePath = modulePath; + options.includePaths.add("."); + CPPCompiler::Output output; if (SLANG_FAILED(compiler->compile(options, output))) { return TestResult::Fail; } - String actualOutput; - - // If the actual compilation failed, then the output will be if (SLANG_FAILED(output.result)) { - actualOutput = _calcSummary(output); - } - else - { - // Execute the binary and see what we get - - CommandLine cmdLine; + // Compilation failed + String actualOutput = _calcSummary(output); - StringBuilder exePath; - exePath << modulePath << ProcessUtil::getExecutableSuffix(); + // Write the output + Slang::File::writeAllText(actualOutputPath, actualOutput); - cmdLine.setExecutablePath(exePath); + // Check that they are the same + { + // Read the expected + String expectedOutput; + try + { + String expectedOutputPath = outputStem + ".expected"; + expectedOutput = Slang::File::readAllText(expectedOutputPath); + } + catch (Slang::IOException) + { + } - ExecuteResult exeRes; - if (SLANG_FAILED(ProcessUtil::execute(cmdLine, exeRes))) + // Compare if they are the same + if (!StringUtil::areLinesEqual(actualOutput.getUnownedSlice(), expectedOutput.getUnownedSlice())) + { + context->reporter->dumpOutputDifference(expectedOutput, actualOutput); + return TestResult::Fail; + } + } + } + else + { + SharedLibrary::Handle handle; + if (SLANG_FAILED(SharedLibrary::loadWithPlatformPath(sharedLibraryPath.getBuffer(), handle))) { return TestResult::Fail; } - // Write the output, and compare to expected - actualOutput = getOutput(exeRes); - } + const int inValue = 10; + const char inBuffer[] = "Hello World!"; - // Write the output - Slang::File::writeAllText(actualOutputPath, actualOutput); + char buffer[128] = ""; + int value = 0; - // Check that they are the same - { - // Read the expected - String expectedOutput; - try + typedef int(*TestFunc)(int intValue, const char* textValue, char* outTextValue); + + // We could capture output if we passed in a ISlangWriter - but for that to work we'd need a + TestFunc testFunc = (TestFunc)SharedLibrary::findFuncByName(handle, "test"); + if (testFunc) { - String expectedOutputPath = outputStem + ".expected"; - expectedOutput = Slang::File::readAllText(expectedOutputPath); + value = testFunc(inValue, inBuffer, buffer); } - catch (Slang::IOException) + else { + printf("Unable to access 'test' function\n"); } - // Compare if they are the same - if (!StringUtil::areLinesEqual(actualOutput.getUnownedSlice(), expectedOutput.getUnownedSlice())) + SharedLibrary::unload(handle); + + if (!(inValue == value && strcmp(inBuffer, buffer) == 0)) { - context->reporter->dumpOutputDifference(expectedOutput, actualOutput); return TestResult::Fail; } } - + return TestResult::Pass; } -static TestResult runCPPCompilerSharedLibrary(TestContext* context, TestInput& input) +static TestResult runCPPCompilerExecute(TestContext* context, TestInput& input) { - CPPCompilerSet* compilerSet = context->getCPPCompilerSet(); - CPPCompiler* compiler = compilerSet ? compilerSet->getDefaultCompiler() : nullptr; - + CPPCompiler* compiler = context->getDefaultCPPCompiler(); if (!compiler) { return TestResult::Ignored; @@ -1549,100 +1561,84 @@ static TestResult runCPPCompilerSharedLibrary(TestContext* context, TestInput& i File::remove(actualOutputPath); // Make the module name the same as the source file - String directory = Path::getParentDirectory(input.outputStem); - String moduleName = Path::getFileNameWithoutExt(filePath); String ext = Path::getFileExt(filePath); - - String modulePath = Path::combine(directory, moduleName); - - // Remove the binary.. - String sharedLibraryPath = SharedLibrary::calcPlatformPath(modulePath.getUnownedSlice()); - File::remove(sharedLibraryPath); + String modulePath = _calcModulePath(input); + // Remove the binary.. + { + StringBuilder moduleExePath; + moduleExePath << modulePath; + moduleExePath << ProcessUtil::getExecutableSuffix(); + File::remove(moduleExePath); + } + // Set up the compilation options CPPCompiler::CompileOptions options; options.sourceType = (ext == "c") ? CPPCompiler::SourceType::C : CPPCompiler::SourceType::CPP; - - // Build a shared library - options.targetType = CPPCompiler::TargetType::SharedLibrary; // Compile this source options.sourceFiles.add(filePath); options.modulePath = modulePath; - options.includePaths.add("."); - CPPCompiler::Output output; if (SLANG_FAILED(compiler->compile(options, output))) { return TestResult::Fail; } + String actualOutput; + + // If the actual compilation failed, then the output will be if (SLANG_FAILED(output.result)) { - // Compilation failed - String actualOutput = _calcSummary(output); - - // Write the output - Slang::File::writeAllText(actualOutputPath, actualOutput); - - // Check that they are the same - { - // Read the expected - String expectedOutput; - try - { - String expectedOutputPath = outputStem + ".expected"; - expectedOutput = Slang::File::readAllText(expectedOutputPath); - } - catch (Slang::IOException) - { - } - - // Compare if they are the same - if (!StringUtil::areLinesEqual(actualOutput.getUnownedSlice(), expectedOutput.getUnownedSlice())) - { - context->reporter->dumpOutputDifference(expectedOutput, actualOutput); - return TestResult::Fail; - } - } + actualOutput = _calcSummary(output); } else { - SharedLibrary::Handle handle; - if (SLANG_FAILED(SharedLibrary::loadWithPlatformPath(sharedLibraryPath.getBuffer(), handle))) + // Execute the binary and see what we get + + CommandLine cmdLine; + + StringBuilder exePath; + exePath << modulePath << ProcessUtil::getExecutableSuffix(); + + cmdLine.setExecutablePath(exePath); + + ExecuteResult exeRes; + if (SLANG_FAILED(ProcessUtil::execute(cmdLine, exeRes))) { return TestResult::Fail; } - const int inValue = 10; - const char inBuffer[] = "Hello World!"; - - char buffer[128] = ""; - int value = 0; + // Write the output, and compare to expected + actualOutput = getOutput(exeRes); + } - typedef int (*TestFunc)(int intValue, const char* textValue, char* outTextValue); + // Write the output + Slang::File::writeAllText(actualOutputPath, actualOutput); - // We could capture output if we passed in a ISlangWriter - but for that to work we'd need a - TestFunc testFunc = (TestFunc)SharedLibrary::findFuncByName(handle, "test"); - if (testFunc) + // Check that they are the same + { + // Read the expected + String expectedOutput; + try { - value = testFunc(inValue, inBuffer, buffer); + String expectedOutputPath = outputStem + ".expected"; + expectedOutput = Slang::File::readAllText(expectedOutputPath); } - else + catch (Slang::IOException) { - printf("Unable to access 'test' function\n"); } - SharedLibrary::unload(handle); - - if (!(inValue == value && strcmp(inBuffer, buffer) == 0)) + // Compare if they are the same + if (!StringUtil::areLinesEqual(actualOutput.getUnownedSlice(), expectedOutput.getUnownedSlice())) { + context->reporter->dumpOutputDifference(expectedOutput, actualOutput); return TestResult::Fail; } } - + return TestResult::Pass; } diff --git a/tools/slang-test/test-context.cpp b/tools/slang-test/test-context.cpp index 5581ab6db..5da998f03 100644 --- a/tools/slang-test/test-context.cpp +++ b/tools/slang-test/test-context.cpp @@ -102,3 +102,10 @@ CPPCompilerSet* TestContext::getCPPCompilerSet() } return cppCompilerSet; } + +Slang::CPPCompiler* TestContext::getDefaultCPPCompiler() +{ + CPPCompilerSet* set = getCPPCompilerSet(); + return set ? set->getDefaultCompiler() : nullptr; +} + diff --git a/tools/slang-test/test-context.h b/tools/slang-test/test-context.h index a66047687..66486e7bc 100644 --- a/tools/slang-test/test-context.h +++ b/tools/slang-test/test-context.h @@ -93,6 +93,7 @@ class TestContext /// Get compiler factory Slang::CPPCompilerSet* getCPPCompilerSet(); + Slang::CPPCompiler* getDefaultCPPCompiler(); /// Ctor TestContext(); -- cgit v1.2.3