# OsiUnitTests.hpp

Go to the documentation of this file.

    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
    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_*/

All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines