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_;
 
   85 int UnitTestData::insersionIndexCounter_ = 0;
 
   88 bool 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;
 
  101 std::string getUnitTestName(
const std::string groupName,
 
  102   const std::string testName)
 
  104   std::ostringstream oss;
 
  105   oss << groupName<<
"_"<<testName<<
"_UnitTest";
 
  110 enum EShowTestDetails {
 
  111   SHOW_TEST_DETAILS_ALL,
 
  112   SHOW_TEST_DETAILS_TEST_NAMES,
 
  113   SHOW_TEST_DETAILS_FINAL_RESULTS
 
  117 bool 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;
 
  172 class 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);
 
  455 UnitTestRepository::UnitTestRepository()
 
  459 void 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." 
  529 UnitTestRepository::InstanceData& UnitTestRepository::getData()
 
  531   static UnitTestRepository::InstanceData data;
 
  536 bool 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";
 
static bool verboseUnitTests()
Returns if unit tests are verbose or not. 
 
static int getNProc()
The number of processes in MPI_COMM_WORLD. 
 
static CommandLineProcessor & getCLP()
Return the CLP to add options to. 
 
bool is_null(const std::shared_ptr< T > &p)
Returns true if p.get()==NULL. 
 
Basic wall-clock timer class. 
 
basic_FancyOStream< char > FancyOStream
 
Teuchos header file which uses auto-configuration information to include necessary C++ headers...
 
Tabbing class for helping to create formated, indented output for a basic_FancyOStream object...
 
static void addUnitTest(UnitTestBase *unitTest, const std::string groupName, const std::string testName)
Add an unit test (called indirectly through macros. 
 
void showTestFailureLocation(bool)
Set if TEUCHOS_PASS_FAIL(...) should print test failure location. 
 
static int runUnitTestsFromMain(int argc, char *argv[])
Run the unit tests from main() passing in (argc, argv). 
 
void start(bool reset=false)
Start the timer, if the timer is enabled (see disable()). 
 
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
Deprecated. 
 
double stop()
Stop the timer, if the timer is enabled (see disable()). 
 
std::ostream subclass that performs the magic of indenting data sent to an std::ostream object among ...
 
Ptr< T > ptr() const 
Get a safer wrapper raw C++ pointer to the underlying object. 
 
static RCP< FancyOStream > getDefaultOStream()
Get the default output stream object. 
 
EParseCommandLineReturn parse(int argc, char *argv[], std::ostream *errout=&std::cerr) const 
Parse a command line. 
 
static void setGloballyReduceTestResult(const bool globallyReduceUnitTestResult)
Set if the unit tests should reduce pass/fail across processes. 
 
static int sum(int localVal)
Sum a set of integers across processes. 
 
EParseCommandLineReturn
Return value for CommandLineProcessor::parse(). Note: These enums are all given non-negative values s...
 
Templated array class derived from the STL std::vector. 
 
Utilities to make writing tests easier. 
 
static bool runUnitTests(FancyOStream &out)
Run the registered unit tests. 
 
void push_back(const value_type &x)
 
Basic command line parser for input from (argc,argv[]) 
 
static bool getGloballyReduceTestResult()
Get if the unit tests should reduce across processes or not. 
 
double totalElapsedTime(bool readCurrentTime=false) const 
The total time in seconds accumulated by this timer. 
 
static void allGather(int localVal, const ArrayView< int > &allVals)
Global all-to-all of a set of integers across processes. 
 
void printFinalTimerSummary(const Ptr< std::ostream > &out=null)
Call to print timers so that they don't get printed in the destructor. 
 
#define TEUCHOS_STANDARD_CATCH_STATEMENTS(VERBOSE, ERR_STREAM, SUCCESS_FLAG)
Simple macro that catches and reports standard exceptions and other exceptions. 
 
#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 ...
 
Class that helps parse command line input arguments from (argc,argv[]) and set options.