00001
00002
00003
00004
00005 #ifndef OSISOLVERINTERFACETEST_HPP_
00006 #define OSISOLVERINTERFACETEST_HPP_
00007
00008 #include <string>
00009 #include <sstream>
00010 #include <vector>
00011 #include <list>
00012 #include <map>
00013
00014 class OsiSolverInterface;
00015 class CoinPackedVectorBase;
00016
00030 void OsiSolverInterfaceMpsUnitTest
00031 (const std::vector<OsiSolverInterface*> & vecEmptySiP,
00032 const std::string& mpsDir);
00033
00038 void OsiSolverInterfaceCommonUnitTest
00039 (const OsiSolverInterface* emptySi,
00040 const std::string& mpsDir,
00041 const std::string& netlibDir);
00042
00044 void OsiColCutUnitTest
00045 (const OsiSolverInterface * baseSiP,
00046 const std::string & mpsDir);
00047
00049 void OsiRowCutUnitTest
00050 (const OsiSolverInterface * baseSiP,
00051 const std::string & mpsDir);
00052
00054 void OsiRowCutDebuggerUnitTest
00055 (const OsiSolverInterface * siP,
00056 const std::string & mpsDir);
00057
00059 void OsiCutsUnitTest();
00060
00061 namespace OsiUnitTest {
00062
00063 class TestOutcomes;
00064
00067 extern unsigned int verbosity;
00068
00074 extern unsigned int haltonerror;
00075
00078 extern TestOutcomes outcomes;
00079
00080 void failureMessage(const std::string &solverName,
00081 const std::string &message) ;
00082 void failureMessage(const OsiSolverInterface &si,
00083 const std::string &message) ;
00084 void failureMessage(const std::string &solverName,
00085 const std::string &testname, const std::string &testcond) ;
00086 void failureMessage(const OsiSolverInterface &si,
00087 const std::string &testname, const std::string &testcond) ;
00088 void testingMessage(const char *const msg) ;
00089
00090 bool equivalentVectors(const OsiSolverInterface * si1,
00091 const OsiSolverInterface * si2,
00092 double tol,
00093 const double * v1,
00094 const double * v2,
00095 int size) ;
00096
00097 bool compareProblems(OsiSolverInterface *osi1, OsiSolverInterface *osi2) ;
00098
00099 bool isEquivalent(const CoinPackedVectorBase &pv, int n, const double *fv) ;
00100
00106 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>());
00107
00108 class TestOutcome {
00109 public:
00110 typedef enum {
00111 NOTE = 0,
00112 PASSED = 1,
00113 WARNING = 2,
00114 ERROR = 3,
00115 LAST = 4
00116 } SeverityLevel;
00117
00118 static std::string SeverityLevelName[LAST];
00119
00120 std::string component;
00121 std::string testname;
00122 std::string testcond;
00123 SeverityLevel severity;
00124 bool expected;
00125
00126 std::string filename;
00127 int linenumber;
00128
00129 TestOutcome(const std::string& comp, const std::string& tst, const char* cond, SeverityLevel sev, const char* file, int line, bool exp = false)
00130 : component(comp), testname(tst), testcond(cond), severity(sev), expected(exp), filename(file), linenumber(line)
00131 { }
00132
00133 void print() const;
00134 };
00135
00136 class TestOutcomes : public std::list<TestOutcome> {
00137 public:
00138 void add(std::string comp, std::string tst, const char* cond, TestOutcome::SeverityLevel sev, const char* file, int line, bool exp = false)
00139 {
00140 push_back(TestOutcome(comp, tst, cond, sev, file, line, exp));
00141 }
00142
00143 void add(const OsiSolverInterface& si, std::string tst, const char* cond, TestOutcome::SeverityLevel sev, const char* file, int line, bool exp = false);
00144
00145 void print() const;
00146
00150 void getCountBySeverity(TestOutcome::SeverityLevel sev, int& total, int& expected) const;
00151 };
00152
00153 #define OSIUNITTEST_QUOTEME_(x) #x
00154 #define OSIUNITTEST_QUOTEME(x) OSIUNITTEST_QUOTEME_(x)
00155
00156 #define OSIUNITTEST_ADD_OUTCOME(component, testname, testcondition, severity, expected) \
00157 OsiUnitTest::outcomes.add(component, testname, testcondition, severity, __FILE__, __LINE__, expected)
00158
00159 #define OSIUNITTEST_ASSERT_SEVERITY_EXPECTED(condition, failurecode, component, testname, severity, expected) \
00160 { \
00161 if( condition ) { \
00162 OSIUNITTEST_ADD_OUTCOME(component, testname, #condition, OsiUnitTest::TestOutcome::PASSED, false); \
00163 if (OsiUnitTest::verbosity >= 2) { \
00164 std::string successmsg(__FILE__ ":" OSIUNITTEST_QUOTEME(__LINE__) ": "); \
00165 successmsg = successmsg + testname; \
00166 successmsg = successmsg + " (condition \'" #condition "\') passed.\n"; \
00167 OsiUnitTest::testingMessage(successmsg.c_str()); \
00168 } \
00169 } else { \
00170 OSIUNITTEST_ADD_OUTCOME(component, testname, #condition, severity, expected); \
00171 OsiUnitTest::failureMessage(component, testname, #condition); \
00172 switch( OsiUnitTest::haltonerror ) { \
00173 case 2: if( severity >= OsiUnitTest::TestOutcome::ERROR ) abort(); break; \
00174 case 1: std::cout << std::endl << "press any key to continue..." << std::endl; getchar(); \
00175 default: ; } \
00176 failurecode; \
00177 } \
00178 }
00179
00180 #define OSIUNITTEST_ASSERT_ERROR(condition, failurecode, component, testname) \
00181 OSIUNITTEST_ASSERT_SEVERITY_EXPECTED(condition, failurecode, component, testname, OsiUnitTest::TestOutcome::ERROR, false)
00182
00183 #define OSIUNITTEST_ASSERT_WARNING(condition, failurecode, component, testname) \
00184 OSIUNITTEST_ASSERT_SEVERITY_EXPECTED(condition, failurecode, component, testname, OsiUnitTest::TestOutcome::WARNING, false)
00185
00186 #define OSIUNITTEST_CATCH_SEVERITY_EXPECTED(trycode, catchcode, component, testname, severity, expected) \
00187 {\
00188 try {\
00189 trycode; \
00190 OSIUNITTEST_ADD_OUTCOME(component, testname, #trycode " did not threw exception", OsiUnitTest::TestOutcome::PASSED, false); \
00191 if (OsiUnitTest::verbosity >= 2) { \
00192 std::string successmsg( __FILE__ ":" OSIUNITTEST_QUOTEME(__LINE__) ": "); \
00193 successmsg = successmsg + testname; \
00194 successmsg = successmsg + " (code \'" #trycode "\') did not throw exception.\n"; \
00195 OsiUnitTest::testingMessage(successmsg.c_str()); \
00196 } \
00197 } catch (CoinError& e) { \
00198 std::stringstream errmsg; \
00199 errmsg << #trycode " threw CoinError: " << e.message(); \
00200 if (e.className().length() > 0) \
00201 errmsg << " in " << e.className(); \
00202 if (e.methodName().length() > 0) \
00203 errmsg << " in " << e.methodName(); \
00204 if (e.lineNumber() >= 0) \
00205 errmsg << " at " << e.fileName() << ":" << e.lineNumber(); \
00206 OSIUNITTEST_ADD_OUTCOME(component, testname, errmsg.str().c_str(), severity, expected); \
00207 OsiUnitTest::failureMessage(component, testname, errmsg.str().c_str()); \
00208 switch( OsiUnitTest::haltonerror ) { \
00209 case 2: if( severity >= OsiUnitTest::TestOutcome::ERROR ) abort(); break; \
00210 case 1: std::cout << std::endl << "press any key to continue..." << std::endl; getchar(); \
00211 default: ; } \
00212 catchcode; \
00213 } catch (...) { \
00214 std::string errmsg; \
00215 errmsg = #trycode; \
00216 errmsg = errmsg + " threw unknown exception"; \
00217 OSIUNITTEST_ADD_OUTCOME(component, testname, errmsg.c_str(), severity, false); \
00218 OsiUnitTest::failureMessage(component, testname, errmsg.c_str()); \
00219 catchcode; \
00220 } \
00221 }
00222
00223 #define OSIUNITTEST_CATCH_ERROR(trycode, catchcode, component, testname) \
00224 OSIUNITTEST_CATCH_SEVERITY_EXPECTED(trycode, catchcode, component, testname, OsiUnitTest::TestOutcome::ERROR, false)
00225
00226 #define OSIUNITTEST_CATCH_WARNING(trycode, catchcode, component, testname) \
00227 OSIUNITTEST_CATCH_SEVERITY_EXPECTED(trycode, catchcode, component, testname, OsiUnitTest::TestOutcome::WARNING, false)
00228
00229 }
00230
00231 #endif