summaryrefslogtreecommitdiffstats
path: root/tools/slang-test
diff options
context:
space:
mode:
authorjsmall-nvidia <jsmall@nvidia.com>2019-06-12 09:05:40 -0400
committerGitHub <noreply@github.com>2019-06-12 09:05:40 -0400
commit9d514e65f00dde0e309f33591f31fbf7f132a005 (patch)
tree7e3a751377651ef9eda06f0b1ad345af1796c596 /tools/slang-test
parentfc083a75b94ac4b4e735b4a7ff566191b9123f74 (diff)
Runtime execution of Visual Studio Compiler (#978)
* Work in progress to be able to invoke VS from within code. * First pass at windows version of refactor of OSProcessSpawner * Closer to getting VS path lookup working. * Make OSString assignable/ctor able * Work out program files directory directly, so don't have to expand %%. * WIP: Improve handling of process spawning. * Add support for splitting input by line. * * Correctly locates visual studio install * Added functionality to invoke vs via cmd * Add option to execute the command line. * Handle in ProcessUtil for windows -> WinHandle. * Rename files slang-win-visual-studio-util.cpp/.h and slang-process-util.h * First pass at unix/linux version of ProcessUtil. * Fix reading Visual Studio path from the registry. * Get compiling on linux with. * Fix vcvarsall.bat name * Use ProcessUtil to execute external code. * Remove OSProcessSpawner. * Remove includes for "os.h" where no longer needed. * Fix tabbing issue in premake5.lua Remove test code from slang-test-main.cpp * Fix premake4.lua tabbing issue. * Small fixes to slang-process-util.h Init ExecuteResult on Win execute. * Improve comments. * Fix bug in StringUtil::calcLines - with oddly terminated source input being able to read past end. Make slang-generate use StringUtil over it's own impl. * Fix off by one bug in working out Visual Studio version. * Fix bug in calculating Visual Studio Version * Fix compilation on linux with string parameter being passed to messageFormat. * Remove erroneous use of kOSError codes - use Result.
Diffstat (limited to 'tools/slang-test')
-rw-r--r--tools/slang-test/options.cpp2
-rw-r--r--tools/slang-test/os.cpp469
-rw-r--r--tools/slang-test/os.h65
-rw-r--r--tools/slang-test/slang-test-main.cpp335
-rw-r--r--tools/slang-test/test-context.cpp2
-rw-r--r--tools/slang-test/test-reporter.cpp40
6 files changed, 199 insertions, 714 deletions
diff --git a/tools/slang-test/options.cpp b/tools/slang-test/options.cpp
index 3e985b493..4c8108f4a 100644
--- a/tools/slang-test/options.cpp
+++ b/tools/slang-test/options.cpp
@@ -1,8 +1,8 @@
// test-context.cpp
#include "options.h"
-#include "os.h"
#include "../../source/core/slang-string-util.h"
+#include "../../source/core/slang-io.h"
#include <stdio.h>
#include <stdlib.h>
diff --git a/tools/slang-test/os.cpp b/tools/slang-test/os.cpp
index a938a71e7..eceeef2d7 100644
--- a/tools/slang-test/os.cpp
+++ b/tools/slang-test/os.cpp
@@ -123,266 +123,6 @@ OSFindFilesResult osFindChildDirectories(
return result;
}
-// OSProcessSpawner
-
-struct OSProcessSpawner_ReaderThreadInfo
-{
- HANDLE file;
- String output;
-};
-
-static DWORD WINAPI osReaderThreadProc(LPVOID threadParam)
-{
- OSProcessSpawner_ReaderThreadInfo* info = (OSProcessSpawner_ReaderThreadInfo*)threadParam;
- HANDLE file = info->file;
-
- static const int kChunkSize = 1024;
- char buffer[kChunkSize];
-
- StringBuilder outputBuilder;
-
- // We need to re-write the output to deal with line
- // endings, so we check for paired '\r' and '\n'
- // characters, which may span chunks.
- int prevChar = -1;
-
- for (;;)
- {
- DWORD bytesRead = 0;
- BOOL readResult = ReadFile(file, buffer, kChunkSize, &bytesRead, nullptr);
-
- if (!readResult || GetLastError() == ERROR_BROKEN_PIPE)
- {
- break;
- }
-
- // walk the buffer and rewrite to eliminate '\r' '\n' pairs
- char* readCursor = buffer;
- char const* end = buffer + bytesRead;
- char* writeCursor = buffer;
-
- while (readCursor != end)
- {
- int p = prevChar;
- int c = *readCursor++;
- prevChar = c;
- switch (c)
- {
- case '\r': case '\n':
- // swallow input if '\r' and '\n' appear in sequence
- if ((p ^ c) == ('\r' ^ '\n'))
- {
- // but don't swallow the next byte
- prevChar = -1;
- continue;
- }
- // always replace '\r' with '\n'
- c = '\n';
- break;
-
- default:
- break;
- }
-
- *writeCursor++ = (char)c;
- }
- bytesRead = (DWORD)(writeCursor - buffer);
-
- // Note: Current "core" implementation gives no way to know
- // the length of the buffer, so we ultimately have
- // to just assume null termination...
- outputBuilder.Append(buffer, bytesRead);
- }
-
- info->output = outputBuilder.ProduceString();
-
- return 0;
-}
-
-void OSProcessSpawner::pushExecutableName(
- Slang::String executableName)
-{
- executableName_ = executableName;
- commandLine_.Append(executableName);
- isExecutablePath_ = false;
-}
-
-void OSProcessSpawner::pushExecutablePath(
- Slang::String executablePath)
-{
- executableName_ = executablePath;
- commandLine_.Append(executablePath);
- isExecutablePath_ = true;
-}
-
-void OSProcessSpawner::pushArgument(
- Slang::String argument)
-{
- // TODO(tfoley): handle cases where arguments need some escaping
- commandLine_.Append(" ");
- commandLine_.Append(argument);
-
- argumentList_.add(argument);
-}
-
-Slang::String OSProcessSpawner::getCommandLine()
-{
- return commandLine_;
-}
-
-OSError OSProcessSpawner::spawnAndWaitForCompletion()
-{
- SECURITY_ATTRIBUTES securityAttributes;
- securityAttributes.nLength = sizeof(securityAttributes);
- securityAttributes.lpSecurityDescriptor = nullptr;
- securityAttributes.bInheritHandle = true;
-
- // create stdout pipe for child process
- HANDLE childStdOutReadTmp = nullptr;
- HANDLE childStdOutWrite = nullptr;
- if (!CreatePipe(&childStdOutReadTmp, &childStdOutWrite, &securityAttributes, 0))
- {
- return kOSError_OperationFailed;
- }
-
- // create stderr pipe for child process
- HANDLE childStdErrReadTmp = nullptr;
- HANDLE childStdErrWrite = nullptr;
- if (!CreatePipe(&childStdErrReadTmp, &childStdErrWrite, &securityAttributes, 0))
- {
- return kOSError_OperationFailed;
- }
-
- // create stdin pipe for child process
- HANDLE childStdInRead = nullptr;
- HANDLE childStdInWriteTmp = nullptr;
- if (!CreatePipe(&childStdInRead, &childStdInWriteTmp, &securityAttributes, 0))
- {
- return kOSError_OperationFailed;
- }
-
- HANDLE currentProcess = GetCurrentProcess();
-
- // create a non-inheritable duplicate of the stdout reader
- HANDLE childStdOutRead = nullptr;
- if (!DuplicateHandle(
- currentProcess, childStdOutReadTmp,
- currentProcess, &childStdOutRead,
- 0, FALSE, DUPLICATE_SAME_ACCESS))
- {
- return kOSError_OperationFailed;
- }
- if (!CloseHandle(childStdOutReadTmp))
- {
- return kOSError_OperationFailed;
- }
-
- // create a non-inheritable duplicate of the stderr reader
- HANDLE childStdErrRead = nullptr;
- if (!DuplicateHandle(
- currentProcess, childStdErrReadTmp,
- currentProcess, &childStdErrRead,
- 0, FALSE, DUPLICATE_SAME_ACCESS))
- {
- return kOSError_OperationFailed;
- }
- if (!CloseHandle(childStdErrReadTmp))
- {
- return kOSError_OperationFailed;
- }
-
- // create a non-inheritable duplicate of the stdin writer
- HANDLE childStdInWrite = nullptr;
- if (!DuplicateHandle(
- currentProcess, childStdInWriteTmp,
- currentProcess, &childStdInWrite,
- 0, FALSE, DUPLICATE_SAME_ACCESS))
- {
- return kOSError_OperationFailed;
- }
- if (!CloseHandle(childStdInWriteTmp))
- {
- return kOSError_OperationFailed;
- }
-
- // Now we can actually get around to starting a process
- PROCESS_INFORMATION processInfo;
- ZeroMemory(&processInfo, sizeof(processInfo));
-
- // TODO: switch to proper wide-character versions of these...
- STARTUPINFOW startupInfo;
- ZeroMemory(&startupInfo, sizeof(startupInfo));
- startupInfo.cb = sizeof(startupInfo);
- startupInfo.hStdError = childStdErrWrite;
- startupInfo.hStdOutput = childStdOutWrite;
- startupInfo.hStdInput = childStdInRead;
- startupInfo.dwFlags = STARTF_USESTDHANDLES;
-
- // `CreateProcess` requires write access to this, for some reason...
- BOOL success = CreateProcessW(
- isExecutablePath_ ? executableName_.toWString().begin() : nullptr,
- (LPWSTR)commandLine_.ToString().toWString().begin(),
- nullptr,
- nullptr,
- true,
- CREATE_NO_WINDOW,
- nullptr, // TODO: allow specifying environment variables?
- nullptr,
- &startupInfo,
- &processInfo);
- if (!success)
- {
- return kOSError_OperationFailed;
- }
-
- // close handles we are now done with
- CloseHandle(processInfo.hThread);
- CloseHandle(childStdOutWrite);
- CloseHandle(childStdErrWrite);
- CloseHandle(childStdInRead);
-
- // Create a thread to read from the child's stdout.
- OSProcessSpawner_ReaderThreadInfo stdOutThreadInfo;
- stdOutThreadInfo.file = childStdOutRead;
- HANDLE stdOutThread = CreateThread(nullptr, 0, &osReaderThreadProc, (LPVOID)&stdOutThreadInfo, 0, nullptr);
-
- // Create a thread to read from the child's stderr.
- OSProcessSpawner_ReaderThreadInfo stdErrThreadInfo;
- stdErrThreadInfo.file = childStdErrRead;
- HANDLE stdErrThread = CreateThread(nullptr, 0, &osReaderThreadProc, (LPVOID)&stdErrThreadInfo, 0, nullptr);
-
- // wait for the process to exit
- // TODO: set a timeout as a safety measure...
- WaitForSingleObject(processInfo.hProcess, INFINITE);
-
- // get exit code for process
- DWORD childExitCode = 0;
- if (!GetExitCodeProcess(processInfo.hProcess, &childExitCode))
- {
- return kOSError_OperationFailed;
- }
-
- // wait for the reader threads
- WaitForSingleObject(stdOutThread, INFINITE);
- WaitForSingleObject(stdErrThread, INFINITE);
-
- CloseHandle(processInfo.hProcess);
- CloseHandle(childStdOutRead);
- CloseHandle(childStdErrRead);
- CloseHandle(childStdInWrite);
-
- standardOutput_ = stdOutThreadInfo.output;
- standardError_ = stdErrThreadInfo.output;
- resultCode_ = childExitCode;
-
- return kOSError_None;
-}
-
-char const* osGetExecutableSuffix()
-{
- return ".exe";
-}
-
#else
static bool advance(OSFindFilesResult& result)
@@ -475,213 +215,4 @@ OSFindFilesResult osFindChildDirectories(
return result;
}
-// OSProcessSpawner
-
-void OSProcessSpawner::pushExecutableName(
- Slang::String executableName)
-{
- executableName_ = executableName;
- arguments_.add(executableName);
- isExecutablePath_ = false;
-}
-
-void OSProcessSpawner::pushExecutablePath(
- Slang::String executablePath)
-{
- executableName_ = executablePath;
- arguments_.add(executablePath);
- isExecutablePath_ = true;
-}
-
-void OSProcessSpawner::pushArgument(
- Slang::String argument)
-{
- arguments_.add(argument);
- argumentList_.add(argument);
-}
-
-Slang::String OSProcessSpawner::getCommandLine()
-{
- Slang::UInt argCount = arguments_.getCount();
-
- Slang::StringBuilder sb;
- for(Slang::UInt ii = 0; ii < argCount; ++ii)
- {
- if(ii != 0) sb << " ";
- sb << arguments_[ii];
- }
- return sb.ProduceString();
-}
-
-OSError OSProcessSpawner::spawnAndWaitForCompletion()
-{
- List<char const*> argPtrs;
- for(auto arg : arguments_)
- {
- argPtrs.add(arg.getBuffer());
- }
- argPtrs.add(NULL);
-
- int stdoutPipe[2];
- int stderrPipe[2];
-
- if(pipe(stdoutPipe) == -1)
- return kOSError_OperationFailed;
-
- if(pipe(stderrPipe) == -1)
- return kOSError_OperationFailed;
-
- pid_t childProcessID = fork();
- if (childProcessID == -1)
- return kOSError_OperationFailed;
-
- if(childProcessID == 0)
- {
- // We are the child process.
-
- dup2(stdoutPipe[1], STDOUT_FILENO);
- dup2(stderrPipe[1], STDERR_FILENO);
-
- close(stdoutPipe[0]);
- close(stdoutPipe[1]);
-
- close(stderrPipe[0]);
- close(stderrPipe[1]);
-
- execvp(
- argPtrs[0],
- (char* const*) &argPtrs[0]);
-
- // If we get here, then `exec` failed
- fprintf(stderr, "error: `exec` failed\n");
- exit(1);
- }
- else
- {
- // We are the parent process
-
- close(stdoutPipe[1]);
- close(stderrPipe[1]);
-
- int stdoutFD = stdoutPipe[0];
- int stderrFD = stderrPipe[0];
-
- pollfd pollInfos[2];
- nfds_t pollInfoCount = 2;
-
- pollInfos[0].fd = stdoutFD;
- pollInfos[0].events = POLLIN;
- pollInfos[0].revents = 0;
- pollInfos[1].fd = stderrFD;
- pollInfos[1].events = POLLIN;
- pollInfos[1].revents = 0;
-
- int remainingCount = 2;
- int iterations = 0;
- while(remainingCount)
- {
- // Safeguard against infinite loop:
- iterations++;
- if (iterations > 10000)
- {
- fprintf(stderr, "poll(): %d iterations\n", iterations);
- return kOSError_OperationFailed;
- }
-
- // Set a timeout of ten seconds;
- // we really shouldn't wait too long...
- int pollTimeout = 10000;
- int pollResult = poll(pollInfos, pollInfoCount, pollTimeout);
- if (pollResult <= 0)
- {
- // If there was a signal that got in
- // the way, then retry...
- if(pollResult == -1 && errno == EINTR)
- continue;
-
- // timeout or error...
- return kOSError_OperationFailed;
- }
-
- enum { kBufferSize = 1024 };
- char buffer[kBufferSize];
-
- if(pollInfos[0].revents)
- {
- auto count = read(stdoutFD, buffer, kBufferSize);
- if (count <= 0)
- {
- // end-of-file
- close(stdoutFD);
- pollInfos[0].fd = -1;
- remainingCount--;
- }
-
- standardOutput_.append(
- buffer, buffer + count);
- }
-
- if(pollInfos[1].revents)
- {
- auto count = read(stderrFD, buffer, kBufferSize);
- if (count <= 0)
- {
- // end-of-file
- close(stderrFD);
- pollInfos[1].fd = -1;
- remainingCount--;
- }
-
- standardError_.append(
- buffer, buffer + count);
- }
- }
-
- int childStatus = 0;
- iterations = 0;
- for(;;)
- {
- // Safeguard against infinite loop:
- iterations++;
- if (iterations > 10000)
- {
- fprintf(stderr, "waitpid(): %d iterations\n", iterations);
- return kOSError_OperationFailed;
- }
-
-
- pid_t terminatedProcessID = waitpid(
- childProcessID,
- &childStatus,
- 0);
- if (terminatedProcessID == -1)
- {
- return kOSError_OperationFailed;
- }
-
- if(terminatedProcessID == childProcessID)
- {
- if(WIFEXITED(childStatus))
- {
- resultCode_ = (int)(int8_t)WEXITSTATUS(childStatus);
- }
- else
- {
- resultCode_ = 1;
- }
-
- return kOSError_None;
- }
- }
-
- }
-
- return kOSError_OperationFailed;
-}
-
-char const* osGetExecutableSuffix()
-{
- return "";
-}
-
#endif
diff --git a/tools/slang-test/os.h b/tools/slang-test/os.h
index 3e6d93942..9dd20c62d 100644
--- a/tools/slang-test/os.h
+++ b/tools/slang-test/os.h
@@ -1,3 +1,6 @@
+#ifndef SLANG_OS_H
+#define SLANG_OS_H
+
// os.h
#include "../../source/core/slang-io.h"
@@ -21,7 +24,7 @@
#include <dirent.h>
#include <errno.h>
-#include <poll.h>
+//#include <poll.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/wait.h>
@@ -129,62 +132,4 @@ OSFindFilesResult osFindFilesInDirectoryMatchingPattern(
OSFindFilesResult osFindFilesInDirectory(
Slang::String directoryPath);
-
-// An `OSProcessSpawner` can be used to launch a process, and handles
-// putting together the arguments in the form required by the target
-// platform, as well as capturing any output from the process (both
-// standard output and standard error) as strings.
-struct OSProcessSpawner
-{
- // Set the executable name for the process to be spawned.
- // Note: this call must be made before any arguments are pushed.
- void pushExecutableName(
- Slang::String executableName);
-
- // Set the executable name for the process to be spawned.
- // Note: this call must be made before any arguments are pushed.
- void pushExecutablePath(
- Slang::String executablePath);
-
- // Append an argument for the process to be spawned.
- void pushArgument(
- Slang::String argument);
-
- // Get a printable version of the command line
- // that will be run (can be used for debugging)
- Slang::String getCommandLine();
-
- // Attempt to spawn the process, and wait for it to complete.
- // Returns an error if the attempt to spawn and/or wait fails,
- // but returns `kOSError_None` if the process is run to completion,
- // whether or not the process returns "successfully" (with a zero
- // result code);
- OSError spawnAndWaitForCompletion();
-
- // If the process is successfully spawned and completes, then
- // the user can query the result code that the process produce
- // on exit, along with the output it wrote to stdout and stderr.
- typedef int ResultCode;
- ResultCode getResultCode() { return resultCode_; }
- Slang::String const& getStandardOutput() { return standardOutput_; }
- Slang::String const& getStandardError() { return standardError_; }
-
- // "private" data follows
- Slang::String standardOutput_;
- Slang::String standardError_;
- ResultCode resultCode_;
- Slang::String executableName_;
-#ifdef WIN32
- Slang::StringBuilder commandLine_;
-#else
- Slang::List<Slang::String> arguments_;
-#endif
-
- // Only holds the argumements in order
- Slang::List<Slang::String> argumentList_;
-
- // Is the executable specified by path, rather than just by name?
- bool isExecutablePath_;
-};
-
-char const* osGetExecutableSuffix();
+#endif // SLANG_OS_H
diff --git a/tools/slang-test/slang-test-main.cpp b/tools/slang-test/slang-test-main.cpp
index f030dc8aa..dac6ff9fe 100644
--- a/tools/slang-test/slang-test-main.cpp
+++ b/tools/slang-test/slang-test-main.cpp
@@ -18,6 +18,8 @@ using namespace Slang;
#include "options.h"
#include "slangc-tool.h"
+#include "../../source/core/slang-process-util.h"
+
#define STB_IMAGE_IMPLEMENTATION
#include "external/stb/stb_image.h"
@@ -93,7 +95,7 @@ typedef TestResult(*TestCallback)(TestContext* context, TestInput& input);
// Globals
// Pre declare
-static void _addRenderTestOptions(const Options& options, OSProcessSpawner& spawner);
+static void _addRenderTestOptions(const Options& options, CommandLine& cmdLine);
/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!! Functions !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */
@@ -382,51 +384,46 @@ TestResult gatherTestsForFile(
return TestResult::Pass;
}
-OSError spawnAndWaitExe(TestContext* context, const String& testPath, OSProcessSpawner& spawner)
+Result spawnAndWaitExe(TestContext* context, const String& testPath, const CommandLine& cmdLine, ExecuteResult& outRes)
{
const auto& options = context->options;
if (options.shouldBeVerbose)
{
- String commandLine = spawner.getCommandLine();
+ String commandLine = ProcessUtil::getCommandLineString(cmdLine);
context->reporter->messageFormat(TestMessageType::Info, "%s\n", commandLine.begin());
}
- OSError err = spawner.spawnAndWaitForCompletion();
- if (err != kOSError_None)
+ Result res = ProcessUtil::execute(cmdLine, outRes);
+ if (SLANG_FAILED(res))
{
// fprintf(stderr, "failed to run test '%S'\n", testPath.ToWString());
context->reporter->messageFormat(TestMessageType::RunError, "failed to run test '%S'", testPath.toWString().begin());
}
- return err;
+ return res;
}
-OSError spawnAndWaitSharedLibrary(TestContext* context, const String& testPath, OSProcessSpawner& spawner)
+Result spawnAndWaitSharedLibrary(TestContext* context, const String& testPath, const CommandLine& cmdLine, ExecuteResult& outRes)
{
const auto& options = context->options;
- String exeName = Path::getFileNameWithoutExt(spawner.executableName_);
+ String exeName = Path::getFileNameWithoutExt(cmdLine.m_executable);
if (options.shouldBeVerbose)
{
- StringBuilder builder;
-
- builder << "slang-test";
+ CommandLine testCmdLine;
+ testCmdLine.setExecutableFilename("slang-test");
if (options.binDir.getLength())
{
- builder << " -bindir " << options.binDir;
+ testCmdLine.addArg("-bindir");
+ testCmdLine.addArg(options.binDir);
}
- builder << " " << exeName;
+ testCmdLine.addArg(exeName);
+ testCmdLine.m_args.addRange(cmdLine.m_args);
- // TODO(js): Potentially this should handle escaping parameters for the command line if need be
- const auto& argList = spawner.argumentList_;
- for (Index i = 0; i < argList.getCount(); ++i)
- {
- builder << " " << argList[i];
- }
-
- context->reporter->messageFormat(TestMessageType::Info, "%s\n", builder.begin());
+ String testCmdLineString = ProcessUtil::getCommandLineString(testCmdLine);
+ context->reporter->messageFormat(TestMessageType::Info, "%s\n", testCmdLineString.getBuffer());
}
auto func = context->getInnerMainFunc(context->options.binDir, exeName);
@@ -452,24 +449,24 @@ OSError spawnAndWaitSharedLibrary(TestContext* context, const String& testPath,
List<const char*> args;
args.add(exeName.getBuffer());
- for (Index i = 0; i < spawner.argumentList_.getCount(); ++i)
+ for (Index i = 0; i < cmdLine.m_args.getCount(); ++i)
{
- args.add(spawner.argumentList_[i].getBuffer());
+ args.add(cmdLine.m_args[i].getBuffer());
}
SlangResult res = func(&stdWriters, context->getSession(), int(args.getCount()), args.begin());
StdWriters::setSingleton(prevStdWriters);
- spawner.standardError_ = stdErrorString;
- spawner.standardOutput_ = stdOutString;
+ outRes.standardError = stdErrorString;
+ outRes.standardOutput = stdOutString;
- spawner.resultCode_ = (int)TestToolUtil::getReturnCode(res);
+ outRes.resultCode = (int)TestToolUtil::getReturnCode(res);
- return kOSError_None;
+ return SLANG_OK;
}
- return kOSError_OperationFailed;
+ return SLANG_FAIL;
}
@@ -580,10 +577,10 @@ static SlangCompileTarget _getCompileTarget(const UnownedStringSlice& name)
return SLANG_TARGET_UNKNOWN;
}
-static SlangResult _extractRenderTestRequirements(OSProcessSpawner& spawner, TestRequirements* ioRequirements)
+static SlangResult _extractRenderTestRequirements(const CommandLine& cmdLine, TestRequirements* ioRequirements)
{
- const auto& args = spawner.argumentList_;
-
+ const auto& args = cmdLine.m_args;
+
// TODO(JS):
// This is rather convoluted in that it has to work out from the command line parameters passed
// to render-test what renderer will be used.
@@ -697,11 +694,11 @@ static SlangResult _extractRenderTestRequirements(OSProcessSpawner& spawner, Tes
return SLANG_OK;
}
-static SlangResult _extractSlangCTestRequirements(OSProcessSpawner& spawner, TestRequirements* ioRequirements)
+static SlangResult _extractSlangCTestRequirements(const CommandLine& cmdLine, TestRequirements* ioRequirements)
{
// This determines what the requirements are for a slangc like command line
- const auto& args = spawner.argumentList_;
-
+ const auto& args = cmdLine.m_args;
+
// First check pass through
{
String passThrough;
@@ -724,27 +721,27 @@ static SlangResult _extractSlangCTestRequirements(OSProcessSpawner& spawner, Tes
}
-static SlangResult _extractReflectionTestRequirements(OSProcessSpawner& spawner, TestRequirements* ioRequirements)
+static SlangResult _extractReflectionTestRequirements(const CommandLine& cmdLine, TestRequirements* ioRequirements)
{
// There are no specialized constraints for a reflection test
return SLANG_OK;
}
-static SlangResult _extractTestRequirements(OSProcessSpawner& spawner, TestRequirements* ioInfo)
+static SlangResult _extractTestRequirements(const CommandLine& cmdLine, TestRequirements* ioInfo)
{
- String exeName = Path::getFileNameWithoutExt(spawner.executableName_);
+ String exeName = Path::getFileNameWithoutExt(cmdLine.m_executable);
if (exeName == "render-test")
{
- return _extractRenderTestRequirements(spawner, ioInfo);
+ return _extractRenderTestRequirements(cmdLine, ioInfo);
}
else if (exeName == "slangc")
{
- return _extractSlangCTestRequirements(spawner, ioInfo);
+ return _extractSlangCTestRequirements(cmdLine, ioInfo);
}
else if (exeName == "slang-reflection-test")
{
- return _extractReflectionTestRequirements(spawner, ioInfo);
+ return _extractReflectionTestRequirements(cmdLine, ioInfo);
}
SLANG_ASSERT(!"Unknown tool type");
@@ -768,20 +765,21 @@ static RenderApiFlags _getAvailableRenderApiFlags(TestContext* context)
if (RenderApiUtil::calcHasApi(apiType))
{
// Try starting up the device
- OSProcessSpawner spawner;
- spawner.pushExecutablePath(Path::combine(context->options.binDir, String("render-test") + osGetExecutableSuffix()));
- _addRenderTestOptions(context->options, spawner);
+ CommandLine cmdLine;
+ cmdLine.setExecutablePath(Path::combine(context->options.binDir, String("render-test") + ProcessUtil::getExecutableSuffix()));
+ _addRenderTestOptions(context->options, cmdLine);
// We just want to see if the device can be started up
- spawner.pushArgument("-only-startup");
+ cmdLine.addArg("-only-startup");
// Select what api to use
StringBuilder builder;
builder << "-" << RenderApiUtil::getApiName(apiType);
- spawner.pushArgument(builder);
+ cmdLine.addArg(builder);
// Run the render-test tool and see if the device could startup
- if (spawnAndWaitSharedLibrary(context, "device-startup", spawner) == OSError::kOSError_None
- && TestToolUtil::getReturnCodeFromInt(spawner.resultCode_) == ToolReturnCode::Success)
+ ExecuteResult exeRes;
+ if (SLANG_SUCCEEDED(spawnAndWaitSharedLibrary(context, "device-startup", cmdLine, exeRes))
+ && TestToolUtil::getReturnCodeFromInt(exeRes.resultCode) == ToolReturnCode::Success)
{
availableRenderApiFlags |= RenderApiFlags(1) << int(apiType);
}
@@ -795,17 +793,17 @@ static RenderApiFlags _getAvailableRenderApiFlags(TestContext* context)
return context->availableRenderApiFlags;
}
-ToolReturnCode getReturnCode(OSProcessSpawner& spawner)
+ToolReturnCode getReturnCode(const ExecuteResult& exeRes)
{
- return TestToolUtil::getReturnCodeFromInt(spawner.getResultCode());
+ return TestToolUtil::getReturnCodeFromInt(exeRes.resultCode);
}
-ToolReturnCode spawnAndWait(TestContext* context, const String& testPath, SpawnType spawnType, OSProcessSpawner& spawner)
+ToolReturnCode spawnAndWait(TestContext* context, const String& testPath, SpawnType spawnType, const CommandLine& cmdLine, ExecuteResult& outExeRes)
{
if (context->isCollectingRequirements())
{
// If we just want info... don't bother running anything
- const SlangResult res = _extractTestRequirements(spawner, context->testRequirements);
+ const SlangResult res = _extractTestRequirements(cmdLine, context->testRequirements);
// Keep compiler happy on release
SLANG_UNUSED(res);
SLANG_ASSERT(SLANG_SUCCEEDED(res));
@@ -815,37 +813,37 @@ ToolReturnCode spawnAndWait(TestContext* context, const String& testPath, SpawnT
const auto& options = context->options;
- OSError spawnResult = kOSError_OperationFailed;
+ SlangResult spawnResult = SLANG_FAIL;
switch (spawnType)
{
case SpawnType::UseExe:
{
- spawnResult = spawnAndWaitExe(context, testPath, spawner);
+ spawnResult = spawnAndWaitExe(context, testPath, cmdLine, outExeRes);
break;
}
case SpawnType::UseSharedLibrary:
{
- spawnResult = spawnAndWaitSharedLibrary(context, testPath, spawner);
+ spawnResult = spawnAndWaitSharedLibrary(context, testPath, cmdLine, outExeRes);
break;
}
default: break;
}
- if (spawnResult != kOSError_None)
+ if (SLANG_FAILED(spawnResult))
{
return ToolReturnCode::FailedToRun;
}
- return getReturnCode(spawner);
+ return getReturnCode(outExeRes);
}
-String getOutput(OSProcessSpawner& spawner)
+String getOutput(const ExecuteResult& exeRes)
{
- OSProcessSpawner::ResultCode resultCode = spawner.getResultCode();
-
- String standardOuptut = spawner.getStandardOutput();
- String standardError = spawner.getStandardError();
-
+ ExecuteResult::ResultCode resultCode = exeRes.resultCode;
+
+ String standardOuptut = exeRes.standardOutput;
+ String standardError = exeRes.standardError;
+
// We construct a single output string that captures the results
StringBuilder actualOutputBuilder;
actualOutputBuilder.Append("result code = ");
@@ -897,13 +895,13 @@ String findExpectedPath(const TestInput& input, const char* postFix)
return "";
}
-static void _initSlangCompiler(TestContext* context, OSProcessSpawner& spawnerOut)
+static void _initSlangCompiler(TestContext* context, CommandLine& ioCmdLine)
{
- spawnerOut.pushExecutablePath(Path::combine(context->options.binDir, String("slangc") + osGetExecutableSuffix()));
+ ioCmdLine.setExecutablePath(Path::combine(context->options.binDir, String("slangc") + ProcessUtil::getExecutableSuffix()));
if (context->options.verbosePaths)
{
- spawnerOut.pushArgument("-verbose-paths");
+ ioCmdLine.addArg("-verbose-paths");
}
}
@@ -933,24 +931,25 @@ TestResult runSimpleTest(TestContext* context, TestInput& input)
auto filePath999 = input.filePath;
auto outputStem = input.outputStem;
- OSProcessSpawner spawner;
- _initSlangCompiler(context, spawner);
+ CommandLine cmdLine;
+ _initSlangCompiler(context, cmdLine);
- spawner.pushArgument(filePath999);
+ cmdLine.addArg(filePath999);
for( auto arg : input.testOptions->args )
{
- spawner.pushArgument(arg);
+ cmdLine.addArg(arg);
}
-
- TEST_RETURN_ON_DONE(spawnAndWait(context, outputStem, input.spawnType, spawner));
+
+ ExecuteResult exeRes;
+ TEST_RETURN_ON_DONE(spawnAndWait(context, outputStem, input.spawnType, cmdLine, exeRes));
if (context->isCollectingRequirements())
{
return TestResult::Pass;
}
- String actualOutput = getOutput(spawner);
+ String actualOutput = getOutput(exeRes);
String expectedOutputPath = outputStem + ".expected";
String expectedOutput;
@@ -1009,24 +1008,25 @@ TestResult runReflectionTest(TestContext* context, TestInput& input)
auto filePath = input.filePath;
auto outputStem = input.outputStem;
- OSProcessSpawner spawner;
-
- spawner.pushExecutablePath(Path::combine(options.binDir, String("slang-reflection-test") + osGetExecutableSuffix()));
- spawner.pushArgument(filePath);
+ CommandLine cmdLine;
+
+ cmdLine.setExecutablePath(Path::combine(options.binDir, String("slang-reflection-test") + ProcessUtil::getExecutableSuffix()));
+ cmdLine.addArg(filePath);
for( auto arg : input.testOptions->args )
{
- spawner.pushArgument(arg);
+ cmdLine.addArg(arg);
}
- TEST_RETURN_ON_DONE(spawnAndWait(context, outputStem, input.spawnType, spawner));
+ ExecuteResult exeRes;
+ TEST_RETURN_ON_DONE(spawnAndWait(context, outputStem, input.spawnType, cmdLine, exeRes));
if (context->isCollectingRequirements())
{
return TestResult::Pass;
}
- String actualOutput = getOutput(spawner);
+ String actualOutput = getOutput(exeRes);
String expectedOutputPath = outputStem + ".expected";
String expectedOutput;
@@ -1097,13 +1097,13 @@ TestResult runCrossCompilerTest(TestContext* context, TestInput& input)
auto filePath = input.filePath;
auto outputStem = input.outputStem;
- OSProcessSpawner actualSpawner;
- OSProcessSpawner expectedSpawner;
+ CommandLine actualCmdLine;
+ CommandLine expectedCmdLine;
- _initSlangCompiler(context, actualSpawner);
- _initSlangCompiler(context, expectedSpawner);
+ _initSlangCompiler(context, actualCmdLine);
+ _initSlangCompiler(context, expectedCmdLine);
- actualSpawner.pushArgument(filePath);
+ actualCmdLine.addArg(filePath);
// TODO(JS): This should no longer be needed with TestInfo accumulated for a test
@@ -1124,23 +1124,23 @@ TestResult runCrossCompilerTest(TestContext* context, TestInput& input)
{
case SLANG_DXIL_ASM:
{
- expectedSpawner.pushArgument(filePath + ".hlsl");
- expectedSpawner.pushArgument("-pass-through");
- expectedSpawner.pushArgument("dxc");
+ expectedCmdLine.addArg(filePath + ".hlsl");
+ expectedCmdLine.addArg("-pass-through");
+ expectedCmdLine.addArg("dxc");
break;
}
case SLANG_DXBC_ASM:
{
- expectedSpawner.pushArgument(filePath + ".hlsl");
- expectedSpawner.pushArgument("-pass-through");
- expectedSpawner.pushArgument("fxc");
+ expectedCmdLine.addArg(filePath + ".hlsl");
+ expectedCmdLine.addArg("-pass-through");
+ expectedCmdLine.addArg("fxc");
break;
}
default:
{
- expectedSpawner.pushArgument(filePath + ".glsl");
- expectedSpawner.pushArgument("-pass-through");
- expectedSpawner.pushArgument("glslang");
+ expectedCmdLine.addArg(filePath + ".glsl");
+ expectedCmdLine.addArg("-pass-through");
+ expectedCmdLine.addArg("glslang");
break;
}
}
@@ -1148,16 +1148,17 @@ TestResult runCrossCompilerTest(TestContext* context, TestInput& input)
for( auto arg : input.testOptions->args )
{
- actualSpawner.pushArgument(arg);
- expectedSpawner.pushArgument(arg);
+ actualCmdLine.addArg(arg);
+ expectedCmdLine.addArg(arg);
}
- TEST_RETURN_ON_DONE(spawnAndWait(context, outputStem, input.spawnType, expectedSpawner));
+ ExecuteResult expectedExeRes;
+ TEST_RETURN_ON_DONE(spawnAndWait(context, outputStem, input.spawnType, expectedCmdLine, expectedExeRes));
String expectedOutput;
if (context->isExecuting())
{
- expectedOutput = getOutput(expectedSpawner);
+ expectedOutput = getOutput(expectedExeRes);
String expectedOutputPath = outputStem + ".expected";
try
{
@@ -1169,14 +1170,15 @@ TestResult runCrossCompilerTest(TestContext* context, TestInput& input)
}
}
- TEST_RETURN_ON_DONE(spawnAndWait(context, outputStem, input.spawnType, actualSpawner));
+ ExecuteResult actualExeRes;
+ TEST_RETURN_ON_DONE(spawnAndWait(context, outputStem, input.spawnType, actualCmdLine, actualExeRes));
if (context->isCollectingRequirements())
{
return TestResult::Pass;
}
- String actualOutput = getOutput(actualSpawner);
+ String actualOutput = getOutput(actualExeRes);
TestResult result = TestResult::Pass;
@@ -1190,7 +1192,7 @@ TestResult runCrossCompilerTest(TestContext* context, TestInput& input)
// to catch situations where, e.g., command-line options parsing
// caused the same error in both the Slang and glslang cases.
//
- if( actualSpawner.getResultCode() != 0 )
+ if(actualExeRes.resultCode != 0 )
{
result = TestResult::Fail;
}
@@ -1214,29 +1216,30 @@ TestResult generateHLSLBaseline(TestContext* context, TestInput& input)
auto filePath999 = input.filePath;
auto outputStem = input.outputStem;
- OSProcessSpawner spawner;
- _initSlangCompiler(context, spawner);
+ CommandLine cmdLine;
+ _initSlangCompiler(context, cmdLine);
- spawner.pushArgument(filePath999);
+ cmdLine.addArg(filePath999);
for( auto arg : input.testOptions->args )
{
- spawner.pushArgument(arg);
+ cmdLine.addArg(arg);
}
- spawner.pushArgument("-target");
- spawner.pushArgument("dxbc-assembly");
- spawner.pushArgument("-pass-through");
- spawner.pushArgument("fxc");
+ cmdLine.addArg("-target");
+ cmdLine.addArg("dxbc-assembly");
+ cmdLine.addArg("-pass-through");
+ cmdLine.addArg("fxc");
- TEST_RETURN_ON_DONE(spawnAndWait(context, outputStem, input.spawnType, spawner));
+ ExecuteResult exeRes;
+ TEST_RETURN_ON_DONE(spawnAndWait(context, outputStem, input.spawnType, cmdLine, exeRes));
if (context->isCollectingRequirements())
{
return TestResult::Pass;
}
- String expectedOutput = getOutput(spawner);
+ String expectedOutput = getOutput(exeRes);
String expectedOutputPath = outputStem + ".expected";
try
{
@@ -1262,24 +1265,25 @@ TestResult runHLSLComparisonTest(TestContext* context, TestInput& input)
// need to execute the stand-alone Slang compiler on the file, and compare its output to what we expect
- OSProcessSpawner spawner;
- _initSlangCompiler(context, spawner);
+ CommandLine cmdLine;
+ _initSlangCompiler(context, cmdLine);
- spawner.pushArgument(filePath999);
+ cmdLine.addArg(filePath999);
for( auto arg : input.testOptions->args )
{
- spawner.pushArgument(arg);
+ cmdLine.addArg(arg);
}
// TODO: The compiler should probably define this automatically...
- spawner.pushArgument("-D");
- spawner.pushArgument("__SLANG__");
+ cmdLine.addArg("-D");
+ cmdLine.addArg("__SLANG__");
- spawner.pushArgument("-target");
- spawner.pushArgument("dxbc-assembly");
+ cmdLine.addArg("-target");
+ cmdLine.addArg("dxbc-assembly");
- TEST_RETURN_ON_DONE(spawnAndWait(context, outputStem, input.spawnType, spawner));
+ ExecuteResult exeRes;
+ TEST_RETURN_ON_DONE(spawnAndWait(context, outputStem, input.spawnType, cmdLine, exeRes));
if (context->isCollectingRequirements())
{
@@ -1289,11 +1293,11 @@ TestResult runHLSLComparisonTest(TestContext* context, TestInput& input)
// We ignore output to stdout, and only worry about what the compiler
// wrote to stderr.
- OSProcessSpawner::ResultCode resultCode = spawner.getResultCode();
-
- String standardOutput = spawner.getStandardOutput();
- String standardError = spawner.getStandardError();
-
+ ExecuteResult::ResultCode resultCode = exeRes.resultCode;
+
+ String standardOutput = exeRes.standardOutput;
+ String standardError = exeRes.standardError;
+
// We construct a single output string that captures the results
StringBuilder actualOutputBuilder;
actualOutputBuilder.Append("result code = ");
@@ -1364,42 +1368,43 @@ TestResult doGLSLComparisonTestRun(TestContext* context,
auto filePath999 = input.filePath;
auto outputStem = input.outputStem;
- OSProcessSpawner spawner;
- _initSlangCompiler(context, spawner);
+ CommandLine cmdLine;
+ _initSlangCompiler(context, cmdLine);
- spawner.pushArgument(filePath999);
+ cmdLine.addArg(filePath999);
if( langDefine )
{
- spawner.pushArgument("-D");
- spawner.pushArgument(langDefine);
+ cmdLine.addArg("-D");
+ cmdLine.addArg(langDefine);
}
if( passThrough )
{
- spawner.pushArgument("-pass-through");
- spawner.pushArgument(passThrough);
+ cmdLine.addArg("-pass-through");
+ cmdLine.addArg(passThrough);
}
- spawner.pushArgument("-target");
- spawner.pushArgument("spirv-assembly");
+ cmdLine.addArg("-target");
+ cmdLine.addArg("spirv-assembly");
for( auto arg : input.testOptions->args )
{
- spawner.pushArgument(arg);
+ cmdLine.addArg(arg);
}
- TEST_RETURN_ON_DONE(spawnAndWait(context, outputStem, input.spawnType, spawner));
+ ExecuteResult exeRes;
+ TEST_RETURN_ON_DONE(spawnAndWait(context, outputStem, input.spawnType, cmdLine, exeRes));
if (context->isCollectingRequirements())
{
return TestResult::Pass;
}
- OSProcessSpawner::ResultCode resultCode = spawner.getResultCode();
+ ExecuteResult::ResultCode resultCode = exeRes.resultCode;
- String standardOuptut = spawner.getStandardOutput();
- String standardError = spawner.getStandardError();
+ String standardOuptut = exeRes.standardOutput;
+ String standardError = exeRes.standardError;
// We construct a single output string that captures the results
StringBuilder outputBuilder;
@@ -1458,12 +1463,12 @@ TestResult runGLSLComparisonTest(TestContext* context, TestInput& input)
return TestResult::Pass;
}
-static void _addRenderTestOptions(const Options& options, OSProcessSpawner& spawner)
+static void _addRenderTestOptions(const Options& options, CommandLine& ioCmdLine)
{
if (options.adapter.getLength())
{
- spawner.pushArgument("-adapter");
- spawner.pushArgument(options.adapter);
+ ioCmdLine.addArg("-adapter");
+ ioCmdLine.addArg(options.adapter);
}
}
@@ -1473,25 +1478,25 @@ TestResult runComputeComparisonImpl(TestContext* context, TestInput& input, cons
auto filePath999 = input.filePath;
auto outputStem = input.outputStem;
- OSProcessSpawner spawner;
+ CommandLine cmdLine;
- spawner.pushExecutablePath(Path::combine(context->options.binDir, String("render-test") + osGetExecutableSuffix()));
- spawner.pushArgument(filePath999);
+ cmdLine.setExecutablePath(Path::combine(context->options.binDir, String("render-test") + ProcessUtil::getExecutableSuffix()));
+ cmdLine.addArg(filePath999);
- _addRenderTestOptions(context->options, spawner);
+ _addRenderTestOptions(context->options, cmdLine);
for (auto arg : input.testOptions->args)
{
- spawner.pushArgument(arg);
+ cmdLine.addArg(arg);
}
for (int i = 0; i < int(numLangOpts); ++i)
{
- spawner.pushArgument(langOpts[i]);
+ cmdLine.addArg(langOpts[i]);
}
- spawner.pushArgument("-o");
+ cmdLine.addArg("-o");
auto actualOutputFile = outputStem + ".actual.txt";
- spawner.pushArgument(actualOutputFile);
+ cmdLine.addArg(actualOutputFile);
if (context->isExecuting())
{
@@ -1499,7 +1504,8 @@ TestResult runComputeComparisonImpl(TestContext* context, TestInput& input, cons
File::writeAllText(actualOutputFile, "");
}
- TEST_RETURN_ON_DONE(spawnAndWait(context, outputStem, input.spawnType, spawner));
+ ExecuteResult exeRes;
+ TEST_RETURN_ON_DONE(spawnAndWait(context, outputStem, input.spawnType, cmdLine, exeRes));
if (context->isCollectingRequirements())
{
@@ -1512,7 +1518,7 @@ TestResult runComputeComparisonImpl(TestContext* context, TestInput& input, cons
return TestResult::Fail;
}
- auto actualOutput = getOutput(spawner);
+ auto actualOutput = getOutput(exeRes);
auto expectedOutput = getExpectedOutput(outputStem);
if (actualOutput != expectedOutput)
{
@@ -1591,34 +1597,35 @@ TestResult doRenderComparisonTestRun(TestContext* context, TestInput& input, cha
auto filePath = input.filePath;
auto outputStem = input.outputStem;
- OSProcessSpawner spawner;
+ CommandLine cmdLine;
- spawner.pushExecutablePath(Path::combine(context->options.binDir, String("render-test") + osGetExecutableSuffix()));
- spawner.pushArgument(filePath);
+ cmdLine.setExecutablePath(Path::combine(context->options.binDir, String("render-test") + ProcessUtil::getExecutableSuffix()));
+ cmdLine.addArg(filePath);
- _addRenderTestOptions(context->options, spawner);
+ _addRenderTestOptions(context->options, cmdLine);
for( auto arg : input.testOptions->args )
{
- spawner.pushArgument(arg);
+ cmdLine.addArg(arg);
}
- spawner.pushArgument(langOption);
- spawner.pushArgument("-o");
- spawner.pushArgument(outputStem + outputKind + ".png");
+ cmdLine.addArg(langOption);
+ cmdLine.addArg("-o");
+ cmdLine.addArg(outputStem + outputKind + ".png");
- TEST_RETURN_ON_DONE(spawnAndWait(context, outputStem, input.spawnType, spawner));
+ ExecuteResult exeRes;
+ TEST_RETURN_ON_DONE(spawnAndWait(context, outputStem, input.spawnType, cmdLine, exeRes));
if (context->isCollectingRequirements())
{
return TestResult::Pass;
}
- OSProcessSpawner::ResultCode resultCode = spawner.getResultCode();
-
- String standardOutput = spawner.getStandardOutput();
- String standardError = spawner.getStandardError();
+ ExecuteResult::ResultCode resultCode = exeRes.resultCode;
+ String standardOutput = exeRes.standardOutput;
+ String standardError = exeRes.standardError;
+
// We construct a single output string that captures the results
StringBuilder outputBuilder;
outputBuilder.Append("result code = ");
diff --git a/tools/slang-test/test-context.cpp b/tools/slang-test/test-context.cpp
index e4d1df449..0b17b3672 100644
--- a/tools/slang-test/test-context.cpp
+++ b/tools/slang-test/test-context.cpp
@@ -1,7 +1,7 @@
// test-context.cpp
#include "test-context.h"
-#include "os.h"
+#include "../../source/core/slang-io.h"
#include "../../source/core/slang-string-util.h"
#include <stdio.h>
diff --git a/tools/slang-test/test-reporter.cpp b/tools/slang-test/test-reporter.cpp
index d2402d61b..f7ab3cf1e 100644
--- a/tools/slang-test/test-reporter.cpp
+++ b/tools/slang-test/test-reporter.cpp
@@ -1,8 +1,8 @@
// test-reporter.cpp
#include "test-reporter.h"
-#include "os.h"
#include "../../source/core/slang-string-util.h"
+#include "../../source/core/slang-process-util.h"
#include <stdio.h>
#include <stdlib.h>
@@ -373,29 +373,31 @@ void TestReporter::_addResult(const TestInfo& info)
break;
}
- OSProcessSpawner spawner;
- spawner.pushExecutableName("appveyor");
- spawner.pushArgument("AddTest");
- spawner.pushArgument(info.name);
- spawner.pushArgument("-FileName");
+ CommandLine cmdLine;
+ cmdLine.setExecutableFilename("appveyor");
+ cmdLine.addArg("AddTest");
+ cmdLine.addArg(info.name);
+ cmdLine.addArg("-FileName");
// TODO: this isn't actually a file name in all cases
- spawner.pushArgument(info.name);
- spawner.pushArgument("-Framework");
- spawner.pushArgument("slang-test");
- spawner.pushArgument("-Outcome");
- spawner.pushArgument(resultString);
-
- auto err = spawner.spawnAndWaitForCompletion();
-
- if (err != kOSError_None)
+ cmdLine.addArg(info.name);
+ cmdLine.addArg("-Framework");
+ cmdLine.addArg("slang-test");
+ cmdLine.addArg("-Outcome");
+ cmdLine.addArg(resultString);
+
+ ExecuteResult exeRes;
+ SlangResult res = ProcessUtil::execute(cmdLine, exeRes);
+
+ if (SLANG_FAILED(res))
{
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_.getBuffer(),
- spawner.getResultCode(),
- spawner.getStandardOutput().begin(),
- spawner.getStandardError().begin());
+ String cmdLineString = ProcessUtil::getCommandLineString(cmdLine);
+ fprintf(stderr, "[%d] TEST RESULT: %s {%d} {%s} {%s}\n", err, cmdLineString.getBuffer(),
+ exeRes.resultCode,
+ exeRes.standardOutput.begin(),
+ exeRes.standardError.begin());
#endif
}