Skip to content

Commit 62b1e58

Browse files
authored
Runs all gfx unit tests through a 'test proxy' (shader-slang#1981)
* #include an absolute path didn't work - because paths were taken to always be relative. * Support for test proxy. * Turn on testing using proxy. * Don't pass sink into check of downstream compiler. * Small change to kick off build. * Remove register specification on transcendental. * Increase poll timeout. Small improvements to proxy. * Disable gfx unit tests. * Put test runner in shared library mode by default. * Change comment. Kick off another CI test. * Small edit to kick off builds. * Run unit tests on proxy. * Turn on using proxy for now. * Enable swift shader. * Fix typo. Add exception support. * Make the default spwan type SharedLibrary Use isolation for gfx unit tests. * Update slang-binaries. * Fix typo. * Report unit test output information.
1 parent dcc2b85 commit 62b1e58

10 files changed

+852
-477
lines changed

premake5.lua

+7
Original file line numberDiff line numberDiff line change
@@ -756,6 +756,13 @@ end
756756

757757
links { "compiler-core", "core" }
758758

759+
760+
tool "test-proxy"
761+
uuid "BE412850-4BB9-429A-877C-BFBC4B34186C"
762+
includedirs { "." }
763+
764+
links { "compiler-core", "core", "slang" }
765+
759766
--
760767
-- `slang-generate` is a tool we use for source code generation on
761768
-- the compiler. It depends on the `core` library, so we need to

slang.sln

+465-450
Large diffs are not rendered by default.

source/core/unix/slang-unix-process-util.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -146,9 +146,9 @@ namespace Slang {
146146
return SLANG_FAIL;
147147
}
148148

149-
// Set a timeout of twenty seconds;
149+
// Set a timeout of 100 seconds;
150150
// we really shouldn't wait too long...
151-
int pollTimeout = 20000;
151+
int pollTimeout = 100000;
152152
int pollResult = poll(pollInfos, pollInfoCount, pollTimeout);
153153
if (pollResult <= 0)
154154
{

source/slang/slang-check.cpp

+4-4
Original file line numberDiff line numberDiff line change
@@ -93,10 +93,10 @@ namespace Slang
9393
if (type == PassThroughMode::GenericCCpp)
9494
{
9595
// try testing for availability on all C/C++ compilers
96-
getOrLoadDownstreamCompiler(PassThroughMode::Clang, sink);
97-
getOrLoadDownstreamCompiler(PassThroughMode::Gcc, sink);
98-
getOrLoadDownstreamCompiler(PassThroughMode::VisualStudio, sink);
99-
getOrLoadDownstreamCompiler(PassThroughMode::LLVM, sink);
96+
getOrLoadDownstreamCompiler(PassThroughMode::Clang, nullptr);
97+
getOrLoadDownstreamCompiler(PassThroughMode::Gcc, nullptr);
98+
getOrLoadDownstreamCompiler(PassThroughMode::VisualStudio, nullptr);
99+
getOrLoadDownstreamCompiler(PassThroughMode::LLVM, nullptr);
100100
}
101101

102102
// Mark that we have tried to load it

tests/compute/transcendental-double.slang

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
//DISABLE_TEST(compute,vulkan):COMPARE_COMPUTE:-vk -output-using-type -shaderobj
99

1010
//TEST_INPUT:ubuffer(data=[0 0 0 0 0 0 0 0], stride=4):out,name=outputBuffer
11-
RWStructuredBuffer<float> outputBuffer : register(u0);
11+
RWStructuredBuffer<float> outputBuffer;
1212

1313
float quantize(double value)
1414
{

tests/compute/transcendental.slang

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
//TEST(compute,vulkan):COMPARE_COMPUTE:-vk -output-using-type -shaderobj
55

66
//TEST_INPUT:ubuffer(data=[0 0 0 0 0 0 0 0], stride=4):out,name=outputBuffer
7-
RWStructuredBuffer<float> outputBuffer : register(u0);
7+
RWStructuredBuffer<float> outputBuffer;
88

99
float quantize(float value)
1010
{

tools/slang-test/options.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -125,9 +125,9 @@ static bool _isSubCommand(const char* arg)
125125
}
126126
optionsOut->binDir = *argCursor++;
127127
}
128-
else if (strcmp(arg, "-useexes") == 0)
128+
else if (strcmp(arg, "-use-test-proxy") == 0)
129129
{
130-
optionsOut->useExes = true;
130+
optionsOut->defaultSpawnType = SpawnType::UseProxy;
131131
}
132132
else if (strcmp(arg, "-v") == 0)
133133
{

tools/slang-test/options.h

+14-3
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,13 @@ struct TestCategorySet
3636
Slang::Dictionary<Slang::String, Slang::RefPtr<TestCategory> > m_categoryMap;
3737
};
3838

39+
enum class SpawnType
40+
{
41+
UseExe,
42+
UseSharedLibrary,
43+
UseProxy,
44+
};
45+
3946
struct Options
4047
{
4148
char const* appName = "slang-test";
@@ -69,9 +76,13 @@ struct Options
6976
// integration builds.
7077
bool dumpOutputOnFailure = false;
7178

72-
// If set, will force using of executables (not shared library) for tests
73-
bool useExes = false;
74-
79+
// Set the default spawn type to use
80+
// Set to SpawnType::UseProxy, if isolation of test execution is desired.
81+
// Having tests isolated, slows down testing considerably, so using UseSharedLibrary is the most
82+
// desirable default usually.
83+
SpawnType defaultSpawnType = SpawnType::UseSharedLibrary;
84+
//SpawnType defaultSpawnType = SpawnType::UseProxy;
85+
7586
// kind of output to generate
7687
TestOutputMode outputMode = TestOutputMode::Default;
7788

tools/slang-test/slang-test-main.cpp

+109-14
Original file line numberDiff line numberDiff line change
@@ -97,11 +97,6 @@ struct FileTestList
9797
List<TestDetails> tests;
9898
};
9999

100-
enum class SpawnType
101-
{
102-
UseExe,
103-
UseSharedLibrary,
104-
};
105100

106101
struct TestInput
107102
{
@@ -531,6 +526,8 @@ static SlangResult _gatherTestsForFile(
531526
return SLANG_OK;
532527
}
533528

529+
530+
534531
Result spawnAndWaitExe(TestContext* context, const String& testPath, const CommandLine& cmdLine, ExecuteResult& outRes)
535532
{
536533
const auto& options = context->options;
@@ -550,6 +547,7 @@ Result spawnAndWaitExe(TestContext* context, const String& testPath, const Comma
550547
return res;
551548
}
552549

550+
553551
Result spawnAndWaitSharedLibrary(TestContext* context, const String& testPath, const CommandLine& cmdLine, ExecuteResult& outRes)
554552
{
555553
const auto& options = context->options;
@@ -620,6 +618,44 @@ Result spawnAndWaitSharedLibrary(TestContext* context, const String& testPath, c
620618
}
621619

622620

621+
Result spawnAndWaitProxy(TestContext* context, const String& testPath, const CommandLine& inCmdLine, ExecuteResult& outRes)
622+
{
623+
// Get the name of the thing to execute
624+
String exeName = Path::getFileNameWithoutExt(inCmdLine.m_executable);
625+
626+
if (exeName == "slangc")
627+
{
628+
// If the test is slangc there is a command line version we can just directly use
629+
//return spawnAndWaitExe(context, testPath, inCmdLine, outRes);
630+
return spawnAndWaitSharedLibrary(context, testPath, inCmdLine, outRes);
631+
}
632+
633+
CommandLine cmdLine(inCmdLine);
634+
635+
// Make the first arg the name of the tool to invoke
636+
cmdLine.m_args.insert(0, exeName);
637+
638+
auto exePath = Path::combine(Path::getParentDirectory(inCmdLine.m_executable), String("test-proxy") + ProcessUtil::getExecutableSuffix());
639+
cmdLine.setExecutablePath(exePath);
640+
641+
const auto& options = context->options;
642+
if (options.shouldBeVerbose)
643+
{
644+
String commandLine = ProcessUtil::getCommandLineString(cmdLine);
645+
context->reporter->messageFormat(TestMessageType::Info, "%s\n", commandLine.begin());
646+
}
647+
648+
// Execute
649+
Result res = ProcessUtil::execute(cmdLine, outRes);
650+
if (SLANG_FAILED(res))
651+
{
652+
// fprintf(stderr, "failed to run test '%S'\n", testPath.ToWString());
653+
context->reporter->messageFormat(TestMessageType::RunError, "failed to run test '%S'", testPath.toWString().begin());
654+
}
655+
656+
return res;
657+
}
658+
623659
static SlangResult _extractArg(const CommandLine& cmdLine, const String& argName, String& outValue)
624660
{
625661
SLANG_ASSERT(argName.getLength() > 0 && argName[0] == '-');
@@ -972,6 +1008,11 @@ ToolReturnCode spawnAndWait(TestContext* context, const String& testPath, SpawnT
9721008
spawnResult = spawnAndWaitSharedLibrary(context, testPath, cmdLine, outExeRes);
9731009
break;
9741010
}
1011+
case SpawnType::UseProxy:
1012+
{
1013+
spawnResult = spawnAndWaitProxy(context, testPath, cmdLine, outExeRes);
1014+
break;
1015+
}
9751016
default: break;
9761017
}
9771018

@@ -2880,8 +2921,6 @@ TestResult runTest(
28802921
return TestResult::Pass;
28812922
}
28822923

2883-
const SpawnType defaultSpawnType = context->options.useExes ? SpawnType::UseExe : SpawnType::UseSharedLibrary;
2884-
28852924
auto testInfo = _findTestCommandInfoByCommand(testOptions.command.getUnownedSlice());
28862925

28872926
if (testInfo)
@@ -2890,7 +2929,7 @@ TestResult runTest(
28902929
testInput.filePath = filePath;
28912930
testInput.outputStem = outputStem;
28922931
testInput.testOptions = &testOptions;
2893-
testInput.spawnType = defaultSpawnType;
2932+
testInput.spawnType = context->options.defaultSpawnType;
28942933

28952934
return testInfo->callback(context, testInput);
28962935
}
@@ -3346,8 +3385,18 @@ static void _disableCPPBackends(TestContext* context)
33463385
}
33473386
}
33483387

3388+
static TestResult _asTestResult(ToolReturnCode retCode)
3389+
{
3390+
switch (retCode)
3391+
{
3392+
default: return TestResult::Fail;
3393+
case ToolReturnCode::Success: return TestResult::Pass;
3394+
case ToolReturnCode::Ignored: return TestResult::Ignored;
3395+
}
3396+
}
3397+
33493398
/// Loads a DLL containing unit test functions and run them one by one.
3350-
static SlangResult runUnitTestModule(TestContext* context, TestOptions& testOptions, const char* moduleName)
3399+
static SlangResult runUnitTestModule(TestContext* context, TestOptions& testOptions, SpawnType spawnType, const char* moduleName)
33513400
{
33523401
SharedLibrary::Handle moduleHandle;
33533402
SLANG_RETURN_ON_FAIL(SharedLibrary::load(
@@ -3368,6 +3417,9 @@ static SlangResult runUnitTestModule(TestContext* context, TestOptions& testOpti
33683417
unitTestContext.workDirectory = "";
33693418
unitTestContext.enabledApis = context->options.enabledApis;
33703419
auto testCount = testModule->getTestCount();
3420+
3421+
TestReporter* reporter = TestReporter::get();
3422+
33713423
for (SlangInt i = 0; i < testCount; i++)
33723424
{
33733425
auto testFunc = testModule->getTestFunc(i);
@@ -3382,9 +3434,50 @@ static SlangResult runUnitTestModule(TestContext* context, TestOptions& testOpti
33823434
{
33833435
if (testPassesCategoryMask(context, testOptions))
33843436
{
3385-
TestReporter::get()->startTest(testOptions.command.getBuffer());
3386-
testFunc(&unitTestContext);
3387-
TestReporter::get()->endTest();
3437+
if (spawnType == SpawnType::UseProxy)
3438+
{
3439+
CommandLine cmdLine;
3440+
3441+
// The 'command' is the module
3442+
cmdLine.setExecutablePath(Path::combine(context->exeDirectoryPath, moduleName));
3443+
3444+
// Pass the test name / index
3445+
cmdLine.addArg(testName);
3446+
3447+
{
3448+
StringBuilder buf;
3449+
buf << i;
3450+
cmdLine.addArg(buf.ProduceString());
3451+
}
3452+
3453+
// Pass the enabled apis
3454+
{
3455+
StringBuilder buf;
3456+
buf << context->options.enabledApis;
3457+
cmdLine.addArg(buf.ProduceString());
3458+
}
3459+
3460+
{
3461+
TestReporter::TestScope scopeTest(reporter, testOptions.command);
3462+
ExecuteResult exeRes;
3463+
3464+
const auto testResult = _asTestResult(spawnAndWait(context, filePath, spawnType, cmdLine, exeRes));
3465+
3466+
// If the test fails, output any output - which might give information about individual tests that have failed.
3467+
if (testResult == TestResult::Fail)
3468+
{
3469+
String output = getOutput(exeRes);
3470+
reporter->message(TestMessageType::TestFailure, output.getBuffer());
3471+
}
3472+
3473+
reporter->addResult(testResult);
3474+
}
3475+
}
3476+
else
3477+
{
3478+
TestReporter::TestScope scopeTest(reporter, testOptions.command);
3479+
testFunc(&unitTestContext);
3480+
}
33883481
}
33893482
}
33903483
}
@@ -3570,13 +3663,15 @@ SlangResult innerMain(int argc, char** argv)
35703663
TestOptions testOptions;
35713664
testOptions.categories.add(unitTestCategory);
35723665
testOptions.categories.add(smokeTestCategory);
3573-
runUnitTestModule(&context, testOptions, "slang-unit-test-tool");
3666+
runUnitTestModule(&context, testOptions, context.options.defaultSpawnType, "slang-unit-test-tool");
35743667
}
3668+
35753669
{
35763670
TestOptions testOptions;
35773671
testOptions.categories.add(unitTestCategory);
3578-
runUnitTestModule(&context, testOptions, "gfx-unit-test-tool");
3672+
runUnitTestModule(&context, testOptions, SpawnType::UseProxy, "gfx-unit-test-tool");
35793673
}
3674+
35803675
TestReporter::set(nullptr);
35813676
}
35823677

0 commit comments

Comments
 (0)