| 1 | //===-- Implementation of libc death test executors -----------------------===// |
| 2 | // |
| 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
| 4 | // See https://llvm.org/LICENSE.txt for license information. |
| 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
| 6 | // |
| 7 | //===----------------------------------------------------------------------===// |
| 8 | |
| 9 | #include "LibcTest.h" |
| 10 | |
| 11 | #include "src/__support/macros/config.h" |
| 12 | #include "test/UnitTest/ExecuteFunction.h" |
| 13 | #include "test/UnitTest/TestLogger.h" |
| 14 | |
| 15 | #include <assert.h> |
| 16 | |
| 17 | namespace { |
| 18 | constexpr unsigned TIMEOUT_MS = 10000; |
| 19 | } // Anonymous namespace |
| 20 | |
| 21 | namespace LIBC_NAMESPACE_DECL { |
| 22 | namespace testing { |
| 23 | |
| 24 | bool Test::testProcessKilled(testutils::FunctionCaller *Func, int Signal, |
| 25 | const char *LHSStr, const char *RHSStr, |
| 26 | internal::Location Loc) { |
| 27 | testutils::ProcessStatus Result = |
| 28 | testutils::invoke_in_subprocess(Func, TIMEOUT_MS); |
| 29 | |
| 30 | if (const char *error = Result.get_error()) { |
| 31 | Ctx->markFail(); |
| 32 | tlog << Loc; |
| 33 | tlog << error << '\n'; |
| 34 | return false; |
| 35 | } |
| 36 | |
| 37 | if (Result.timed_out()) { |
| 38 | Ctx->markFail(); |
| 39 | tlog << Loc; |
| 40 | tlog << "Process timed out after " << TIMEOUT_MS << " milliseconds.\n" ; |
| 41 | return false; |
| 42 | } |
| 43 | |
| 44 | if (Result.exited_normally()) { |
| 45 | Ctx->markFail(); |
| 46 | tlog << Loc; |
| 47 | tlog << "Expected " << LHSStr |
| 48 | << " to be killed by a signal\nBut it exited normally!\n" ; |
| 49 | return false; |
| 50 | } |
| 51 | |
| 52 | int KilledBy = Result.get_fatal_signal(); |
| 53 | assert(KilledBy != 0 && "Not killed by any signal" ); |
| 54 | if (Signal == -1 || KilledBy == Signal) |
| 55 | return true; |
| 56 | |
| 57 | using testutils::signal_as_string; |
| 58 | Ctx->markFail(); |
| 59 | tlog << Loc; |
| 60 | tlog << " Expected: " << LHSStr << '\n' |
| 61 | << "To be killed by signal: " << Signal << '\n' |
| 62 | << " Which is: " << signal_as_string(Signal) << '\n' |
| 63 | << " But it was killed by: " << KilledBy << '\n' |
| 64 | << " Which is: " << signal_as_string(KilledBy) << '\n'; |
| 65 | return false; |
| 66 | } |
| 67 | |
| 68 | bool Test::testProcessExits(testutils::FunctionCaller *Func, int ExitCode, |
| 69 | const char *LHSStr, const char *RHSStr, |
| 70 | internal::Location Loc) { |
| 71 | testutils::ProcessStatus Result = |
| 72 | testutils::invoke_in_subprocess(Func, TIMEOUT_MS); |
| 73 | |
| 74 | if (const char *error = Result.get_error()) { |
| 75 | Ctx->markFail(); |
| 76 | tlog << Loc; |
| 77 | tlog << error << '\n'; |
| 78 | return false; |
| 79 | } |
| 80 | |
| 81 | if (Result.timed_out()) { |
| 82 | Ctx->markFail(); |
| 83 | tlog << Loc; |
| 84 | tlog << "Process timed out after " << TIMEOUT_MS << " milliseconds.\n" ; |
| 85 | return false; |
| 86 | } |
| 87 | |
| 88 | if (!Result.exited_normally()) { |
| 89 | Ctx->markFail(); |
| 90 | tlog << Loc; |
| 91 | tlog << "Expected " << LHSStr << '\n' |
| 92 | << "to exit with exit code " << ExitCode << '\n' |
| 93 | << "But it exited abnormally!\n" ; |
| 94 | return false; |
| 95 | } |
| 96 | |
| 97 | int ActualExit = Result.get_exit_code(); |
| 98 | if (ActualExit == ExitCode) |
| 99 | return true; |
| 100 | |
| 101 | Ctx->markFail(); |
| 102 | tlog << Loc; |
| 103 | tlog << "Expected exit code of: " << LHSStr << '\n' |
| 104 | << " Which is: " << ActualExit << '\n' |
| 105 | << " To be equal to: " << RHSStr << '\n' |
| 106 | << " Which is: " << ExitCode << '\n'; |
| 107 | return false; |
| 108 | } |
| 109 | |
| 110 | } // namespace testing |
| 111 | } // namespace LIBC_NAMESPACE_DECL |
| 112 | |