μHAL (v2.7.9)
Part of the IPbus software repository
run_uhal_tests.cxx
Go to the documentation of this file.
1 /*
2 ---------------------------------------------------------------------------
3 
4  This file is part of uHAL.
5 
6  uHAL is a hardware access library and programming framework
7  originally developed for upgrades of the Level-1 trigger of the CMS
8  experiment at CERN.
9 
10  uHAL is free software: you can redistribute it and/or modify
11  it under the terms of the GNU General Public License as published by
12  the Free Software Foundation, either version 3 of the License, or
13  (at your option) any later version.
14 
15  uHAL is distributed in the hope that it will be useful,
16  but WITHOUT ANY WARRANTY; without even the implied warranty of
17  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18  GNU General Public License for more details.
19 
20  You should have received a copy of the GNU General Public License
21  along with uHAL. If not, see <http://www.gnu.org/licenses/>.
22 
23  Marc Magrans de Abril, CERN
24  email: marc.magrans.de.abril <AT> cern.ch
25 
26  Andrew Rose, Imperial College, London
27  email: awr01 <AT> imperial.ac.uk
28 
29  Tom Williams, Rutherford Appleton Laboratory, Oxfordshire
30  email: tom.williams <AT> cern.ch
31 
32 ---------------------------------------------------------------------------
33 */
34 
35 
36 /*
37  * File: run_uhal_tests.cxx
38  * Author: Tom Williams
39  * Date: September 2017
40  */
41 
42 
43 
44 #define BOOST_TEST_MODULE uhalTests
45 
46 // BOOST_TEST_NO_MAIN: Disable auto-generation of main function, in order to define our own, which parses some arguments
47 #define BOOST_TEST_NO_MAIN
48 
49 
50 #include <boost/program_options.hpp>
51 #include <boost/test/unit_test.hpp>
52 #if BOOST_VERSION >= 105900
53  #include <boost/test/tree/traverse.hpp>
54  #include <boost/test/tree/visitor.hpp>
55 #endif
56 
58 #include "uhal/tests/fixtures.hpp"
59 #include "uhal/tests/tools.hpp"
60 #include "uhal/log/log.hpp"
61 
62 
63 #ifdef BOOST_TEST_DYN_LINK
64 
65 // Inspired by https://stackoverflow.com/questions/25385011/getting-all-boost-test-suites-test-cases
66 struct ListWritingVisitor : boost::unit_test::test_tree_visitor
67 {
68  size_t level;
69  size_t maxDepth;
70 
71  ListWritingVisitor(const size_t aMaxDepth) :
72  level(0),
73  maxDepth(aMaxDepth == 0 ? std::numeric_limits<size_t>::max() : aMaxDepth)
74  {}
75 
76  void visit( boost::unit_test::test_case const& test )
77  {
78  if ((level+1) <= maxDepth)
79  std::cout << std::string(2 * (level > 2 ? level - 2 : 0), ' ') << " └> " << test.p_name << std::endl;
80  }
81 
82  bool test_suite_start( boost::unit_test::test_suite const& suite )
83  {
84  level += 1;
85 
86  if (level <= maxDepth)
87  std::cout << std::string(2 * (level > 2 ? level - 2 : 0), ' ') << (level > 1 ? "└ " : "") << suite.p_name << std::endl;
88  return true;
89  }
90 
91  void test_suite_finish( boost::unit_test::test_suite const& suite )
92  {
93  level -= 1;
94  }
95 };
96 
97 
98 using namespace uhal::tests;
99 
100 const std::string kOptionHelp = "help";
101 const std::string kOptionList = "list";
102 const std::string kOptionConnFile = "connection-file";
103 const std::string kOptionHwTimeout = "timeout";
104 const std::string kOptionQuickTest = "quick";
105 const std::string kOptionVerbose = "verbose";
106 const std::string kOptionVeryVerbose = "very-verbose";
107 
108 int BOOST_TEST_CALL_DECL
109 main( int argc, char* argv[] )
110 {
111  namespace po = boost::program_options;
112 
113  size_t lListDepth = 0;
114 
115  po::options_description lDesc ( "Allowed options" );
116  lDesc.add_options()
117  ( (kOptionHelp + ",h").c_str(), "produce help message" )
118  ( (kOptionList + ",l").c_str(), po::value<size_t>(&lListDepth)->implicit_value(0), "List all test suites and test cases (max depth can be specified if wanted; if not, all depths are shown)" )
119  ( (kOptionConnFile + ",c").c_str(), po::value<std::string>(&AbstractFixture::connectionFileURI), "Connection file URI" )
120  ( (kOptionHwTimeout + ",t").c_str(), po::value<size_t>(&AbstractFixture::timeout)->default_value(1000), "Timeout for Client/HwInterface (unit: ms)" )
121  ( kOptionQuickTest.c_str(), "Run brief tests (fewer iterations)" )
122  ( (kOptionVerbose + ",v").c_str(), "Verbose output" )
123  ( (kOptionVeryVerbose + ",V").c_str(), "Very verbose output" )
124  ;
125  po::variables_map vm;
126 
127 
128  std::vector<std::string> lOptionsForBoostUTF;
129  try
130  {
131  po::parsed_options lParsedOptions = po::command_line_parser(argc, argv).options(lDesc).allow_unregistered().run();
132  po::store ( lParsedOptions, vm );
133  po::notify ( vm );
134  lOptionsForBoostUTF = po::collect_unrecognized(lParsedOptions.options, po::include_positional);
135  }
136  catch ( std::exception& e )
137  {
138  std::cerr << "ERROR : " << e.what() << std::endl << std::endl;
139  std::cout << "Usage : " << argv[0] << " [OPTIONS]" << std::endl;
140  std::cout << lDesc << std::endl;
141  exit ( 1 );
142  }
143 
144  if ( vm.count ( kOptionHelp ) )
145  {
146  std::cout << "Usage: " << argv[0] << " [OPTIONS]" << std::endl;
147  std::cout << lDesc << std::endl;
148  exit ( 0 );
149  }
150 
151  if ( vm.count ( kOptionList ) )
152  {
153  ListWritingVisitor lVisitor(lListDepth);
154  boost::unit_test::traverse_test_tree( boost::unit_test::framework::master_test_suite(), lVisitor);
155  exit ( 0 );
156  }
157 
158  if ( vm.count (kOptionConnFile) == 0)
159  {
160  std::cerr << " ERROR : Option '" << kOptionConnFile << "' must be specified under normal running mode." << std::endl << std::endl;
161  std::cout << "Usage: " << argv[0] << " [OPTIONS]" << std::endl;
162  std::cout << lDesc << std::endl;
163  exit ( 1 );
164  }
165  else if ( AbstractFixture::connectionFileURI.find("file://") != 0 )
167 
168  AbstractFixture::quickTest = ( vm.count(kOptionQuickTest) > 0);
169 
170  std::cout << "Supplied arguments ..." << std::endl;
171  std::cout << " connection file = " << AbstractFixture::connectionFileURI << std::endl;
172  std::cout << " timeout = " << AbstractFixture::timeout << " ms" << std::endl;
173  std::cout << " " << (AbstractFixture::quickTest ? "quick" : "full") << " test will be run" << std::endl;
174 
175  std::cout << "Log level set to ";
176  if ( vm.count ( kOptionVeryVerbose ) ) {
178  std::cout << "DEBUG";
179  }
180  else if ( vm.count ( kOptionVerbose ) ) {
182  std::cout << "NOTICE";
183  }
184  else {
186  std::cout << "FATAL";
187  }
188  std::cout << std::endl << std::endl;
189 
190 
191  std::vector<const char*> lArgvForBoostUTF;
192  lArgvForBoostUTF.push_back(argv[0]);
193  if (lOptionsForBoostUTF.empty())
194  std::cout << "N.B. Didn't find any arguments/options to pass to boost UTF" << std::endl;
195  else {
196  std::cout << "Passing " << lOptionsForBoostUTF.size() << " arguments/options to boost UTF:" << std::endl << " ";
197  for (size_t i=0; i<lOptionsForBoostUTF.size(); i++) {
198  std::cout << " " << lOptionsForBoostUTF.at(i);
199  lArgvForBoostUTF.push_back(lOptionsForBoostUTF.at(i).c_str());
200  }
201  }
202  std::cout << std::endl << std::endl;
203 
204  lArgvForBoostUTF.push_back(0);
205  return ::boost::unit_test::unit_test_main( &init_unit_test, lArgvForBoostUTF.size()-1, const_cast<char**>(lArgvForBoostUTF.data()) );
206 }
207 
208 #endif
tools.hpp
uhal::tests
Definition: definitions.hpp:37
fixtures.hpp
uhal::tests::AbstractFixture::connectionFileURI
static std::string connectionFileURI
Definition: fixtures.hpp:56
uhal::tests::AbstractFixture::timeout
static size_t timeout
Definition: fixtures.hpp:58
uhal::setLogLevelTo
void setLogLevelTo(const FatalLevel &)
Function to specify, at runtime, that only messages with a severity level above Fatal should be logge...
Definition: log.cpp:88
definitions.hpp
main
int main(int argc, char *argv[])
Definition: generator.cxx:427
uhal::Debug
DebugLevel Debug
Definition: LogLevels.cpp:133
uhal::Notice
NoticeLevel Notice
Definition: LogLevels.cpp:97
log.hpp
uhal::Fatal
FatalLevel Fatal
Definition: LogLevels.cpp:43
uhal::tests::AbstractFixture::quickTest
static bool quickTest
Definition: fixtures.hpp:59