diff options
| author | jsmall-nvidia <jsmall@nvidia.com> | 2021-11-18 15:58:12 -0500 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2021-11-18 15:58:12 -0500 |
| commit | 1d5f815b3964edee8a2d701e1a6cc078c89d677f (patch) | |
| tree | aa5b4b1473344e635d7ce1d2159fc57eeb40b841 /tools | |
| parent | b482844b689eb109ee1d70c527e098400ac6d409 (diff) | |
RTTI/JSON (#2021)
* #include an absolute path didn't work - because paths were taken to always be relative.
* Use 'Process' to communicate with an command line tool.
* Remove slang-win-stream
* Tidy up windows ProcessUtil.
* First version of BufferedReadStream.
* Windows working IPC for steams.
* Test proxy count option.
* Split Process/ProcessUtil. Process is platform dependant. ProcessUtil are functions that are platform independent.
* First implementation of Unix Process interface.
* Unix process compiles on cygwin.
* Fix typo in unix process.
* Separate unix pipe stream error of invalid access, from pipe availability.
* Fix in standard line extraction.
* Make fd non blocking.
* Fix issues with Windows Process streams.
* Added UnixPipe.
* Some fixes around UnixPipeStream.
* Make a unix stream closed explicit.
* Hack to debug linux process/stream.
* Revert to old linux pipe handling.
* Pass executable path for unit tests.
Split out CommandLine into own source.
* Small improvements in process/command line.
* Check process behavior with crash.
* Make stderr and stdout unbuffered for crash testing.
* Only turn disable buffering in crash test.
* Disable crash test on CI.
* Fix crash on clang/linux.
* Enable crash test.
Remove _appendBuffer as can use StreamUtil functionality.
* Added inital processing for http headers.
* Small improvements to HttpHeader.
* First pass HTTPPacketConnection working on windows.
* Enable other Process communication tests.
* Update comments.
* WIP JSON RPC.
* Add terminate to Process.
Made JSONRPC a Util.
* Small tidy up around HTTPPacketConnection.
* Improve process termination options.
* WIP for test-server.
* Add diagnostics error handling to test-server.
* Improved JSON support.
Parsing/creating JSON-RPC messages.
* WIP JSONRPC parsing.
* First pass RttiInfo support.
* WIP converting between JSON/native types.
* Project files.
* Split out RttiUtil.
Made RttiInfo constuction thread safe.
* WIP RTTI<->JSON.
* Add diagnostics to JSON<->native conversions.
* Make RttiInfo for structs globals. Avoids problem around derived types (like pointers), being able to cause an abort.
* Add pointer support to RTTI.
Fixed some compilation issues on linux.
* Add fixed array support.
* Added Rtti unit test.
* Add rtti unit test.
* Split out quoted/unquoted key handling.
Fix bugs in JSON value/container.
Added JSON native test.
* Make default array allocator use malloc/free.
Remove the new[] handler (doesn't work on visuals studio).
* Fix for linux warning.
* Remove some test code.
* Fix issues on x86 win.
* Fix warning on aarch64.
Diffstat (limited to 'tools')
| -rw-r--r-- | tools/slang-unit-test/unit-test-json-native.cpp | 117 | ||||
| -rw-r--r-- | tools/slang-unit-test/unit-test-rtti.cpp | 74 | ||||
| -rw-r--r-- | tools/test-server/test-server-diagnostic-defs.h | 26 | ||||
| -rw-r--r-- | tools/test-server/test-server-diagnostics.cpp | 13 | ||||
| -rw-r--r-- | tools/test-server/test-server-diagnostics.h | 21 | ||||
| -rw-r--r-- | tools/test-server/test-server-main.cpp | 510 |
6 files changed, 761 insertions, 0 deletions
diff --git a/tools/slang-unit-test/unit-test-json-native.cpp b/tools/slang-unit-test/unit-test-json-native.cpp new file mode 100644 index 000000000..1d2085751 --- /dev/null +++ b/tools/slang-unit-test/unit-test-json-native.cpp @@ -0,0 +1,117 @@ +// unit-test-json-native.cpp + +#include "../../source/core/slang-rtti-info.h" + +#include "../../source/compiler-core/slang-json-native.h" +#include "../../source/compiler-core/slang-json-parser.h" + +#include "tools/unit-test/slang-unit-test.h" + +using namespace Slang; + +namespace { // anonymous + +struct SomeStruct +{ + typedef SomeStruct ThisType; + + bool operator==(const ThisType& rhs) const + { + return a == rhs.a && b == rhs.b && s == rhs.s && list == rhs.list; + } + bool operator!=(const ThisType& rhs) const { return !(*this == rhs); } + + int a = 0; + float b = 2.0f; + String s; + List<String> list; + + static const StructRttiInfo g_rttiInfo; +}; + +} // anonymous + +static const StructRttiInfo _makeSomeStructRtti() +{ + SomeStruct obj; + StructRttiBuilder builder(&obj, "SomeStruct", nullptr); + + builder.addField("a", &obj.a); + builder.addField("b", &obj.b); + builder.addField("s", &obj.s); + builder.addField("list", &obj.list); + + return builder.make(); +} +/* static */const StructRttiInfo SomeStruct::g_rttiInfo = _makeSomeStructRtti(); + +static SlangResult _check() +{ + // Convert into a JSON string + + SomeStruct s; + s.list.add("Hello!"); + s.s = "There"; + + // Try serializing it out + + SourceManager sourceManager; + sourceManager.initialize(nullptr, nullptr); + + DiagnosticSink sink(&sourceManager, &JSONLexer::calcLexemeLocation); + + RefPtr<JSONContainer> container(new JSONContainer(&sourceManager)); + + String json; + { + NativeToJSONConverter converter(container, &sink); + + JSONValue value; + SLANG_RETURN_ON_FAIL(converter.convert(GetRttiInfo<SomeStruct>::get(), &s, value)); + + // Convert into a string + JSONWriter writer(JSONWriter::IndentationStyle::Allman); + container->traverseRecursively(value, &writer); + + json = writer.getBuilder(); + } + + JSONValue readValue; + { + // Now need to parse as JSON + String contents(json); + SourceFile* sourceFile = sourceManager.createSourceFileWithString(PathInfo::makeUnknown(), contents); + SourceView* sourceView = sourceManager.createSourceView(sourceFile, nullptr, SourceLoc()); + + JSONLexer lexer; + lexer.init(sourceView, &sink); + + JSONBuilder builder(container); + + JSONParser parser; + SLANG_RETURN_ON_FAIL(parser.parse(&lexer, sourceView, &builder, &sink)); + + readValue = builder.getRootValue(); + } + + // Convert back to native + { + JSONToNativeConverter converter(container, &sink); + + { + SomeStruct readS; + SLANG_RETURN_ON_FAIL(converter.convert(readValue, GetRttiInfo<SomeStruct>::get(), &readS)); + + // Should be equal + SLANG_CHECK(readS == s); + } + } + + return SLANG_OK; +} + +SLANG_UNIT_TEST(JSONNative) +{ + SLANG_CHECK(SLANG_SUCCEEDED(_check())); + +} diff --git a/tools/slang-unit-test/unit-test-rtti.cpp b/tools/slang-unit-test/unit-test-rtti.cpp new file mode 100644 index 000000000..f72cfbde2 --- /dev/null +++ b/tools/slang-unit-test/unit-test-rtti.cpp @@ -0,0 +1,74 @@ +// unit-test-rtti.cpp + +#include "../../source/core/slang-rtti-info.h" + +#include "tools/unit-test/slang-unit-test.h" + +using namespace Slang; + +namespace { // anonymous + +struct SomeStruct +{ + int a = 0; + float b = 2.0f; + String s; + List<String> list; + + static const StructRttiInfo g_rttiInfo; +}; + +} // anonymous + +static const StructRttiInfo _makeSomeStructRtti() +{ + SomeStruct obj; + StructRttiBuilder builder(&obj, "SomeStruct", nullptr); + + builder.addField("a", &obj.a); + builder.addField("b", &obj.b); + builder.addField("s", &obj.s); + builder.addField("list", &obj.list); + + return builder.make(); +} +/* static */const StructRttiInfo SomeStruct::g_rttiInfo = _makeSomeStructRtti(); + +SLANG_UNIT_TEST(Rtti) +{ + using namespace Slang; + + const RttiInfo* types[] = + { + GetRttiInfo<int32_t>::get(), + GetRttiInfo<int32_t[10]>::get(), + GetRttiInfo<String>::get(), + GetRttiInfo<List<String>>::get(), + GetRttiInfo<List<List<String>>>::get(), + GetRttiInfo<int32_t[2][3]>::get(), + GetRttiInfo<SomeStruct>::get(), + GetRttiInfo<SomeStruct*>::get(), + GetRttiInfo<const float*const>::get(), + }; + + StringBuilder buf; + + for (auto type : types) + { + RttiInfo::append(type, buf); + buf << "\n"; + } + + const char expected[] = + "int32_t\n" + "int32_t[10]\n" + "String\n" + "List<String>\n" + "List<List<String>>\n" + "int32_t[2][3]\n" + "SomeStruct\n" + "SomeStruct*\n" + "float*\n"; + + SLANG_CHECK(buf == expected) +} diff --git a/tools/test-server/test-server-diagnostic-defs.h b/tools/test-server/test-server-diagnostic-defs.h new file mode 100644 index 000000000..ef0b280e8 --- /dev/null +++ b/tools/test-server/test-server-diagnostic-defs.h @@ -0,0 +1,26 @@ +// + +// The file is meant to be included multiple times, to produce different +// pieces of declaration/definition code related to diagnostic messages +// +// Each diagnostic is declared here with: +// +// DIAGNOSTIC(id, severity, name, messageFormat) +// +// Where `id` is the unique diagnostic ID, `severity` is the default +// severity (from the `Severity` enum), `name` is a name used to refer +// to this diagnostic from code, and `messageFormat` is the default +// (non-localized) message for the diagnostic, with placeholders +// for any arguments. + +#ifndef DIAGNOSTIC +#error Need to #define DIAGNOSTIC(...) before including "test-server-diagnostics-defs.h" +#define DIAGNOSTIC(id, severity, name, messageFormat) /* */ +#endif + +DIAGNOSTIC(100000, Error, unableToLoadSharedLibrary, "Unable to load shared library '$0'") +DIAGNOSTIC(100001, Error, unableToFindFunctionInSharedLibrary, "Unable to find function '$0' in shared library") +DIAGNOSTIC(100002, Error, unableToGetUnitTestModule, "Unable to get unit test module") +DIAGNOSTIC(100003, Error, unableToFindTest, "Unable to find test '$0'") + +#undef DIAGNOSTIC diff --git a/tools/test-server/test-server-diagnostics.cpp b/tools/test-server/test-server-diagnostics.cpp new file mode 100644 index 000000000..ddefc53d3 --- /dev/null +++ b/tools/test-server/test-server-diagnostics.cpp @@ -0,0 +1,13 @@ +#include "test-server-diagnostics.h" + +namespace TestServer { + +namespace ServerDiagnostics +{ +using namespace Slang; + +#define DIAGNOSTIC(id, severity, name, messageFormat) const DiagnosticInfo name = { id, Severity::severity, #name, messageFormat }; +#include "test-server-diagnostic-defs.h" +} + +} // namespace TestServer diff --git a/tools/test-server/test-server-diagnostics.h b/tools/test-server/test-server-diagnostics.h new file mode 100644 index 000000000..be816135a --- /dev/null +++ b/tools/test-server/test-server-diagnostics.h @@ -0,0 +1,21 @@ +#ifndef TEST_SERVER_DIAGNOSTICS_H +#define TEST_SERVER_DIAGNOSTICS_H + +#include "../../source/core/slang-basic.h" +#include "../../source/core/slang-writer.h" + +#include "../../source/compiler-core/slang-source-loc.h" +#include "../../source/compiler-core/slang-diagnostic-sink.h" + +namespace TestServer { +using namespace Slang; + +namespace ServerDiagnostics { + +#define DIAGNOSTIC(id, severity, name, messageFormat) extern const DiagnosticInfo name; +#include "test-server-diagnostic-defs.h" + +} // ServerDiagnostics +} // TestServer + +#endif diff --git a/tools/test-server/test-server-main.cpp b/tools/test-server/test-server-main.cpp new file mode 100644 index 000000000..7e4180441 --- /dev/null +++ b/tools/test-server/test-server-main.cpp @@ -0,0 +1,510 @@ +// test-server.cpp + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include "../../source/core/slang-secure-crt.h" + +#include "../../slang-com-helper.h" + +#include "../../source/core/slang-string.h" +#include "../../source/core/slang-io.h" +#include "../../source/core/slang-writer.h" +#include "../../source/core/slang-string-util.h" +#include "../../source/core/slang-process-util.h" + +#include "../../source/core/slang-shared-library.h" + +#include "../../source/core/slang-test-tool-util.h" +#include "../../source/core/slang-http.h" + +#include "../../source/compiler-core/slang-source-loc.h" +#include "../../source/compiler-core/slang-diagnostic-sink.h" + +#include "../../source/compiler-core/slang-json-parser.h" +#include "../../source/compiler-core/slang-json-rpc.h" +#include "../../source/compiler-core/slang-json-value.h" + +#include "test-server-diagnostics.h" + +#include "tools/unit-test/slang-unit-test.h" + +namespace TestServer +{ +using namespace Slang; + +class TestReporter : public ITestReporter +{ +public: + // ITestReporter + virtual SLANG_NO_THROW void SLANG_MCALL startTest(const char* testName) SLANG_OVERRIDE { } + virtual SLANG_NO_THROW void SLANG_MCALL addResult(TestResult result)SLANG_OVERRIDE; + virtual SLANG_NO_THROW void SLANG_MCALL addResultWithLocation(TestResult result, const char* testText, const char* file, int line) SLANG_OVERRIDE; + virtual SLANG_NO_THROW void SLANG_MCALL addResultWithLocation(bool testSucceeded, const char* testText, const char* file, int line) SLANG_OVERRIDE; + virtual SLANG_NO_THROW void SLANG_MCALL addExecutionTime(double time) SLANG_OVERRIDE { } + virtual SLANG_NO_THROW void SLANG_MCALL message(TestMessageType type, const char* message) SLANG_OVERRIDE; + virtual SLANG_NO_THROW void SLANG_MCALL endTest() SLANG_OVERRIDE { } + + StringBuilder m_buf; + Index m_failCount = 0; + Index m_testCount = 0; +}; + +class TestServer +{ +public: + typedef Slang::TestToolUtil::InnerMainFunc InnerMainFunc; + + SlangResult init(int argc, const char* const* argv); + + /// Can return nullptr if cannot create the session + slang::IGlobalSession* getGlobalSession(); + + /// Can return nullptr if cannot load the tool + ISlangSharedLibrary* loadSharedLibrary(const String& name, DiagnosticSink* sink = nullptr); + + /// Get a unit test module. Returns nullptr if not found. + IUnitTestModule* getUnitTestModule(const String& name, DiagnosticSink* sink = nullptr); + + /// Given a tool name return it's function pointer. Or nullptr on failure. + InnerMainFunc getToolFunction(const String& name, DiagnosticSink* sink = nullptr); + + /// Execute the server + SlangResult execute(); + + /// Dtor + ~TestServer(); + +protected: + SlangResult _executeSingle(); + SlangResult _executeUnitTest(JSONContainer* container, const JSONValue& root); + SlangResult _executeTool(JSONContainer* container, const JSONValue& root); + SlangResult _writeResponse(JSONContainer* containers, const JSONValue& root); + + bool m_quit = false; + + ComPtr<slang::IGlobalSession> m_session; + + Dictionary<String, ComPtr<ISlangSharedLibrary>> m_sharedLibraryMap; ///< Maps tool names to the dll + Dictionary<String, IUnitTestModule*> m_unitTestModules; + + String m_exePath; ///< Path to executable + + DiagnosticSink m_diagnosticSink; + SourceManager m_sourceManager; + + RefPtr<HTTPPacketConnection> m_connection; +}; + +/* !!!!!!!!!!!!!!!!!!!!!!!!!!!! TestServer !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */ + +SlangResult TestServer::init(int argc, const char* const* argv) +{ + m_exePath = Path::getParentDirectory(argv[0]); + + RefPtr<Stream> stdinStream, stdoutStream; + + Process::getStdStream(Process::StreamType::StdIn, stdinStream); + Process::getStdStream(Process::StreamType::StdOut, stdoutStream); + + RefPtr<BufferedReadStream> readStream(new BufferedReadStream(stdinStream)); + + m_connection = new HTTPPacketConnection(readStream, stdoutStream); + + m_sourceManager.initialize(nullptr, nullptr); + m_diagnosticSink.init(&m_sourceManager, &JSONLexer::calcLexemeLocation); + + return SLANG_OK; +} + +TestServer::~TestServer() +{ + for (auto& pair : m_unitTestModules) + { + pair.Value->destroy(); + } +} + +slang::IGlobalSession* TestServer::getGlobalSession() +{ + if (!m_session) + { + // Just create the global session in the regular way if there isn't one set + if (SLANG_FAILED(slang_createGlobalSession(SLANG_API_VERSION, m_session.writeRef()))) + { + return nullptr; + } + TestToolUtil::setSessionDefaultPreludeFromExePath(m_exePath.getBuffer(), m_session); + } + + return m_session; +} + +ISlangSharedLibrary* TestServer::loadSharedLibrary(const String& name, DiagnosticSink* sink) +{ + ComPtr<ISlangSharedLibrary> lib; + if (m_sharedLibraryMap.TryGetValue(name, lib)) + { + return lib; + } + + auto loader = DefaultSharedLibraryLoader::getSingleton(); + + auto toolPath = Path::combine(m_exePath, name); + + ComPtr<ISlangSharedLibrary> sharedLibrary; + if (SLANG_FAILED(loader->loadSharedLibrary(toolPath.getBuffer(), sharedLibrary.writeRef()))) + { + if (sink) + { + sink->diagnose(SourceLoc(), ServerDiagnostics::unableToLoadSharedLibrary, name); + } + + return nullptr; + } + + m_sharedLibraryMap.Add(name, sharedLibrary); + return sharedLibrary; +} + +IUnitTestModule* TestServer::getUnitTestModule(const String& name, DiagnosticSink* sink) +{ + auto unitTestModulePtr = m_unitTestModules.TryGetValue(name); + if (unitTestModulePtr) + { + return *unitTestModulePtr; + } + + ISlangSharedLibrary* sharedLibrary = loadSharedLibrary(name, sink); + if (!sharedLibrary) + { + return nullptr; + } + + UnownedStringSlice funcName = UnownedStringSlice::fromLiteral("slangUnitTestGetModule"); + + // get the unit test export name + UnitTestGetModuleFunc getModuleFunc = (UnitTestGetModuleFunc)sharedLibrary->findFuncByName(funcName.begin()); + if (!getModuleFunc) + { + if (sink) + { + sink->diagnose(SourceLoc(), ServerDiagnostics::unableToFindFunctionInSharedLibrary, funcName); + } + return nullptr; + } + + IUnitTestModule* testModule = getModuleFunc(); + if (!testModule) + { + if (sink) + { + sink->diagnose(SourceLoc(), ServerDiagnostics::unableToGetUnitTestModule); + } + return nullptr; + } + + m_unitTestModules.Add(name, testModule); + return testModule; +} + +TestServer::InnerMainFunc TestServer::getToolFunction(const String& name, DiagnosticSink* sink) +{ + StringBuilder sharedLibToolBuilder; + sharedLibToolBuilder.append(name); + sharedLibToolBuilder.append("-tool"); + + ISlangSharedLibrary* sharedLibrary = loadSharedLibrary(sharedLibToolBuilder, sink); + if (!sharedLibrary) + { + return nullptr; + } + + UnownedStringSlice funcName = UnownedStringSlice::fromLiteral("innerMain"); + + auto func = (InnerMainFunc)sharedLibrary->findFuncByName(funcName.begin()); + if (!func && sink) + { + sink->diagnose(SourceLoc(), ServerDiagnostics::unableToFindFunctionInSharedLibrary, funcName); + } + + return func; +} + +SlangResult TestServer::_writeResponse(JSONContainer* container, const JSONValue& root) +{ + // TODO(JS): We may want a non indented style, to reduce size + JSONWriter writer(JSONWriter::IndentationStyle::Allman); + container->traverseRecursively(root, &writer); + const StringBuilder& builder = writer.getBuilder(); + return m_connection->write(builder.getBuffer(), builder.getLength()); +} + +SlangResult TestServer::_executeSingle() +{ + // Block waiting for content (or error/closed) + SLANG_RETURN_ON_FAIL(m_connection->waitForResult()); + + // If we don't have content, we can quit for now + if (!m_connection->hasContent()) + { + return SLANG_OK; + } + + auto content = m_connection->getContent(); + + UnownedStringSlice slice((const char*)content.begin(), content.getCount()); + + // Reset for parse + m_sourceManager.reset(); + m_diagnosticSink.reset(); + + JSONContainer container(&m_sourceManager); + + // Parse as RPC JSON + JSONValue root; + + { + SlangResult res = JSONRPCUtil::parseJSON(slice, &container, &m_diagnosticSink, root); + // Consume that content/packet + m_connection->consumeContent(); + + if (SLANG_FAILED(res)) + { + return _writeResponse(&container, JSONRPCUtil::createErrorResponse(&container, JSONRPCUtil::ErrorCode::InvalidRequest, UnownedStringSlice::fromLiteral("Unable to parse JSON"))); + } + } + + JSONRPCUtil::Call call; + { + SlangResult res = JSONRPCUtil::parseCall(&container, root, call); + if (SLANG_FAILED(res)) + { + return _writeResponse(&container, JSONRPCUtil::createErrorResponse(&container, Index(JSONRPCUtil::ErrorCode::InvalidRequest), UnownedStringSlice::fromLiteral("Cannot parse call"))); + } + } + + const auto& method = call.method; + + // Do different things + if (method == "quit") + { + m_quit = true; + return SLANG_OK; + } + else if (method == "unitTest") + { + SLANG_RETURN_ON_FAIL(_executeUnitTest(&container, root)); + return SLANG_OK; + } + else if (method == "tool") + { + SLANG_RETURN_ON_FAIL(_executeTool(&container, root)); + return SLANG_OK; + } + + return SLANG_FAIL; +} + +static Index _findTestIndex(IUnitTestModule* testModule, const String& name) +{ + const auto testCount = testModule->getTestCount(); + for (SlangInt i = 0; i < testCount; ++i) + { + auto testName = testModule->getTestName(i); + + if (name == testName) + { + return Index(i); + } + } + return -1; +} + +SlangResult TestServer::_executeUnitTest(JSONContainer* container, const JSONValue& root) +{ + String moduleName; + String testName; + Int enabledApis = 0; + + IUnitTestModule* testModule = getUnitTestModule(moduleName, &m_diagnosticSink); + if (!testModule) + { + return SLANG_FAIL; + } + + Index testIndex = _findTestIndex(testModule, moduleName); + if (testIndex < 0) + { + m_diagnosticSink.diagnose(SourceLoc(), ServerDiagnostics::unableToFindTest, testName); + return SLANG_FAIL; + } + + TestReporter testReporter; + + testModule->setTestReporter(&testReporter); + + // Assume we will used the shared session + slang::IGlobalSession* session = getGlobalSession(); + if (!session) + { + return SLANG_FAIL; + } + + UnitTestContext unitTestContext; + unitTestContext.slangGlobalSession = session; + unitTestContext.workDirectory = ""; + unitTestContext.enabledApis = RenderApiFlags(enabledApis); + unitTestContext.executableDirectory = m_exePath.getBuffer(); + + auto testCount = testModule->getTestCount(); + SLANG_ASSERT(testIndex >= 0 && testIndex < testCount); + + UnitTestFunc testFunc = testModule->getTestFunc(testIndex); + + try + { + testFunc(&unitTestContext); + } + catch (...) + { + testReporter.m_failCount++; + } + + if (testReporter.m_failCount > 0) + { + // Write out to stderr... + auto writers = StdWriters::createDefault(); + writers->getError().put(testReporter.m_buf.getUnownedSlice()); + return SLANG_FAIL; + } + + if (testReporter.m_testCount == 0) + { + return SLANG_E_NOT_AVAILABLE; + } + + return SLANG_OK; +} + +SlangResult TestServer::_executeTool(JSONContainer* container, const JSONValue& root) +{ + String toolName; + + auto func = getToolFunction(toolName, &m_diagnosticSink); + if (!func) + { + // Write out to diagnostics + return SLANG_FAIL; + } + + // Assume we will used the shared session + slang::IGlobalSession* session = getGlobalSession(); + if (!session) + { + return SLANG_FAIL; + } + + // Get the args list + + // Work out the args sent to the shared library + List<const char*> args; + + + RefPtr<StdWriters> stdWriters = StdWriters::createDefault(); + + const SlangResult res = func(stdWriters, session, int(args.getCount()), args.begin()); + if (SLANG_FAILED(res)) + { + return res; + } + return res; +} + + +SlangResult TestServer::execute() +{ + DiagnosticSink diagnosticSink; + + while (m_connection->isActive() && !m_quit) + { + SlangResult res = _executeSingle(); + if (m_quit) + { + break; + } + + if (SLANG_FAILED(res)) + { + // Return a result + } + } + + return SLANG_OK; +} + +/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! TestReporter !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */ + +void TestReporter::message(TestMessageType type, const char* message) +{ + if (type == TestMessageType::RunError || + type == TestMessageType::TestFailure) + { + m_failCount++; + } + + m_buf << message << "\n"; +} + +void TestReporter::addResultWithLocation(TestResult result, const char* testText, const char* file, int line) +{ + if (result == TestResult::Fail) + { + addResultWithLocation(false, testText, file, line); + } + else + { + m_testCount++; + } +} + +void TestReporter::addResultWithLocation(bool testSucceeded, const char* testText, const char* file, int line) +{ + m_testCount++; + + if (testSucceeded) + { + return; + } + + m_buf << "[Failed]: " << testText << "\n"; + m_buf << file << ":" << line << "\n"; + + m_failCount++; +} + +void TestReporter::addResult(TestResult result) +{ + if (result == TestResult::Fail) + { + m_failCount++; + } +} + + +SlangResult _execute(int argc, const char* const* argv) +{ + TestServer server; + SLANG_RETURN_ON_FAIL(server.init(argc, argv)); + SLANG_RETURN_ON_FAIL(server.execute()); + + return SLANG_OK; +} + +} // namespace TestServer + +int main(int argc, const char* const* argv) +{ + return (int)Slang::TestToolUtil::getReturnCode(TestServer:: _execute(argc, argv)); +} |
