diff options
author | Kyle Edwards <kyle.edwards@kitware.com> | 2023-06-02 20:02:23 (GMT) |
---|---|---|
committer | Kyle Edwards <kyle.edwards@kitware.com> | 2023-06-08 18:56:27 (GMT) |
commit | 891b60d691812c45b92d4ad2127e1559f80f8332 (patch) | |
tree | 835fea3aab501b9a2d1f431093f58e6083a8c56f /Tests | |
parent | 5be0cd9f3c07b60b1f60ea678c1d82c38185ca27 (diff) | |
download | CMake-891b60d691812c45b92d4ad2127e1559f80f8332.zip CMake-891b60d691812c45b92d4ad2127e1559f80f8332.tar.gz CMake-891b60d691812c45b92d4ad2127e1559f80f8332.tar.bz2 |
cmUVProcessChain: Add Status::SpawnResult field
Diffstat (limited to 'Tests')
-rw-r--r-- | Tests/CMakeLib/testUVProcessChain.cxx | 263 | ||||
-rw-r--r-- | Tests/CMakeLib/testUVProcessChainHelper.cxx | 4 |
2 files changed, 203 insertions, 64 deletions
diff --git a/Tests/CMakeLib/testUVProcessChain.cxx b/Tests/CMakeLib/testUVProcessChain.cxx index 7027689..e0a67e9 100644 --- a/Tests/CMakeLib/testUVProcessChain.cxx +++ b/Tests/CMakeLib/testUVProcessChain.cxx @@ -20,7 +20,6 @@ struct ExpectedStatus { - bool Finished; bool MatchExitStatus; bool MatchTermSignal; cmUVProcessChain::Status Status; @@ -28,38 +27,6 @@ struct ExpectedStatus std::string ExceptionString; }; -static const std::vector<ExpectedStatus> status1 = { - { false, false, false, { 0, 0 }, cmUVProcessChain::ExceptionCode::None, "" }, - { false, false, false, { 0, 0 }, cmUVProcessChain::ExceptionCode::None, "" }, - { false, false, false, { 0, 0 }, cmUVProcessChain::ExceptionCode::None, "" }, -}; - -static const std::vector<ExpectedStatus> status2 = { - { true, true, true, { 0, 0 }, cmUVProcessChain::ExceptionCode::None, "" }, - { false, false, false, { 0, 0 }, cmUVProcessChain::ExceptionCode::None, "" }, - { false, false, false, { 0, 0 }, cmUVProcessChain::ExceptionCode::None, "" }, -}; - -static const std::vector<ExpectedStatus> status3 = { - { true, true, true, { 0, 0 }, cmUVProcessChain::ExceptionCode::None, "" }, - { true, true, true, { 1, 0 }, cmUVProcessChain::ExceptionCode::None, "" }, -#ifdef _WIN32 - { true, - true, - true, - { STATUS_ACCESS_VIOLATION, 0 }, - cmUVProcessChain::ExceptionCode::Fault, - "Access violation" }, -#else - { true, - false, - true, - { 0, SIGABRT }, - cmUVProcessChain::ExceptionCode::Other, - "Subprocess aborted" }, -#endif -}; - static const char* ExceptionCodeToString(cmUVProcessChain::ExceptionCode code) { switch (code) { @@ -73,6 +40,8 @@ static const char* ExceptionCodeToString(cmUVProcessChain::ExceptionCode code) return "Interrupt"; case cmUVProcessChain::ExceptionCode::Numerical: return "Numerical"; + case cmUVProcessChain::ExceptionCode::Spawn: + return "Spawn"; case cmUVProcessChain::ExceptionCode::Other: return "Other"; default: @@ -83,9 +52,10 @@ static const char* ExceptionCodeToString(cmUVProcessChain::ExceptionCode code) bool operator==(const cmUVProcessChain::Status* actual, const ExpectedStatus& expected) { - if (!expected.Finished) { - return !actual; - } else if (!actual) { + if (expected.Status.SpawnResult != actual->SpawnResult) { + return false; + } + if (expected.Status.Finished != actual->Finished) { return false; } if (expected.MatchExitStatus && @@ -96,7 +66,7 @@ bool operator==(const cmUVProcessChain::Status* actual, expected.Status.TermSignal != actual->TermSignal) { return false; } - if (expected.Finished && + if (expected.Status.Finished && std::make_pair(expected.ExceptionCode, expected.ExceptionString) != actual->GetException()) { return false; @@ -150,39 +120,96 @@ static void printResults( { std::cout << "Expected: " << std::endl; for (auto const& e : expected) { - if (e.Finished) { - std::cout << " ExitStatus: " - << printExpected(e.MatchExitStatus, e.Status.ExitStatus) - << ", TermSignal: " - << printExpected(e.MatchTermSignal, e.Status.TermSignal) - << ", ExceptionCode: " - << printExpected(e.Finished, - ExceptionCodeToString(e.ExceptionCode)) - << ", ExceptionString: \"" - << printExpected(e.Finished, e.ExceptionString) << '"' - << std::endl; - } else { - std::cout << " null" << std::endl; - } + std::cout << " SpawnResult: " << e.Status.SpawnResult + << ", Finished: " << e.Status.Finished << ", ExitStatus: " + << printExpected(e.MatchExitStatus, e.Status.ExitStatus) + << ", TermSignal: " + << printExpected(e.MatchTermSignal, e.Status.TermSignal) + << ", ExceptionCode: " + << printExpected(e.Status.Finished, + ExceptionCodeToString(e.ExceptionCode)) + << ", ExceptionString: \"" + << printExpected(e.Status.Finished, e.ExceptionString) << '"' + << std::endl; } std::cout << "Actual:" << std::endl; for (auto const& a : actual) { - if (a) { - auto exception = a->GetException(); - std::cout << " ExitStatus: " << a->ExitStatus - << ", TermSignal: " << a->TermSignal << ", ExceptionCode: " - << ExceptionCodeToString(exception.first) - << ", ExceptionString: \"" << exception.second << '"' - << std::endl; - } else { - std::cout << " null" << std::endl; - } + auto exception = a->GetException(); + std::cout << " SpawnResult: " << a->SpawnResult + << ", Finished: " << a->Finished + << ", ExitStatus: " << a->ExitStatus + << ", TermSignal: " << a->TermSignal + << ", ExceptionCode: " << ExceptionCodeToString(exception.first) + << ", ExceptionString: \"" << exception.second << '"' + << std::endl; } } static bool checkExecution(cmUVProcessChainBuilder& builder, std::unique_ptr<cmUVProcessChain>& chain) { + static const std::vector<ExpectedStatus> status1 = { + { false, + false, + { 0, false, 0, 0 }, + cmUVProcessChain::ExceptionCode::None, + "" }, + { false, + false, + { 0, false, 0, 0 }, + cmUVProcessChain::ExceptionCode::None, + "" }, + { false, + false, + { 0, false, 0, 0 }, + cmUVProcessChain::ExceptionCode::None, + "" }, + }; + + static const std::vector<ExpectedStatus> status2 = { + { true, + true, + { 0, true, 0, 0 }, + cmUVProcessChain::ExceptionCode::None, + "" }, + { false, + false, + { 0, false, 0, 0 }, + cmUVProcessChain::ExceptionCode::None, + "" }, + { false, + false, + { 0, false, 0, 0 }, + cmUVProcessChain::ExceptionCode::None, + "" }, + }; + + static const std::vector<ExpectedStatus> status3 = { + { true, + true, + { 0, true, 0, 0 }, + cmUVProcessChain::ExceptionCode::None, + "" }, + { true, + true, + { 0, true, 1, 0 }, + cmUVProcessChain::ExceptionCode::None, + "" }, +#ifdef _WIN32 + { true, + true, + { 0, true, STATUS_ACCESS_VIOLATION, 0 }, + cmUVProcessChain::ExceptionCode::Fault, + "Access violation" }, +#else + { false, + true, + { 0, true, 0, SIGABRT }, + cmUVProcessChain::ExceptionCode::Other, + "Subprocess aborted" }, +#endif + }; + std::vector<const cmUVProcessChain::Status*> status; chain = cm::make_unique<cmUVProcessChain>(builder.Start()); @@ -201,7 +228,7 @@ static bool checkExecution(cmUVProcessChainBuilder& builder, return false; } - if (chain->Wait(6000)) { + if (chain->Wait(9000)) { std::cout << "Wait() returned true, should be false" << std::endl; return false; } @@ -481,6 +508,113 @@ bool testUVProcessChainCwdChanged(const char* helperCommand) return true; } +bool testUVProcessChainSpawnFail(const char* helperCommand) +{ + static const std::vector<ExpectedStatus> status1 = { + { false, + false, + { 0, false, 0, 0 }, + cmUVProcessChain::ExceptionCode::None, + "" }, + { false, + false, + { UV_ENOENT, true, 0, 0 }, + cmUVProcessChain::ExceptionCode::Spawn, + uv_strerror(UV_ENOENT) }, +#ifdef _WIN32 + { true, + true, + { 0, true, STATUS_ACCESS_VIOLATION, 0 }, + cmUVProcessChain::ExceptionCode::Fault, + "Access violation" }, +#else + { false, + true, + { 0, true, 0, SIGABRT }, + cmUVProcessChain::ExceptionCode::Other, + "Subprocess aborted" }, +#endif + }; + + static const std::vector<ExpectedStatus> status2 = { +#ifdef _WIN32 + { true, + true, + { 0, true, 0, 0 }, + cmUVProcessChain::ExceptionCode::None, + "" }, +#else + { false, + true, + { 0, true, 0, SIGPIPE }, + cmUVProcessChain::ExceptionCode::Other, + "SIGPIPE" }, +#endif + { false, + false, + { UV_ENOENT, true, 0, 0 }, + cmUVProcessChain::ExceptionCode::Spawn, + uv_strerror(UV_ENOENT) }, +#ifdef _WIN32 + { true, + true, + { 0, true, STATUS_ACCESS_VIOLATION, 0 }, + cmUVProcessChain::ExceptionCode::Fault, + "Access violation" }, +#else + { false, + true, + { 0, true, 0, SIGABRT }, + cmUVProcessChain::ExceptionCode::Other, + "Subprocess aborted" }, +#endif + }; + + std::vector<const cmUVProcessChain::Status*> status; + + cmUVProcessChainBuilder builder; + builder.AddCommand({ helperCommand, "echo" }) + .AddCommand({ "this_command_is_for_cmake_and_should_never_exist" }) + .AddCommand({ helperCommand, "dedup" }) + .SetBuiltinStream(cmUVProcessChainBuilder::Stream_OUTPUT) + .SetBuiltinStream(cmUVProcessChainBuilder::Stream_ERROR); + + auto chain = builder.Start(); + if (!chain.Valid()) { + std::cout << "Valid() returned false, should be true" << std::endl; + return false; + } + + // Some platforms, like Solaris 10, take a long time to report a trapped + // subprocess to the parent process (about 1.7 seconds in the case of + // Solaris 10.) Wait 3 seconds to give it enough time. + if (chain.Wait(3000)) { + std::cout << "Wait() did not time out" << std::endl; + return false; + } + + status = chain.GetStatus(); + if (!resultsMatch(status, status1)) { + std::cout << "GetStatus() did not produce expected output" << std::endl; + printResults(status, status1); + return false; + } + + if (!chain.Wait()) { + std::cout << "Wait() timed out" << std::endl; + return false; + } + + status = chain.GetStatus(); + if (!resultsMatch(status, status2)) { + std::cout << "GetStatus() did not produce expected output" << std::endl; + printResults(status, status2); + return false; + } + + return true; +} + int testUVProcessChain(int argc, char** const argv) { if (argc < 2) { @@ -518,5 +652,10 @@ int testUVProcessChain(int argc, char** const argv) return -1; } + if (!testUVProcessChainSpawnFail(argv[1])) { + std::cout << "While executing testUVProcessChainSpawnFail().\n"; + return -1; + } + return 0; } diff --git a/Tests/CMakeLib/testUVProcessChainHelper.cxx b/Tests/CMakeLib/testUVProcessChainHelper.cxx index 99743e7..fcc45b0 100644 --- a/Tests/CMakeLib/testUVProcessChainHelper.cxx +++ b/Tests/CMakeLib/testUVProcessChainHelper.cxx @@ -32,13 +32,13 @@ int main(int argc, char** argv) std::string command = argv[1]; if (command == "echo") { - std::this_thread::sleep_for(std::chrono::milliseconds(3000)); + std::this_thread::sleep_for(std::chrono::milliseconds(6000)); std::cout << "HELLO world!" << std::flush; std::cerr << "1" << std::flush; return 0; } if (command == "capitalize") { - std::this_thread::sleep_for(std::chrono::milliseconds(9000)); + std::this_thread::sleep_for(std::chrono::milliseconds(12000)); std::string input = getStdin(); for (auto& c : input) { c = static_cast<char>(std::toupper(c)); |