48#include "Teuchos_Assert.hpp"
49#include "Teuchos_VerboseObject.hpp"
51#include "Teuchos_Assert.hpp"
53#include "Teuchos_StandardCatchMacros.hpp"
62 std::string groupName;
68 const std::string groupName_in,
69 const std::string testName_in
71 : unitTest(unitTest_in), groupName(groupName_in), testName(testName_in),
72 insertionIndex(insersionIndexCounter_++)
81 static int insersionIndexCounter_;
85int UnitTestData::insersionIndexCounter_ = 0;
88bool operator<(
const UnitTestData &a,
const UnitTestData &b)
90 if (a.groupName < b.groupName) {
93 else if (a.groupName > b.groupName) {
96 return a.insertionIndex < b.insertionIndex;
101std::string getUnitTestName(
const std::string groupName,
102 const std::string testName)
104 std::ostringstream oss;
105 oss << groupName<<
"_"<<testName<<
"_UnitTest";
110enum EShowTestDetails {
111 SHOW_TEST_DETAILS_ALL,
112 SHOW_TEST_DETAILS_TEST_NAMES,
113 SHOW_TEST_DETAILS_FINAL_RESULTS
117bool strMatch(
const std::string &fullMatchStr,
const std::string &str )
120 const std::string::size_type npos = std::string::npos;
122 const size_t strLen = str.length();
123 const size_t fullMatchStrLen = fullMatchStr.length();
125 if (fullMatchStrLen == 0) {
129 const bool beginGlob = fullMatchStr[0] ==
'*';
130 const bool endGlob = fullMatchStr[fullMatchStrLen-1] ==
'*';
132 const size_t matchStrLen =
133 fullMatchStrLen + (beginGlob ? -1 : 0) + (endGlob ? -1 : 0);
135 if (matchStrLen == 0) {
139 if (matchStrLen > strLen) {
143 if (beginGlob && endGlob) {
144 return str.find(fullMatchStr.substr(1, matchStrLen)) != npos;
148 return fullMatchStr.substr(0, matchStrLen) == str.substr(0, matchStrLen);
152 return fullMatchStr.substr(1, matchStrLen) ==
153 str.substr(strLen-matchStrLen, matchStrLen);
156 return fullMatchStr == str;
172class UnitTestRepository::InstanceData {
177 unitTests_t unitTests;
178 CommandLineProcessor clp;
179 EShowTestDetails showTestDetails;
180 bool globallyReduceUnitTestResult;
181 bool showSrcLocation;
182 bool showFailSrcLocation;
184 std::string groupName;
185 std::string testName;
186 std::string notUnitTestName;
191 showTestDetails(SHOW_TEST_DETAILS_TEST_NAMES),
192#if defined(HAVE_TEUCHOS_GLOBALLY_REDUCE_UNITTEST_RESULTS)
193 globallyReduceUnitTestResult(true),
195 globallyReduceUnitTestResult(false),
197 showSrcLocation(false),
198 showFailSrcLocation(true),
211 return getData().clp;
216 const bool globallyReduceUnitTestResult)
218 getData().globallyReduceUnitTestResult = globallyReduceUnitTestResult;
224 return getData().globallyReduceUnitTestResult;
233 using std::setprecision;
235 Time overallTimer(
"overallTimer",
true);
238 const int timerPrec = 3;
240 out <<
"\n***\n*** Unit test suite ...\n***\n\n";
242 InstanceData &data = getData();
244 const bool showAll = data.showTestDetails == SHOW_TEST_DETAILS_ALL;
245 const bool showTestNames = data.showTestDetails == SHOW_TEST_DETAILS_TEST_NAMES || showAll;
252 int numTestsFailed = 0;
258 out <<
"\nSorting tests by group name then by the order they were added ...";
260 std::sort( data.unitTests.begin(), data.unitTests.end() );
262 out <<
" (time = "<<setprecision(timerPrec)<<timer.
totalElapsedTime()<<
")\n";
264 out <<
"\nRunning unit tests ...\n\n";
265 unitTests_t::iterator iter = data.unitTests.begin();
266 for ( ; iter != data.unitTests.end(); ++iter, ++testCounter ) {
268 const UnitTestData &utd = (*iter);
270 const std::string unitTestName = getUnitTestName(utd.groupName, utd.testName);
274 strMatch(data.groupName, utd.groupName)
276 strMatch(data.testName, utd.testName)
280 data.notUnitTestName.length() == 0
282 !strMatch(data.notUnitTestName, unitTestName)
289 std::ostringstream testHeaderOSS;
290 testHeaderOSS <<testCounter<<
". "<<unitTestName<<
" ... ";
291 const std::string testHeader = testHeaderOSS.str();
297 out <<testHeader<<std::flush;
305 localOut = rcpFromRef(out);
308 oss =
rcp(
new std::ostringstream);
309 localOut = fancyOStream(rcp_implicit_cast<std::ostream>(oss));
317 const bool result = runUnitTestImpl(*utd.unitTest, *localOut);
325 out <<testHeader<<
"\n"<<std::flush;
335 <<
" "<<unitTestName<<
"\n"
336 <<
"Location: "<<utd.unitTest->unitTestFile()<<
":"
337 <<utd.unitTest->unitTestFileLineNumber()<<
"\n";
353 if (showAll && data.showSrcLocation)
355 <<
"Location: "<<utd.unitTest->unitTestFile()<<
":"
356 <<utd.unitTest->unitTestFileLineNumber()<<
"\n";
364 out <<
"[Not Run]\n";
379 if (failedTests.
size()) {
380 out <<
"\nThe following tests FAILED:\n";
381 for (Teuchos_Ordinal i = 0; i < failedTests.
size(); ++i)
382 out <<
" " << failedTests[i] <<
"\n";
386 out <<
"\nTotal Time: " << setprecision(timerPrec)
390 <<
"\nSummary: total = " << testCounter
391 <<
", run = " << numTestsRun;
395 <<
", passed = " << (numTestsRun-numTestsFailed)
396 <<
", failed = " << numTestsFailed <<
"\n";
401 <<
", failed = ???\n";
415 setUpCLP(outArg(clp));
417 clp.
parse(argc,argv);
419 *out <<
"\nEnd Result: TEST FAILED" << std::endl;
426 *out <<
"\nEnd Result: TEST PASSED" << std::endl;
428 *out <<
"\nEnd Result: TEST FAILED" << std::endl;
432 return (success ? 0 : 1);
438 const std::string groupName,
const std::string testName_in )
440 InstanceData &data = getData();
441 std::string testName = testName_in;
442 data.unitTests.push_back(UnitTestData(unitTest, groupName, testName));
448 return (getData().showTestDetails == SHOW_TEST_DETAILS_ALL);
455UnitTestRepository::UnitTestRepository()
459void UnitTestRepository::setUpCLP(
const Ptr<CommandLineProcessor>& clp)
462 clp->addOutputSetupOptions(
true);
464 const int numShowTestDetails = 3;
465 const EShowTestDetails showTestDetailsValues[numShowTestDetails] =
466 { SHOW_TEST_DETAILS_ALL,
467 SHOW_TEST_DETAILS_TEST_NAMES,
468 SHOW_TEST_DETAILS_FINAL_RESULTS
470 const char* showTestDetailsNames[numShowTestDetails] =
476 "show-test-details", &getData().showTestDetails,
477 numShowTestDetails, showTestDetailsValues, showTestDetailsNames,
478 "Level of detail to show in the tests"
481 "details", &getData().showTestDetails,
482 numShowTestDetails, showTestDetailsValues, showTestDetailsNames,
483 "Short for --show-test-details"
487 "show-src-location",
"no-show-src-location", &getData().showSrcLocation,
488 "If true, then the location of the unit test source code is shown."
489 " Only meaningful if --show-test-details=ALL."
493 "show-fail-src-location",
"no-show-fail-src-location", &getData().showFailSrcLocation,
494 "If true, then the location of every failed unit test check is printed."
498 "globally-reduce-test-result",
"no-globally-reduce-test-result",
499 &getData().globallyReduceUnitTestResult,
500 "If true, individual unit test pass/fail is globally reduced across MPI processes."
504 "group-name", &getData().groupName,
505 "If specified, selects only tests that match the group name glob." );
507 "group", &getData().groupName,
508 "Short for --group-name." );
511 "test-name", &getData().testName,
512 "If specified, selects only tests that match the test name glob." );
514 "test", &getData().testName,
515 "Short for --test-name." );
518 "not-unit-test", &getData().notUnitTestName,
519 "If specified, full unit tests with glob matches will *not* be run." );
522 "no-op",
"do-op", &getData().noOp,
523 "If --no-op, then only the names of the tests that would be run are run."
529UnitTestRepository::InstanceData& UnitTestRepository::getData()
531 static UnitTestRepository::InstanceData data;
536bool UnitTestRepository::runUnitTestImpl(
const UnitTestBase &unitTest,
539 const bool result = unitTest.runUnitTest(out);
540 if (getData().globallyReduceUnitTestResult) {
542 if (globalSum == 0) {
551 out <<
"NOTE: Global reduction shows failures on other processes!\n"
552 <<
"(rerun with --output-to-root-rank-only=-1 to see output\n"
553 <<
"from other processes to see what process failed!)\n";
560 Array<int> passFailFlags(numProcs);
562 Array<int> procsThatFailed;
563 for (
int proc_k = 0; proc_k < numProcs; ++proc_k ) {
564 if (passFailFlags[proc_k] != 0) {
565 procsThatFailed.push_back(proc_k);
571 if (procsThatFailed.size() == numProcs) {
572 out <<
"NOTE: Unit test failed on all processes!\n";
577 out <<
"NOTE: Unit test failed on processes = " << procsThatFailed <<
"\n"
578 <<
"(rerun with --output-to-root-rank-only=<procID> to see output\n"
579 <<
"from individual processes where the unit test is failing!)\n";
Templated array class derived from the STL std::vector.
Basic command line parser for input from (argc,argv[])
Teuchos header file which uses auto-configuration information to include necessary C++ headers.
Utilities to make writing tests easier.
Basic wall-clock timer class.
Replacement for std::vector that is compatible with the Teuchos Memory Management classes.
void push_back(const value_type &x)
Class that helps parse command line input arguments from (argc,argv[]) and set options.
EParseCommandLineReturn
Return value for CommandLineProcessor::parse(). Note: These enums are all given non-negative values s...
EParseCommandLineReturn parse(int argc, char *argv[], std::ostream *errout=&std::cerr) const
Parse a command line.
void printFinalTimerSummary(const Ptr< std::ostream > &out=null)
Call to print timers so that they don't get printed in the destructor.
static int sum(int localVal)
Sum a set of integers across processes.
static int getNProc()
The number of processes in MPI_COMM_WORLD.
static void allGather(int localVal, const ArrayView< int > &allVals)
Global all-to-all of a set of integers across processes.
Smart reference counting pointer class for automatic garbage collection.
Ptr< T > ptr() const
Get a safer wrapper raw C++ pointer to the underlying object.
double totalElapsedTime(bool readCurrentTime=false) const
The total time in seconds accumulated by this timer.
void start(bool reset=false)
Start the timer, if the timer is enabled (see disable()).
double stop()
Stop the timer, if the timer is enabled (see disable()).
static bool verboseUnitTests()
Returns if unit tests are verbose or not.
static bool runUnitTests(FancyOStream &out)
Run the registered unit tests.
static bool getGloballyReduceTestResult()
Get if the unit tests should reduce across processes or not.
static CommandLineProcessor & getCLP()
Return the CLP to add options to.
static int runUnitTestsFromMain(int argc, char *argv[])
Run the unit tests from main() passing in (argc, argv).
static void addUnitTest(UnitTestBase *unitTest, const std::string groupName, const std::string testName)
Add an unit test (called indirectly through macros.
static void setGloballyReduceTestResult(const bool globallyReduceUnitTestResult)
Set if the unit tests should reduce pass/fail across processes.
static RCP< FancyOStream > getDefaultOStream()
Get the default output stream object.
std::ostream subclass that performs the magic of indenting data sent to an std::ostream object among ...
Tabbing class for helping to create formated, indented output for a basic_FancyOStream object.
#define TEUCHOS_ASSERT(assertion_test)
This macro is throws when an assert fails.
#define TEUCHOS_ASSERT_EQUALITY(val1, val2)
This macro is checks that to numbers are equal and if not then throws an exception with a good error ...
bool is_null(const std::shared_ptr< T > &p)
Returns true if p.get()==NULL.
#define TEUCHOS_STANDARD_CATCH_STATEMENTS(VERBOSE, ERR_STREAM, SUCCESS_FLAG)
Simple macro that catches and reports standard exceptions and other exceptions.
basic_FancyOStream< char > FancyOStream
bool showTestFailureLocation()
Return if TEUCHOS_PASS_FAIL(...) should print test failure location.
The Teuchos namespace contains all of the classes, structs and enums used by Teuchos,...
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
Deprecated.