fw4spl
cppunit_main.cpp
1 /* ***** BEGIN LICENSE BLOCK *****
2  * FW4SPL - Copyright (C) IRCAD, 2004-2018.
3  * Distributed under the terms of the GNU Lesser General Public License (LGPL) as
4  * published by the Free Software Foundation.
5  * ****** END LICENSE BLOCK ****** */
6 
7 /* ***** BEGIN LICENSE BLOCK *****
8  * Copyright (C) IRCAD, 2004-2010.
9  * Distributed under the terms of the BSD Licence as
10  * published by the Open Source Initiative.
11  * ****** END LICENSE BLOCK ****** */
12 
13 #include <stdexcept>
14 
15 #include <cppunit/BriefTestProgressListener.h>
16 #include <cppunit/CompilerOutputter.h>
17 #include <cppunit/TestResult.h>
18 #include <cppunit/TestResultCollector.h>
19 #include <cppunit/TestRunner.h>
20 #include <cppunit/TextTestProgressListener.h>
21 #include <cppunit/XmlOutputter.h>
22 #include <cppunit/extensions/TestFactoryRegistry.h>
23 
24 #ifdef BUNDLE_TEST_PROFILE
25 
26 #include <boost/filesystem/operations.hpp>
27 #include <boost/filesystem/path.hpp>
28 
29 #include <fwRuntime/operations.hpp>
30 #include <fwRuntime/profile/Profile.hpp>
31 #include <fwRuntime/io/ProfileReader.hpp>
32 
33 class MiniLauncher
34 {
35 public:
36  MiniLauncher( ::boost::filesystem::path profilePath )
37  {
39  runtime->addDefaultBundles();
40 
41  ::boost::filesystem::path cwd = runtime->getWorkingPath();
42 
43  if (!::boost::filesystem::exists( profilePath ))
44  {
45  profilePath = cwd / profilePath;
46  }
47 
48  if (!::boost::filesystem::exists( profilePath ))
49  {
50  throw (std::invalid_argument("<" + profilePath.string() + "> not found." ));
51  }
52 
53  m_profile = ::fwRuntime::io::ProfileReader::createProfile(profilePath);
54  ::fwRuntime::profile::setCurrentProfile(m_profile);
55 
56  m_profile->setParams(0, NULL);
57  m_profile->start();
58  m_profile->setup();
59  }
60 
61  ~MiniLauncher()
62  {
63  m_profile->cleanup();
64  m_profile->stop();
65  m_profile.reset();
66  ::fwRuntime::profile::setCurrentProfile(m_profile);
67  }
68 
69 private:
70  ::fwRuntime::profile::Profile::sptr m_profile;
71 
72 };
73 
74 #endif
75 
76 struct Options
77 {
78  bool verbose;
79  bool xmlReport;
80  bool listTests;
81  std::string xmlReportFile;
82  std::vector< std::string > testsToRun;
83 
84 #ifdef BUNDLE_TEST_PROFILE
85  std::string profile;
86 #endif
87 
88  Options() :
89  verbose(false),
90  xmlReport(false),
91  listTests(false)
92 #ifdef BUNDLE_TEST_PROFILE
93  ,
94  profile( BUNDLE_TEST_PROFILE )
95 #endif
96  {
97  }
98 
99  //------------------------------------------------------------------------------
100 
101  bool parse(int argc, char* argv[])
102  {
103  if (argc < 1)
104  {
105  return true;
106  }
107 
108  std::string programName( *argv != 0 ? *argv : "test_runner" );
109 
110  char** args = argv + 1;
111  char** argsEnd = argv + argc;
112  while (args < argsEnd)
113  {
114  std::string arg(*args);
115 
116  if(arg == "--help" || arg == "-h")
117  {
118  std::cout
119  << "usage : " << programName << " "
120  << "[--help|-h] [--verbose|-v] [--xml|-x] [-o FILE] [--list|-l] [test1 ... testN]"
121  << std::endl
122  << " -h,--help Shows this help" << std::endl
123  << " -s,--verbose Shows each run test name and it status" << std::endl
124  << " -x,--xml Output results to a xml file" << std::endl
125  << " -o FILE Specify xml file name" << std::endl
126  << " -l,--list Lists test names" << std::endl
127 #ifdef BUNDLE_TEST_PROFILE
128  << " -p,--profile Profile to launch for bundle tests" << std::endl
129 #endif
130  << " test1 ... testN Test names to run" << std::endl
131  << std::endl;
132  return false;
133  }
134  else if( arg == "--verbose" || arg == "-v")
135  {
136  this->verbose = true;
137  }
138  else if( arg == "--xml" || arg == "-x")
139  {
140  this->xmlReport = true;
141  }
142  else if( arg == "-o")
143  {
144  args++;
145  if(args >= argsEnd)
146  {
147  std::cerr << "value for -o is missing" << std::endl;
148  return false;
149  }
150  this->xmlReportFile = std::string(*args);
151  }
152  else if( arg == "--list" || arg == "-l")
153  {
154  this->listTests = true;
155  }
156 #ifdef BUNDLE_TEST_PROFILE
157  else if( arg == "--profile" || arg == "-p")
158  {
159  args++;
160  if(args >= argsEnd)
161  {
162  std::cerr << "value for -p/--profile is missing" << std::endl;
163  return false;
164  }
165  this->profile = std::string(*args);
166  }
167 #endif
168  else
169  {
170  this->testsToRun.push_back(arg);
171  }
172 
173  args++;
174  }
175  return true;
176  }
177 
178 };
179 
180 CPPUNIT_NS_BEGIN
181 class SynchronizationObject;
182 
183 class TestLister : public TestResult
184 {
185 public:
186  TestLister( SynchronizationObject* syncObject = 0 )
187  {
188  }
189 
190  //------------------------------------------------------------------------------
191 
192  virtual void startTest( Test* test )
193  {
194  std::cout << test->getName() << std::endl;
195  }
196 
197  //------------------------------------------------------------------------------
198 
199  virtual void runTest( Test* test )
200  {
201  test->run( this );
202  }
203 
204  //------------------------------------------------------------------------------
205 
206  virtual bool protect( const Functor& functor,
207  Test* test,
208  const std::string& shortDescription = std::string("") )
209  {
210  return false;
211  }
212 
213 };
214 //------------------------------------------------------------------------------
215 
216 CPPUNIT_NS_END
217 
218 int main( int argc, char* argv[] )
219 {
220 
221  Options options;
222 
223  std::string testExecutable = (argc >= 1) ? std::string(argv[0]) : "unknown";
224  options.xmlReportFile = testExecutable + "-cppunit-report.xml";
225 
226  if (!options.parse(argc, argv))
227  {
228  return 1;
229  }
230 
231 #ifdef BUNDLE_TEST_PROFILE
232  MiniLauncher miniLaucher( options.profile );
233 #endif
234 
235  CPPUNIT_NS::Test* testSuite = CPPUNIT_NS::TestFactoryRegistry::getRegistry().makeTest();
236 
237  // Add the top suite to the test runner
238  CPPUNIT_NS::TestRunner runner;
239  runner.addTest( testSuite );
240 
241  if( options.listTests )
242  {
243  CPPUNIT_NS::TestLister lister;
244  runner.run( lister );
245  return 0;
246  }
247 
248  // Create the event manager and test controller
249  CPPUNIT_NS::TestResult controller;
250 
251  // Add a listener that colllects test result
252  CPPUNIT_NS::TestResultCollector result;
253  controller.addListener( &result );
254 
255  // Listener that prints the name of each test before running it.
256  CPPUNIT_NS::BriefTestProgressListener BriefProgress;
257 
258  // Listener that print dots as test run.
259  CPPUNIT_NS::TextTestProgressListener textProgress;
260 
261  if(options.verbose)
262  {
263  controller.addListener( &BriefProgress );
264  }
265  else
266  {
267  controller.addListener( &textProgress );
268  }
269 
270  if(options.testsToRun.empty())
271  {
272  options.testsToRun.push_back("");
273  }
274 
275  std::vector< std::string >::const_iterator iter = options.testsToRun.begin();
276 
277  for(; iter != options.testsToRun.end(); ++iter)
278  {
279  try
280  {
281  runner.run( controller, *iter );
282  }
283  catch ( std::exception& e )
284  {
285  std::cerr << "[" << ((iter->empty()) ? "All tests" : *iter) << "]" << "Error: " << e.what() << std::endl;
286  return 1;
287  }
288  catch ( ... )
289  {
290  std::cerr << "[" << ((iter->empty()) ? "All tests" : *iter) << "]" << "Unexpected error. " << std::endl;
291  return 1;
292  }
293  }
294 
295  // Print test results in a compiler compatible format.
296  CPPUNIT_NS::CompilerOutputter outputter( &result, std::cerr );
297  outputter.write();
298 
299  if(options.xmlReport)
300  {
301  std::ofstream file( options.xmlReportFile.c_str() );
302  CPPUNIT_NS::XmlOutputter xml( &result, file );
303  xml.write();
304  file.close();
305  }
306 
307  if (result.testFailuresTotal())
308  {
309  return 1;
310  }
311 
312  return 0;
313 }
static FWRUNTIME_API Runtime * getDefault()
Retrieves the default runtime instance.
Definition: Runtime.cpp:286
Defines the runtime class.
Definition: Runtime.hpp:37
static FWRUNTIME_API std::shared_ptr< ::fwRuntime::profile::Profile > createProfile(const boost::filesystem::path &path)
Creates a profile from an xml file located at the given path.
FWRUNTIME_API void addDefaultBundles()
Adds all bundle found at the default location.
Definition: Runtime.cpp:119
FWRUNTIME_API::boost::filesystem::path getWorkingPath() const
Get the path where Bundles and share folder are located.
Definition: Runtime.cpp:402