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 114cfccd51SMichael Jones #include "utils/testutils/ExecuteFunction.h" 124cfccd51SMichael Jones #include <cassert> 134cfccd51SMichael Jones #include <iostream> 144cfccd51SMichael Jones #include <string> 154cfccd51SMichael Jones 164cfccd51SMichael Jones namespace __llvm_libc { 174cfccd51SMichael Jones namespace testing { 184cfccd51SMichael Jones 194cfccd51SMichael Jones // This need not be a class as all it has is a single read-write state variable. 204cfccd51SMichael Jones // But, we make it class as then its implementation can be hidden from the 214cfccd51SMichael Jones // header file. 224cfccd51SMichael Jones class RunContext { 234cfccd51SMichael Jones public: 244cfccd51SMichael Jones enum RunResult { Result_Pass = 1, Result_Fail = 2 }; 254cfccd51SMichael Jones 264cfccd51SMichael Jones RunResult status() const { return Status; } 274cfccd51SMichael Jones 284cfccd51SMichael Jones void markFail() { Status = Result_Fail; } 294cfccd51SMichael Jones 304cfccd51SMichael Jones private: 314cfccd51SMichael Jones RunResult Status = Result_Pass; 324cfccd51SMichael Jones }; 334cfccd51SMichael Jones 344cfccd51SMichael Jones namespace internal { 354cfccd51SMichael Jones 364cfccd51SMichael Jones // When the value is of integral type, just display it as normal. 374cfccd51SMichael Jones template <typename ValType> 384cfccd51SMichael Jones cpp::EnableIfType<cpp::IsIntegral<ValType>::Value, std::string> 394cfccd51SMichael Jones describeValue(ValType Value) { 404cfccd51SMichael Jones return std::to_string(Value); 414cfccd51SMichael Jones } 424cfccd51SMichael Jones 434cfccd51SMichael Jones std::string describeValue(std::string Value) { return std::string(Value); } 444cfccd51SMichael Jones 45*ce6bfd10SDominic Chen #ifdef __SIZEOF_INT128__ 464cfccd51SMichael Jones // When the value is __uint128_t, also show its hexadecimal digits. 474cfccd51SMichael Jones // Using template to force exact match, prevent ambiguous promotion. 48b62d72f3SMichael Jones std::string describeValue128(__uint128_t Value) { 494cfccd51SMichael Jones std::string S(sizeof(__uint128_t) * 2, '0'); 504cfccd51SMichael Jones 514cfccd51SMichael Jones for (auto I = S.rbegin(), End = S.rend(); I != End; ++I, Value >>= 4) { 524cfccd51SMichael Jones unsigned char Mod = static_cast<unsigned char>(Value) & 15; 534cfccd51SMichael Jones *I = Mod < 10 ? '0' + Mod : 'a' + Mod - 10; 544cfccd51SMichael Jones } 554cfccd51SMichael Jones 564cfccd51SMichael Jones return "0x" + S; 574cfccd51SMichael Jones } 584cfccd51SMichael Jones 59b62d72f3SMichael Jones template <> std::string describeValue<__int128_t>(__int128_t Value) { 60b62d72f3SMichael Jones return describeValue128(Value); 61b62d72f3SMichael Jones } 62b62d72f3SMichael Jones template <> std::string describeValue<__uint128_t>(__uint128_t Value) { 63b62d72f3SMichael Jones return describeValue128(Value); 64b62d72f3SMichael Jones } 65*ce6bfd10SDominic Chen #endif 66b62d72f3SMichael Jones 674cfccd51SMichael Jones template <typename ValType> 684cfccd51SMichael Jones void explainDifference(ValType LHS, ValType RHS, const char *LHSStr, 694cfccd51SMichael Jones const char *RHSStr, const char *File, unsigned long Line, 704cfccd51SMichael Jones std::string OpString) { 714cfccd51SMichael Jones size_t OffsetLength = OpString.size() > 2 ? OpString.size() - 2 : 0; 724cfccd51SMichael Jones std::string Offset(OffsetLength, ' '); 734cfccd51SMichael Jones 744cfccd51SMichael Jones std::cout << File << ":" << Line << ": FAILURE\n" 754cfccd51SMichael Jones << Offset << "Expected: " << LHSStr << '\n' 764cfccd51SMichael Jones << Offset << "Which is: " << describeValue(LHS) << '\n' 774cfccd51SMichael Jones << "To be " << OpString << ": " << RHSStr << '\n' 784cfccd51SMichael Jones << Offset << "Which is: " << describeValue(RHS) << '\n'; 794cfccd51SMichael Jones } 804cfccd51SMichael Jones 814cfccd51SMichael Jones template <typename ValType> 824cfccd51SMichael Jones bool test(RunContext *Ctx, TestCondition Cond, ValType LHS, ValType RHS, 834cfccd51SMichael Jones const char *LHSStr, const char *RHSStr, const char *File, 844cfccd51SMichael Jones unsigned long Line) { 854cfccd51SMichael Jones auto ExplainDifference = [=](std::string OpString) { 864cfccd51SMichael Jones explainDifference(LHS, RHS, LHSStr, RHSStr, File, Line, OpString); 874cfccd51SMichael Jones }; 884cfccd51SMichael Jones 894cfccd51SMichael Jones switch (Cond) { 904cfccd51SMichael Jones case Cond_EQ: 914cfccd51SMichael Jones if (LHS == RHS) 924cfccd51SMichael Jones return true; 934cfccd51SMichael Jones 944cfccd51SMichael Jones Ctx->markFail(); 954cfccd51SMichael Jones ExplainDifference("equal to"); 964cfccd51SMichael Jones return false; 974cfccd51SMichael Jones case Cond_NE: 984cfccd51SMichael Jones if (LHS != RHS) 994cfccd51SMichael Jones return true; 1004cfccd51SMichael Jones 1014cfccd51SMichael Jones Ctx->markFail(); 1024cfccd51SMichael Jones ExplainDifference("not equal to"); 1034cfccd51SMichael Jones return false; 1044cfccd51SMichael Jones case Cond_LT: 1054cfccd51SMichael Jones if (LHS < RHS) 1064cfccd51SMichael Jones return true; 1074cfccd51SMichael Jones 1084cfccd51SMichael Jones Ctx->markFail(); 1094cfccd51SMichael Jones ExplainDifference("less than"); 1104cfccd51SMichael Jones return false; 1114cfccd51SMichael Jones case Cond_LE: 1124cfccd51SMichael Jones if (LHS <= RHS) 1134cfccd51SMichael Jones return true; 1144cfccd51SMichael Jones 1154cfccd51SMichael Jones Ctx->markFail(); 1164cfccd51SMichael Jones ExplainDifference("less than or equal to"); 1174cfccd51SMichael Jones return false; 1184cfccd51SMichael Jones case Cond_GT: 1194cfccd51SMichael Jones if (LHS > RHS) 1204cfccd51SMichael Jones return true; 1214cfccd51SMichael Jones 1224cfccd51SMichael Jones Ctx->markFail(); 1234cfccd51SMichael Jones ExplainDifference("greater than"); 1244cfccd51SMichael Jones return false; 1254cfccd51SMichael Jones case Cond_GE: 1264cfccd51SMichael Jones if (LHS >= RHS) 1274cfccd51SMichael Jones return true; 1284cfccd51SMichael Jones 1294cfccd51SMichael Jones Ctx->markFail(); 1304cfccd51SMichael Jones ExplainDifference("greater than or equal to"); 1314cfccd51SMichael Jones return false; 1324cfccd51SMichael Jones default: 1334cfccd51SMichael Jones Ctx->markFail(); 1344cfccd51SMichael Jones std::cout << "Unexpected test condition.\n"; 1354cfccd51SMichael Jones return false; 1364cfccd51SMichael Jones } 1374cfccd51SMichael Jones } 1384cfccd51SMichael Jones 1394cfccd51SMichael Jones } // namespace internal 1404cfccd51SMichael Jones 1414cfccd51SMichael Jones Test *Test::Start = nullptr; 1424cfccd51SMichael Jones Test *Test::End = nullptr; 1434cfccd51SMichael Jones 1444cfccd51SMichael Jones void Test::addTest(Test *T) { 1454cfccd51SMichael Jones if (End == nullptr) { 1464cfccd51SMichael Jones Start = T; 1474cfccd51SMichael Jones End = T; 1484cfccd51SMichael Jones return; 1494cfccd51SMichael Jones } 1504cfccd51SMichael Jones 1514cfccd51SMichael Jones End->Next = T; 1524cfccd51SMichael Jones End = T; 1534cfccd51SMichael Jones } 1544cfccd51SMichael Jones 155fa7a9ef1SCaitlyn Cano int Test::runTests(const char *TestFilter) { 1564cfccd51SMichael Jones int TestCount = 0; 1574cfccd51SMichael Jones int FailCount = 0; 158fa7a9ef1SCaitlyn Cano for (Test *T = Start; T != nullptr; T = T->Next) { 1594cfccd51SMichael Jones const char *TestName = T->getName(); 160fa7a9ef1SCaitlyn Cano std::string StrTestName(TestName); 1614cfccd51SMichael Jones constexpr auto GREEN = "\033[32m"; 1624cfccd51SMichael Jones constexpr auto RED = "\033[31m"; 1634cfccd51SMichael Jones constexpr auto RESET = "\033[0m"; 164fa7a9ef1SCaitlyn Cano if ((TestFilter != nullptr) && (StrTestName != TestFilter)) { 165fa7a9ef1SCaitlyn Cano continue; 166fa7a9ef1SCaitlyn Cano } 1674cfccd51SMichael Jones std::cout << GREEN << "[ RUN ] " << RESET << TestName << '\n'; 1684cfccd51SMichael Jones RunContext Ctx; 1694cfccd51SMichael Jones T->SetUp(); 1704cfccd51SMichael Jones T->setContext(&Ctx); 1714cfccd51SMichael Jones T->Run(); 1724cfccd51SMichael Jones T->TearDown(); 1734cfccd51SMichael Jones auto Result = Ctx.status(); 1744cfccd51SMichael Jones switch (Result) { 1754cfccd51SMichael Jones case RunContext::Result_Fail: 1764cfccd51SMichael Jones std::cout << RED << "[ FAILED ] " << RESET << TestName << '\n'; 1774cfccd51SMichael Jones ++FailCount; 1784cfccd51SMichael Jones break; 1794cfccd51SMichael Jones case RunContext::Result_Pass: 1804cfccd51SMichael Jones std::cout << GREEN << "[ OK ] " << RESET << TestName << '\n'; 1814cfccd51SMichael Jones break; 1824cfccd51SMichael Jones } 183fa7a9ef1SCaitlyn Cano ++TestCount; 1844cfccd51SMichael Jones } 1854cfccd51SMichael Jones 186fa7a9ef1SCaitlyn Cano if (TestCount > 0) { 1874cfccd51SMichael Jones std::cout << "Ran " << TestCount << " tests. " 1884cfccd51SMichael Jones << " PASS: " << TestCount - FailCount << ' ' 1894cfccd51SMichael Jones << " FAIL: " << FailCount << '\n'; 190fa7a9ef1SCaitlyn Cano } else { 191fa7a9ef1SCaitlyn Cano std::cout << "No tests run.\n"; 192fa7a9ef1SCaitlyn Cano if (TestFilter) { 193fa7a9ef1SCaitlyn Cano std::cout << "No matching test for " << TestFilter << '\n'; 194fa7a9ef1SCaitlyn Cano } 195fa7a9ef1SCaitlyn Cano } 1964cfccd51SMichael Jones 197fa7a9ef1SCaitlyn Cano return FailCount > 0 || TestCount == 0 ? 1 : 0; 1984cfccd51SMichael Jones } 1994cfccd51SMichael Jones 200d2c59546SGuillaume Chatelet namespace internal { 201d2c59546SGuillaume Chatelet 202d2c59546SGuillaume Chatelet template bool test<char>(RunContext *Ctx, TestCondition Cond, char LHS, 203d2c59546SGuillaume Chatelet char RHS, const char *LHSStr, const char *RHSStr, 204d2c59546SGuillaume Chatelet const char *File, unsigned long Line); 205d2c59546SGuillaume Chatelet 206d2c59546SGuillaume Chatelet template bool test<short>(RunContext *Ctx, TestCondition Cond, short LHS, 207d2c59546SGuillaume Chatelet short RHS, const char *LHSStr, const char *RHSStr, 208d2c59546SGuillaume Chatelet const char *File, unsigned long Line); 209d2c59546SGuillaume Chatelet 210d2c59546SGuillaume Chatelet template bool test<int>(RunContext *Ctx, TestCondition Cond, int LHS, int RHS, 2114cfccd51SMichael Jones const char *LHSStr, const char *RHSStr, 2124cfccd51SMichael Jones const char *File, unsigned long Line); 2134cfccd51SMichael Jones 214d2c59546SGuillaume Chatelet template bool test<long>(RunContext *Ctx, TestCondition Cond, long LHS, 215d2c59546SGuillaume Chatelet long RHS, const char *LHSStr, const char *RHSStr, 2164cfccd51SMichael Jones const char *File, unsigned long Line); 2174cfccd51SMichael Jones 218d2c59546SGuillaume Chatelet template bool test<long long>(RunContext *Ctx, TestCondition Cond, 219d2c59546SGuillaume Chatelet long long LHS, long long RHS, const char *LHSStr, 2204cfccd51SMichael Jones const char *RHSStr, const char *File, 2214cfccd51SMichael Jones unsigned long Line); 2224cfccd51SMichael Jones 223*ce6bfd10SDominic Chen #ifdef __SIZEOF_INT128__ 224d2c59546SGuillaume Chatelet template bool test<__int128_t>(RunContext *Ctx, TestCondition Cond, 225d2c59546SGuillaume Chatelet __int128_t LHS, __int128_t RHS, 226d2c59546SGuillaume Chatelet const char *LHSStr, const char *RHSStr, 227d2c59546SGuillaume Chatelet const char *File, unsigned long Line); 228*ce6bfd10SDominic Chen #endif 229b62d72f3SMichael Jones 230d2c59546SGuillaume Chatelet template bool test<unsigned char>(RunContext *Ctx, TestCondition Cond, 2314cfccd51SMichael Jones unsigned char LHS, unsigned char RHS, 2324cfccd51SMichael Jones const char *LHSStr, const char *RHSStr, 2334cfccd51SMichael Jones const char *File, unsigned long Line); 2344cfccd51SMichael Jones 235d2c59546SGuillaume Chatelet template bool test<unsigned short>(RunContext *Ctx, TestCondition Cond, 236d2c59546SGuillaume Chatelet unsigned short LHS, unsigned short RHS, 237d2c59546SGuillaume Chatelet const char *LHSStr, const char *RHSStr, 238d2c59546SGuillaume Chatelet const char *File, unsigned long Line); 2394cfccd51SMichael Jones 240d2c59546SGuillaume Chatelet template bool test<unsigned int>(RunContext *Ctx, TestCondition Cond, 241d2c59546SGuillaume Chatelet unsigned int LHS, unsigned int RHS, 242d2c59546SGuillaume Chatelet const char *LHSStr, const char *RHSStr, 243d2c59546SGuillaume Chatelet const char *File, unsigned long Line); 244d2c59546SGuillaume Chatelet 245d2c59546SGuillaume Chatelet template bool test<unsigned long>(RunContext *Ctx, TestCondition Cond, 246d2c59546SGuillaume Chatelet unsigned long LHS, unsigned long RHS, 247d2c59546SGuillaume Chatelet const char *LHSStr, const char *RHSStr, 248d2c59546SGuillaume Chatelet const char *File, unsigned long Line); 249d2c59546SGuillaume Chatelet 250d2c59546SGuillaume Chatelet template bool test<bool>(RunContext *Ctx, TestCondition Cond, bool LHS, 251d2c59546SGuillaume Chatelet bool RHS, const char *LHSStr, const char *RHSStr, 252d2c59546SGuillaume Chatelet const char *File, unsigned long Line); 253d2c59546SGuillaume Chatelet 254d2c59546SGuillaume Chatelet template bool test<unsigned long long>(RunContext *Ctx, TestCondition Cond, 255d2c59546SGuillaume Chatelet unsigned long long LHS, 256d2c59546SGuillaume Chatelet unsigned long long RHS, 257d2c59546SGuillaume Chatelet const char *LHSStr, const char *RHSStr, 258d2c59546SGuillaume Chatelet const char *File, unsigned long Line); 259d2c59546SGuillaume Chatelet 260*ce6bfd10SDominic Chen #ifdef __SIZEOF_INT128__ 261d2c59546SGuillaume Chatelet template bool test<__uint128_t>(RunContext *Ctx, TestCondition Cond, 262d2c59546SGuillaume Chatelet __uint128_t LHS, __uint128_t RHS, 263d2c59546SGuillaume Chatelet const char *LHSStr, const char *RHSStr, 264d2c59546SGuillaume Chatelet const char *File, unsigned long Line); 265*ce6bfd10SDominic Chen #endif 266d2c59546SGuillaume Chatelet 267d2c59546SGuillaume Chatelet } // namespace internal 2684cfccd51SMichael Jones 2694cfccd51SMichael Jones bool Test::testStrEq(const char *LHS, const char *RHS, const char *LHSStr, 2704cfccd51SMichael Jones const char *RHSStr, const char *File, unsigned long Line) { 2714cfccd51SMichael Jones return internal::test(Ctx, Cond_EQ, LHS ? std::string(LHS) : std::string(), 2724cfccd51SMichael Jones RHS ? std::string(RHS) : std::string(), LHSStr, RHSStr, 2734cfccd51SMichael Jones File, Line); 2744cfccd51SMichael Jones } 2754cfccd51SMichael Jones 2764cfccd51SMichael Jones bool Test::testStrNe(const char *LHS, const char *RHS, const char *LHSStr, 2774cfccd51SMichael Jones const char *RHSStr, const char *File, unsigned long Line) { 2784cfccd51SMichael Jones return internal::test(Ctx, Cond_NE, LHS ? std::string(LHS) : std::string(), 2794cfccd51SMichael Jones RHS ? std::string(RHS) : std::string(), LHSStr, RHSStr, 2804cfccd51SMichael Jones File, Line); 2814cfccd51SMichael Jones } 2824cfccd51SMichael Jones 2834cfccd51SMichael Jones bool Test::testMatch(bool MatchResult, MatcherBase &Matcher, const char *LHSStr, 2844cfccd51SMichael Jones const char *RHSStr, const char *File, unsigned long Line) { 2854cfccd51SMichael Jones if (MatchResult) 2864cfccd51SMichael Jones return true; 2874cfccd51SMichael Jones 2884cfccd51SMichael Jones Ctx->markFail(); 2894cfccd51SMichael Jones std::cout << File << ":" << Line << ": FAILURE\n" 2904cfccd51SMichael Jones << "Failed to match " << LHSStr << " against " << RHSStr << ".\n"; 2914cfccd51SMichael Jones testutils::StreamWrapper OutsWrapper = testutils::outs(); 2924cfccd51SMichael Jones Matcher.explainError(OutsWrapper); 2934cfccd51SMichael Jones return false; 2944cfccd51SMichael Jones } 2954cfccd51SMichael Jones 2966344a583SSiva Chandra Reddy #ifdef ENABLE_SUBPROCESS_TESTS 2976344a583SSiva Chandra Reddy 2984cfccd51SMichael Jones bool Test::testProcessKilled(testutils::FunctionCaller *Func, int Signal, 2994cfccd51SMichael Jones const char *LHSStr, const char *RHSStr, 3004cfccd51SMichael Jones const char *File, unsigned long Line) { 30125226f3eSMichael Jones testutils::ProcessStatus Result = testutils::invoke_in_subprocess(Func, 500); 3024cfccd51SMichael Jones 30325226f3eSMichael Jones if (const char *error = Result.get_error()) { 3044cfccd51SMichael Jones Ctx->markFail(); 3054cfccd51SMichael Jones std::cout << File << ":" << Line << ": FAILURE\n" << error << '\n'; 3064cfccd51SMichael Jones return false; 3074cfccd51SMichael Jones } 3084cfccd51SMichael Jones 30925226f3eSMichael Jones if (Result.timed_out()) { 3104cfccd51SMichael Jones Ctx->markFail(); 3114cfccd51SMichael Jones std::cout << File << ":" << Line << ": FAILURE\n" 3124cfccd51SMichael Jones << "Process timed out after " << 500 << " milliseconds.\n"; 3134cfccd51SMichael Jones return false; 3144cfccd51SMichael Jones } 3154cfccd51SMichael Jones 31625226f3eSMichael Jones if (Result.exited_normally()) { 3174cfccd51SMichael Jones Ctx->markFail(); 3184cfccd51SMichael Jones std::cout << File << ":" << Line << ": FAILURE\n" 3194cfccd51SMichael Jones << "Expected " << LHSStr 3204cfccd51SMichael Jones << " to be killed by a signal\nBut it exited normally!\n"; 3214cfccd51SMichael Jones return false; 3224cfccd51SMichael Jones } 3234cfccd51SMichael Jones 32425226f3eSMichael Jones int KilledBy = Result.get_fatal_signal(); 3254cfccd51SMichael Jones assert(KilledBy != 0 && "Not killed by any signal"); 3264cfccd51SMichael Jones if (Signal == -1 || KilledBy == Signal) 3274cfccd51SMichael Jones return true; 3284cfccd51SMichael Jones 32925226f3eSMichael Jones using testutils::signal_as_string; 3304cfccd51SMichael Jones Ctx->markFail(); 3314cfccd51SMichael Jones std::cout << File << ":" << Line << ": FAILURE\n" 3324cfccd51SMichael Jones << " Expected: " << LHSStr << '\n' 3334cfccd51SMichael Jones << "To be killed by signal: " << Signal << '\n' 33425226f3eSMichael Jones << " Which is: " << signal_as_string(Signal) << '\n' 3354cfccd51SMichael Jones << " But it was killed by: " << KilledBy << '\n' 33625226f3eSMichael Jones << " Which is: " << signal_as_string(KilledBy) << '\n'; 3374cfccd51SMichael Jones return false; 3384cfccd51SMichael Jones } 3394cfccd51SMichael Jones 3404cfccd51SMichael Jones bool Test::testProcessExits(testutils::FunctionCaller *Func, int ExitCode, 3414cfccd51SMichael Jones const char *LHSStr, const char *RHSStr, 3424cfccd51SMichael Jones const char *File, unsigned long Line) { 34325226f3eSMichael Jones testutils::ProcessStatus Result = testutils::invoke_in_subprocess(Func, 500); 3444cfccd51SMichael Jones 34525226f3eSMichael Jones if (const char *error = Result.get_error()) { 3464cfccd51SMichael Jones Ctx->markFail(); 3474cfccd51SMichael Jones std::cout << File << ":" << Line << ": FAILURE\n" << error << '\n'; 3484cfccd51SMichael Jones return false; 3494cfccd51SMichael Jones } 3504cfccd51SMichael Jones 35125226f3eSMichael Jones if (Result.timed_out()) { 3524cfccd51SMichael Jones Ctx->markFail(); 3534cfccd51SMichael Jones std::cout << File << ":" << Line << ": FAILURE\n" 3544cfccd51SMichael Jones << "Process timed out after " << 500 << " milliseconds.\n"; 3554cfccd51SMichael Jones return false; 3564cfccd51SMichael Jones } 3574cfccd51SMichael Jones 35825226f3eSMichael Jones if (!Result.exited_normally()) { 3594cfccd51SMichael Jones Ctx->markFail(); 3604cfccd51SMichael Jones std::cout << File << ":" << Line << ": FAILURE\n" 3614cfccd51SMichael Jones << "Expected " << LHSStr << '\n' 3624cfccd51SMichael Jones << "to exit with exit code " << ExitCode << '\n' 3634cfccd51SMichael Jones << "But it exited abnormally!\n"; 3644cfccd51SMichael Jones return false; 3654cfccd51SMichael Jones } 3664cfccd51SMichael Jones 36725226f3eSMichael Jones int ActualExit = Result.get_exit_code(); 3684cfccd51SMichael Jones if (ActualExit == ExitCode) 3694cfccd51SMichael Jones return true; 3704cfccd51SMichael Jones 3714cfccd51SMichael Jones Ctx->markFail(); 3724cfccd51SMichael Jones std::cout << File << ":" << Line << ": FAILURE\n" 3734cfccd51SMichael Jones << "Expected exit code of: " << LHSStr << '\n' 3744cfccd51SMichael Jones << " Which is: " << ActualExit << '\n' 3754cfccd51SMichael Jones << " To be equal to: " << RHSStr << '\n' 3764cfccd51SMichael Jones << " Which is: " << ExitCode << '\n'; 3774cfccd51SMichael Jones return false; 3784cfccd51SMichael Jones } 3794cfccd51SMichael Jones 3806344a583SSiva Chandra Reddy #endif // ENABLE_SUBPROCESS_TESTS 3814cfccd51SMichael Jones } // namespace testing 3824cfccd51SMichael Jones } // namespace __llvm_libc 383