15#include "Teuchos_Assert.hpp"
16#include "Teuchos_VerboseObject.hpp"
18#include "Teuchos_Assert.hpp"
20#include "Teuchos_StandardCatchMacros.hpp"
29 std::string groupName;
35 const std::string groupName_in,
36 const std::string testName_in
38 : unitTest(unitTest_in), groupName(groupName_in), testName(testName_in),
39 insertionIndex(insersionIndexCounter_++)
48 static int insersionIndexCounter_;
52int UnitTestData::insersionIndexCounter_ = 0;
55bool operator<(
const UnitTestData &a,
const UnitTestData &b)
57 if (a.groupName < b.groupName) {
60 else if (a.groupName > b.groupName) {
63 return a.insertionIndex < b.insertionIndex;
68std::string getUnitTestName(
const std::string groupName,
69 const std::string testName)
71 std::ostringstream oss;
72 oss << groupName<<
"_"<<testName<<
"_UnitTest";
77enum EShowTestDetails {
78 SHOW_TEST_DETAILS_ALL,
79 SHOW_TEST_DETAILS_TEST_NAMES,
80 SHOW_TEST_DETAILS_FINAL_RESULTS
84bool strMatch(
const std::string &fullMatchStr,
const std::string &str )
87 const std::string::size_type npos = std::string::npos;
89 const size_t strLen = str.length();
90 const size_t fullMatchStrLen = fullMatchStr.length();
92 if (fullMatchStrLen == 0) {
96 const bool beginGlob = fullMatchStr[0] ==
'*';
97 const bool endGlob = fullMatchStr[fullMatchStrLen-1] ==
'*';
99 const size_t matchStrLen =
100 fullMatchStrLen + (beginGlob ? -1 : 0) + (endGlob ? -1 : 0);
102 if (matchStrLen == 0) {
106 if (matchStrLen > strLen) {
110 if (beginGlob && endGlob) {
111 return str.find(fullMatchStr.substr(1, matchStrLen)) != npos;
115 return fullMatchStr.substr(0, matchStrLen) == str.substr(0, matchStrLen);
119 return fullMatchStr.substr(1, matchStrLen) ==
120 str.substr(strLen-matchStrLen, matchStrLen);
123 return fullMatchStr == str;
139class UnitTestRepository::InstanceData {
144 unitTests_t unitTests;
145 CommandLineProcessor clp;
146 EShowTestDetails showTestDetails;
147 bool globallyReduceUnitTestResult;
148 bool showSrcLocation;
149 bool showFailSrcLocation;
151 std::string groupName;
152 std::string testName;
153 std::string notUnitTestName;
158 showTestDetails(SHOW_TEST_DETAILS_TEST_NAMES),
159#if defined(HAVE_TEUCHOS_GLOBALLY_REDUCE_UNITTEST_RESULTS)
160 globallyReduceUnitTestResult(true),
162 globallyReduceUnitTestResult(false),
164 showSrcLocation(false),
165 showFailSrcLocation(true),
178 return getData().clp;
183 const bool globallyReduceUnitTestResult)
185 getData().globallyReduceUnitTestResult = globallyReduceUnitTestResult;
191 return getData().globallyReduceUnitTestResult;
200 using std::setprecision;
207 out <<
"\n***\n*** Unit test suite ...\n***\n\n";
209 InstanceData &data = getData();
211 const bool showAll = data.showTestDetails == SHOW_TEST_DETAILS_ALL;
225 out <<
"\nSorting tests by group name then by the order they were added ...";
227 std::sort( data.unitTests.begin(), data.unitTests.end() );
231 out <<
"\nRunning unit tests ...\n\n";
232 unitTests_t::iterator
iter = data.unitTests.begin();
233 for ( ;
iter != data.unitTests.end(); ++
iter, ++testCounter ) {
235 const UnitTestData &
utd = (*iter);
241 strMatch(data.groupName,
utd.groupName)
243 strMatch(data.testName,
utd.testName)
247 data.notUnitTestName.length() == 0
275 oss =
rcp(
new std::ostringstream);
303 <<
"Location: "<<
utd.unitTest->unitTestFile()<<
":"
304 <<
utd.unitTest->unitTestFileLineNumber()<<
"\n";
320 if (
showAll && data.showSrcLocation)
322 <<
"Location: "<<
utd.unitTest->unitTestFile()<<
":"
323 <<
utd.unitTest->unitTestFileLineNumber()<<
"\n";
331 out <<
"[Not Run]\n";
347 out <<
"\nThe following tests FAILED:\n";
357 <<
"\nSummary: total = " << testCounter
368 <<
", failed = ???\n";
382 setUpCLP(outArg(clp));
386 *out <<
"\nEnd Result: TEST FAILED" << std::endl;
393 *out <<
"\nEnd Result: TEST PASSED" << std::endl;
395 *out <<
"\nEnd Result: TEST FAILED" << std::endl;
405 const std::string groupName,
const std::string
testName_in )
407 InstanceData &data = getData();
409 data.unitTests.push_back(UnitTestData(unitTest, groupName, testName));
415 return (getData().showTestDetails == SHOW_TEST_DETAILS_ALL);
422UnitTestRepository::UnitTestRepository()
426void UnitTestRepository::setUpCLP(
const Ptr<CommandLineProcessor>& clp)
429 clp->addOutputSetupOptions(
true);
431 const int numShowTestDetails = 3;
432 const EShowTestDetails showTestDetailsValues[numShowTestDetails] =
433 { SHOW_TEST_DETAILS_ALL,
434 SHOW_TEST_DETAILS_TEST_NAMES,
435 SHOW_TEST_DETAILS_FINAL_RESULTS
437 const char* showTestDetailsNames[numShowTestDetails] =
443 "show-test-details", &getData().showTestDetails,
444 numShowTestDetails, showTestDetailsValues, showTestDetailsNames,
445 "Level of detail to show in the tests"
448 "details", &getData().showTestDetails,
449 numShowTestDetails, showTestDetailsValues, showTestDetailsNames,
450 "Short for --show-test-details"
454 "show-src-location",
"no-show-src-location", &getData().showSrcLocation,
455 "If true, then the location of the unit test source code is shown."
456 " Only meaningful if --show-test-details=ALL."
460 "show-fail-src-location",
"no-show-fail-src-location", &getData().showFailSrcLocation,
461 "If true, then the location of every failed unit test check is printed."
465 "globally-reduce-test-result",
"no-globally-reduce-test-result",
466 &getData().globallyReduceUnitTestResult,
467 "If true, individual unit test pass/fail is globally reduced across MPI processes."
471 "group-name", &getData().groupName,
472 "If specified, selects only tests that match the group name glob." );
474 "group", &getData().groupName,
475 "Short for --group-name." );
478 "test-name", &getData().testName,
479 "If specified, selects only tests that match the test name glob." );
481 "test", &getData().testName,
482 "Short for --test-name." );
485 "not-unit-test", &getData().notUnitTestName,
486 "If specified, full unit tests with glob matches will *not* be run." );
489 "no-op",
"do-op", &getData().noOp,
490 "If --no-op, then only the names of the tests that would be run are run."
496UnitTestRepository::InstanceData& UnitTestRepository::getData()
498 static UnitTestRepository::InstanceData data;
503bool UnitTestRepository::runUnitTestImpl(
const UnitTestBase &unitTest,
506 const bool result = unitTest.runUnitTest(out);
507 if (getData().globallyReduceUnitTestResult) {
509 if (globalSum == 0) {
518 out <<
"NOTE: Global reduction shows failures on other processes!\n"
519 <<
"(rerun with --output-to-root-rank-only=-1 to see output\n"
520 <<
"from other processes to see what process failed!)\n";
527 Array<int> passFailFlags(numProcs);
529 Array<int> procsThatFailed;
530 for (
int proc_k = 0; proc_k < numProcs; ++proc_k ) {
531 if (passFailFlags[proc_k] != 0) {
532 procsThatFailed.push_back(proc_k);
538 if (procsThatFailed.size() == numProcs) {
539 out <<
"NOTE: Unit test failed on all processes!\n";
544 out <<
"NOTE: Unit test failed on processes = " << procsThatFailed <<
"\n"
545 <<
"(rerun with --output-to-root-rank-only=<procID> to see output\n"
546 <<
"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.
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.
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.