Osi  0.108.4
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 
38 void OsiSolverInterfaceMpsUnitTest(const std::vector< OsiSolverInterface * > &vecEmptySiP,
39  const std::string &mpsDir);
40 
46  const std::string &mpsDir,
47  const std::string &netlibDir);
48 
50 void OsiColCutUnitTest(const OsiSolverInterface *baseSiP,
51  const std::string &mpsDir);
52 
54 void OsiRowCutUnitTest(const OsiSolverInterface *baseSiP,
55  const std::string &mpsDir);
56 
59  const std::string &mpsDir);
60 
62 void OsiCutsUnitTest();
63 
65 namespace OsiUnitTest {
66 
67 class TestOutcomes;
68 
73 extern unsigned int verbosity;
74 
81 extern unsigned int haltonerror;
82 
88 extern TestOutcomes outcomes;
89 
97 void failureMessage(const std::string &solverName,
98  const std::string &message);
100 void failureMessage(const OsiSolverInterface &si,
101  const std::string &message);
102 
109 void failureMessage(const std::string &solverName,
110  const std::string &testname, const std::string &testcond);
111 
113 void failureMessage(const OsiSolverInterface &si,
114  const std::string &testname, const std::string &testcond);
115 
120 void testingMessage(const char *const msg);
121 
128 bool equivalentVectors(const OsiSolverInterface *si1,
129  const OsiSolverInterface *si2,
130  double tol, const double *v1, const double *v2, int size);
131 
139 
146 bool isEquivalent(const CoinPackedVectorBase &pv, int n, const double *fv);
147 
156 bool processParameters(int argc, const char **argv,
157  std::map< std::string, std::string > &parms,
158  const std::map< std::string, int > &ignorekeywords = std::map< std::string, int >());
159 
161 class TestOutcome {
162 public:
164  typedef enum {
165  NOTE = 0,
166  PASSED = 1,
167  WARNING = 2,
168  ERROR = 3,
169  LAST = 4
170  } SeverityLevel;
172  static std::string SeverityLevelName[LAST];
174  std::string component;
176  std::string testname;
178  std::string testcond;
182  bool expected;
184  std::string filename;
188  TestOutcome(const std::string &comp, const std::string &tst,
189  const char *cond, SeverityLevel sev,
190  const char *file, int line, bool exp = false)
191  : component(comp)
192  , testname(tst)
193  , testcond(cond)
194  , severity(sev)
195  , expected(exp)
196  , filename(file)
197  , linenumber(line)
198  {
199  }
201  void print() const;
202 };
203 
205 class TestOutcomes : public std::list< TestOutcome > {
206 public:
208  void add(std::string comp, std::string tst, const char *cond,
209  TestOutcome::SeverityLevel sev, const char *file, int line,
210  bool exp = false)
211  {
212  push_back(TestOutcome(comp, tst, cond, sev, file, line, exp));
213  }
214 
219  void add(const OsiSolverInterface &si, std::string tst, const char *cond,
220  TestOutcome::SeverityLevel sev, const char *file, int line,
221  bool exp = false);
223  void print() const;
230  int &total, int &expected) const;
231 };
232 
234 #define OSIUNITTEST_QUOTEME_(x) #x
235 #define OSIUNITTEST_QUOTEME(x) OSIUNITTEST_QUOTEME_(x)
237 
238 template < typename Component >
240  bool condition, const char *condition_str, const char *filename,
241  int line, const Component &component, const std::string &testname,
242  TestOutcome::SeverityLevel severity, bool expected)
243 {
244  if (condition) {
245  OsiUnitTest::outcomes.add(component, testname, condition_str,
246  OsiUnitTest::TestOutcome::PASSED, filename, line, false);
247  if (OsiUnitTest::verbosity >= 2) {
248  std::ostringstream successmsg;
249  successmsg << __FILE__ << ":" << __LINE__ << ": " << testname
250  << " (condition \'" << condition_str << "\') passed.\n";
251  OsiUnitTest::testingMessage(successmsg.str().c_str());
252  }
253  return true;
254  }
255  OsiUnitTest::outcomes.add(component, testname, condition_str,
256  severity, filename, line, expected);
257  OsiUnitTest::failureMessage(component, testname, condition_str);
258  switch (OsiUnitTest::haltonerror) {
259  case 2: {
260  if (severity >= OsiUnitTest::TestOutcome::ERROR)
261  std::abort();
262  break;
263  }
264  case 1: {
265  std::cout << std::endl
266  << "press any key to continue..." << std::endl;
267  std::getchar();
268  break;
269  }
270  default:;
271  }
272  return false;
273 }
274 
276 #define OSIUNITTEST_ADD_OUTCOME(component, testname, testcondition, severity, expected) \
277  OsiUnitTest::outcomes.add(component, testname, testcondition, severity, \
278  __FILE__, __LINE__, expected)
279 
289 #define OSIUNITTEST_ASSERT_SEVERITY_EXPECTED(condition, failurecode, component, \
290  testname, severity, expected) \
291  { \
292  if (!OsiUnitTestAssertSeverityExpected(condition, #condition, \
293  __FILE__, __LINE__, component, testname, severity, expected)) { \
294  failurecode; \
295  } \
296  }
297 
301 #define OSIUNITTEST_ASSERT_ERROR(condition, failurecode, component, testname) \
302  OSIUNITTEST_ASSERT_SEVERITY_EXPECTED(condition, failurecode, component, testname, \
303  OsiUnitTest::TestOutcome::ERROR, false)
304 
308 #define OSIUNITTEST_ASSERT_WARNING(condition, failurecode, component, testname) \
309  OSIUNITTEST_ASSERT_SEVERITY_EXPECTED(condition, failurecode, component, testname, \
310  OsiUnitTest::TestOutcome::WARNING, false)
311 
322 #define OSIUNITTEST_CATCH_SEVERITY_EXPECTED(trycode, catchcode, component, testname, \
323  severity, expected) \
324  { \
325  try { \
326  trycode; \
327  OSIUNITTEST_ADD_OUTCOME(component, testname, #trycode " did not throw exception", \
328  OsiUnitTest::TestOutcome::PASSED, false); \
329  if (OsiUnitTest::verbosity >= 2) { \
330  std::string successmsg(__FILE__ ":" OSIUNITTEST_QUOTEME(__LINE__) ": "); \
331  successmsg = successmsg + testname; \
332  successmsg = successmsg + " (code \'" #trycode "\') did not throw exception"; \
333  successmsg = successmsg + ".\n"; \
334  OsiUnitTest::testingMessage(successmsg.c_str()); \
335  } \
336  } catch (CoinError & e) { \
337  std::stringstream errmsg; \
338  errmsg << #trycode " threw CoinError: " << e.message(); \
339  if (e.className().length() > 0) \
340  errmsg << " in " << e.className(); \
341  if (e.methodName().length() > 0) \
342  errmsg << " in " << e.methodName(); \
343  if (e.lineNumber() >= 0) \
344  errmsg << " at " << e.fileName() << ":" << e.lineNumber(); \
345  OSIUNITTEST_ADD_OUTCOME(component, testname, errmsg.str().c_str(), \
346  severity, expected); \
347  OsiUnitTest::failureMessage(component, testname, errmsg.str().c_str()); \
348  switch (OsiUnitTest::haltonerror) { \
349  case 2: { \
350  if (severity >= OsiUnitTest::TestOutcome::ERROR) \
351  abort(); \
352  break; \
353  } \
354  case 1: { \
355  std::cout << std::endl \
356  << "press any key to continue..." << std::endl; \
357  getchar(); \
358  break; \
359  } \
360  default:; \
361  } \
362  catchcode; \
363  } catch (...) { \
364  std::string errmsg; \
365  errmsg = #trycode; \
366  errmsg = errmsg + " threw unknown exception"; \
367  OSIUNITTEST_ADD_OUTCOME(component, testname, errmsg.c_str(), severity, false); \
368  OsiUnitTest::failureMessage(component, testname, errmsg.c_str()); \
369  catchcode; \
370  } \
371  }
372 
376 #define OSIUNITTEST_CATCH_ERROR(trycode, catchcode, component, testname) \
377  OSIUNITTEST_CATCH_SEVERITY_EXPECTED(trycode, catchcode, component, testname, OsiUnitTest::TestOutcome::ERROR, false)
378 
382 #define OSIUNITTEST_CATCH_WARNING(trycode, catchcode, component, testname) \
383  OSIUNITTEST_CATCH_SEVERITY_EXPECTED(trycode, catchcode, component, testname, OsiUnitTest::TestOutcome::WARNING, false)
384 
385 } // end namespace OsiUnitTest
386 
387 #endif /*OSISOLVERINTERFACETEST_HPP_*/
388 
389 /* vi: softtabstop=2 shiftwidth=2 expandtab tabstop=2
390 */
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.