159 lines · cpp
1//===- OmptTesterStandalone.cpp - Standalone unit testing impl. -*- 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' ompTest unit testing core11/// implementation, defining the general test suite and test case execution.12///13//===----------------------------------------------------------------------===//14 15#include "OmptTesterStandalone.h"16#include "OmptCallbackHandler.h"17 18#include <algorithm>19#include <cassert>20#include <iomanip>21#include <iostream>22#include <memory>23#include <string>24#include <utility>25#include <vector>26 27using namespace omptest;28 29Error TestCase::exec() {30 Error E;31 E.Fail = false;32 33 if (IsDisabled)34 return E;35 36 OmptCallbackHandler::get().subscribe(SequenceAsserter.get());37 OmptCallbackHandler::get().subscribe(SetAsserter.get());38 OmptCallbackHandler::get().subscribe(EventReporter.get());39 40 execImpl();41 42 // Actively flush potential in-flight trace records43 flush_traced_devices();44 45 // We remove subscribers to not be notified of events after our test case46 // finished.47 OmptCallbackHandler::get().clearSubscribers();48 omptest::AssertState SequenceResultState = SequenceAsserter->checkState();49 omptest::AssertState SetResultState = SetAsserter->checkState();50 bool AnyFail = SequenceResultState == omptest::AssertState::Fail ||51 SetResultState == omptest::AssertState::Fail;52 bool AllPass = SequenceResultState == omptest::AssertState::Pass &&53 SetResultState == omptest::AssertState::Pass;54 if (ExpectedState == omptest::AssertState::Pass && AnyFail)55 E.Fail = true;56 else if (ExpectedState == omptest::AssertState::Fail && AllPass)57 E.Fail = true;58 if (AnyFail)59 ResultState = omptest::AssertState::Fail;60 return E;61}62 63TestSuite::TestSuite(TestSuite &&O) {64 Name = O.Name;65 TestCases.swap(O.TestCases);66}67 68void TestSuite::setup() {}69 70void TestSuite::teardown() {}71 72TestSuite::TestCaseVec::iterator TestSuite::begin() {73 return TestCases.begin();74}75 76TestSuite::TestCaseVec::iterator TestSuite::end() { return TestCases.end(); }77 78TestRegistrar &TestRegistrar::get() {79 static TestRegistrar TR;80 return TR;81}82 83std::vector<TestSuite> TestRegistrar::getTestSuites() {84 std::vector<TestSuite> TSs;85 for (auto &[k, v] : Tests)86 TSs.emplace_back(std::move(v));87 return TSs;88}89 90void TestRegistrar::addCaseToSuite(TestCase *TC, const std::string &TSName) {91 // Search the test suites for a matching name92 auto It = std::find_if(Tests.begin(), Tests.end(),93 [&](const auto &P) { return P.first == TSName; });94 95 if (It != Tests.end()) {96 // Test suite exists: add the test case97 It->second.TestCases.emplace_back(TC);98 } else {99 // Test suite does not exist: construct it and add the test case100 TestSuite TS(TSName);101 TS.TestCases.emplace_back(TC);102 // Move and emplace the suite103 Tests.emplace_back(TSName, std::move(TS));104 }105}106 107Registerer::Registerer(TestCase *TC, const std::string SuiteName) {108 std::cout << "Adding " << TC->Name << " to " << SuiteName << std::endl;109 TestRegistrar::get().addCaseToSuite(TC, SuiteName);110}111 112int Runner::run() {113 int ErrorCount = 0;114 for (auto &TS : TestSuites) {115 std::cout << "\n======\nExecuting for " << TS.Name << std::endl;116 TS.setup();117 for (auto &TC : TS) {118 std::cout << "\nExecuting " << TC->Name << std::endl;119 if (Error Err = TC->exec()) {120 reportError(Err);121 abortOrKeepGoing();122 ++ErrorCount;123 }124 }125 TS.teardown();126 }127 printSummary();128 return ErrorCount;129}130 131void Runner::reportError(const Error &Err) {}132 133void Runner::abortOrKeepGoing() {}134 135void Runner::printSummary() {136 std::cout << "\n====== SUMMARY\n";137 for (auto &TS : TestSuites) {138 std::cout << " - " << TS.Name;139 for (auto &TC : TS) {140 std::string Result;141 if (TC->IsDisabled) {142 Result = "-#-#-";143 } else if (TC->ResultState == TC->ExpectedState) {144 if (TC->ResultState == omptest::AssertState::Pass)145 Result = "PASS";146 else if (TC->ResultState == omptest::AssertState::Fail)147 Result = "XFAIL";148 } else {149 if (TC->ResultState == omptest::AssertState::Fail)150 Result = "FAIL";151 else if (TC->ResultState == omptest::AssertState::Pass)152 Result = "UPASS";153 }154 std::cout << "\n " << std::setw(5) << Result << " : " << TC->Name;155 }156 std::cout << std::endl;157 }158}159