diff options
| author | Brad King <brad.king@kitware.com> | 2024-01-25 15:52:01 (GMT) |
|---|---|---|
| committer | Brad King <brad.king@kitware.com> | 2024-01-25 15:53:04 (GMT) |
| commit | 151601c2e3419bd65bb276e77588c551487b4744 (patch) | |
| tree | 6fef8b57dd7aa10c9f15447b18dc74951de68dad /Source/cmCTest.cxx | |
| parent | 23747f705602cbc47672c6db6716afbe8b5b013e (diff) | |
| parent | bcbb212df704d36736731aa567b291fd97401804 (diff) | |
| download | CMake-151601c2e3419bd65bb276e77588c551487b4744.zip CMake-151601c2e3419bd65bb276e77588c551487b4744.tar.gz CMake-151601c2e3419bd65bb276e77588c551487b4744.tar.bz2 | |
Merge topic 'revert-replace-cmsysprocess-with-cmuvprocesschain' into release-3.28
bcbb212df7 Revert use of libuv for process execution for 3.28
Acked-by: Kitware Robot <kwrobot@kitware.com>
Merge-request: !9176
Diffstat (limited to 'Source/cmCTest.cxx')
| -rw-r--r-- | Source/cmCTest.cxx | 429 |
1 files changed, 198 insertions, 231 deletions
diff --git a/Source/cmCTest.cxx b/Source/cmCTest.cxx index 6e684a3..988a4eb 100644 --- a/Source/cmCTest.cxx +++ b/Source/cmCTest.cxx @@ -5,7 +5,6 @@ #include <algorithm> #include <cctype> #include <chrono> -#include <cstdint> #include <cstdio> #include <cstdlib> #include <cstring> @@ -25,13 +24,13 @@ #include <cmext/string_view> #include <cm3p/curl/curl.h> -#include <cm3p/uv.h> #include <cm3p/zlib.h> #include "cmsys/Base64.h" #include "cmsys/Directory.hxx" #include "cmsys/FStream.hxx" #include "cmsys/Glob.hxx" +#include "cmsys/Process.h" #include "cmsys/RegularExpression.hxx" #include "cmsys/SystemInformation.hxx" #if defined(_WIN32) @@ -65,9 +64,6 @@ #include "cmStateTypes.h" #include "cmStringAlgorithms.h" #include "cmSystemTools.h" -#include "cmUVHandlePtr.h" -#include "cmUVProcessChain.h" -#include "cmUVStream.h" #include "cmValue.h" #include "cmVersion.h" #include "cmVersionConfig.h" @@ -1077,9 +1073,9 @@ int cmCTest::GetTestModelFromString(const std::string& str) // ###################################################################### // ###################################################################### -bool cmCTest::RunMakeCommand(const std::string& command, std::string& output, - int* retVal, const char* dir, cmDuration timeout, - std::ostream& ofs, Encoding encoding) +int cmCTest::RunMakeCommand(const std::string& command, std::string& output, + int* retVal, const char* dir, cmDuration timeout, + std::ostream& ofs, Encoding encoding) { // First generate the command and arguments std::vector<std::string> args = cmSystemTools::ParseArguments(command); @@ -1088,107 +1084,107 @@ bool cmCTest::RunMakeCommand(const std::string& command, std::string& output, return false; } + std::vector<const char*> argv; + argv.reserve(args.size() + 1); + for (std::string const& a : args) { + argv.push_back(a.c_str()); + } + argv.push_back(nullptr); + output.clear(); cmCTestLog(this, HANDLER_VERBOSE_OUTPUT, "Run command:"); - for (auto const& arg : args) { + for (char const* arg : argv) { + if (!arg) { + break; + } cmCTestLog(this, HANDLER_VERBOSE_OUTPUT, " \"" << arg << "\""); } cmCTestLog(this, HANDLER_VERBOSE_OUTPUT, std::endl); // Now create process object - cmUVProcessChainBuilder builder; - builder.AddCommand(args).SetMergedBuiltinStreams(); - if (dir) { - builder.SetWorkingDirectory(dir); - } - auto chain = builder.Start(); - cm::uv_pipe_ptr outputStream; - outputStream.init(chain.GetLoop(), 0); - uv_pipe_open(outputStream, chain.OutputStream()); + cmsysProcess* cp = cmsysProcess_New(); + cmsysProcess_SetCommand(cp, argv.data()); + cmsysProcess_SetWorkingDirectory(cp, dir); + cmsysProcess_SetOption(cp, cmsysProcess_Option_HideWindow, 1); + cmsysProcess_SetTimeout(cp, timeout.count()); + cmsysProcess_Execute(cp); // Initialize tick's std::string::size_type tick = 0; std::string::size_type tick_len = 1024; std::string::size_type tick_line_len = 50; + char* data; + int length; cmProcessOutput processOutput(encoding); + std::string strdata; cmCTestLog(this, HANDLER_PROGRESS_OUTPUT, " Each . represents " << tick_len << " bytes of output\n" " " << std::flush); - auto outputHandle = cmUVStreamRead( - outputStream, - [this, &processOutput, &output, &tick, &tick_len, &tick_line_len, - &ofs](std::vector<char> data) { - std::string strdata; - processOutput.DecodeText(data.data(), data.size(), strdata); - for (char& cc : strdata) { - if (cc == 0) { - cc = '\n'; - } + while (cmsysProcess_WaitForData(cp, &data, &length, nullptr)) { + processOutput.DecodeText(data, length, strdata); + for (char& cc : strdata) { + if (cc == 0) { + cc = '\n'; } - output.append(strdata); - while (output.size() > (tick * tick_len)) { - tick++; - cmCTestLog(this, HANDLER_PROGRESS_OUTPUT, "." << std::flush); - if (tick % tick_line_len == 0 && tick > 0) { - cmCTestLog(this, HANDLER_PROGRESS_OUTPUT, - " Size: " << int((double(output.size()) / 1024.0) + 1) - << "K\n " << std::flush); - } - } - cmCTestLog(this, HANDLER_VERBOSE_OUTPUT, - cmCTestLogWrite(strdata.c_str(), strdata.size())); - if (ofs) { - ofs << cmCTestLogWrite(strdata.c_str(), strdata.size()); - } - }, - [this, &processOutput, &output, &ofs]() { - std::string strdata; - processOutput.DecodeText(std::string(), strdata); - if (!strdata.empty()) { - output.append(strdata); - cmCTestLog(this, HANDLER_VERBOSE_OUTPUT, - cmCTestLogWrite(strdata.c_str(), strdata.size())); - if (ofs) { - ofs << cmCTestLogWrite(strdata.c_str(), strdata.size()); - } + } + output.append(strdata); + while (output.size() > (tick * tick_len)) { + tick++; + cmCTestLog(this, HANDLER_PROGRESS_OUTPUT, "." << std::flush); + if (tick % tick_line_len == 0 && tick > 0) { + cmCTestLog(this, HANDLER_PROGRESS_OUTPUT, + " Size: " << int((double(output.size()) / 1024.0) + 1) + << "K\n " << std::flush); } - }); - - bool finished = chain.Wait(static_cast<uint64_t>(timeout.count() * 1000.0)); + } + cmCTestLog(this, HANDLER_VERBOSE_OUTPUT, + cmCTestLogWrite(strdata.c_str(), strdata.size())); + if (ofs) { + ofs << cmCTestLogWrite(strdata.c_str(), strdata.size()); + } + } + processOutput.DecodeText(std::string(), strdata); + if (!strdata.empty()) { + output.append(strdata); + cmCTestLog(this, HANDLER_VERBOSE_OUTPUT, + cmCTestLogWrite(strdata.c_str(), strdata.size())); + if (ofs) { + ofs << cmCTestLogWrite(strdata.c_str(), strdata.size()); + } + } cmCTestLog(this, HANDLER_PROGRESS_OUTPUT, " Size of output: " << int(double(output.size()) / 1024.0) << "K" << std::endl); - if (finished) { - auto const& status = chain.GetStatus(0); - auto exception = status.GetException(); - switch (exception.first) { - case cmUVProcessChain::ExceptionCode::None: - *retVal = static_cast<int>(status.ExitStatus); - cmCTestLog(this, HANDLER_VERBOSE_OUTPUT, - "Command exited with the value: " << *retVal << std::endl); - break; - case cmUVProcessChain::ExceptionCode::Spawn: - output += "\n*** ERROR executing: "; - output += exception.second; - output += "\n***The build process failed."; - cmCTestLog(this, ERROR_MESSAGE, - "There was an error: " << exception.second << std::endl); - break; - default: - *retVal = static_cast<int>(exception.first); - cmCTestLog(this, WARNING, - "There was an exception: " << *retVal << std::endl); - break; - } - } else { + cmsysProcess_WaitForExit(cp, nullptr); + + int result = cmsysProcess_GetState(cp); + + if (result == cmsysProcess_State_Exited) { + *retVal = cmsysProcess_GetExitValue(cp); + cmCTestLog(this, HANDLER_VERBOSE_OUTPUT, + "Command exited with the value: " << *retVal << std::endl); + } else if (result == cmsysProcess_State_Exception) { + *retVal = cmsysProcess_GetExitException(cp); + cmCTestLog(this, WARNING, + "There was an exception: " << *retVal << std::endl); + } else if (result == cmsysProcess_State_Expired) { cmCTestLog(this, WARNING, "There was a timeout" << std::endl); + } else if (result == cmsysProcess_State_Error) { + output += "\n*** ERROR executing: "; + output += cmsysProcess_GetErrorString(cp); + output += "\n***The build process failed."; + cmCTestLog(this, ERROR_MESSAGE, + "There was an error: " << cmsysProcess_GetErrorString(cp) + << std::endl); } - return true; + cmsysProcess_Delete(cp); + + return result; } // ###################################################################### @@ -1196,10 +1192,9 @@ bool cmCTest::RunMakeCommand(const std::string& command, std::string& output, // ###################################################################### // ###################################################################### -bool cmCTest::RunTest(const std::vector<std::string>& argv, - std::string* output, int* retVal, std::ostream* log, - cmDuration testTimeOut, - std::vector<std::string>* environment, Encoding encoding) +int cmCTest::RunTest(std::vector<const char*> argv, std::string* output, + int* retVal, std::ostream* log, cmDuration testTimeOut, + std::vector<std::string>* environment, Encoding encoding) { bool modifyEnv = (environment && !environment->empty()); @@ -1238,16 +1233,19 @@ bool cmCTest::RunTest(const std::vector<std::string>& argv, inst.SetStreams(&oss, &oss); std::vector<std::string> args; - for (auto const& i : argv) { - // make sure we pass the timeout in for any build and test - // invocations. Since --build-generator is required this is a - // good place to check for it, and to add the arguments in - if (i == "--build-generator" && timeout != cmCTest::MaxDuration() && - timeout > cmDuration::zero()) { - args.emplace_back("--test-timeout"); - args.push_back(std::to_string(cmDurationTo<unsigned int>(timeout))); + for (char const* i : argv) { + if (i) { + // make sure we pass the timeout in for any build and test + // invocations. Since --build-generator is required this is a + // good place to check for it, and to add the arguments in + if (strcmp(i, "--build-generator") == 0 && + timeout != cmCTest::MaxDuration() && + timeout > cmDuration::zero()) { + args.emplace_back("--test-timeout"); + args.push_back(std::to_string(cmDurationTo<unsigned int>(timeout))); + } + args.emplace_back(i); } - args.emplace_back(i); } if (log) { *log << "* Run internal CTest" << std::endl; @@ -1273,7 +1271,7 @@ bool cmCTest::RunTest(const std::vector<std::string>& argv, << std::endl); } - return true; + return cmsysProcess_State_Exited; } std::vector<char> tempOutput; if (output) { @@ -1286,43 +1284,41 @@ bool cmCTest::RunTest(const std::vector<std::string>& argv, cmSystemTools::AppendEnv(*environment); } - cmUVProcessChainBuilder builder; - builder.AddCommand(argv).SetMergedBuiltinStreams(); + cmsysProcess* cp = cmsysProcess_New(); + cmsysProcess_SetCommand(cp, argv.data()); cmCTestLog(this, DEBUG, "Command is: " << argv[0] << std::endl); - auto chain = builder.Start(); + if (cmSystemTools::GetRunCommandHideConsole()) { + cmsysProcess_SetOption(cp, cmsysProcess_Option_HideWindow, 1); + } + cmsysProcess_SetTimeout(cp, timeout.count()); + cmsysProcess_Execute(cp); + + char* data; + int length; cmProcessOutput processOutput(encoding); - cm::uv_pipe_ptr outputStream; - outputStream.init(chain.GetLoop(), 0); - uv_pipe_open(outputStream, chain.OutputStream()); - auto outputHandle = cmUVStreamRead( - outputStream, - [this, &processOutput, &output, &tempOutput, - &log](std::vector<char> data) { - std::string strdata; - processOutput.DecodeText(data.data(), data.size(), strdata); - if (output) { - cm::append(tempOutput, data.data(), data.data() + data.size()); - } - cmCTestLog(this, HANDLER_VERBOSE_OUTPUT, - cmCTestLogWrite(strdata.c_str(), strdata.size())); - if (log) { - log->write(strdata.c_str(), strdata.size()); - } - }, - [this, &processOutput, &log]() { - std::string strdata; - processOutput.DecodeText(std::string(), strdata); - if (!strdata.empty()) { - cmCTestLog(this, HANDLER_VERBOSE_OUTPUT, - cmCTestLogWrite(strdata.c_str(), strdata.size())); - if (log) { - log->write(strdata.c_str(), strdata.size()); - } - } - }); + std::string strdata; + while (cmsysProcess_WaitForData(cp, &data, &length, nullptr)) { + processOutput.DecodeText(data, length, strdata); + if (output) { + cm::append(tempOutput, data, data + length); + } + cmCTestLog(this, HANDLER_VERBOSE_OUTPUT, + cmCTestLogWrite(strdata.c_str(), strdata.size())); + if (log) { + log->write(strdata.c_str(), strdata.size()); + } + } + processOutput.DecodeText(std::string(), strdata); + if (!strdata.empty()) { + cmCTestLog(this, HANDLER_VERBOSE_OUTPUT, + cmCTestLogWrite(strdata.c_str(), strdata.size())); + if (log) { + log->write(strdata.c_str(), strdata.size()); + } + } - bool complete = chain.Wait(static_cast<uint64_t>(timeout.count() * 1000.0)); + cmsysProcess_WaitForExit(cp, nullptr); processOutput.DecodeText(tempOutput, tempOutput); if (output && tempOutput.begin() != tempOutput.end()) { output->append(tempOutput.data(), tempOutput.size()); @@ -1330,41 +1326,33 @@ bool cmCTest::RunTest(const std::vector<std::string>& argv, cmCTestLog(this, HANDLER_VERBOSE_OUTPUT, "-- Process completed" << std::endl); - bool result = false; + int result = cmsysProcess_GetState(cp); - if (complete) { - auto const& status = chain.GetStatus(0); - auto exception = status.GetException(); - switch (exception.first) { - case cmUVProcessChain::ExceptionCode::None: - *retVal = static_cast<int>(status.ExitStatus); - if (*retVal != 0 && this->Impl->OutputTestOutputOnTestFailure) { - this->OutputTestErrors(tempOutput); - } - result = true; - break; - case cmUVProcessChain::ExceptionCode::Spawn: { - std::string outerr = - cmStrCat("\n*** ERROR executing: ", exception.second); - if (output) { - *output += outerr; - } - cmCTestLog(this, HANDLER_VERBOSE_OUTPUT, outerr << std::endl); - } break; - default: { - if (this->Impl->OutputTestOutputOnTestFailure) { - this->OutputTestErrors(tempOutput); - } - *retVal = status.TermSignal; - std::string outerr = - cmStrCat("\n*** Exception executing: ", exception.second); - if (output) { - *output += outerr; - } - cmCTestLog(this, HANDLER_VERBOSE_OUTPUT, outerr << std::endl); - } break; + if (result == cmsysProcess_State_Exited) { + *retVal = cmsysProcess_GetExitValue(cp); + if (*retVal != 0 && this->Impl->OutputTestOutputOnTestFailure) { + this->OutputTestErrors(tempOutput); + } + } else if (result == cmsysProcess_State_Exception) { + if (this->Impl->OutputTestOutputOnTestFailure) { + this->OutputTestErrors(tempOutput); + } + *retVal = cmsysProcess_GetExitException(cp); + std::string outerr = cmStrCat("\n*** Exception executing: ", + cmsysProcess_GetExceptionString(cp)); + if (output) { + *output += outerr; + } + cmCTestLog(this, HANDLER_VERBOSE_OUTPUT, outerr << std::endl); + } else if (result == cmsysProcess_State_Error) { + std::string outerr = + cmStrCat("\n*** ERROR executing: ", cmsysProcess_GetErrorString(cp)); + if (output) { + *output += outerr; } + cmCTestLog(this, HANDLER_VERBOSE_OUTPUT, outerr << std::endl); } + cmsysProcess_Delete(cp); return result; } @@ -3482,70 +3470,49 @@ bool cmCTest::RunCommand(std::vector<std::string> const& args, stdOut->clear(); stdErr->clear(); - cmUVProcessChainBuilder builder; - builder.AddCommand(args) - .SetBuiltinStream(cmUVProcessChainBuilder::Stream_OUTPUT) - .SetBuiltinStream(cmUVProcessChainBuilder::Stream_ERROR); - if (dir) { - builder.SetWorkingDirectory(dir); - } - auto chain = builder.Start(); - - cm::uv_timer_ptr timer; - bool timedOut = false; - if (timeout.count()) { - timer.init(chain.GetLoop(), &timedOut); - timer.start( - [](uv_timer_t* t) { - auto* timedOutPtr = static_cast<bool*>(t->data); - *timedOutPtr = true; - }, - static_cast<uint64_t>(timeout.count() * 1000.0), 0); + cmsysProcess* cp = cmsysProcess_New(); + cmsysProcess_SetCommand(cp, argv.data()); + cmsysProcess_SetWorkingDirectory(cp, dir); + if (cmSystemTools::GetRunCommandHideConsole()) { + cmsysProcess_SetOption(cp, cmsysProcess_Option_HideWindow, 1); } + cmsysProcess_SetTimeout(cp, timeout.count()); + cmsysProcess_Execute(cp); std::vector<char> tempOutput; - bool outFinished = false; - cm::uv_pipe_ptr outStream; std::vector<char> tempError; - bool errFinished = false; - cm::uv_pipe_ptr errStream; + char* data; + int length; cmProcessOutput processOutput(encoding); - auto startRead = [this, &chain, &processOutput]( - cm::uv_pipe_ptr& pipe, int stream, - std::vector<char>& temp, - bool& finished) -> std::unique_ptr<cmUVStreamReadHandle> { - pipe.init(chain.GetLoop(), 0); - uv_pipe_open(pipe, stream); - return cmUVStreamRead( - pipe, - [this, &temp, &processOutput](std::vector<char> data) { - cm::append(temp, data); - if (this->Impl->ExtraVerbose) { - std::string strdata; - processOutput.DecodeText(data.data(), data.size(), strdata); - cmSystemTools::Stdout(strdata); - } - }, - [&finished]() { finished = true; }); - }; - auto outputHandle = - startRead(outStream, chain.OutputStream(), tempOutput, outFinished); - auto errorHandle = - startRead(errStream, chain.ErrorStream(), tempError, errFinished); - while (!timedOut && !(outFinished && errFinished)) { - uv_run(&chain.GetLoop(), UV_RUN_ONCE); + std::string strdata; + int res; + bool done = false; + while (!done) { + res = cmsysProcess_WaitForData(cp, &data, &length, nullptr); + switch (res) { + case cmsysProcess_Pipe_STDOUT: + cm::append(tempOutput, data, data + length); + break; + case cmsysProcess_Pipe_STDERR: + cm::append(tempError, data, data + length); + break; + default: + done = true; + } + if ((res == cmsysProcess_Pipe_STDOUT || res == cmsysProcess_Pipe_STDERR) && + this->Impl->ExtraVerbose) { + processOutput.DecodeText(data, length, strdata); + cmSystemTools::Stdout(strdata); + } } if (this->Impl->ExtraVerbose) { - std::string strdata; processOutput.DecodeText(std::string(), strdata); if (!strdata.empty()) { cmSystemTools::Stdout(strdata); } } - while (!timedOut && !chain.Finished()) { - uv_run(&chain.GetLoop(), UV_RUN_ONCE); - } + cmsysProcess_WaitForExit(cp, nullptr); if (!tempOutput.empty()) { processOutput.DecodeText(tempOutput, tempOutput); stdOut->append(tempOutput.data(), tempOutput.size()); @@ -3556,32 +3523,32 @@ bool cmCTest::RunCommand(std::vector<std::string> const& args, } bool result = true; - if (timedOut) { + if (cmsysProcess_GetState(cp) == cmsysProcess_State_Exited) { + if (retVal) { + *retVal = cmsysProcess_GetExitValue(cp); + } else { + if (cmsysProcess_GetExitValue(cp) != 0) { + result = false; + } + } + } else if (cmsysProcess_GetState(cp) == cmsysProcess_State_Exception) { + const char* exception_str = cmsysProcess_GetExceptionString(cp); + cmCTestLog(this, ERROR_MESSAGE, exception_str << std::endl); + stdErr->append(exception_str, strlen(exception_str)); + result = false; + } else if (cmsysProcess_GetState(cp) == cmsysProcess_State_Error) { + const char* error_str = cmsysProcess_GetErrorString(cp); + cmCTestLog(this, ERROR_MESSAGE, error_str << std::endl); + stdErr->append(error_str, strlen(error_str)); + result = false; + } else if (cmsysProcess_GetState(cp) == cmsysProcess_State_Expired) { const char* error_str = "Process terminated due to timeout\n"; cmCTestLog(this, ERROR_MESSAGE, error_str << std::endl); stdErr->append(error_str, strlen(error_str)); result = false; - } else { - auto const& status = chain.GetStatus(0); - auto exception = status.GetException(); - switch (exception.first) { - case cmUVProcessChain::ExceptionCode::None: - if (retVal) { - *retVal = static_cast<int>(status.ExitStatus); - } else { - if (status.ExitStatus != 0) { - result = false; - } - } - break; - default: { - cmCTestLog(this, ERROR_MESSAGE, exception.second << std::endl); - stdErr->append(exception.second); - result = false; - } break; - } } + cmsysProcess_Delete(cp); return result; } |
