Osi
trunk
|
00001 // Copyright (C) 2010 00002 // All Rights Reserved. 00003 // This code is licensed under the terms of the Eclipse Public License (EPL). 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 00232 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 } // end namespace OsiUnitTest 00373 00374 #endif /*OSISOLVERINTERFACETEST_HPP_*/