Group::TestResult Group::RunTest(TestRef &tr, vector<TestRef> &skipTest) { string work; if (TestExists(tr) == false) return TR_NOTFOUND; // Take out a valid deque<>::iterator to the test under execution deque<Test *>::iterator myTest = mTests[tr.xLev][tr.yLev].begin(); advance(myTest, tr.zLev); LOG_NRM("-----------------START TEST-----------------"); FORMAT_GROUP_DESCRIPTION(work, this) LOG_NRM("%s", work.c_str()); FORMAT_TEST_NUM(work, "", tr.xLev, tr.yLev, tr.zLev) work += (*myTest)->GetClassName(); work += ": "; work += (*myTest)->GetShortDescription(); LOG_NRM("%s", work.c_str()); LOG_NRM("Compliance: %s", (*myTest)->GetComplianceDescription().c_str()); LOG_NRM("%s", (*myTest)->GetLongDescription(false, 0).c_str()); TestResult result; if (SkippingTest(tr, skipTest)) { result = TR_SKIPPING; } else { result = (*myTest)->Run() ? TR_SUCCESS: TR_FAIL; if (result == TR_FAIL) { FORMAT_GROUP_DESCRIPTION(work, this) LOG_NRM(" %s", work.c_str()); FORMAT_TEST_NUM(work, "", tr.xLev, tr.yLev, tr.zLev) work += (*myTest)->GetClassName(); work += ": "; work += (*myTest)->GetShortDescription(); LOG_NRM(" %s", work.c_str()); } else { LOG_NRM("SUCCESSFUL test case run"); } } LOG_NRM("------------------END TEST------------------"); // Guarantee nothing residual or unintended is left around. Enforce this // by destroying the existing test obj and replace it with a clone of // itself so looping tests over can still be supported. LOG_DBG("Enforcing test obj cleanup, cloning & destroying"); Test *cleanMeUp = (*myTest); // Refer to test obj deque<Test *>::iterator insertPos = mTests[tr.xLev][tr.yLev].erase(myTest); mTests[tr.xLev][tr.yLev].insert(insertPos, cleanMeUp->Clone()); delete cleanMeUp; return result; }
TestResult Group::RunTest(TestSetType &dependencies, int64_t &tstIdx, vector<TestRef> &skipTest, int64_t &numSkipped, bool preserve, vector<TestRef> &failedTests, vector<TestRef> &skippedTests) { string work; numSkipped = 0; TestResult result = TR_FAIL; // Preliminary error checking if ((tstIdx >= (int64_t)dependencies.size()) || (tstIdx == -1)) { tstIdx = -1; return TR_NOTFOUND; } // Get a pointer to the test to execute TestRef tr = dependencies[tstIdx]; if (TestExists(tr) == false) { tstIdx = -1; return TR_NOTFOUND; } deque<Test *>::iterator myTest = mTests[tr.xLev][tr.yLev].begin(); advance(myTest, tr.zLev); // The first test within every group must be proceeded with a chance to // save the state of the DUT, if and only if the feature is enabled. if (gCmdLine.restore && (tstIdx == 0)) { LOG_NRM("Saving the state of the DUT"); if (SaveState() == false) { LOG_ERR("Unable to save the state of the DUT"); tstIdx = -1; return TR_FAIL; } } LOG_NRM("-----------------START TEST-----------------"); FORMAT_GROUP_DESCRIPTION(work, this) LOG_NRM("%s", work.c_str()); FORMAT_TEST_NUM(work, "", tr.xLev, tr.yLev, tr.zLev) work += (*myTest)->GetClassName(); work += ": "; work += (*myTest)->GetShortDescription(); LOG_NRM("%s", work.c_str()); LOG_NRM("Compliance: %s", (*myTest)->GetComplianceDescription().c_str()); LOG_NRM("%s", (*myTest)->GetLongDescription(false, 0).c_str()); if (SkippingTest(tr, skipTest)) { result = TR_SKIPPING; skippedTests.push_back(tr); numSkipped = (AdvanceDependencies(dependencies, tstIdx, false, skippedTests) + 1); } else { switch ((*myTest)->Runnable(preserve)) { case Test::RUN_TRUE: result = (*myTest)->Run(); if (result == TR_FAIL) { failedTests.push_back(tr); numSkipped = AdvanceDependencies(dependencies, tstIdx, true, skippedTests); } else { if (++tstIdx >= (int64_t)dependencies.size()) tstIdx = -1; LOG_NRM("SUCCESSFUL test case run"); } break; case Test::RUN_FALSE: result = TR_SKIPPING; skippedTests.push_back(tr); numSkipped = (AdvanceDependencies(dependencies, tstIdx, false, skippedTests) + 1); LOG_WARN("Reporting not runnable, skipping test: %ld:%ld.%ld.%ld", tr.group, tr.xLev, tr.yLev, tr.zLev); break; default: case Test::RUN_FAIL: failedTests.push_back(tr); numSkipped = AdvanceDependencies(dependencies, tstIdx, true, skippedTests); break; } } FORMAT_GROUP_DESCRIPTION(work, this) LOG_NRM("%s", work.c_str()); FORMAT_TEST_NUM(work, "", tr.xLev, tr.yLev, tr.zLev) work += (*myTest)->GetClassName(); work += ": "; work += (*myTest)->GetShortDescription(); LOG_NRM("%s", work.c_str()); LOG_NRM("------------------END TEST------------------"); // The last test within every group or a test failure must be following // with a chance to restore the state of the DUT, if and only if the // feature is enabled. if (gCmdLine.restore && ((tstIdx == -1) || (result == TR_FAIL))) { LOG_NRM("Restoring the state of the DUT"); if (RestoreState() == false) { LOG_ERR("Unable to restore the state of the DUT"); tstIdx = -1; return TR_FAIL; } } // Guarantee nothing residing or unintended is left around. Enforce this // by destroying the existing test obj and replace it with a clone of // itself so looping tests over can still be supported. LOG_DBG("Enforcing test obj cleanup, cloning & destroying"); Test *cleanMeUp = (*myTest); // Refer to test obj deque<Test *>::iterator insertPos = mTests[tr.xLev][tr.yLev].erase(myTest); mTests[tr.xLev][tr.yLev].insert(insertPos, cleanMeUp->Clone()); delete cleanMeUp; return result; }