00001
00002
00003
00004
00010 #ifndef OSISOLVERINTERFACETEST_HPP_
00011 #define OSISOLVERINTERFACETEST_HPP_
00012
00013 #include <string>
00014 #include <sstream>
00015 #include <vector>
00016 #include <list>
00017 #include <map>
00018
00019 class OsiSolverInterface;
00020 class CoinPackedVectorBase;
00021
00035 void OsiSolverInterfaceMpsUnitTest
00036 (const std::vector<OsiSolverInterface*> & vecEmptySiP,
00037 const std::string& mpsDir);
00038
00043 void OsiSolverInterfaceCommonUnitTest
00044 (const OsiSolverInterface* emptySi,
00045 const std::string& mpsDir,
00046 const std::string& netlibDir);
00047
00049 void OsiColCutUnitTest
00050 (const OsiSolverInterface * baseSiP,
00051 const std::string & mpsDir);
00052
00054 void OsiRowCutUnitTest
00055 (const OsiSolverInterface * baseSiP,
00056 const std::string & mpsDir);
00057
00059 void OsiRowCutDebuggerUnitTest
00060 (const OsiSolverInterface * siP,
00061 const std::string & mpsDir);
00062
00064 void OsiCutsUnitTest();
00065
00067 namespace OsiUnitTest {
00068
00069 class TestOutcomes;
00070
00075 extern unsigned int verbosity;
00076
00083 extern unsigned int haltonerror;
00084
00090 extern TestOutcomes outcomes;
00091
00099 void failureMessage(const std::string &solverName,
00100 const std::string &message) ;
00102 void failureMessage(const OsiSolverInterface &si,
00103 const std::string &message) ;
00104
00111 void failureMessage(const std::string &solverName,
00112 const std::string &testname, const std::string &testcond) ;
00113
00115 void failureMessage(const OsiSolverInterface &si,
00116 const std::string &testname, const std::string &testcond) ;
00117
00122 void testingMessage(const char *const msg) ;
00123
00130 bool equivalentVectors(const OsiSolverInterface * si1,
00131 const OsiSolverInterface * si2,
00132 double tol, const double * v1, const double * v2, int size) ;
00133
00140 bool compareProblems(OsiSolverInterface *osi1, OsiSolverInterface *osi2) ;
00141
00148 bool isEquivalent(const CoinPackedVectorBase &pv, int n, const double *fv) ;
00149
00158 bool processParameters (int argc, const char **argv,
00159 std::map<std::string,std::string>& parms,
00160 const std::map<std::string,int>& ignorekeywords = std::map<std::string,int>());
00161
00163 class TestOutcome {
00164 public:
00166 typedef enum {
00167 NOTE = 0,
00168 PASSED = 1,
00169 WARNING = 2,
00170 ERROR = 3,
00171 LAST = 4
00172 } SeverityLevel;
00174 static std::string SeverityLevelName[LAST];
00176 std::string component;
00178 std::string testname;
00180 std::string testcond;
00182 SeverityLevel severity;
00184 bool expected;
00186 std::string filename;
00188 int linenumber;
00190 TestOutcome(const std::string& comp, const std::string& tst,
00191 const char* cond, SeverityLevel sev,
00192 const char* file, int line, bool exp = false)
00193 : component(comp),testname(tst),testcond(cond),severity(sev),
00194 expected(exp),filename(file),linenumber(line)
00195 { }
00197 void print() const;
00198 };
00199
00201 class TestOutcomes : public std::list<TestOutcome> {
00202 public:
00204 void add(std::string comp, std::string tst, const char* cond,
00205 TestOutcome::SeverityLevel sev, const char* file, int line,
00206 bool exp = false)
00207 { push_back(TestOutcome(comp,tst,cond,sev,file,line,exp)); }
00208
00213 void add(const OsiSolverInterface& si, std::string tst, const char* cond,
00214 TestOutcome::SeverityLevel sev, const char* file, int line,
00215 bool exp = false);
00217 void print() const;
00223 void getCountBySeverity(TestOutcome::SeverityLevel sev,
00224 int& total, int& expected) const;
00225 };
00226
00228 #define OSIUNITTEST_QUOTEME_(x) #x
00230 #define OSIUNITTEST_QUOTEME(x) OSIUNITTEST_QUOTEME_(x)
00231
00233 #define OSIUNITTEST_ADD_OUTCOME(component,testname,testcondition,severity,expected) \
00234 OsiUnitTest::outcomes.add(component,testname,testcondition,severity,\
00235 __FILE__,__LINE__,expected)
00236
00246 #define OSIUNITTEST_ASSERT_SEVERITY_EXPECTED(condition,failurecode,component,\
00247 testname, severity, expected) \
00248 { \
00249 if (condition) { \
00250 OSIUNITTEST_ADD_OUTCOME(component,testname,#condition,\
00251 OsiUnitTest::TestOutcome::PASSED, false); \
00252 if (OsiUnitTest::verbosity >= 2) { \
00253 std::string successmsg(__FILE__ ":" OSIUNITTEST_QUOTEME(__LINE__) ": "); \
00254 successmsg = successmsg + testname; \
00255 successmsg = successmsg + " (condition \'" #condition "\') passed.\n"; \
00256 OsiUnitTest::testingMessage(successmsg.c_str()); \
00257 } \
00258 } else { \
00259 OSIUNITTEST_ADD_OUTCOME(component,testname,#condition,severity,expected); \
00260 OsiUnitTest::failureMessage(component,testname,#condition); \
00261 switch (OsiUnitTest::haltonerror) { \
00262 case 2: \
00263 { if (severity >= OsiUnitTest::TestOutcome::ERROR ) abort(); break; } \
00264 case 1: \
00265 { std::cout << std::endl << "press any key to continue..." << std::endl; \
00266 getchar(); \
00267 break ; } \
00268 default: ; \
00269 } \
00270 failurecode; \
00271 } \
00272 }
00273
00277 #define OSIUNITTEST_ASSERT_ERROR(condition, failurecode, component, testname) \
00278 OSIUNITTEST_ASSERT_SEVERITY_EXPECTED(condition,failurecode,component,testname,\
00279 OsiUnitTest::TestOutcome::ERROR,false)
00280
00284 #define OSIUNITTEST_ASSERT_WARNING(condition, failurecode, component, testname) \
00285 OSIUNITTEST_ASSERT_SEVERITY_EXPECTED(condition,failurecode,component,testname,\
00286 OsiUnitTest::TestOutcome::WARNING,false)
00287
00298 #define OSIUNITTEST_CATCH_SEVERITY_EXPECTED(trycode, catchcode, component, testname,\
00299 severity, expected) \
00300 { \
00301 try { \
00302 trycode; \
00303 OSIUNITTEST_ADD_OUTCOME(component,testname,#trycode " did not throw exception",\
00304 OsiUnitTest::TestOutcome::PASSED,false); \
00305 if (OsiUnitTest::verbosity >= 2) { \
00306 std::string successmsg( __FILE__ ":" OSIUNITTEST_QUOTEME(__LINE__) ": "); \
00307 successmsg = successmsg + testname; \
00308 successmsg = successmsg + " (code \'" #trycode "\') did not throw exception"; \
00309 successmsg = successmsg + ".\n" ; \
00310 OsiUnitTest::testingMessage(successmsg.c_str()); \
00311 } \
00312 } catch (CoinError& e) { \
00313 std::stringstream errmsg; \
00314 errmsg << #trycode " threw CoinError: " << e.message(); \
00315 if (e.className().length() > 0) \
00316 errmsg << " in " << e.className(); \
00317 if (e.methodName().length() > 0) \
00318 errmsg << " in " << e.methodName(); \
00319 if (e.lineNumber() >= 0) \
00320 errmsg << " at " << e.fileName() << ":" << e.lineNumber(); \
00321 OSIUNITTEST_ADD_OUTCOME(component,testname,errmsg.str().c_str(),\
00322 severity,expected); \
00323 OsiUnitTest::failureMessage(component,testname,errmsg.str().c_str()); \
00324 switch(OsiUnitTest::haltonerror) { \
00325 case 2: \
00326 { if (severity >= OsiUnitTest::TestOutcome::ERROR) abort(); break; } \
00327 case 1: \
00328 { std::cout << std::endl << "press any key to continue..." << std::endl; \
00329 getchar(); \
00330 break ; } \
00331 default: ; \
00332 } \
00333 catchcode; \
00334 } catch (...) { \
00335 std::string errmsg; \
00336 errmsg = #trycode; \
00337 errmsg = errmsg + " threw unknown exception"; \
00338 OSIUNITTEST_ADD_OUTCOME(component,testname,errmsg.c_str(),severity,false); \
00339 OsiUnitTest::failureMessage(component,testname,errmsg.c_str()); \
00340 catchcode; \
00341 } \
00342 }
00343
00347 #define OSIUNITTEST_CATCH_ERROR(trycode, catchcode, component, testname) \
00348 OSIUNITTEST_CATCH_SEVERITY_EXPECTED(trycode, catchcode, component, testname, OsiUnitTest::TestOutcome::ERROR, false)
00349
00353 #define OSIUNITTEST_CATCH_WARNING(trycode, catchcode, component, testname) \
00354 OSIUNITTEST_CATCH_SEVERITY_EXPECTED(trycode, catchcode, component, testname, OsiUnitTest::TestOutcome::WARNING, false)
00355
00356 }
00357
00358 #endif