blob: 6f13939c929414a61b0c1664ac2760f56c622392 [file] [log] [blame] [edit]
//===- OmptTesterStandalone.cpp - Standalone unit testing impl. -*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
///
/// \file
/// This file represents the 'standalone' ompTest unit testing core
/// implementation, defining the general test suite and test case execution.
///
//===----------------------------------------------------------------------===//
#include "OmptTesterStandalone.h"
#include "OmptCallbackHandler.h"
#include <algorithm>
#include <cassert>
#include <iomanip>
#include <iostream>
#include <memory>
#include <string>
#include <utility>
#include <vector>
using namespace omptest;
Error TestCase::exec() {
Error E;
E.Fail = false;
if (IsDisabled)
return E;
OmptCallbackHandler::get().subscribe(SequenceAsserter.get());
OmptCallbackHandler::get().subscribe(SetAsserter.get());
OmptCallbackHandler::get().subscribe(EventReporter.get());
execImpl();
// Actively flush potential in-flight trace records
flush_traced_devices();
// We remove subscribers to not be notified of events after our test case
// finished.
OmptCallbackHandler::get().clearSubscribers();
omptest::AssertState SequenceResultState = SequenceAsserter->checkState();
omptest::AssertState SetResultState = SetAsserter->checkState();
bool AnyFail = SequenceResultState == omptest::AssertState::Fail ||
SetResultState == omptest::AssertState::Fail;
bool AllPass = SequenceResultState == omptest::AssertState::Pass &&
SetResultState == omptest::AssertState::Pass;
if (ExpectedState == omptest::AssertState::Pass && AnyFail)
E.Fail = true;
else if (ExpectedState == omptest::AssertState::Fail && AllPass)
E.Fail = true;
if (AnyFail)
ResultState = omptest::AssertState::Fail;
return E;
}
TestSuite::TestSuite(TestSuite &&O) {
Name = O.Name;
TestCases.swap(O.TestCases);
}
void TestSuite::setup() {}
void TestSuite::teardown() {}
TestSuite::TestCaseVec::iterator TestSuite::begin() {
return TestCases.begin();
}
TestSuite::TestCaseVec::iterator TestSuite::end() { return TestCases.end(); }
TestRegistrar &TestRegistrar::get() {
static TestRegistrar TR;
return TR;
}
std::vector<TestSuite> TestRegistrar::getTestSuites() {
std::vector<TestSuite> TSs;
for (auto &[k, v] : Tests)
TSs.emplace_back(std::move(v));
return TSs;
}
void TestRegistrar::addCaseToSuite(TestCase *TC, const std::string &TSName) {
// Search the test suites for a matching name
auto It = std::find_if(Tests.begin(), Tests.end(),
[&](const auto &P) { return P.first == TSName; });
if (It != Tests.end()) {
// Test suite exists: add the test case
It->second.TestCases.emplace_back(TC);
} else {
// Test suite does not exist: construct it and add the test case
TestSuite TS(TSName);
TS.TestCases.emplace_back(TC);
// Move and emplace the suite
Tests.emplace_back(TSName, std::move(TS));
}
}
Registerer::Registerer(TestCase *TC, const std::string SuiteName) {
std::cout << "Adding " << TC->Name << " to " << SuiteName << std::endl;
TestRegistrar::get().addCaseToSuite(TC, SuiteName);
}
int Runner::run() {
int ErrorCount = 0;
for (auto &TS : TestSuites) {
std::cout << "\n======\nExecuting for " << TS.Name << std::endl;
TS.setup();
for (auto &TC : TS) {
std::cout << "\nExecuting " << TC->Name << std::endl;
if (Error Err = TC->exec()) {
reportError(Err);
abortOrKeepGoing();
++ErrorCount;
}
}
TS.teardown();
}
printSummary();
return ErrorCount;
}
void Runner::reportError(const Error &Err) {}
void Runner::abortOrKeepGoing() {}
void Runner::printSummary() {
std::cout << "\n====== SUMMARY\n";
for (auto &TS : TestSuites) {
std::cout << " - " << TS.Name;
for (auto &TC : TS) {
std::string Result;
if (TC->IsDisabled) {
Result = "-#-#-";
} else if (TC->ResultState == TC->ExpectedState) {
if (TC->ResultState == omptest::AssertState::Pass)
Result = "PASS";
else if (TC->ResultState == omptest::AssertState::Fail)
Result = "XFAIL";
} else {
if (TC->ResultState == omptest::AssertState::Fail)
Result = "FAIL";
else if (TC->ResultState == omptest::AssertState::Pass)
Result = "UPASS";
}
std::cout << "\n " << std::setw(5) << Result << " : " << TC->Name;
}
std::cout << std::endl;
}
}