15#include "Teuchos_Assert.hpp"
16#include "Teuchos_VerboseObject.hpp"
18#include "Teuchos_Assert.hpp"
20#include "Teuchos_StandardCatchMacros.hpp"
28 const Teuchos::UnitTestBase * unitTest;
29 std::string groupName;
34 Teuchos::UnitTestBase *unitTest_in,
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 {
142 typedef Teuchos::Array<UnitTestData> unitTests_t;
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;
198 typedef InstanceData::unitTests_t unitTests_t;
200 using std::setprecision;
202 Time overallTimer(
"overallTimer",
true);
205 const int timerPrec = 3;
207 out <<
"\n***\n*** Unit test suite ...\n***\n\n";
209 InstanceData &data = getData();
211 const bool showAll = data.showTestDetails == SHOW_TEST_DETAILS_ALL;
212 const bool showTestNames = data.showTestDetails == SHOW_TEST_DETAILS_TEST_NAMES || showAll;
219 int numTestsFailed = 0;
225 out <<
"\nSorting tests by group name then by the order they were added ...";
227 std::sort( data.unitTests.
begin(), data.unitTests.
end() );
229 out <<
" (time = "<<setprecision(timerPrec)<<timer.
totalElapsedTime()<<
")\n";
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);
237 const std::string unitTestName = getUnitTestName(utd.groupName, utd.testName);
241 strMatch(data.groupName, utd.groupName)
243 strMatch(data.testName, utd.testName)
247 data.notUnitTestName.length() == 0
249 !strMatch(data.notUnitTestName, unitTestName)
256 std::ostringstream testHeaderOSS;
257 testHeaderOSS <<testCounter<<
". "<<unitTestName<<
" ... ";
258 const std::string testHeader = testHeaderOSS.str();
264 out <<testHeader<<std::flush;
275 oss =
rcp(
new std::ostringstream);
284 const bool result = runUnitTestImpl(*utd.unitTest, *localOut);
292 out <<testHeader<<
"\n"<<std::flush;
302 <<
" "<<unitTestName<<
"\n"
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";
346 if (failedTests.
size()) {
347 out <<
"\nThe following tests FAILED:\n";
348 for (Teuchos_Ordinal i = 0; i < failedTests.
size(); ++i)
349 out <<
" " << failedTests[i] <<
"\n";
353 out <<
"\nTotal Time: " << setprecision(timerPrec)
357 <<
"\nSummary: total = " << testCounter
358 <<
", run = " << numTestsRun;
362 <<
", passed = " << (numTestsRun-numTestsFailed)
363 <<
", failed = " << numTestsFailed <<
"\n";
368 <<
", failed = ???\n";
384 clp.
parse(argc,argv);
386 *out <<
"\nEnd Result: TEST FAILED" << std::endl;
393 *out <<
"\nEnd Result: TEST PASSED" << std::endl;
395 *out <<
"\nEnd Result: TEST FAILED" << std::endl;
399 return (success ? 0 : 1);
405 const std::string groupName,
const std::string testName_in )
407 InstanceData &data = getData();
408 std::string testName = testName_in;
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.
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.
Ptr< T > outArg(T &arg)
create a non-persisting (required or optional) output argument for a function call.
Smart reference counting pointer class for automatic garbage collection.
RCP< T2 > rcp_implicit_cast(const RCP< T1 > &p1)
Implicit cast of underlying RCP type from T1* to T2*.
RCP< T > rcpFromRef(T &r)
Return a non-owning weak RCP object from a raw object reference for a defined type.
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.
RCP< basic_FancyOStream< CharT, Traits > > tab(const RCP< basic_FancyOStream< CharT, Traits > > &out, const int tabs=1, const std::basic_string< CharT, Traits > linePrefix="")
Create a tab for an RCP-wrapped basic_FancyOStream object to cause the indentation of all output auto...
RCP< basic_FancyOStream< char > > fancyOStream(const RCP< std::basic_ostream< char > > &oStream, const std::basic_string< char > &tabIndentStr=" ", const int startingTab=0, const bool showLinePrefix=false, const int maxLenLinePrefix=10, const bool showTabCount=false, const bool showProcRank=false)
Dynamically allocate a FancyOStream and return it wrapped in an RCP 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.
TypeTo as(const TypeFrom &t)
Convert from one value type to another.
#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
basic_OSTab< char > OSTab
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.