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 <cassert>
16
17 namespace {
18 constexpr unsigned TIMEOUT_MS = 10000;
19 } // Anonymous namespace
20
21 namespace LIBC_NAMESPACE_DECL {
22 namespace testing {
23
testProcessKilled(testutils::FunctionCaller * Func,int Signal,const char * LHSStr,const char * RHSStr,internal::Location Loc)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
testProcessExits(testutils::FunctionCaller * Func,int ExitCode,const char * LHSStr,const char * RHSStr,internal::Location Loc)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