[libc][NFC] Make test macros callable from helper methods of test classes.

This is acheived by making the RunContext a state variable of the test
classes.

Reviewed By: lntue

Differential Revision: https://reviews.llvm.org/D90805
This commit is contained in:
Siva Chandra Reddy 2020-11-04 13:09:26 -08:00
parent 41e74e400d
commit 0e3532da98
2 changed files with 115 additions and 131 deletions

View File

@ -70,7 +70,7 @@ void explainDifference(ValType LHS, ValType RHS, const char *LHSStr,
}
template <typename ValType>
bool test(RunContext &Ctx, TestCondition Cond, ValType LHS, ValType RHS,
bool test(RunContext *Ctx, TestCondition Cond, ValType LHS, ValType RHS,
const char *LHSStr, const char *RHSStr, const char *File,
unsigned long Line) {
auto ExplainDifference = [=](llvm::StringRef OpString) {
@ -82,46 +82,46 @@ bool test(RunContext &Ctx, TestCondition Cond, ValType LHS, ValType RHS,
if (LHS == RHS)
return true;
Ctx.markFail();
Ctx->markFail();
ExplainDifference("equal to");
return false;
case Cond_NE:
if (LHS != RHS)
return true;
Ctx.markFail();
Ctx->markFail();
ExplainDifference("not equal to");
return false;
case Cond_LT:
if (LHS < RHS)
return true;
Ctx.markFail();
Ctx->markFail();
ExplainDifference("less than");
return false;
case Cond_LE:
if (LHS <= RHS)
return true;
Ctx.markFail();
Ctx->markFail();
ExplainDifference("less than or equal to");
return false;
case Cond_GT:
if (LHS > RHS)
return true;
Ctx.markFail();
Ctx->markFail();
ExplainDifference("greater than");
return false;
case Cond_GE:
if (LHS >= RHS)
return true;
Ctx.markFail();
Ctx->markFail();
ExplainDifference("greater than or equal to");
return false;
default:
Ctx.markFail();
Ctx->markFail();
llvm::outs() << "Unexpected test condition.\n";
return false;
}
@ -154,7 +154,8 @@ int Test::runTests() {
llvm::outs() << GREEN << "[ RUN ] " << RESET << TestName << '\n';
RunContext Ctx;
T->SetUp();
T->Run(Ctx);
T->setContext(&Ctx);
T->Run();
T->TearDown();
auto Result = Ctx.status();
switch (Result) {
@ -175,91 +176,83 @@ int Test::runTests() {
return FailCount > 0 ? 1 : 0;
}
template bool Test::test<char, 0>(RunContext &Ctx, TestCondition Cond, char LHS,
char RHS, const char *LHSStr,
const char *RHSStr, const char *File,
unsigned long Line);
template bool Test::test<char, 0>(TestCondition Cond, char LHS, char RHS,
const char *LHSStr, const char *RHSStr,
const char *File, unsigned long Line);
template bool Test::test<short, 0>(RunContext &Ctx, TestCondition Cond,
short LHS, short RHS, const char *LHSStr,
const char *RHSStr, const char *File,
unsigned long Line);
template bool Test::test<short, 0>(TestCondition Cond, short LHS, short RHS,
const char *LHSStr, const char *RHSStr,
const char *File, unsigned long Line);
template bool Test::test<int, 0>(RunContext &Ctx, TestCondition Cond, int LHS,
int RHS, const char *LHSStr,
const char *RHSStr, const char *File,
unsigned long Line);
template bool Test::test<int, 0>(TestCondition Cond, int LHS, int RHS,
const char *LHSStr, const char *RHSStr,
const char *File, unsigned long Line);
template bool Test::test<long, 0>(RunContext &Ctx, TestCondition Cond, long LHS,
long RHS, const char *LHSStr,
const char *RHSStr, const char *File,
unsigned long Line);
template bool Test::test<long, 0>(TestCondition Cond, long LHS, long RHS,
const char *LHSStr, const char *RHSStr,
const char *File, unsigned long Line);
template bool Test::test<long long, 0>(RunContext &Ctx, TestCondition Cond,
long long LHS, long long RHS,
const char *LHSStr, const char *RHSStr,
const char *File, unsigned long Line);
template bool Test::test<long long, 0>(TestCondition Cond, long long LHS,
long long RHS, const char *LHSStr,
const char *RHSStr, const char *File,
unsigned long Line);
template bool Test::test<unsigned char, 0>(RunContext &Ctx, TestCondition Cond,
template bool Test::test<unsigned char, 0>(TestCondition Cond,
unsigned char LHS, unsigned char RHS,
const char *LHSStr,
const char *RHSStr, const char *File,
unsigned long Line);
template bool
Test::test<unsigned short, 0>(RunContext &Ctx, TestCondition Cond,
unsigned short LHS, unsigned short RHS,
const char *LHSStr, const char *RHSStr,
const char *File, unsigned long Line);
Test::test<unsigned short, 0>(TestCondition Cond, unsigned short LHS,
unsigned short RHS, const char *LHSStr,
const char *RHSStr, const char *File,
unsigned long Line);
template bool Test::test<unsigned int, 0>(RunContext &Ctx, TestCondition Cond,
unsigned int LHS, unsigned int RHS,
const char *LHSStr,
template bool Test::test<unsigned int, 0>(TestCondition Cond, unsigned int LHS,
unsigned int RHS, const char *LHSStr,
const char *RHSStr, const char *File,
unsigned long Line);
template bool Test::test<unsigned long, 0>(RunContext &Ctx, TestCondition Cond,
template bool Test::test<unsigned long, 0>(TestCondition Cond,
unsigned long LHS, unsigned long RHS,
const char *LHSStr,
const char *RHSStr, const char *File,
unsigned long Line);
template bool Test::test<bool, 0>(RunContext &Ctx, TestCondition Cond, bool LHS,
bool RHS, const char *LHSStr,
template bool Test::test<bool, 0>(TestCondition Cond, bool LHS, bool RHS,
const char *LHSStr, const char *RHSStr,
const char *File, unsigned long Line);
template bool
Test::test<unsigned long long, 0>(TestCondition Cond, unsigned long long LHS,
unsigned long long RHS, const char *LHSStr,
const char *RHSStr, const char *File,
unsigned long Line);
template bool Test::test<unsigned long long, 0>(
RunContext &Ctx, TestCondition Cond, unsigned long long LHS,
unsigned long long RHS, const char *LHSStr, const char *RHSStr,
const char *File, unsigned long Line);
template bool Test::test<__uint128_t, 0>(TestCondition Cond, __uint128_t LHS,
__uint128_t RHS, const char *LHSStr,
const char *RHSStr, const char *File,
unsigned long Line);
template bool Test::test<__uint128_t, 0>(RunContext &Ctx, TestCondition Cond,
__uint128_t LHS, __uint128_t RHS,
const char *LHSStr, const char *RHSStr,
const char *File, unsigned long Line);
bool Test::testStrEq(RunContext &Ctx, const char *LHS, const char *RHS,
const char *LHSStr, const char *RHSStr, const char *File,
unsigned long Line) {
bool Test::testStrEq(const char *LHS, const char *RHS, const char *LHSStr,
const char *RHSStr, const char *File, unsigned long Line) {
return internal::test(Ctx, Cond_EQ, llvm::StringRef(LHS),
llvm::StringRef(RHS), LHSStr, RHSStr, File, Line);
}
bool Test::testStrNe(RunContext &Ctx, const char *LHS, const char *RHS,
const char *LHSStr, const char *RHSStr, const char *File,
unsigned long Line) {
bool Test::testStrNe(const char *LHS, const char *RHS, const char *LHSStr,
const char *RHSStr, const char *File, unsigned long Line) {
return internal::test(Ctx, Cond_NE, llvm::StringRef(LHS),
llvm::StringRef(RHS), LHSStr, RHSStr, File, Line);
}
bool Test::testMatch(RunContext &Ctx, bool MatchResult, MatcherBase &Matcher,
const char *LHSStr, const char *RHSStr, const char *File,
unsigned long Line) {
bool Test::testMatch(bool MatchResult, MatcherBase &Matcher, const char *LHSStr,
const char *RHSStr, const char *File, unsigned long Line) {
if (MatchResult)
return true;
Ctx.markFail();
Ctx->markFail();
llvm::outs() << File << ":" << Line << ": FAILURE\n"
<< "Failed to match " << LHSStr << " against " << RHSStr
<< ".\n";
@ -268,26 +261,26 @@ bool Test::testMatch(RunContext &Ctx, bool MatchResult, MatcherBase &Matcher,
return false;
}
bool Test::testProcessKilled(RunContext &Ctx, testutils::FunctionCaller *Func,
int Signal, const char *LHSStr, const char *RHSStr,
bool Test::testProcessKilled(testutils::FunctionCaller *Func, int Signal,
const char *LHSStr, const char *RHSStr,
const char *File, unsigned long Line) {
testutils::ProcessStatus Result = testutils::invokeInSubprocess(Func, 500);
if (const char *error = Result.getError()) {
Ctx.markFail();
Ctx->markFail();
llvm::outs() << File << ":" << Line << ": FAILURE\n" << error << '\n';
return false;
}
if (Result.timedOut()) {
Ctx.markFail();
Ctx->markFail();
llvm::outs() << File << ":" << Line << ": FAILURE\n"
<< "Process timed out after " << 500 << " milliseconds.\n";
return false;
}
if (Result.exitedNormally()) {
Ctx.markFail();
Ctx->markFail();
llvm::outs() << File << ":" << Line << ": FAILURE\n"
<< "Expected " << LHSStr
<< " to be killed by a signal\nBut it exited normally!\n";
@ -300,7 +293,7 @@ bool Test::testProcessKilled(RunContext &Ctx, testutils::FunctionCaller *Func,
return true;
using testutils::signalAsString;
Ctx.markFail();
Ctx->markFail();
llvm::outs() << File << ":" << Line << ": FAILURE\n"
<< " Expected: " << LHSStr << '\n'
<< "To be killed by signal: " << Signal << '\n'
@ -311,27 +304,26 @@ bool Test::testProcessKilled(RunContext &Ctx, testutils::FunctionCaller *Func,
return false;
}
bool Test::testProcessExits(RunContext &Ctx, testutils::FunctionCaller *Func,
int ExitCode, const char *LHSStr,
const char *RHSStr, const char *File,
unsigned long Line) {
bool Test::testProcessExits(testutils::FunctionCaller *Func, int ExitCode,
const char *LHSStr, const char *RHSStr,
const char *File, unsigned long Line) {
testutils::ProcessStatus Result = testutils::invokeInSubprocess(Func, 500);
if (const char *error = Result.getError()) {
Ctx.markFail();
Ctx->markFail();
llvm::outs() << File << ":" << Line << ": FAILURE\n" << error << '\n';
return false;
}
if (Result.timedOut()) {
Ctx.markFail();
Ctx->markFail();
llvm::outs() << File << ":" << Line << ": FAILURE\n"
<< "Process timed out after " << 500 << " milliseconds.\n";
return false;
}
if (!Result.exitedNormally()) {
Ctx.markFail();
Ctx->markFail();
llvm::outs() << File << ":" << Line << ": FAILURE\n"
<< "Expected " << LHSStr << '\n'
<< "to exit with exit code " << ExitCode << '\n'
@ -343,7 +335,7 @@ bool Test::testProcessExits(RunContext &Ctx, testutils::FunctionCaller *Func,
if (ActualExit == ExitCode)
return true;
Ctx.markFail();
Ctx->markFail();
llvm::outs() << File << ":" << Line << ": FAILURE\n"
<< "Expected exit code of: " << LHSStr << '\n'
<< " Which is: " << ActualExit << '\n'

View File

@ -39,7 +39,7 @@ enum TestCondition {
namespace internal {
template <typename ValType>
bool test(RunContext &Ctx, TestCondition Cond, ValType LHS, ValType RHS,
bool test(RunContext *Ctx, TestCondition Cond, ValType LHS, ValType RHS,
const char *LHSStr, const char *RHSStr, const char *File,
unsigned long Line);
@ -59,6 +59,9 @@ template <typename T> struct Matcher : public MatcherBase { bool match(T &t); };
class Test {
private:
Test *Next = nullptr;
RunContext *Ctx = nullptr;
void setContext(RunContext *C) { Ctx = C; }
public:
virtual ~Test() {}
@ -79,43 +82,36 @@ protected:
// of type promotion.
template <typename ValType,
cpp::EnableIfType<cpp::IsIntegral<ValType>::Value, int> = 0>
static bool test(RunContext &Ctx, TestCondition Cond, ValType LHS,
ValType RHS, const char *LHSStr, const char *RHSStr,
const char *File, unsigned long Line) {
bool test(TestCondition Cond, ValType LHS, ValType RHS, const char *LHSStr,
const char *RHSStr, const char *File, unsigned long Line) {
return internal::test(Ctx, Cond, LHS, RHS, LHSStr, RHSStr, File, Line);
}
template <
typename ValType,
cpp::EnableIfType<cpp::IsPointerType<ValType>::Value, ValType> = nullptr>
static bool test(RunContext &Ctx, TestCondition Cond, ValType LHS,
ValType RHS, const char *LHSStr, const char *RHSStr,
const char *File, unsigned long Line) {
bool test(TestCondition Cond, ValType LHS, ValType RHS, const char *LHSStr,
const char *RHSStr, const char *File, unsigned long Line) {
return internal::test(Ctx, Cond, (unsigned long long)LHS,
(unsigned long long)RHS, LHSStr, RHSStr, File, Line);
}
static bool testStrEq(RunContext &Ctx, const char *LHS, const char *RHS,
bool testStrEq(const char *LHS, const char *RHS, const char *LHSStr,
const char *RHSStr, const char *File, unsigned long Line);
bool testStrNe(const char *LHS, const char *RHS, const char *LHSStr,
const char *RHSStr, const char *File, unsigned long Line);
bool testMatch(bool MatchResult, MatcherBase &Matcher, const char *LHSStr,
const char *RHSStr, const char *File, unsigned long Line);
bool testProcessExits(testutils::FunctionCaller *Func, int ExitCode,
const char *LHSStr, const char *RHSStr,
const char *File, unsigned long Line);
static bool testStrNe(RunContext &Ctx, const char *LHS, const char *RHS,
const char *LHSStr, const char *RHSStr,
const char *File, unsigned long Line);
static bool testMatch(RunContext &Ctx, bool MatchResult, MatcherBase &Matcher,
const char *LHSStr, const char *RHSStr,
const char *File, unsigned long Line);
static bool testProcessExits(RunContext &Ctx, testutils::FunctionCaller *Func,
int ExitCode, const char *LHSStr,
const char *RHSStr, const char *File,
unsigned long Line);
static bool testProcessKilled(RunContext &Ctx,
testutils::FunctionCaller *Func, int Signal,
const char *LHSStr, const char *RHSStr,
const char *File, unsigned long Line);
bool testProcessKilled(testutils::FunctionCaller *Func, int Signal,
const char *LHSStr, const char *RHSStr,
const char *File, unsigned long Line);
template <typename Func> testutils::FunctionCaller *createCallable(Func f) {
struct Callable : public testutils::FunctionCaller {
@ -128,7 +124,7 @@ protected:
}
private:
virtual void Run(RunContext &Ctx) = 0;
virtual void Run() = 0;
virtual const char *getName() const = 0;
static Test *Start;
@ -142,74 +138,72 @@ private:
class SuiteName##_##TestName : public __llvm_libc::testing::Test { \
public: \
SuiteName##_##TestName() { addTest(this); } \
void Run(__llvm_libc::testing::RunContext &) override; \
void Run() override; \
const char *getName() const override { return #SuiteName "." #TestName; } \
}; \
SuiteName##_##TestName SuiteName##_##TestName##_Instance; \
void SuiteName##_##TestName::Run(__llvm_libc::testing::RunContext &Ctx)
void SuiteName##_##TestName::Run()
#define TEST_F(SuiteClass, TestName) \
class SuiteClass##_##TestName : public SuiteClass { \
public: \
SuiteClass##_##TestName() { addTest(this); } \
void Run(__llvm_libc::testing::RunContext &) override; \
void Run() override; \
const char *getName() const override { return #SuiteClass "." #TestName; } \
}; \
SuiteClass##_##TestName SuiteClass##_##TestName##_Instance; \
void SuiteClass##_##TestName::Run(__llvm_libc::testing::RunContext &Ctx)
void SuiteClass##_##TestName::Run()
#define EXPECT_EQ(LHS, RHS) \
__llvm_libc::testing::Test::test(Ctx, __llvm_libc::testing::Cond_EQ, (LHS), \
(RHS), #LHS, #RHS, __FILE__, __LINE__)
this->test(__llvm_libc::testing::Cond_EQ, (LHS), (RHS), #LHS, #RHS, \
__FILE__, __LINE__)
#define ASSERT_EQ(LHS, RHS) \
if (!EXPECT_EQ(LHS, RHS)) \
return
#define EXPECT_NE(LHS, RHS) \
__llvm_libc::testing::Test::test(Ctx, __llvm_libc::testing::Cond_NE, (LHS), \
(RHS), #LHS, #RHS, __FILE__, __LINE__)
this->test(__llvm_libc::testing::Cond_NE, (LHS), (RHS), #LHS, #RHS, \
__FILE__, __LINE__)
#define ASSERT_NE(LHS, RHS) \
if (!EXPECT_NE(LHS, RHS)) \
return
#define EXPECT_LT(LHS, RHS) \
__llvm_libc::testing::Test::test(Ctx, __llvm_libc::testing::Cond_LT, (LHS), \
(RHS), #LHS, #RHS, __FILE__, __LINE__)
this->test(__llvm_libc::testing::Cond_LT, (LHS), (RHS), #LHS, #RHS, \
__FILE__, __LINE__)
#define ASSERT_LT(LHS, RHS) \
if (!EXPECT_LT(LHS, RHS)) \
return
#define EXPECT_LE(LHS, RHS) \
__llvm_libc::testing::Test::test(Ctx, __llvm_libc::testing::Cond_LE, (LHS), \
(RHS), #LHS, #RHS, __FILE__, __LINE__)
this->test(__llvm_libc::testing::Cond_LE, (LHS), (RHS), #LHS, #RHS, \
__FILE__, __LINE__)
#define ASSERT_LE(LHS, RHS) \
if (!EXPECT_LE(LHS, RHS)) \
return
#define EXPECT_GT(LHS, RHS) \
__llvm_libc::testing::Test::test(Ctx, __llvm_libc::testing::Cond_GT, (LHS), \
(RHS), #LHS, #RHS, __FILE__, __LINE__)
this->test(__llvm_libc::testing::Cond_GT, (LHS), (RHS), #LHS, #RHS, \
__FILE__, __LINE__)
#define ASSERT_GT(LHS, RHS) \
if (!EXPECT_GT(LHS, RHS)) \
return
#define EXPECT_GE(LHS, RHS) \
__llvm_libc::testing::Test::test(Ctx, __llvm_libc::testing::Cond_GE, (LHS), \
(RHS), #LHS, #RHS, __FILE__, __LINE__)
this->test(__llvm_libc::testing::Cond_GE, (LHS), (RHS), #LHS, #RHS, \
__FILE__, __LINE__)
#define ASSERT_GE(LHS, RHS) \
if (!EXPECT_GE(LHS, RHS)) \
return
#define EXPECT_STREQ(LHS, RHS) \
__llvm_libc::testing::Test::testStrEq(Ctx, (LHS), (RHS), #LHS, #RHS, \
__FILE__, __LINE__)
this->testStrEq((LHS), (RHS), #LHS, #RHS, __FILE__, __LINE__)
#define ASSERT_STREQ(LHS, RHS) \
if (!EXPECT_STREQ(LHS, RHS)) \
return
#define EXPECT_STRNE(LHS, RHS) \
__llvm_libc::testing::Test::testStrNe(Ctx, (LHS), (RHS), #LHS, #RHS, \
__FILE__, __LINE__)
this->testStrNe((LHS), (RHS), #LHS, #RHS, __FILE__, __LINE__)
#define ASSERT_STRNE(LHS, RHS) \
if (!EXPECT_STRNE(LHS, RHS)) \
return
@ -227,18 +221,16 @@ private:
return
#define EXPECT_EXITS(FUNC, EXIT) \
__llvm_libc::testing::Test::testProcessExits( \
Ctx, __llvm_libc::testing::Test::createCallable(FUNC), EXIT, #FUNC, \
#EXIT, __FILE__, __LINE__)
this->testProcessExits(__llvm_libc::testing::Test::createCallable(FUNC), \
EXIT, #FUNC, #EXIT, __FILE__, __LINE__)
#define ASSERT_EXITS(FUNC, EXIT) \
if (!EXPECT_EXITS(FUNC, EXIT)) \
return
#define EXPECT_DEATH(FUNC, SIG) \
__llvm_libc::testing::Test::testProcessKilled( \
Ctx, __llvm_libc::testing::Test::createCallable(FUNC), SIG, #FUNC, #SIG, \
__FILE__, __LINE__)
this->testProcessKilled(__llvm_libc::testing::Test::createCallable(FUNC), \
SIG, #FUNC, #SIG, __FILE__, __LINE__)
#define ASSERT_DEATH(FUNC, EXIT) \
if (!EXPECT_DEATH(FUNC, EXIT)) \
@ -251,17 +243,17 @@ private:
#define EXPECT_THAT(MATCH, MATCHER) \
do { \
auto UNIQUE_VAR(__matcher) = (MATCHER); \
__llvm_libc::testing::Test::testMatch( \
Ctx, UNIQUE_VAR(__matcher).match((MATCH)), UNIQUE_VAR(__matcher), \
#MATCH, #MATCHER, __FILE__, __LINE__); \
this->testMatch(UNIQUE_VAR(__matcher).match((MATCH)), \
UNIQUE_VAR(__matcher), #MATCH, #MATCHER, __FILE__, \
__LINE__); \
} while (0)
#define ASSERT_THAT(MATCH, MATCHER) \
do { \
auto UNIQUE_VAR(__matcher) = (MATCHER); \
if (!__llvm_libc::testing::Test::testMatch( \
Ctx, UNIQUE_VAR(__matcher).match((MATCH)), UNIQUE_VAR(__matcher), \
#MATCH, #MATCHER, __FILE__, __LINE__)) \
if (!this->testMatch(UNIQUE_VAR(__matcher).match((MATCH)), \
UNIQUE_VAR(__matcher), #MATCH, #MATCHER, __FILE__, \
__LINE__)) \
return; \
} while (0)