1fa7a9ef1SCaitlyn Cano //===-- Implementation of the base class for libc unittests----------------===//
24cfccd51SMichael Jones //
34cfccd51SMichael Jones // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
44cfccd51SMichael Jones // See https://llvm.org/LICENSE.txt for license information.
54cfccd51SMichael Jones // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
64cfccd51SMichael Jones //
74cfccd51SMichael Jones //===----------------------------------------------------------------------===//
84cfccd51SMichael Jones 
94cfccd51SMichael Jones #include "LibcTest.h"
104cfccd51SMichael Jones 
11*300f8da8SSiva Chandra Reddy #include "src/__support/CPP/UInt128.h"
124cfccd51SMichael Jones #include "utils/testutils/ExecuteFunction.h"
134cfccd51SMichael Jones #include <cassert>
144cfccd51SMichael Jones #include <iostream>
154cfccd51SMichael Jones #include <string>
164cfccd51SMichael Jones 
174cfccd51SMichael Jones namespace __llvm_libc {
184cfccd51SMichael Jones namespace testing {
194cfccd51SMichael Jones 
204cfccd51SMichael Jones // This need not be a class as all it has is a single read-write state variable.
214cfccd51SMichael Jones // But, we make it class as then its implementation can be hidden from the
224cfccd51SMichael Jones // header file.
234cfccd51SMichael Jones class RunContext {
244cfccd51SMichael Jones public:
254cfccd51SMichael Jones   enum RunResult { Result_Pass = 1, Result_Fail = 2 };
264cfccd51SMichael Jones 
status() const274cfccd51SMichael Jones   RunResult status() const { return Status; }
284cfccd51SMichael Jones 
markFail()294cfccd51SMichael Jones   void markFail() { Status = Result_Fail; }
304cfccd51SMichael Jones 
314cfccd51SMichael Jones private:
324cfccd51SMichael Jones   RunResult Status = Result_Pass;
334cfccd51SMichael Jones };
344cfccd51SMichael Jones 
354cfccd51SMichael Jones namespace internal {
364cfccd51SMichael Jones 
374cfccd51SMichael Jones // When the value is of integral type, just display it as normal.
384cfccd51SMichael Jones template <typename ValType>
394cfccd51SMichael Jones cpp::EnableIfType<cpp::IsIntegral<ValType>::Value, std::string>
describeValue(ValType Value)404cfccd51SMichael Jones describeValue(ValType Value) {
414cfccd51SMichael Jones   return std::to_string(Value);
424cfccd51SMichael Jones }
434cfccd51SMichael Jones 
describeValue(std::string Value)444cfccd51SMichael Jones std::string describeValue(std::string Value) { return std::string(Value); }
45*300f8da8SSiva Chandra Reddy 
46*300f8da8SSiva Chandra Reddy // When the value is UInt128 or __uint128_t, show its hexadecimal digits.
47*300f8da8SSiva Chandra Reddy // We cannot just use a UInt128 specialization as that resolves to only
48*300f8da8SSiva Chandra Reddy // one type, UInt<128> or __uint128_t. We want both overloads as we want to
49*300f8da8SSiva Chandra Reddy // be able to unittest UInt<128> on platforms where UInt128 resolves to
50*300f8da8SSiva Chandra Reddy // UInt128.
51*300f8da8SSiva Chandra Reddy template <typename UInt128Type>
describeValue128(UInt128Type Value)52*300f8da8SSiva Chandra Reddy std::string describeValue128(UInt128Type Value) {
53*300f8da8SSiva Chandra Reddy   std::string S(sizeof(UInt128) * 2, '0');
544cfccd51SMichael Jones 
554cfccd51SMichael Jones   for (auto I = S.rbegin(), End = S.rend(); I != End; ++I, Value >>= 4) {
564cfccd51SMichael Jones     unsigned char Mod = static_cast<unsigned char>(Value) & 15;
574cfccd51SMichael Jones     *I = Mod < 10 ? '0' + Mod : 'a' + Mod - 10;
584cfccd51SMichael Jones   }
594cfccd51SMichael Jones 
604cfccd51SMichael Jones   return "0x" + S;
614cfccd51SMichael Jones }
624cfccd51SMichael Jones 
63*300f8da8SSiva Chandra Reddy #ifdef __SIZEOF_INT128__
describeValue(__uint128_t Value)64b62d72f3SMichael Jones template <> std::string describeValue<__uint128_t>(__uint128_t Value) {
65b62d72f3SMichael Jones   return describeValue128(Value);
66b62d72f3SMichael Jones }
67ce6bfd10SDominic Chen #endif
68b62d72f3SMichael Jones 
691170951cSMichael Jones template <>
701170951cSMichael Jones std::string
describeValue(__llvm_libc::cpp::UInt<128> Value)711170951cSMichael Jones describeValue<__llvm_libc::cpp::UInt<128>>(__llvm_libc::cpp::UInt<128> Value) {
72*300f8da8SSiva Chandra Reddy   return describeValue128(Value);
731170951cSMichael Jones }
741170951cSMichael Jones 
754cfccd51SMichael Jones template <typename ValType>
explainDifference(ValType LHS,ValType RHS,const char * LHSStr,const char * RHSStr,const char * File,unsigned long Line,std::string OpString)764cfccd51SMichael Jones void explainDifference(ValType LHS, ValType RHS, const char *LHSStr,
774cfccd51SMichael Jones                        const char *RHSStr, const char *File, unsigned long Line,
784cfccd51SMichael Jones                        std::string OpString) {
794cfccd51SMichael Jones   size_t OffsetLength = OpString.size() > 2 ? OpString.size() - 2 : 0;
804cfccd51SMichael Jones   std::string Offset(OffsetLength, ' ');
814cfccd51SMichael Jones 
824cfccd51SMichael Jones   std::cout << File << ":" << Line << ": FAILURE\n"
834cfccd51SMichael Jones             << Offset << "Expected: " << LHSStr << '\n'
844cfccd51SMichael Jones             << Offset << "Which is: " << describeValue(LHS) << '\n'
854cfccd51SMichael Jones             << "To be " << OpString << ": " << RHSStr << '\n'
864cfccd51SMichael Jones             << Offset << "Which is: " << describeValue(RHS) << '\n';
874cfccd51SMichael Jones }
884cfccd51SMichael Jones 
894cfccd51SMichael Jones template <typename ValType>
test(RunContext * Ctx,TestCondition Cond,ValType LHS,ValType RHS,const char * LHSStr,const char * RHSStr,const char * File,unsigned long Line)904cfccd51SMichael Jones bool test(RunContext *Ctx, TestCondition Cond, ValType LHS, ValType RHS,
914cfccd51SMichael Jones           const char *LHSStr, const char *RHSStr, const char *File,
924cfccd51SMichael Jones           unsigned long Line) {
934cfccd51SMichael Jones   auto ExplainDifference = [=](std::string OpString) {
944cfccd51SMichael Jones     explainDifference(LHS, RHS, LHSStr, RHSStr, File, Line, OpString);
954cfccd51SMichael Jones   };
964cfccd51SMichael Jones 
974cfccd51SMichael Jones   switch (Cond) {
984cfccd51SMichael Jones   case Cond_EQ:
994cfccd51SMichael Jones     if (LHS == RHS)
1004cfccd51SMichael Jones       return true;
1014cfccd51SMichael Jones 
1024cfccd51SMichael Jones     Ctx->markFail();
1034cfccd51SMichael Jones     ExplainDifference("equal to");
1044cfccd51SMichael Jones     return false;
1054cfccd51SMichael Jones   case Cond_NE:
1064cfccd51SMichael Jones     if (LHS != RHS)
1074cfccd51SMichael Jones       return true;
1084cfccd51SMichael Jones 
1094cfccd51SMichael Jones     Ctx->markFail();
1104cfccd51SMichael Jones     ExplainDifference("not equal to");
1114cfccd51SMichael Jones     return false;
1124cfccd51SMichael Jones   case Cond_LT:
1134cfccd51SMichael Jones     if (LHS < RHS)
1144cfccd51SMichael Jones       return true;
1154cfccd51SMichael Jones 
1164cfccd51SMichael Jones     Ctx->markFail();
1174cfccd51SMichael Jones     ExplainDifference("less than");
1184cfccd51SMichael Jones     return false;
1194cfccd51SMichael Jones   case Cond_LE:
1204cfccd51SMichael Jones     if (LHS <= RHS)
1214cfccd51SMichael Jones       return true;
1224cfccd51SMichael Jones 
1234cfccd51SMichael Jones     Ctx->markFail();
1244cfccd51SMichael Jones     ExplainDifference("less than or equal to");
1254cfccd51SMichael Jones     return false;
1264cfccd51SMichael Jones   case Cond_GT:
1274cfccd51SMichael Jones     if (LHS > RHS)
1284cfccd51SMichael Jones       return true;
1294cfccd51SMichael Jones 
1304cfccd51SMichael Jones     Ctx->markFail();
1314cfccd51SMichael Jones     ExplainDifference("greater than");
1324cfccd51SMichael Jones     return false;
1334cfccd51SMichael Jones   case Cond_GE:
1344cfccd51SMichael Jones     if (LHS >= RHS)
1354cfccd51SMichael Jones       return true;
1364cfccd51SMichael Jones 
1374cfccd51SMichael Jones     Ctx->markFail();
1384cfccd51SMichael Jones     ExplainDifference("greater than or equal to");
1394cfccd51SMichael Jones     return false;
1404cfccd51SMichael Jones   default:
1414cfccd51SMichael Jones     Ctx->markFail();
1424cfccd51SMichael Jones     std::cout << "Unexpected test condition.\n";
1434cfccd51SMichael Jones     return false;
1444cfccd51SMichael Jones   }
1454cfccd51SMichael Jones }
1464cfccd51SMichael Jones 
1474cfccd51SMichael Jones } // namespace internal
1484cfccd51SMichael Jones 
1494cfccd51SMichael Jones Test *Test::Start = nullptr;
1504cfccd51SMichael Jones Test *Test::End = nullptr;
1514cfccd51SMichael Jones 
addTest(Test * T)1524cfccd51SMichael Jones void Test::addTest(Test *T) {
1534cfccd51SMichael Jones   if (End == nullptr) {
1544cfccd51SMichael Jones     Start = T;
1554cfccd51SMichael Jones     End = T;
1564cfccd51SMichael Jones     return;
1574cfccd51SMichael Jones   }
1584cfccd51SMichael Jones 
1594cfccd51SMichael Jones   End->Next = T;
1604cfccd51SMichael Jones   End = T;
1614cfccd51SMichael Jones }
1624cfccd51SMichael Jones 
runTests(const char * TestFilter)163fa7a9ef1SCaitlyn Cano int Test::runTests(const char *TestFilter) {
1644cfccd51SMichael Jones   int TestCount = 0;
1654cfccd51SMichael Jones   int FailCount = 0;
166fa7a9ef1SCaitlyn Cano   for (Test *T = Start; T != nullptr; T = T->Next) {
1674cfccd51SMichael Jones     const char *TestName = T->getName();
168fa7a9ef1SCaitlyn Cano     std::string StrTestName(TestName);
1694cfccd51SMichael Jones     constexpr auto GREEN = "\033[32m";
1704cfccd51SMichael Jones     constexpr auto RED = "\033[31m";
1714cfccd51SMichael Jones     constexpr auto RESET = "\033[0m";
172fa7a9ef1SCaitlyn Cano     if ((TestFilter != nullptr) && (StrTestName != TestFilter)) {
173fa7a9ef1SCaitlyn Cano       continue;
174fa7a9ef1SCaitlyn Cano     }
1754cfccd51SMichael Jones     std::cout << GREEN << "[ RUN      ] " << RESET << TestName << '\n';
1764cfccd51SMichael Jones     RunContext Ctx;
1774cfccd51SMichael Jones     T->SetUp();
1784cfccd51SMichael Jones     T->setContext(&Ctx);
1794cfccd51SMichael Jones     T->Run();
1804cfccd51SMichael Jones     T->TearDown();
1814cfccd51SMichael Jones     auto Result = Ctx.status();
1824cfccd51SMichael Jones     switch (Result) {
1834cfccd51SMichael Jones     case RunContext::Result_Fail:
1844cfccd51SMichael Jones       std::cout << RED << "[  FAILED  ] " << RESET << TestName << '\n';
1854cfccd51SMichael Jones       ++FailCount;
1864cfccd51SMichael Jones       break;
1874cfccd51SMichael Jones     case RunContext::Result_Pass:
1884cfccd51SMichael Jones       std::cout << GREEN << "[       OK ] " << RESET << TestName << '\n';
1894cfccd51SMichael Jones       break;
1904cfccd51SMichael Jones     }
191fa7a9ef1SCaitlyn Cano     ++TestCount;
1924cfccd51SMichael Jones   }
1934cfccd51SMichael Jones 
194fa7a9ef1SCaitlyn Cano   if (TestCount > 0) {
1954cfccd51SMichael Jones     std::cout << "Ran " << TestCount << " tests. "
1964cfccd51SMichael Jones               << " PASS: " << TestCount - FailCount << ' '
1974cfccd51SMichael Jones               << " FAIL: " << FailCount << '\n';
198fa7a9ef1SCaitlyn Cano   } else {
199fa7a9ef1SCaitlyn Cano     std::cout << "No tests run.\n";
200fa7a9ef1SCaitlyn Cano     if (TestFilter) {
201fa7a9ef1SCaitlyn Cano       std::cout << "No matching test for " << TestFilter << '\n';
202fa7a9ef1SCaitlyn Cano     }
203fa7a9ef1SCaitlyn Cano   }
2044cfccd51SMichael Jones 
205fa7a9ef1SCaitlyn Cano   return FailCount > 0 || TestCount == 0 ? 1 : 0;
2064cfccd51SMichael Jones }
2074cfccd51SMichael Jones 
208d2c59546SGuillaume Chatelet namespace internal {
209d2c59546SGuillaume Chatelet 
210d2c59546SGuillaume Chatelet template bool test<char>(RunContext *Ctx, TestCondition Cond, char LHS,
211d2c59546SGuillaume Chatelet                          char RHS, const char *LHSStr, const char *RHSStr,
212d2c59546SGuillaume Chatelet                          const char *File, unsigned long Line);
213d2c59546SGuillaume Chatelet 
214d2c59546SGuillaume Chatelet template bool test<short>(RunContext *Ctx, TestCondition Cond, short LHS,
215d2c59546SGuillaume Chatelet                           short RHS, const char *LHSStr, const char *RHSStr,
216d2c59546SGuillaume Chatelet                           const char *File, unsigned long Line);
217d2c59546SGuillaume Chatelet 
218d2c59546SGuillaume Chatelet template bool test<int>(RunContext *Ctx, TestCondition Cond, int LHS, int RHS,
2194cfccd51SMichael Jones                         const char *LHSStr, const char *RHSStr,
2204cfccd51SMichael Jones                         const char *File, unsigned long Line);
2214cfccd51SMichael Jones 
222d2c59546SGuillaume Chatelet template bool test<long>(RunContext *Ctx, TestCondition Cond, long LHS,
223d2c59546SGuillaume Chatelet                          long RHS, const char *LHSStr, const char *RHSStr,
2244cfccd51SMichael Jones                          const char *File, unsigned long Line);
2254cfccd51SMichael Jones 
226d2c59546SGuillaume Chatelet template bool test<long long>(RunContext *Ctx, TestCondition Cond,
227d2c59546SGuillaume Chatelet                               long long LHS, long long RHS, const char *LHSStr,
2284cfccd51SMichael Jones                               const char *RHSStr, const char *File,
2294cfccd51SMichael Jones                               unsigned long Line);
2304cfccd51SMichael Jones 
231d2c59546SGuillaume Chatelet template bool test<unsigned char>(RunContext *Ctx, TestCondition Cond,
2324cfccd51SMichael Jones                                   unsigned char LHS, unsigned char RHS,
2334cfccd51SMichael Jones                                   const char *LHSStr, const char *RHSStr,
2344cfccd51SMichael Jones                                   const char *File, unsigned long Line);
2354cfccd51SMichael Jones 
236d2c59546SGuillaume Chatelet template bool test<unsigned short>(RunContext *Ctx, TestCondition Cond,
237d2c59546SGuillaume Chatelet                                    unsigned short LHS, unsigned short RHS,
238d2c59546SGuillaume Chatelet                                    const char *LHSStr, const char *RHSStr,
239d2c59546SGuillaume Chatelet                                    const char *File, unsigned long Line);
2404cfccd51SMichael Jones 
241d2c59546SGuillaume Chatelet template bool test<unsigned int>(RunContext *Ctx, TestCondition Cond,
242d2c59546SGuillaume Chatelet                                  unsigned int LHS, unsigned int RHS,
243d2c59546SGuillaume Chatelet                                  const char *LHSStr, const char *RHSStr,
244d2c59546SGuillaume Chatelet                                  const char *File, unsigned long Line);
245d2c59546SGuillaume Chatelet 
246d2c59546SGuillaume Chatelet template bool test<unsigned long>(RunContext *Ctx, TestCondition Cond,
247d2c59546SGuillaume Chatelet                                   unsigned long LHS, unsigned long RHS,
248d2c59546SGuillaume Chatelet                                   const char *LHSStr, const char *RHSStr,
249d2c59546SGuillaume Chatelet                                   const char *File, unsigned long Line);
250d2c59546SGuillaume Chatelet 
251d2c59546SGuillaume Chatelet template bool test<bool>(RunContext *Ctx, TestCondition Cond, bool LHS,
252d2c59546SGuillaume Chatelet                          bool RHS, const char *LHSStr, const char *RHSStr,
253d2c59546SGuillaume Chatelet                          const char *File, unsigned long Line);
254d2c59546SGuillaume Chatelet 
255d2c59546SGuillaume Chatelet template bool test<unsigned long long>(RunContext *Ctx, TestCondition Cond,
256d2c59546SGuillaume Chatelet                                        unsigned long long LHS,
257d2c59546SGuillaume Chatelet                                        unsigned long long RHS,
258d2c59546SGuillaume Chatelet                                        const char *LHSStr, const char *RHSStr,
259d2c59546SGuillaume Chatelet                                        const char *File, unsigned long Line);
260d2c59546SGuillaume Chatelet 
261*300f8da8SSiva Chandra Reddy // We cannot just use a single UInt128 specialization as that resolves to only
262*300f8da8SSiva Chandra Reddy // one type, UInt<128> or __uint128_t. We want both overloads as we want to
263*300f8da8SSiva Chandra Reddy // be able to unittest UInt<128> on platforms where UInt128 resolves to
264*300f8da8SSiva Chandra Reddy // UInt128.
265ce6bfd10SDominic Chen #ifdef __SIZEOF_INT128__
266*300f8da8SSiva Chandra Reddy // When builtin __uint128_t type is available, include its specialization
267*300f8da8SSiva Chandra Reddy // also.
268d2c59546SGuillaume Chatelet template bool test<__uint128_t>(RunContext *Ctx, TestCondition Cond,
269d2c59546SGuillaume Chatelet                                 __uint128_t LHS, __uint128_t RHS,
270d2c59546SGuillaume Chatelet                                 const char *LHSStr, const char *RHSStr,
271d2c59546SGuillaume Chatelet                                 const char *File, unsigned long Line);
272ce6bfd10SDominic Chen #endif
273d2c59546SGuillaume Chatelet 
274*300f8da8SSiva Chandra Reddy template bool test<__llvm_libc::cpp::UInt<128>>(
275*300f8da8SSiva Chandra Reddy     RunContext *Ctx, TestCondition Cond, __llvm_libc::cpp::UInt<128> LHS,
276*300f8da8SSiva Chandra Reddy     __llvm_libc::cpp::UInt<128> RHS, const char *LHSStr, const char *RHSStr,
277*300f8da8SSiva Chandra Reddy     const char *File, unsigned long Line);
278*300f8da8SSiva Chandra Reddy 
279d2c59546SGuillaume Chatelet } // namespace internal
2804cfccd51SMichael Jones 
testStrEq(const char * LHS,const char * RHS,const char * LHSStr,const char * RHSStr,const char * File,unsigned long Line)2814cfccd51SMichael Jones bool Test::testStrEq(const char *LHS, const char *RHS, const char *LHSStr,
2824cfccd51SMichael Jones                      const char *RHSStr, const char *File, unsigned long Line) {
2834cfccd51SMichael Jones   return internal::test(Ctx, Cond_EQ, LHS ? std::string(LHS) : std::string(),
2844cfccd51SMichael Jones                         RHS ? std::string(RHS) : std::string(), LHSStr, RHSStr,
2854cfccd51SMichael Jones                         File, Line);
2864cfccd51SMichael Jones }
2874cfccd51SMichael Jones 
testStrNe(const char * LHS,const char * RHS,const char * LHSStr,const char * RHSStr,const char * File,unsigned long Line)2884cfccd51SMichael Jones bool Test::testStrNe(const char *LHS, const char *RHS, const char *LHSStr,
2894cfccd51SMichael Jones                      const char *RHSStr, const char *File, unsigned long Line) {
2904cfccd51SMichael Jones   return internal::test(Ctx, Cond_NE, LHS ? std::string(LHS) : std::string(),
2914cfccd51SMichael Jones                         RHS ? std::string(RHS) : std::string(), LHSStr, RHSStr,
2924cfccd51SMichael Jones                         File, Line);
2934cfccd51SMichael Jones }
2944cfccd51SMichael Jones 
testMatch(bool MatchResult,MatcherBase & Matcher,const char * LHSStr,const char * RHSStr,const char * File,unsigned long Line)2954cfccd51SMichael Jones bool Test::testMatch(bool MatchResult, MatcherBase &Matcher, const char *LHSStr,
2964cfccd51SMichael Jones                      const char *RHSStr, const char *File, unsigned long Line) {
2974cfccd51SMichael Jones   if (MatchResult)
2984cfccd51SMichael Jones     return true;
2994cfccd51SMichael Jones 
3004cfccd51SMichael Jones   Ctx->markFail();
3014cfccd51SMichael Jones   std::cout << File << ":" << Line << ": FAILURE\n"
3024cfccd51SMichael Jones             << "Failed to match " << LHSStr << " against " << RHSStr << ".\n";
3034cfccd51SMichael Jones   testutils::StreamWrapper OutsWrapper = testutils::outs();
3044cfccd51SMichael Jones   Matcher.explainError(OutsWrapper);
3054cfccd51SMichael Jones   return false;
3064cfccd51SMichael Jones }
3074cfccd51SMichael Jones 
3086344a583SSiva Chandra Reddy #ifdef ENABLE_SUBPROCESS_TESTS
3096344a583SSiva Chandra Reddy 
testProcessKilled(testutils::FunctionCaller * Func,int Signal,const char * LHSStr,const char * RHSStr,const char * File,unsigned long Line)3104cfccd51SMichael Jones bool Test::testProcessKilled(testutils::FunctionCaller *Func, int Signal,
3114cfccd51SMichael Jones                              const char *LHSStr, const char *RHSStr,
3124cfccd51SMichael Jones                              const char *File, unsigned long Line) {
31325226f3eSMichael Jones   testutils::ProcessStatus Result = testutils::invoke_in_subprocess(Func, 500);
3144cfccd51SMichael Jones 
31525226f3eSMichael Jones   if (const char *error = Result.get_error()) {
3164cfccd51SMichael Jones     Ctx->markFail();
3174cfccd51SMichael Jones     std::cout << File << ":" << Line << ": FAILURE\n" << error << '\n';
3184cfccd51SMichael Jones     return false;
3194cfccd51SMichael Jones   }
3204cfccd51SMichael Jones 
32125226f3eSMichael Jones   if (Result.timed_out()) {
3224cfccd51SMichael Jones     Ctx->markFail();
3234cfccd51SMichael Jones     std::cout << File << ":" << Line << ": FAILURE\n"
3244cfccd51SMichael Jones               << "Process timed out after " << 500 << " milliseconds.\n";
3254cfccd51SMichael Jones     return false;
3264cfccd51SMichael Jones   }
3274cfccd51SMichael Jones 
32825226f3eSMichael Jones   if (Result.exited_normally()) {
3294cfccd51SMichael Jones     Ctx->markFail();
3304cfccd51SMichael Jones     std::cout << File << ":" << Line << ": FAILURE\n"
3314cfccd51SMichael Jones               << "Expected " << LHSStr
3324cfccd51SMichael Jones               << " to be killed by a signal\nBut it exited normally!\n";
3334cfccd51SMichael Jones     return false;
3344cfccd51SMichael Jones   }
3354cfccd51SMichael Jones 
33625226f3eSMichael Jones   int KilledBy = Result.get_fatal_signal();
3374cfccd51SMichael Jones   assert(KilledBy != 0 && "Not killed by any signal");
3384cfccd51SMichael Jones   if (Signal == -1 || KilledBy == Signal)
3394cfccd51SMichael Jones     return true;
3404cfccd51SMichael Jones 
34125226f3eSMichael Jones   using testutils::signal_as_string;
3424cfccd51SMichael Jones   Ctx->markFail();
3434cfccd51SMichael Jones   std::cout << File << ":" << Line << ": FAILURE\n"
3444cfccd51SMichael Jones             << "              Expected: " << LHSStr << '\n'
3454cfccd51SMichael Jones             << "To be killed by signal: " << Signal << '\n'
34625226f3eSMichael Jones             << "              Which is: " << signal_as_string(Signal) << '\n'
3474cfccd51SMichael Jones             << "  But it was killed by: " << KilledBy << '\n'
34825226f3eSMichael Jones             << "              Which is: " << signal_as_string(KilledBy) << '\n';
3494cfccd51SMichael Jones   return false;
3504cfccd51SMichael Jones }
3514cfccd51SMichael Jones 
testProcessExits(testutils::FunctionCaller * Func,int ExitCode,const char * LHSStr,const char * RHSStr,const char * File,unsigned long Line)3524cfccd51SMichael Jones bool Test::testProcessExits(testutils::FunctionCaller *Func, int ExitCode,
3534cfccd51SMichael Jones                             const char *LHSStr, const char *RHSStr,
3544cfccd51SMichael Jones                             const char *File, unsigned long Line) {
35525226f3eSMichael Jones   testutils::ProcessStatus Result = testutils::invoke_in_subprocess(Func, 500);
3564cfccd51SMichael Jones 
35725226f3eSMichael Jones   if (const char *error = Result.get_error()) {
3584cfccd51SMichael Jones     Ctx->markFail();
3594cfccd51SMichael Jones     std::cout << File << ":" << Line << ": FAILURE\n" << error << '\n';
3604cfccd51SMichael Jones     return false;
3614cfccd51SMichael Jones   }
3624cfccd51SMichael Jones 
36325226f3eSMichael Jones   if (Result.timed_out()) {
3644cfccd51SMichael Jones     Ctx->markFail();
3654cfccd51SMichael Jones     std::cout << File << ":" << Line << ": FAILURE\n"
3664cfccd51SMichael Jones               << "Process timed out after " << 500 << " milliseconds.\n";
3674cfccd51SMichael Jones     return false;
3684cfccd51SMichael Jones   }
3694cfccd51SMichael Jones 
37025226f3eSMichael Jones   if (!Result.exited_normally()) {
3714cfccd51SMichael Jones     Ctx->markFail();
3724cfccd51SMichael Jones     std::cout << File << ":" << Line << ": FAILURE\n"
3734cfccd51SMichael Jones               << "Expected " << LHSStr << '\n'
3744cfccd51SMichael Jones               << "to exit with exit code " << ExitCode << '\n'
3754cfccd51SMichael Jones               << "But it exited abnormally!\n";
3764cfccd51SMichael Jones     return false;
3774cfccd51SMichael Jones   }
3784cfccd51SMichael Jones 
37925226f3eSMichael Jones   int ActualExit = Result.get_exit_code();
3804cfccd51SMichael Jones   if (ActualExit == ExitCode)
3814cfccd51SMichael Jones     return true;
3824cfccd51SMichael Jones 
3834cfccd51SMichael Jones   Ctx->markFail();
3844cfccd51SMichael Jones   std::cout << File << ":" << Line << ": FAILURE\n"
3854cfccd51SMichael Jones             << "Expected exit code of: " << LHSStr << '\n'
3864cfccd51SMichael Jones             << "             Which is: " << ActualExit << '\n'
3874cfccd51SMichael Jones             << "       To be equal to: " << RHSStr << '\n'
3884cfccd51SMichael Jones             << "             Which is: " << ExitCode << '\n';
3894cfccd51SMichael Jones   return false;
3904cfccd51SMichael Jones }
3914cfccd51SMichael Jones 
3926344a583SSiva Chandra Reddy #endif // ENABLE_SUBPROCESS_TESTS
3934cfccd51SMichael Jones } // namespace testing
3944cfccd51SMichael Jones } // namespace __llvm_libc
395