torc-master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
UnitTestMain.cpp
Go to the documentation of this file.
1 // Torc - Copyright 2011-2013 University of Southern California. All Rights Reserved.
2 // $HeadURL$
3 // $Id$
4 
5 // This program is free software: you can redistribute it and/or modify it under the terms of the
6 // GNU General Public License as published by the Free Software Foundation, either version 3 of the
7 // License, or (at your option) any later version.
8 //
9 // This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
10 // without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
11 // the GNU General Public License for more details.
12 //
13 // You should have received a copy of the GNU General Public License along with this program. If
14 // not, see <http://www.gnu.org/licenses/>.
15 
16 /// \file
17 /// \brief Main function and test fixture declaration for Boost.Test.
18 
19 /// \brief Request dynamic linking of Boost.Test.
20 #define BOOST_TEST_DYN_LINK
21 /// \brief Define the top-level test module.
22 #define BOOST_TEST_MODULE torc
23 /// \brief Prototype for Boost.Test bool init_unit_test(void).
24 bool init_unit_test(void);
25 #include <boost/test/unit_test.hpp>
27 #include <iostream>
28 
29 /// \brief Test suite visitor to disable regression tests.
30 class RegressionFilter : public boost::unit_test::test_tree_visitor {
31 // typedefs
32  typedef boost::unit_test::test_suite test_suite; ///< Imported type.
33  typedef std::string string; ///< Imported type.
34 // members
35  /// \brief Vector of test suite pointers.
36  std::vector<const test_suite*> mTestSuiteVector;
37  /// \brief Vector of test suite usage flags.
38  std::vector<bool> mTestSuiteUsed;
39  /// \brief Vector of test suites to remove.
40  std::vector<boost::unit_test::test_unit_id> mTestSuitePruningIDs;
41 public:
42  /// \brief Removes all test suites marked for pruning.
43  virtual ~RegressionFilter(void) {
44  for(size_t i = 0; i < mTestSuitePruningIDs.size(); i++) {
45  boost::unit_test::framework::master_test_suite().remove(mTestSuitePruningIDs[i]);
46  }
47  }
48  /// \brief Returns the current fully qualified test suite path.
49  virtual string getFullyQualifiedPath(void) {
50  // assemble all of the test suite names
51  string name = "";
52  for(size_t i = 0; i < mTestSuiteVector.size(); i++) {
53  name += mTestSuiteVector[i]->p_name.get() + "/";
54  }
55  return name;
56  }
57  /// \brief Returns a fully qualified name for the given test case.
58  virtual string getFullyQualifiedName(const boost::unit_test::test_case& inTestCase) {
59  // assemble the fully qualified name
60  return getFullyQualifiedPath() + inTestCase.p_name.get();
61  }
62  /// \brief Flags the given test case and its parents as being used.
63  virtual void useTest(const boost::unit_test::test_case& inTestCase) {
64  // mark this suite and all parents as used
65  for(size_t i = 0; i < mTestSuiteVector.size(); i++) mTestSuiteUsed[i] = true;
66  }
67  /// \brief Determines whether or not to include the given test case.
68  virtual void visit(const boost::unit_test::test_case& inTestCase) {
69  string name = getFullyQualifiedName(inTestCase);
70  // determine whether to include the test
71  if(name.find("Regression") == string::npos && name.find("regression") == string::npos) {
72 std::cout << "keeping case " << name << std::endl;
73  useTest(inTestCase);
74  } else {
75  inTestCase.p_enabled.set(false);
76  boost::unit_test::framework::master_test_suite().remove(inTestCase.p_id);
77 std::cout << "pruning case " << name << std::endl;
78  }
79  }
80  /// \brief Enters a new test suite.
81  virtual bool test_suite_start(const boost::unit_test::test_suite& inTestSuite) {
82  // push the new suite information
83  mTestSuiteVector.push_back(&inTestSuite);
84  mTestSuiteUsed.push_back(false);
85 //std::cout << "entering test suite " << getFullyQualifiedPath() << std::endl;
86  return true;
87  }
88  /// \brief Exits a test suite and prunes it if no test cases remain in it.
89  virtual void test_suite_finish(const boost::unit_test::test_suite& inTestSuite) {
90 //std::cout << "leaving test suite " << getFullyQualifiedPath() << std::endl;
91  // if nobody needs this test suite, remove it
92  if(!mTestSuiteUsed.back()) {
93  inTestSuite.p_enabled.set(false);
94  mTestSuitePruningIDs.push_back(inTestSuite.p_id);
95  std::cout << "pruning suite " << getFullyQualifiedPath() << std::endl;
96  }
97  // pop the suite information
98  mTestSuiteVector.pop_back();
99  mTestSuiteUsed.pop_back();
100  }
101 };
102 
103 /// \brief Test suite visitor to disable tests for debugging.
104 class DebugFilter : public boost::unit_test::test_tree_visitor {
105 public:
106  virtual void visit(const boost::unit_test::test_case& inTestCase) {
107  std::string enabled =
108  "architecture/iterate_configmaps"
109  "bitstream/VirtexEMapUnitTest"
110  ;
111  inTestCase.p_enabled.set((enabled.find(inTestCase.p_name.get()) != std::string::npos));
112  // std::string disabled =
113  // "architecture/iterate_configmaps"
114  // ;
115  // inTestCase.p_enabled.set((disabled.find(inTestCase.p_name.get()) == std::string::npos));
116  }
117 };
118 
119 /// \brief Convenience test fixture struct to request desired logging level from Boost.Test.
120 struct TestFixture {
121  TestFixture(void) {
122  boost::unit_test::log_level log_level =
123  boost::unit_test::log_successful_tests
124  // boost::unit_test::log_test_units
125  // boost::unit_test::log_messages
126  // boost::unit_test::log_warnings
127  // boost::unit_test::log_all_errors
128  // boost::unit_test::log_cpp_exception_errors
129  // boost::unit_test::log_system_errors
130  // boost::unit_test::log_fatal_errors
131  // boost::unit_test::log_nothing
132  ;
133  boost::unit_test::unit_test_log.set_threshold_level(log_level);
134 
135  // initialize the directory tree
136  char**& argv = boost::unit_test::framework::master_test_suite().argv;
137  int argc = boost::unit_test::framework::master_test_suite().argc;
138  torc::common::DirectoryTree directoryTree(argv[0]);
139 
140  // determine whether the user requested regression tests
141  std::string regression("-regression");
142  bool regressionRequested = false;
143  for(int i = 1; i < argc; i++) {
144  if(argv[i] == regression) {
145  regressionRequested = true;
146  break;
147  }
148  }
149 
150  // allow for special debug filtering
151  //DebugFilter debugTestFilter;
152  //boost::unit_test::traverse_test_tree(boost::unit_test::framework::master_test_suite(),
153  // debugTestFilter);
154 
155  // disable all regression tests unless the user requested them
156  if(regressionRequested == false) {
157  std::cout << "NOTE: Disabling all regression tests. Use -regression to enable them."
158  << std::endl;
159  RegressionFilter regressionTestFilter;
160  boost::unit_test::traverse_test_tree(boost::unit_test::framework::master_test_suite(),
161  regressionTestFilter);
162  }
163  }
164 };
165 /// \brief Global test fixture to request desired logging level from Boost.Test.
166 BOOST_GLOBAL_FIXTURE(TestFixture)
Test suite visitor to disable regression tests.
bool init_unit_test(void)
Prototype for Boost.Test bool init_unit_test(void).
virtual string getFullyQualifiedPath(void)
Returns the current fully qualified test suite path.
Test suite visitor to disable tests for debugging.
boost::unit_test::test_suite test_suite
Imported type.
virtual void visit(const boost::unit_test::test_case &inTestCase)
Determines whether or not to include the given test case.
Header for the DirectoryTree class.
virtual bool test_suite_start(const boost::unit_test::test_suite &inTestSuite)
Enters a new test suite.
virtual void test_suite_finish(const boost::unit_test::test_suite &inTestSuite)
Exits a test suite and prunes it if no test cases remain in it.
Convenience test fixture struct to request desired logging level from Boost.Test. ...
std::string string
Imported type.
virtual ~RegressionFilter(void)
Removes all test suites marked for pruning.
std::string string
virtual string getFullyQualifiedName(const boost::unit_test::test_case &inTestCase)
Returns a fully qualified name for the given test case.
Encapsulation of filesystem paths that are used by the library.
virtual void visit(const boost::unit_test::test_case &inTestCase)
std::vector< const test_suite * > mTestSuiteVector
Vector of test suite pointers.
virtual void useTest(const boost::unit_test::test_case &inTestCase)
Flags the given test case and its parents as being used.
std::vector< boost::unit_test::test_unit_id > mTestSuitePruningIDs
Vector of test suites to remove.
std::vector< bool > mTestSuiteUsed
Vector of test suite usage flags.