OsiUnitTests.hpp
Go to the documentation of this file.
1 // Copyright (C) 2010
2 // All Rights Reserved.
3 // This code is licensed under the terms of the Eclipse Public License (EPL).
4 
10 #ifndef OSISOLVERINTERFACETEST_HPP_
11 #define OSISOLVERINTERFACETEST_HPP_
12 
13 #include <cstdio>
14 #include <cstdlib>
15 #include <iostream>
16 #include <string>
17 #include <sstream>
18 #include <vector>
19 #include <list>
20 #include <map>
21 
22 class OsiSolverInterface;
24 
39  (const std::vector<OsiSolverInterface*> & vecEmptySiP,
40  const std::string& mpsDir);
41 
47  (const OsiSolverInterface* emptySi,
48  const std::string& mpsDir,
49  const std::string& netlibDir);
50 
53  (const OsiSolverInterface * baseSiP,
54  const std::string & mpsDir);
55 
58  (const OsiSolverInterface * baseSiP,
59  const std::string & mpsDir);
60 
63  (const OsiSolverInterface * siP,
64  const std::string & mpsDir);
65 
67 void OsiCutsUnitTest();
68 
70 namespace OsiUnitTest {
71 
72 class TestOutcomes;
73 
78 extern unsigned int verbosity;
79 
86 extern unsigned int haltonerror;
87 
93 extern TestOutcomes outcomes;
94 
102 void failureMessage(const std::string &solverName,
103  const std::string &message) ;
105 void failureMessage(const OsiSolverInterface &si,
106  const std::string &message) ;
107 
114 void failureMessage(const std::string &solverName,
115  const std::string &testname, const std::string &testcond) ;
116 
118 void failureMessage(const OsiSolverInterface &si,
119  const std::string &testname, const std::string &testcond) ;
120 
125 void testingMessage(const char *const msg) ;
126 
133 bool equivalentVectors(const OsiSolverInterface * si1,
134  const OsiSolverInterface * si2,
135  double tol, const double * v1, const double * v2, int size) ;
136 
144 
151 bool isEquivalent(const CoinPackedVectorBase &pv, int n, const double *fv) ;
152 
161 bool processParameters (int argc, const char **argv,
162  std::map<std::string,std::string>& parms,
163  const std::map<std::string,int>& ignorekeywords = std::map<std::string,int>());
164 
166 class TestOutcome {
167  public:
169  typedef enum {
170  NOTE = 0,
171  PASSED = 1,
172  WARNING = 2,
173  ERROR = 3,
174  LAST = 4
175  } SeverityLevel;
177  static std::string SeverityLevelName[LAST];
179  std::string component;
181  std::string testname;
183  std::string testcond;
187  bool expected;
189  std::string filename;
193  TestOutcome(const std::string& comp, const std::string& tst,
194  const char* cond, SeverityLevel sev,
195  const char* file, int line, bool exp = false)
196  : component(comp),testname(tst),testcond(cond),severity(sev),
197  expected(exp),filename(file),linenumber(line)
198  { }
200  void print() const;
201 };
202 
204 class TestOutcomes : public std::list<TestOutcome> {
205  public:
207  void add(std::string comp, std::string tst, const char* cond,
208  TestOutcome::SeverityLevel sev, const char* file, int line,
209  bool exp = false)
210  { push_back(TestOutcome(comp,tst,cond,sev,file,line,exp)); }
211 
216  void add(const OsiSolverInterface& si, std::string tst, const char* cond,
217  TestOutcome::SeverityLevel sev, const char* file, int line,
218  bool exp = false);
220  void print() const;
227  int& total, int& expected) const;
228 };
229 
231 #define OSIUNITTEST_QUOTEME_(x) #x
232 #define OSIUNITTEST_QUOTEME(x) OSIUNITTEST_QUOTEME_(x)
234 
235 template <typename Component>
237  bool condition, const char * condition_str, const char *filename,
238  int line, const Component& component, const std::string& testname,
239  TestOutcome::SeverityLevel severity, bool expected)
240 {
241  if (condition) {
242  OsiUnitTest::outcomes.add(component, testname, condition_str,
243  OsiUnitTest::TestOutcome::PASSED, filename, line, false);
244  if (OsiUnitTest::verbosity >= 2) {
245  std::ostringstream successmsg;
246  successmsg << __FILE__ << ":" << __LINE__ << ": " << testname
247  << " (condition \'" << condition_str << "\') passed.\n";
248  OsiUnitTest::testingMessage(successmsg.str().c_str());
249  }
250  return true;
251  }
252  OsiUnitTest::outcomes.add(component, testname, condition_str,
253  severity, filename, line, expected);
254  OsiUnitTest::failureMessage(component, testname, condition_str);
255  switch (OsiUnitTest::haltonerror) {
256  case 2:
257  { if (severity >= OsiUnitTest::TestOutcome::ERROR ) std::abort(); break; }
258  case 1:
259  { std::cout << std::endl << "press any key to continue..." << std::endl;
260  std::getchar();
261  break ; }
262  default: ;
263  }
264  return false;
265 }
266 
268 #define OSIUNITTEST_ADD_OUTCOME(component,testname,testcondition,severity,expected) \
269  OsiUnitTest::outcomes.add(component,testname,testcondition,severity,\
270  __FILE__,__LINE__,expected)
271 
281 #define OSIUNITTEST_ASSERT_SEVERITY_EXPECTED(condition,failurecode,component,\
282  testname, severity, expected) \
283 { \
284  if (!OsiUnitTestAssertSeverityExpected(condition, #condition, \
285  __FILE__, __LINE__, component, testname, severity, expected)) { \
286  failurecode; \
287  } \
288 }
289 
293 #define OSIUNITTEST_ASSERT_ERROR(condition, failurecode, component, testname) \
294  OSIUNITTEST_ASSERT_SEVERITY_EXPECTED(condition,failurecode,component,testname,\
295  OsiUnitTest::TestOutcome::ERROR,false)
296 
300 #define OSIUNITTEST_ASSERT_WARNING(condition, failurecode, component, testname) \
301  OSIUNITTEST_ASSERT_SEVERITY_EXPECTED(condition,failurecode,component,testname,\
302  OsiUnitTest::TestOutcome::WARNING,false)
303 
314 #define OSIUNITTEST_CATCH_SEVERITY_EXPECTED(trycode, catchcode, component, testname,\
315  severity, expected) \
316 { \
317  try { \
318  trycode; \
319  OSIUNITTEST_ADD_OUTCOME(component,testname,#trycode " did not throw exception",\
320  OsiUnitTest::TestOutcome::PASSED,false); \
321  if (OsiUnitTest::verbosity >= 2) { \
322  std::string successmsg( __FILE__ ":" OSIUNITTEST_QUOTEME(__LINE__) ": "); \
323  successmsg = successmsg + testname; \
324  successmsg = successmsg + " (code \'" #trycode "\') did not throw exception"; \
325  successmsg = successmsg + ".\n" ; \
326  OsiUnitTest::testingMessage(successmsg.c_str()); \
327  } \
328  } catch (CoinError& e) { \
329  std::stringstream errmsg; \
330  errmsg << #trycode " threw CoinError: " << e.message(); \
331  if (e.className().length() > 0) \
332  errmsg << " in " << e.className(); \
333  if (e.methodName().length() > 0) \
334  errmsg << " in " << e.methodName(); \
335  if (e.lineNumber() >= 0) \
336  errmsg << " at " << e.fileName() << ":" << e.lineNumber(); \
337  OSIUNITTEST_ADD_OUTCOME(component,testname,errmsg.str().c_str(),\
338  severity,expected); \
339  OsiUnitTest::failureMessage(component,testname,errmsg.str().c_str()); \
340  switch(OsiUnitTest::haltonerror) { \
341  case 2: \
342  { if (severity >= OsiUnitTest::TestOutcome::ERROR) abort(); break; } \
343  case 1: \
344  { std::cout << std::endl << "press any key to continue..." << std::endl; \
345  getchar(); \
346  break ; } \
347  default: ; \
348  } \
349  catchcode; \
350  } catch (...) { \
351  std::string errmsg; \
352  errmsg = #trycode; \
353  errmsg = errmsg + " threw unknown exception"; \
354  OSIUNITTEST_ADD_OUTCOME(component,testname,errmsg.c_str(),severity,false); \
355  OsiUnitTest::failureMessage(component,testname,errmsg.c_str()); \
356  catchcode; \
357  } \
358 }
359 
363 #define OSIUNITTEST_CATCH_ERROR(trycode, catchcode, component, testname) \
364  OSIUNITTEST_CATCH_SEVERITY_EXPECTED(trycode, catchcode, component, testname, OsiUnitTest::TestOutcome::ERROR, false)
365 
369 #define OSIUNITTEST_CATCH_WARNING(trycode, catchcode, component, testname) \
370  OSIUNITTEST_CATCH_SEVERITY_EXPECTED(trycode, catchcode, component, testname, OsiUnitTest::TestOutcome::WARNING, false)
371 
372 } // end namespace OsiUnitTest
373 
374 #endif /*OSISOLVERINTERFACETEST_HPP_*/
std::string testname
Name of test.
SeverityLevel severity
Test result.
void testingMessage(const char *const msg)
Print a message.
TestOutcomes outcomes
Test outcomes.
Utility class to maintain a list of test outcomes.
bool isEquivalent(const CoinPackedVectorBase &pv, int n, const double *fv)
Compare a packed vector with an expanded vector.
Abstract base class for various sparse vectors.
bool processParameters(int argc, const char **argv, std::map< std::string, std::string > &parms, const std::map< std::string, int > &ignorekeywords=std::map< std::string, int >())
Process command line parameters.
A single test outcome record.
std::string component
Name of component under test.
unsigned int haltonerror
Behaviour on failing a test.
void print() const
Print the test outcome.
void OsiSolverInterfaceCommonUnitTest(const OsiSolverInterface *emptySi, const std::string &mpsDir, const std::string &netlibDir)
A function that tests the methods in the OsiSolverInterface class.
TestOutcome(const std::string &comp, const std::string &tst, const char *cond, SeverityLevel sev, const char *file, int line, bool exp=false)
Standard constructor.
void OsiSolverInterfaceMpsUnitTest(const std::vector< OsiSolverInterface * > &vecEmptySiP, const std::string &mpsDir)
A function that tests that a lot of problems given in MPS files (mostly the NETLIB problems) solve pr...
unsigned int verbosity
Verbosity level of unit tests.
void OsiColCutUnitTest(const OsiSolverInterface *baseSiP, const std::string &mpsDir)
A function that tests the methods in the OsiColCut class.
std::string testcond
Condition being tested.
Abstract Base Class for describing an interface to a solver.
bool equivalentVectors(const OsiSolverInterface *si1, const OsiSolverInterface *si2, double tol, const double *v1, const double *v2, int size)
Utility method to check equality.
static std::string SeverityLevelName[LAST]
Print strings for SeverityLevel.
int linenumber
Line number in code file where test executed.
void OsiRowCutDebuggerUnitTest(const OsiSolverInterface *siP, const std::string &mpsDir)
A function that tests the methods in the OsiRowCutDebugger class.
bool OsiUnitTestAssertSeverityExpected(bool condition, const char *condition_str, const char *filename, int line, const Component &component, const std::string &testname, TestOutcome::SeverityLevel severity, bool expected)
void add(std::string comp, std::string tst, const char *cond, TestOutcome::SeverityLevel sev, const char *file, int line, bool exp=false)
Add an outcome to the list.
void print() const
Print the list of outcomes.
bool compareProblems(OsiSolverInterface *osi1, OsiSolverInterface *osi2)
Compare two problems for equality.
void OsiRowCutUnitTest(const OsiSolverInterface *baseSiP, const std::string &mpsDir)
A function that tests the methods in the OsiRowCut class.
std::string filename
Name of code file where test executed.
void failureMessage(const std::string &solverName, const std::string &message)
Print an error message.
void OsiCutsUnitTest()
A function that tests the methods in the OsiCuts class.
bool expected
Set to true if problem is expected.
void getCountBySeverity(TestOutcome::SeverityLevel sev, int &total, int &expected) const
Count total and expected outcomes at given severity level.