Osi  0.107.8
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;
23 class CoinPackedVectorBase;
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_*/
bool compareProblems(OsiSolverInterface *osi1, OsiSolverInterface *osi2)
Compare two problems for equality.
void print() const
Print the test outcome.
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.
void OsiCutsUnitTest()
A function that tests the methods in the OsiCuts class.
void OsiRowCutUnitTest(const OsiSolverInterface *baseSiP, const std::string &mpsDir)
A function that tests the methods in the OsiRowCut class.
void OsiColCutUnitTest(const OsiSolverInterface *baseSiP, const std::string &mpsDir)
A function that tests the methods in the OsiColCut class.
std::string filename
Name of code file where test executed.
SeverityLevel severity
Test result.
unsigned int verbosity
Verbosity level of unit tests.
bool isEquivalent(const CoinPackedVectorBase &pv, int n, const double *fv)
Compare a packed vector with an expanded vector.
Utility class to maintain a list of test outcomes.
TestOutcome(const std::string &comp, const std::string &tst, const char *cond, SeverityLevel sev, const char *file, int line, bool exp=false)
Standard constructor.
int linenumber
Line number in code file where test executed.
bool expected
Set to true if problem is expected.
void print() const
Print the list of outcomes.
void OsiRowCutDebuggerUnitTest(const OsiSolverInterface *siP, const std::string &mpsDir)
A function that tests the methods in the OsiRowCutDebugger class.
Abstract Base Class for describing an interface to a solver.
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.
std::string testcond
Condition being tested.
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)
unsigned int haltonerror
Behaviour on failing a test.
TestOutcomes outcomes
Test outcomes.
void getCountBySeverity(TestOutcome::SeverityLevel sev, int &total, int &expected) const
Count total and expected outcomes at given severity level.
A single test outcome record.
void testingMessage(const char *const msg)
Print a message.
std::string testname
Name of test.
std::string component
Name of component under test.
A namespace so we can define a few ‘global’ variables to use during tests.
void OsiSolverInterfaceCommonUnitTest(const OsiSolverInterface *emptySi, const std::string &mpsDir, const std::string &netlibDir)
A function that tests the methods in the OsiSolverInterface class.
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...
static std::string SeverityLevelName[LAST]
Print strings for SeverityLevel.
void failureMessage(const std::string &solverName, const std::string &message)
Print an error message.
bool equivalentVectors(const OsiSolverInterface *si1, const OsiSolverInterface *si2, double tol, const double *v1, const double *v2, int size)
Utility method to check equality.