summaryrefslogtreecommitdiff
path: root/tools/slang-test
diff options
context:
space:
mode:
authorYong He <yonghe@outlook.com>2023-09-01 01:25:31 -0700
committerGitHub <noreply@github.com>2023-09-01 01:25:31 -0700
commit9c11a87f8f811a9a110d73a24ab93443ea347506 (patch)
tree9b1b0f154cff0faf7efd8d77fcd7f7911aea4a44 /tools/slang-test
parentb7d19330c2d42937835d674758a05af3891e025b (diff)
Fix GLSL code gen around RayQuery and HitObject types. (#3173)
* Update slang-llvm. * Fix. * fix. * Fix unit tests for multi-thread execution. * Fix tests. * fixes. * update tests. * Add gfx-smoke to linux expected failure list. * Try fix test. --------- Co-authored-by: Yong He <yhe@nvidia.com>
Diffstat (limited to 'tools/slang-test')
-rw-r--r--tools/slang-test/slang-test-main.cpp213
-rw-r--r--tools/slang-test/test-context.h4
2 files changed, 141 insertions, 76 deletions
diff --git a/tools/slang-test/slang-test-main.cpp b/tools/slang-test/slang-test-main.cpp
index c910d83cc..b726caea3 100644
--- a/tools/slang-test/slang-test-main.cpp
+++ b/tools/slang-test/slang-test-main.cpp
@@ -879,7 +879,11 @@ static Result _executeRPC(TestContext* context, SpawnType spawnType, const Unown
}
// Execute
- SLANG_RETURN_ON_FAIL(rpcConnection->sendCall(method, rttiInfo, args));
+ if (SLANG_FAILED(rpcConnection->sendCall(method, rttiInfo, args)))
+ {
+ context->destroyRPCConnection();
+ return SLANG_FAIL;
+ }
// Wait for the result
rpcConnection->waitForResult(context->connectionTimeOutInMs);
@@ -893,12 +897,17 @@ static Result _executeRPC(TestContext* context, SpawnType spawnType, const Unown
if (rpcConnection->getMessageType() != JSONRPCMessageType::Result)
{
+ context->destroyRPCConnection();
return SLANG_FAIL;
}
// Get the result
TestServerProtocol::ExecutionResult exeRes;
- SLANG_RETURN_ON_FAIL(rpcConnection->getMessage(&exeRes));
+ if (SLANG_FAILED(rpcConnection->getMessage(&exeRes)))
+ {
+ context->destroyRPCConnection();
+ return SLANG_FAIL;
+ }
outRes.resultCode = exeRes.returnCode;
outRes.standardError = exeRes.stdError;
@@ -1648,7 +1657,10 @@ TestResult runExecutableTest(TestContext* context, TestInput& input)
// Just use shared library now, TestServer spawn mode seems to cause slangc to fail to find its own
// executable path, and thus failed to find the `gfx.slang` file sitting along side `slangc.exe`.
// We need to figure out what happened to `Path::getExecutablePath()` inside test-server.
- TEST_RETURN_ON_DONE(spawnAndWait(context, outputStem, SpawnType::UseSharedLibrary, cmdLine, exeRes));
+ SpawnType slangcSpawnType = input.spawnType;
+ if (slangcSpawnType == SpawnType::UseTestServer)
+ slangcSpawnType = SpawnType::UseExe;
+ TEST_RETURN_ON_DONE(spawnAndWait(context, outputStem, slangcSpawnType, cmdLine, exeRes));
String actualOutput;
@@ -1702,6 +1714,9 @@ TestResult runExecutableTest(TestContext* context, TestInput& input)
TestResult runLanguageServerTest(TestContext* context, TestInput& input)
{
+ // We don't support running language server tests in parallel yet.
+ std::lock_guard lock(context->mutex);
+
if (!context->m_languageServerConnection)
{
if (SLANG_FAILED(context->createLanguageServerJSONRPCConnection(context->m_languageServerConnection)))
@@ -4072,6 +4087,42 @@ void getFilesInDirectory(String directoryPath, List<String>& files)
}
}
+template<typename F>
+void runTestsInParallel(TestContext* context, int count, const F& f)
+{
+ auto originalReporter = context->getTestReporter();
+ std::atomic<int> consumePtr;
+ consumePtr = 0;
+ auto threadFunc = [&](int threadId)
+ {
+ TestReporter reporter;
+ reporter.init(context->options.outputMode, context->options.expectedFailureList, true);
+ TestReporter::SuiteScope suiteScope(&reporter, "tests");
+ context->setThreadIndex(threadId);
+ context->setTestReporter(&reporter);
+ do
+ {
+ int index = consumePtr.fetch_add(1);
+ if (index >= count)
+ break;
+ f(index);
+ } while (true);
+ {
+ std::lock_guard<std::mutex> lock(context->mutex);
+ originalReporter->consolidateWith(&reporter);
+ }
+ context->setTestReporter(nullptr);
+ };
+ List<std::thread> threads;
+ for (int threadId = 0; threadId < context->options.serverCount; threadId++)
+ {
+ threads.add(std::thread(threadFunc, threadId));
+ }
+ for (auto& t : threads)
+ t.join();
+ context->setTestReporter(originalReporter);
+}
+
void runTestsInDirectory(
TestContext* context,
String directoryPath)
@@ -4119,37 +4170,10 @@ void runTestsInDirectory(
}
else
{
- auto originalReporter = context->getTestReporter();
- std::atomic<int> consumePtr;
- consumePtr = 0;
- auto threadFunc = [&](int threadId)
- {
- TestReporter reporter;
- reporter.init(context->options.outputMode, context->options.expectedFailureList, true);
- TestReporter::SuiteScope suiteScope(&reporter, "tests");
- context->setThreadIndex(threadId);
- context->setTestReporter(&reporter);
- do
+ runTestsInParallel(context, (int)files.getCount(), [&](int index)
{
- int index = consumePtr.fetch_add(1);
- if (index >= (int)files.getCount())
- break;
processFile(files[index]);
- } while (true);
- {
- std::lock_guard<std::mutex> lock(context->mutex);
- originalReporter->consolidateWith(&reporter);
- }
- context->setTestReporter(nullptr);
- };
- List<std::thread> threads;
- for (int threadId = 0; threadId < context->options.serverCount; threadId++)
- {
- threads.add(std::thread(threadFunc, threadId));
- }
- for (auto& t : threads)
- t.join();
- context->setTestReporter(originalReporter);
+ });
}
}
@@ -4205,10 +4229,6 @@ static SlangResult runUnitTestModule(TestContext* context, TestOptions& testOpti
if (!testModule)
return SLANG_FAIL;
- auto reporter = TestReporter::get();
-
- testModule->setTestReporter(reporter);
-
UnitTestContext unitTestContext;
unitTestContext.slangGlobalSession = context->getSession();
unitTestContext.workDirectory = "";
@@ -4217,6 +4237,16 @@ static SlangResult runUnitTestModule(TestContext* context, TestOptions& testOpti
auto testCount = testModule->getTestCount();
+ struct TestItem
+ {
+ UnitTestFunc testFunc;
+ String testName;
+ String command;
+ };
+
+ List<TestItem> tests;
+
+ // Discover all tests first.
for (SlangInt i = 0; i < testCount; i++)
{
auto testFunc = testModule->getTestFunc(i);
@@ -4224,59 +4254,94 @@ static SlangResult runUnitTestModule(TestContext* context, TestOptions& testOpti
StringBuilder filePath;
filePath << moduleName << "/" << testName << ".internal";
+ auto command = filePath.produceString();
- testOptions.command = filePath;
-
- if (shouldRunTest(context, testOptions.command))
+ if (shouldRunTest(context, command))
{
if (testPassesCategoryMask(context, testOptions))
{
- if (spawnType == SpawnType::UseTestServer ||
- spawnType == SpawnType::UseFullyIsolatedTestServer)
- {
- TestServerProtocol::ExecuteUnitTestArgs args;
- args.enabledApis = context->options.enabledApis;
- args.moduleName = moduleName;
- args.testName = testName;
+ tests.add(TestItem{ testFunc, testName, command });
+ }
+ }
+ }
- {
- TestReporter::TestScope scopeTest(reporter, testOptions.command);
- ExecuteResult exeRes;
+ auto runUnitTest = [&](TestItem test)
+ {
+ auto reporter = context->getTestReporter();
+ TestOptions options = testOptions;
+ options.command = test.command;
- SlangResult rpcRes = _executeRPC(context, spawnType, TestServerProtocol::ExecuteUnitTestArgs::g_methodName, &args, exeRes);
- const auto testResult = _asTestResult(ToolReturnCode(exeRes.resultCode));
+ if (spawnType == SpawnType::UseTestServer ||
+ spawnType == SpawnType::UseFullyIsolatedTestServer)
+ {
+ TestServerProtocol::ExecuteUnitTestArgs args;
+ args.enabledApis = context->options.enabledApis;
+ args.moduleName = moduleName;
+ args.testName = test.testName;
- // If the test fails, output any output - which might give information about individual tests that have failed.
- if (SLANG_FAILED(rpcRes) || testResult == TestResult::Fail)
- {
- String output = getOutput(exeRes);
- reporter->message(TestMessageType::TestFailure, output.getBuffer());
- }
+ {
+ TestReporter::TestScope scopeTest(reporter, options.command);
+ ExecuteResult exeRes;
- reporter->addResult(testResult);
- }
- }
- else
+ SlangResult rpcRes = _executeRPC(context, spawnType, TestServerProtocol::ExecuteUnitTestArgs::g_methodName, &args, exeRes);
+ const auto testResult = _asTestResult(ToolReturnCode(exeRes.resultCode));
+
+ // If the test fails, output any output - which might give information about individual tests that have failed.
+ if (SLANG_FAILED(rpcRes) || testResult == TestResult::Fail)
{
- TestReporter::TestScope scopeTest(reporter, testOptions.command);
+ String output = getOutput(exeRes);
+ reporter->message(TestMessageType::TestFailure, output.getBuffer());
+ }
- // TODO(JS): Problem here could be exception not handled properly across
- // shared library boundary.
+ reporter->addResult(testResult);
+ }
+ }
+ else
+ {
+ TestReporter::TestScope scopeTest(reporter, options.command);
- try
- {
- testFunc(&unitTestContext);
- }
- catch (...)
- {
- reporter->message(TestMessageType::TestFailure, "Exception was thrown during execution");
- reporter->addResult(TestResult::Fail);
- }
- }
+ // TODO(JS): Problem here could be exception not handled properly across
+ // shared library boundary.
+ testModule->setTestReporter(reporter);
+ try
+ {
+ test.testFunc(&unitTestContext);
}
+ catch (...)
+ {
+ reporter->message(TestMessageType::TestFailure, "Exception was thrown during execution");
+ reporter->addResult(TestResult::Fail);
+ }
+ }
+ };
+
+ bool useMultiThread = false;
+ if (spawnType == SpawnType::UseTestServer ||
+ spawnType == SpawnType::UseFullyIsolatedTestServer)
+ {
+ if (context->options.serverCount > 1)
+ {
+ useMultiThread = true;
}
}
+ if (useMultiThread)
+ {
+ runTestsInParallel(context, (int)tests.getCount(), [&](int index)
+ {
+ runUnitTest(tests[index]);
+ });
+ }
+ else
+ {
+ auto reporter = TestReporter::get();
+
+ testModule->setTestReporter(reporter);
+
+ for (auto t : tests)
+ runUnitTest(t);
+ }
+
testModule->destroy();
return SLANG_OK;
}
diff --git a/tools/slang-test/test-context.h b/tools/slang-test/test-context.h
index 00aad5888..ad8a45042 100644
--- a/tools/slang-test/test-context.h
+++ b/tools/slang-test/test-context.h
@@ -159,8 +159,8 @@ class TestContext
/// TODO(JS): We could split the stdlib compilation from other actions, and have timeout specific for
/// that. To do this we could have a 'compileStdLib' RPC method.
///
- /// Current default is 2 mins.
- Slang::Int connectionTimeOutInMs = 2 * 60 * 1000;
+ /// Current default is 20 seconds.
+ Slang::Int connectionTimeOutInMs = 20 * 1000;
void setThreadIndex(int index);
void setMaxTestRunnerThreadCount(int count);