#include <pcrecpp.h>
#include <algorithm>
#include <cstdio>
-#include <memory.h>
+#include <exception>
+#include <functional>
+#include <memory>
+#include <string>
#include <libxml/xpath.h>
#include <libxml/xpathInternals.h>
}
-
namespace DPL {
namespace Test {
-void TestRunner::RegisterTest(const char *testName, TestCase proc)
+TestResult::FailStatus TryCatch(const std::function<void(void)> &func, std::string &reason) {
+ try {
+ func();
+ } catch (const DPL::Test::TestFailed &e) {
+ reason = e.GetMessage();
+ return TestResult::FailStatus::FAILED;
+ } catch (const DPL::Test::TestIgnored &e) {
+ reason = e.GetMessage();
+ return TestResult::FailStatus::IGNORED;
+ } catch (const std::exception &e) {
+ reason = e.what();
+ return TestResult::FailStatus::FAILED;
+ } catch (...) {
+ reason = "Unknown exception";
+ return TestResult::FailStatus::FAILED;
+ }
+ reason = std::string();
+ return TestResult::FailStatus::NONE;
+}
+
+void TestRunner::RegisterTest(TestCasePtr testCase)
{
- m_testGroups[m_currentGroup].push_back(TestCaseStruct(testName, proc));
+ m_testGroups[m_currentGroup].push_back(testCase);
+ m_testCaseSet.insert(testCase);
}
void TestRunner::InitGroup(const char* name)
{
if(!cit->second.empty())
{
- for(TestCaseStructList::const_iterator cj = cit->second.begin(); cj != cit->second.end(); ++cj)
+ for(TestCaseList::const_iterator cj = cit->second.begin(); cj != cit->second.end(); ++cj)
{
- std::string name = cj->name;
+ std::string name = (*cj)->GetName();
std::string::size_type st = name.find('_');
if(st != std::string::npos)
{
bool TestRunner::filterByXML(std::map<std::string, bool> & casesMap)
{
for (auto &group : m_testGroups) {
- TestCaseStructList newList;
+ TestCaseList newList;
for (auto &tc : group.second)
{
- if (casesMap.find(tc.name) != casesMap.end()) {
- casesMap[tc.name] = true;
+ if (casesMap.find(tc->GetName()) != casesMap.end()) {
+ casesMap[tc->GetName()] = true;
newList.push_back(tc);
}
}
return true;
}
-void TestRunner::RunTestCase(const TestCaseStruct& testCase)
+void TestRunner::RunTestCase(TestCasePtr testCase)
{
- setCurrentTestCase(&(const_cast<TestCaseStruct &>(testCase)));
- m_deferDeepness = 0U;
- try {
- testCase.proc();
- } catch (const TestFailed &e) {
- // Simple test failure
- CollectResult(testCase.name,
- TestResult(TestResult::FailStatus::FAILED,
- getConcatedFailReason(e.GetMessage())));
-
- setCurrentTestCase(nullptr);
- return;
- } catch (const TestIgnored &e) {
- if (m_runIgnored) {
- // Simple test have to be implemented
- CollectResult(testCase.name,
- TestResult(TestResult::FailStatus::IGNORED, e.GetMessage()));
- }
-
+ setCurrentTestCase(testCase);
+
+ std::string initReason;
+ TestResult::FailStatus initStatus = TryCatch(std::bind(&TestCase::Init, testCase),
+ initReason);
+ if (initStatus != TestResult::FailStatus::NONE) {
+ CollectResult(testCase->GetName(),
+ TestResult(initStatus, getConcatedFailReason(initReason), testCase->GetPerformance()));
setCurrentTestCase(nullptr);
return;
- } catch (const std::exception &) {
- // std exception failure
- CollectResult(testCase.name,
- TestResult(TestResult::FailStatus::FAILED, "std exception"));
+ }
- setCurrentTestCase(nullptr);
- return;
- } catch (...) {
- // Unknown exception failure
- CollectResult(testCase.name,
- TestResult(TestResult::FailStatus::FAILED, "unknown exception"));
- setCurrentTestCase(nullptr);
- return;
+ std::string testReason;
+ TestResult::FailStatus testStatus = TryCatch(std::bind(&TestCase::Test, testCase),
+ testReason);
+ testReason = getConcatedFailReason(testReason);
+ std::string finishReason;
+ TestResult::FailStatus finishStatus = TryCatch(std::bind(&TestCase::Finish, testCase),
+ finishReason);
+ finishReason = getConcatedFailReason(finishReason);
+
+ switch (finishStatus) {
+ case TestResult::FailStatus::FAILED:
+ testStatus = TestResult::FailStatus::FAILED;
+ if (!testReason.empty())
+ testReason += "\n";
+ testReason += finishReason;
+ break;
+ case TestResult::FailStatus::IGNORED:
+ if (testStatus == TestResult::FailStatus::NONE)
+ testStatus = TestResult::FailStatus::IGNORED;
+ if (!testReason.empty())
+ testReason += "\n";
+ testReason += finishReason;
+ case TestResult::FailStatus::NONE:
+ break;
+ default:
+ Assert(false && "Unhandled fail status");
}
- // Everything OK
- CollectResult(testCase.name,
- TestResult(TestResult::FailStatus::NONE,
- std::string(),
- testCase.performance));
+ CollectResult(testCase->GetName(),
+ TestResult(testStatus, testReason, testCase->GetPerformance()));
setCurrentTestCase(nullptr);
}
fprintf(stderr, "%sFound %d testcases...%s\n", GREEN_BEGIN, count, GREEN_END);
fprintf(stderr, "%s%s%s\n", GREEN_BEGIN, "Running tests...", GREEN_END);
for (auto &group : m_testGroups) {
- TestCaseStructList list = group.second;
+ TestCaseList list = group.second;
if (!list.empty()) {
for (auto &collector : m_collectors) {
collector.second->CollectCurrentTestGroupName(group.first);
}
list.sort();
- for (TestCaseStructList::const_iterator iterator = list.begin();
+ for (TestCaseList::const_iterator iterator = list.begin();
iterator != list.end();
++iterator)
{
- TestCaseStruct test = *iterator;
- if (m_startTestId == test.name) {
+ TestCasePtr test = *iterator;
+ if (m_startTestId == test->GetName()) {
m_startTestId = "";
}
fprintf(stderr, "%s%s%s\n\n", GREEN_BEGIN, "Finished", GREEN_END);
}
-TestRunner::TestCaseStruct *TestRunner::getCurrentTestCase()
+TestCasePtr TestRunner::getCurrentTestCase()
{
return m_currentTestCase;
}
-void TestRunner::setCurrentTestCase(TestCaseStruct* testCase)
+void TestRunner::setCurrentTestCase(TestCasePtr testCase)
{
m_currentTestCase = testCase;
}
void TestRunner::beginPerformance(std::chrono::system_clock::duration maxDurationInMicroseconds)
{
- TestCaseStruct* testCase = getCurrentTestCase();
+ TestCasePtr testCase = getCurrentTestCase();
if (!testCase)
return;
- if (!testCase->performance)
- testCase->performance.reset(new PerformanceResult(maxDurationInMicroseconds));
+ if (!testCase->GetPerformance())
+ testCase->SetPerformance(
+ std::unique_ptr<PerformanceResult> \
+ (new PerformanceResult(maxDurationInMicroseconds)));
}
void TestRunner::endPerformance()
{
- TestCaseStruct* testCase = getCurrentTestCase();
+ TestCasePtr testCase = getCurrentTestCase();
if (!testCase)
return;
- testCase->performance->Finish();
+ testCase->GetPerformance()->Finish();
}
ConstPerformanceResultPtr TestRunner::getCurrentTestCasePerformanceResult()
{
- TestCaseStruct* testCase = getCurrentTestCase();
+ TestCasePtr testCase = getCurrentTestCase();
if (!testCase)
return nullptr;
- return testCase->performance;
+ return testCase->GetPerformance();
}
void TestRunner::setCurrentTestCasePerformanceResult(const PerformanceResultPtr &performance)
{
- TestCaseStruct* testCase = getCurrentTestCase();
+ TestCasePtr testCase = getCurrentTestCase();
if (!testCase)
return;
- testCase->performance = performance;
+ testCase->SetPerformance(performance);
}
void TestRunner::addFailReason(const std::string &reason)
return reason + ret;
}
+TestRunner::~TestRunner()
+{
+ for(auto &t : m_testCaseSet)
+ delete t;
+}
+
void TestRunner::CollectResult(const std::string& id, const TestResult& result)
{
+ if (result.GetFailStatus() == TestResult::FailStatus::IGNORED && m_runIgnored)
+ return;
+
std::for_each(m_collectors.begin(),
m_collectors.end(),
[&](const TestResultsCollectors::value_type & collector)
arg.erase(0, startCmd.length());
for (auto &group : m_testGroups) {
for (auto &tc : group.second) {
- if (tc.name == arg) {
+ if (tc->GetName() == arg) {
m_startTestId = arg;
break;
}
TestCaseGroupMap::iterator found = m_testGroups.find(arg);
if (found != m_testGroups.end()) {
std::string name = found->first;
- TestCaseStructList newList = found->second;
+ TestCaseList newList = found->second;
m_testGroups.clear();
m_testGroups[name] = newList;
} else {
} else if (arg.find(listInGroup) == 0) {
arg.erase(0, listInGroup.length());
for (auto &test : m_testGroups[arg]) {
- printf("ID:%s\n", test.name.c_str());
+ printf("ID:%s\n", test->GetName().c_str());
}
return 0;
} else if (arg.find(allowChildLogs) == 0) {
pcrecpp::RE re(arg.c_str());
for (auto &group : m_testGroups) {
- TestCaseStructList newList;
+ TestCaseList newList;
for (auto &tc : group.second)
{
- if (re.PartialMatch(tc.name)) {
+ if (re.PartialMatch(tc->GetName())) {
newList.push_back(tc);
}
}
{
for (auto &group : m_testGroups) {
for (auto &tc : group.second) {
- printf("ID:%s:%s\n", group.first.c_str(), tc.name.c_str());
+ printf("ID:%s:%s\n", group.first.c_str(), tc->GetName().c_str());
}
}
return 0;