libMesh
driver.C
Go to the documentation of this file.
1 // Ignore overloaded-virtual warnings coming from cppunit headers
2 #include <libmesh/ignore_warnings.h>
3 #include <cppunit/extensions/TestFactoryRegistry.h>
4 #include <cppunit/ui/text/TestRunner.h>
5 #include <libmesh/restore_warnings.h>
6 
7 // libMesh includes
8 #include <libmesh/libmesh.h>
9 
10 #include "libmesh_cppunit.h"
11 #include "test_comm.h"
12 
13 #ifdef LIBMESH_HAVE_CXX11_REGEX
14 
15 // C++ includes
16 #include <regex>
17 
18 // Add Tests to runner that match user-provided regex.
19 int add_matching_tests_to_runner(CppUnit::Test * test,
20  const std::string & allow_r_str,
21  const std::regex & allow_r,
22  const std::string & deny_r_str,
23  const std::regex & deny_r,
24  CppUnit::TextUi::TestRunner & runner,
25  CppUnit::TestSuite & rejects)
26 {
27  int n_tests_added = 0;
28 
29  // If running all tests, just add the "All Tests" test and return
30  if (test->getName() == "All Tests" && allow_r_str == "All Tests" &&
31  deny_r_str == "^$")
32  {
33  libMesh::out << test->getName() << std::endl;
34  runner.addTest(test);
35  return -12345;
36  }
37 
38  if (test->getChildTestCount() == 0)
39  {
40  // Add the test to the runner
41  if ((allow_r_str == "All Tests" ||
42  std::regex_search(test->getName(), allow_r)) &&
43  !std::regex_search(test->getName(), deny_r))
44  {
45  libMesh::out << test->getName() << std::endl;
46  n_tests_added ++;
47  runner.addTest(test);
48  }
49  // Add the test to the rejects it can be cleaned up later
50  else
51  rejects.addTest(test);
52  }
53 
54  // Call this recursively on each of our children, if any.
55  for (int i = 0; i < test->getChildTestCount(); i++)
56  n_tests_added +=
57  add_matching_tests_to_runner(test->getChildTestAt(i), allow_r_str, allow_r,
58  deny_r_str, deny_r, runner, rejects);
59 
60  return n_tests_added;
61 }
62 
63 #endif
64 
65 
66 int main(int argc, char ** argv)
67 {
68  // Initialize the library. This is necessary because the library
69  // may depend on a number of other libraries (i.e. MPI and Petsc)
70  // that require initialization before use.
71  libMesh::LibMeshInit init(argc, argv);
72  TestCommWorld = &init.comm();
73 
74  // See how long each of our tests are taking to run. This should be
75  // coarse-grained enough to enable even if we're not performance
76  // logging inside the library itself. We need to do this early, so
77  // we can query unitlog when first initializing tests.
78  libMesh::PerfLog driver_unitlog ("Unit Tests");
79  unitlog = &driver_unitlog;
80 
81  // Print just logs summarized by test suite, not every test
82  // individually
83  if (!libMesh::on_command_line("--full-logs"))
84  driver_unitlog.enable_summarized_logs();
85 
86  // We can now run all tests that match a regular expression, for
87  // example, "--re PartitionerTest" will match all the Partitioner
88  // unit tests. If the user does not specify a regex, we run all the
89  // tests returned by makeTest().
90 
91  // An example regex_string that would _exactly_ match a _single_ test is:
92  // "PartitionerTest_HilbertSFCPartitioner_ReplicatedMesh::testPartition2"
93  // On the other hand, the regex "HilbertSFC" would match all of the
94  // following tests:
95  //
96  // PartitionerTest_HilbertSFCPartitioner_ReplicatedMesh
97  // PartitionerTest_HilbertSFCPartitioner_ReplicatedMesh::testPartitionEmpty
98  // PartitionerTest_HilbertSFCPartitioner_ReplicatedMesh::testPartition1
99  // PartitionerTest_HilbertSFCPartitioner_ReplicatedMesh::testPartition2
100  // PartitionerTest_HilbertSFCPartitioner_ReplicatedMesh::testPartitionNProc
101  //
102  // If the user does not provide a a regex, the default re is "All Tests",
103  // which runs all the unit tests.
104 
105  // We can also skip tests that match a regular expression, with e.g.
106  // "--deny_re PartitionerTest" to skip all the Partitioner unit
107  // tests (even if a "--re" option would have included them.)
108 
109  // Read command line argument specifying the allowlist regular expression.
110  std::string allow_regex_string = "All Tests";
111  allow_regex_string = libMesh::command_line_next("--re", allow_regex_string);
112 
113  // Read command line argument specifying the allowlist regular expression.
114  std::string deny_regex_string = "^$";
115  deny_regex_string = libMesh::command_line_next("--deny_re", deny_regex_string);
116 
117  // Recursively add tests matching the regex to the runner object.
118  CppUnit::TextUi::TestRunner runner;
119 
120  // The Cppunit registry object that knows about all the tests.
121  CppUnit::TestFactoryRegistry & registry = CppUnit::TestFactoryRegistry::getRegistry();
122 
123  // A test suite container for holding tests not matching the regex. When main's
124  // scope ends, this class's destructor will delete the rejected tests
125  CppUnit::TestSuite rejects("rejects");
126 
127 #ifdef LIBMESH_HAVE_CXX11_REGEX
128  // Make regex objects from user's input.
129  const std::regex allow_regex(allow_regex_string);
130  const std::regex deny_regex(deny_regex_string);
131 
132  // Add all tests which match the re to the runner object.
133  libMesh::out << "Will run the following tests:" << std::endl;
134  const int n_tests_added =
135  add_matching_tests_to_runner(registry.makeTest(),
136  allow_regex_string, allow_regex,
137  deny_regex_string, deny_regex,
138  runner, rejects);
139  if (n_tests_added >= 0)
140  libMesh::out << "--- Running " << n_tests_added << " tests in total." << std::endl;
141 #else
142  // If no C++11 <regex> just run all the tests.
143  runner.addTest(registry.makeTest());
144 #endif
145 
146  // Actually run all the requested tests.
147  bool succeeded = runner.run();
148 
149  // Many users won't care at all about the PerfLog
150 #ifndef LIBMESH_ENABLE_PERFORMANCE_LOGGING
151  if (!libMesh::on_command_line("--full-logs"))
152  driver_unitlog.clear();
153 #endif
154 
155  // 1 for failure, 0 for success
156  return !succeeded;
157 }
158 
160 
T command_line_next(std::string name, T default_value)
Use GetPot&#39;s search()/next() functions to get following arguments from the command line...
Definition: libmesh.C:1011
libMesh::Parallel::Communicator * TestCommWorld
Definition: driver.C:159
int add_matching_tests_to_runner(CppUnit::Test *test, const std::string &allow_r_str, const std::regex &allow_r, const std::string &deny_r_str, const std::regex &deny_r, CppUnit::TextUi::TestRunner &runner, CppUnit::TestSuite &rejects)
Definition: driver.C:19
The LibMeshInit class, when constructed, initializes the dependent libraries (e.g.
Definition: libmesh.h:90
The PerfLog class allows monitoring of specific events.
Definition: perf_log.h:145
void enable_summarized_logs()
Tells the PerfLog to only print log results summarized by header.
Definition: perf_log.h:191
void init(triangulateio &t)
Initializes the fields of t to nullptr/0 as necessary.
void clear()
Clears all the internal data and restores the data structures to a pristine state.
Definition: perf_log.C:78
libMesh::PerfLog * unitlog
Definition: driver.C:161
OStreamProxy out
int main(int argc, char **argv)
Definition: driver.C:66
bool on_command_line(std::string arg)
Definition: libmesh.C:924