00001
00002
00003
00004
00010 #ifndef OSISOLVERINTERFACETEST_HPP_
00011 #define OSISOLVERINTERFACETEST_HPP_
00012
00013 #include <cstdio>
00014 #include <cstdlib>
00015 #include <iostream>
00016 #include <string>
00017 #include <sstream>
00018 #include <vector>
00019 #include <list>
00020 #include <map>
00021
00022 class OsiSolverInterface;
00023 class CoinPackedVectorBase;
00024
00038 void OsiSolverInterfaceMpsUnitTest
00039 (const std::vector<OsiSolverInterface*> & vecEmptySiP,
00040 const std::string& mpsDir);
00041
00046 void OsiSolverInterfaceCommonUnitTest
00047 (const OsiSolverInterface* emptySi,
00048 const std::string& mpsDir,
00049 const std::string& netlibDir);
00050
00052 void OsiColCutUnitTest
00053 (const OsiSolverInterface * baseSiP,
00054 const std::string & mpsDir);
00055
00057 void OsiRowCutUnitTest
00058 (const OsiSolverInterface * baseSiP,
00059 const std::string & mpsDir);
00060
00062 void OsiRowCutDebuggerUnitTest
00063 (const OsiSolverInterface * siP,
00064 const std::string & mpsDir);
00065
00067 void OsiCutsUnitTest();
00068
00070 namespace OsiUnitTest {
00071
00072 class TestOutcomes;
00073
00078 extern unsigned int verbosity;
00079
00086 extern unsigned int haltonerror;
00087
00093 extern TestOutcomes outcomes;
00094
00102 void failureMessage(const std::string &solverName,
00103 const std::string &message) ;
00105 void failureMessage(const OsiSolverInterface &si,
00106 const std::string &message) ;
00107
00114 void failureMessage(const std::string &solverName,
00115 const std::string &testname, const std::string &testcond) ;
00116
00118 void failureMessage(const OsiSolverInterface &si,
00119 const std::string &testname, const std::string &testcond) ;
00120
00125 void testingMessage(const char *const msg) ;
00126
00133 bool equivalentVectors(const OsiSolverInterface * si1,
00134 const OsiSolverInterface * si2,
00135 double tol, const double * v1, const double * v2, int size) ;
00136
00143 bool compareProblems(OsiSolverInterface *osi1, OsiSolverInterface *osi2) ;
00144
00151 bool isEquivalent(const CoinPackedVectorBase &pv, int n, const double *fv) ;
00152
00161 bool processParameters (int argc, const char **argv,
00162 std::map<std::string,std::string>& parms,
00163 const std::map<std::string,int>& ignorekeywords = std::map<std::string,int>());
00164
00166 class TestOutcome {
00167 public:
00169 typedef enum {
00170 NOTE = 0,
00171 PASSED = 1,
00172 WARNING = 2,
00173 ERROR = 3,
00174 LAST = 4
00175 } SeverityLevel;
00177 static std::string SeverityLevelName[LAST];
00179 std::string component;
00181 std::string testname;
00183 std::string testcond;
00185 SeverityLevel severity;
00187 bool expected;
00189 std::string filename;
00191 int linenumber;
00193 TestOutcome(const std::string& comp, const std::string& tst,
00194 const char* cond, SeverityLevel sev,
00195 const char* file, int line, bool exp = false)
00196 : component(comp),testname(tst),testcond(cond),severity(sev),
00197 expected(exp),filename(file),linenumber(line)
00198 { }
00200 void print() const;
00201 };
00202
00204 class TestOutcomes : public std::list<TestOutcome> {
00205 public:
00207 void add(std::string comp, std::string tst, const char* cond,
00208 TestOutcome::SeverityLevel sev, const char* file, int line,
00209 bool exp = false)
00210 { push_back(TestOutcome(comp,tst,cond,sev,file,line,exp)); }
00211
00216 void add(const OsiSolverInterface& si, std::string tst, const char* cond,
00217 TestOutcome::SeverityLevel sev, const char* file, int line,
00218 bool exp = false);
00220 void print() const;
00226 void getCountBySeverity(TestOutcome::SeverityLevel sev,
00227 int& total, int& expected) const;
00228 };
00229
00231 #define OSIUNITTEST_QUOTEME_(x) #x
00233 #define OSIUNITTEST_QUOTEME(x) OSIUNITTEST_QUOTEME_(x)
00234
00235 template <typename Component>
00236 bool OsiUnitTestAssertSeverityExpected(
00237 bool condition, const char * condition_str, const char *filename,
00238 int line, const Component& component, const std::string& testname,
00239 TestOutcome::SeverityLevel severity, bool expected)
00240 {
00241 if (condition) {
00242 OsiUnitTest::outcomes.add(component, testname, condition_str,
00243 OsiUnitTest::TestOutcome::PASSED, filename, line, false);
00244 if (OsiUnitTest::verbosity >= 2) {
00245 std::ostringstream successmsg;
00246 successmsg << __FILE__ << ":" << __LINE__ << ": " << testname
00247 << " (condition \'" << condition_str << "\') passed.\n";
00248 OsiUnitTest::testingMessage(successmsg.str().c_str());
00249 }
00250 return true;
00251 }
00252 OsiUnitTest::outcomes.add(component, testname, condition_str,
00253 severity, filename, line, expected);
00254 OsiUnitTest::failureMessage(component, testname, condition_str);
00255 switch (OsiUnitTest::haltonerror) {
00256 case 2:
00257 { if (severity >= OsiUnitTest::TestOutcome::ERROR ) std::abort(); break; }
00258 case 1:
00259 { std::cout << std::endl << "press any key to continue..." << std::endl;
00260 std::getchar();
00261 break ; }
00262 default: ;
00263 }
00264 return false;
00265 }
00266
00268 #define OSIUNITTEST_ADD_OUTCOME(component,testname,testcondition,severity,expected) \
00269 OsiUnitTest::outcomes.add(component,testname,testcondition,severity,\
00270 __FILE__,__LINE__,expected)
00271
00281 #define OSIUNITTEST_ASSERT_SEVERITY_EXPECTED(condition,failurecode,component,\
00282 testname, severity, expected) \
00283 { \
00284 if (!OsiUnitTestAssertSeverityExpected(condition, #condition, \
00285 __FILE__, __LINE__, component, testname, severity, expected)) { \
00286 failurecode; \
00287 } \
00288 }
00289
00293 #define OSIUNITTEST_ASSERT_ERROR(condition, failurecode, component, testname) \
00294 OSIUNITTEST_ASSERT_SEVERITY_EXPECTED(condition,failurecode,component,testname,\
00295 OsiUnitTest::TestOutcome::ERROR,false)
00296
00300 #define OSIUNITTEST_ASSERT_WARNING(condition, failurecode, component, testname) \
00301 OSIUNITTEST_ASSERT_SEVERITY_EXPECTED(condition,failurecode,component,testname,\
00302 OsiUnitTest::TestOutcome::WARNING,false)
00303
00314 #define OSIUNITTEST_CATCH_SEVERITY_EXPECTED(trycode, catchcode, component, testname,\
00315 severity, expected) \
00316 { \
00317 try { \
00318 trycode; \
00319 OSIUNITTEST_ADD_OUTCOME(component,testname,#trycode " did not throw exception",\
00320 OsiUnitTest::TestOutcome::PASSED,false); \
00321 if (OsiUnitTest::verbosity >= 2) { \
00322 std::string successmsg( __FILE__ ":" OSIUNITTEST_QUOTEME(__LINE__) ": "); \
00323 successmsg = successmsg + testname; \
00324 successmsg = successmsg + " (code \'" #trycode "\') did not throw exception"; \
00325 successmsg = successmsg + ".\n" ; \
00326 OsiUnitTest::testingMessage(successmsg.c_str()); \
00327 } \
00328 } catch (CoinError& e) { \
00329 std::stringstream errmsg; \
00330 errmsg << #trycode " threw CoinError: " << e.message(); \
00331 if (e.className().length() > 0) \
00332 errmsg << " in " << e.className(); \
00333 if (e.methodName().length() > 0) \
00334 errmsg << " in " << e.methodName(); \
00335 if (e.lineNumber() >= 0) \
00336 errmsg << " at " << e.fileName() << ":" << e.lineNumber(); \
00337 OSIUNITTEST_ADD_OUTCOME(component,testname,errmsg.str().c_str(),\
00338 severity,expected); \
00339 OsiUnitTest::failureMessage(component,testname,errmsg.str().c_str()); \
00340 switch(OsiUnitTest::haltonerror) { \
00341 case 2: \
00342 { if (severity >= OsiUnitTest::TestOutcome::ERROR) abort(); break; } \
00343 case 1: \
00344 { std::cout << std::endl << "press any key to continue..." << std::endl; \
00345 getchar(); \
00346 break ; } \
00347 default: ; \
00348 } \
00349 catchcode; \
00350 } catch (...) { \
00351 std::string errmsg; \
00352 errmsg = #trycode; \
00353 errmsg = errmsg + " threw unknown exception"; \
00354 OSIUNITTEST_ADD_OUTCOME(component,testname,errmsg.c_str(),severity,false); \
00355 OsiUnitTest::failureMessage(component,testname,errmsg.c_str()); \
00356 catchcode; \
00357 } \
00358 }
00359
00363 #define OSIUNITTEST_CATCH_ERROR(trycode, catchcode, component, testname) \
00364 OSIUNITTEST_CATCH_SEVERITY_EXPECTED(trycode, catchcode, component, testname, OsiUnitTest::TestOutcome::ERROR, false)
00365
00369 #define OSIUNITTEST_CATCH_WARNING(trycode, catchcode, component, testname) \
00370 OSIUNITTEST_CATCH_SEVERITY_EXPECTED(trycode, catchcode, component, testname, OsiUnitTest::TestOutcome::WARNING, false)
00371
00372 }
00373
00374 #endif