127 lines · c
1//===- OmptTesterStandalone.h - Standalone header variant -------*- C++ -*-===//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-exception6//7//===----------------------------------------------------------------------===//8///9/// \file10/// This file represents the 'standalone' header variant, defining the actual11/// test classes and their behavior (it does not have external dependencies).12///13//===----------------------------------------------------------------------===//14 15#ifndef OPENMP_TOOLS_OMPTEST_INCLUDE_OMPTTESTERSTANDALONE_H16#define OPENMP_TOOLS_OMPTEST_INCLUDE_OMPTTESTERSTANDALONE_H17 18#include "OmptAssertEvent.h"19#include "OmptAsserter.h"20#include "OmptTesterGlobals.h"21 22#include <utility>23#include <vector>24 25// Forward declarations.26namespace omptest {27struct OmptEventAsserter;28class OmptEventReporter;29class OmptSequencedAsserter;30} // namespace omptest31 32struct Error {33 operator bool() { return Fail; }34 bool Fail;35};36 37/// A pretty crude test case abstraction38struct TestCase {39 TestCase(const std::string &name)40 : IsDisabled(name.rfind("DISABLED_", 0) == 0), Name(name) {}41 TestCase(const std::string &name, const omptest::AssertState &expected)42 : IsDisabled(name.rfind("DISABLED_", 0) == 0), Name(name),43 ExpectedState(expected) {}44 virtual ~TestCase() = default;45 Error exec();46 virtual void execImpl() { assert(false && "Allocating base class"); }47 48 bool IsDisabled{false};49 std::string Name;50 omptest::AssertState ExpectedState{omptest::AssertState::Pass};51 omptest::AssertState ResultState{omptest::AssertState::Pass};52 53 std::unique_ptr<omptest::OmptSequencedAsserter> SequenceAsserter =54 std::make_unique<omptest::OmptSequencedAsserter>();55 std::unique_ptr<omptest::OmptEventAsserter> SetAsserter =56 std::make_unique<omptest::OmptEventAsserter>();57 std::unique_ptr<omptest::OmptEventReporter> EventReporter =58 std::make_unique<omptest::OmptEventReporter>();59};60/// A pretty crude test suite abstraction61struct TestSuite {62 using TestCaseVec = std::vector<std::unique_ptr<TestCase>>;63 TestSuite() = default;64 TestSuite(const std::string &TSName) : Name(TSName) {}65 TestSuite(const TestSuite &O) = delete;66 TestSuite(TestSuite &&O);67 void setup();68 void teardown();69 TestCaseVec::iterator begin();70 TestCaseVec::iterator end();71 std::string Name;72 TestCaseVec TestCases;73};74/// Static class used to register all test cases and provide them to the driver75class TestRegistrar {76public:77 static TestRegistrar &get();78 static std::vector<TestSuite> getTestSuites();79 static void addCaseToSuite(TestCase *TC, const std::string &TSName);80 81private:82 TestRegistrar() = default;83 TestRegistrar(const TestRegistrar &o) = delete;84 TestRegistrar operator=(const TestRegistrar &o) = delete;85 // Keep tests in order 'of appearance', i.e. top -> bottom.86 // This effectively mimicks the (observed) behavior of GoogleTest.87 // Avoid maps as they do not have corresponding order guarantees.88 static std::vector<std::pair<std::string, TestSuite>> Tests;89};90/// Hack to register test cases91struct Registerer {92 Registerer(TestCase *TC, const std::string SuiteName);93};94/// Eventually executes all test suites and cases, should contain logic to skip95/// stuff if needed96struct Runner {97 Runner() : TestSuites(TestRegistrar::get().getTestSuites()) {}98 int run();99 void reportError(const Error &Err);100 void abortOrKeepGoing();101 // Print an execution summary of all testsuites and their corresponding102 // testcases.103 void printSummary();104 std::vector<TestSuite> TestSuites;105};106 107/// MACROS TO DEFINE A TESTSUITE + TESTCASE (like GoogleTest does)108#define XQUOTE(str) QUOTE(str)109#define QUOTE(str) #str110 111#define TEST_TEMPLATE(SuiteName, CaseName, ExpectedState) \112 struct SuiteName##_##CaseName : public TestCase { \113 SuiteName##_##CaseName() \114 : TestCase(XQUOTE(CaseName), omptest::AssertState::ExpectedState) {} \115 virtual void execImpl() override; \116 }; \117 static Registerer R_##SuiteName##CaseName(new SuiteName##_##CaseName(), \118 #SuiteName); \119 void SuiteName##_##CaseName::execImpl()120 121#define TEST(SuiteName, CaseName) \122 TEST_TEMPLATE(SuiteName, CaseName, /*ExpectedState=*/Pass)123#define TEST_XFAIL(SuiteName, CaseName) \124 TEST_TEMPLATE(SuiteName, CaseName, /*ExpectedState=*/Fail)125 126#endif127