Ignore:
Timestamp:
Jun 12, 2011 11:59:15 AM (9 years ago)
Author:
stefan
Message:

convert osi unittest to use new TestOutcomes? facility

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/Clp/test/osiUnitTest.cpp

    r1709 r1740  
    55
    66#include "CoinPragma.hpp"
    7 
    87#include "OsiConfig.h"
    98
    10 #ifdef NDEBUG
    11 #undef NDEBUG
    12 #endif
    13 
    14 #include <cassert>
    159#include <cstdio>
    1610#include <iostream>
    17 #include <map>
    1811
    1912#include "OsiUnitTests.hpp"
     
    2619#include "OsiClpSolverInterface.hpp"
    2720
    28 namespace {
    29 
    30 // Display message on stdout and stderr. Flush cout buffer before printing the
    31 // message, so that output comes out in order in spite of buffered cout.
    32 
    33 void testingMessage( const char * const msg )
    34 {
    35   std::cout.flush() ;
    36   std::cerr <<msg;
    37   //cout <<endl <<"*****************************************"
    38   //     <<endl <<msg <<endl;
    39 }
    40 
    41 
    42 /*
    43   Utility routine to process command line parameters. An unrecognised parameter
    44   will trigger the help message and a return value of false.
    45  
    46   This should be replaced with the one of the standard CoinUtils parameter
    47   mechanisms.
    48 */
    49 bool processParameters (int argc, const char **argv,
    50                         std::map<std::string,std::string> &parms)
    51 
    52 {
    53   assert(argc >= 1);
    54   assert(argv != NULL);
    55 /*
    56   Initialise the parameter keywords.
    57 */
    58   std::set<std::string> definedKeyWords;
    59   definedKeyWords.insert("-cerr2cout");
    60   definedKeyWords.insert("-mpsDir");
    61   definedKeyWords.insert("-netlibDir");
    62   definedKeyWords.insert("-testOsiSolverInterface");
    63   definedKeyWords.insert("-nobuf");
    64 /*
    65   Set default values for data directories.
    66 */
    67   const char dirsep =  CoinFindDirSeparator() ;
    68   std::string pathTmp ;
    69 
    70   pathTmp = ".." ;
    71   pathTmp += dirsep ;
    72   pathTmp += ".." ;
    73   pathTmp += dirsep ;
    74   pathTmp += "Data" ;
    75   pathTmp += dirsep ;
    76 # ifdef COIN_MSVS
    77   // Visual Studio build is deeper
    78   pathTmp = "..\\..\\" + pathTmp ;
    79 # endif
    80 
    81   parms["-mpsDir"] = pathTmp + "Sample"  ;
    82   parms["-netlibDir"] = pathTmp + "Netlib" ;
    83 
    84 /*
    85   Read the command line parameters and fill a map of parameter keys and
    86   associated data. The parser allows for parameters which are only a keyword,
    87   or parameters of the form keyword=value (no spaces).
    88 */
    89   for (int i = 1 ; i < argc ; i++)
    90   { std::string parm(argv[i]) ;
    91     std::string key,value ;
    92     std::string::size_type eqPos = parm.find('=');
    93 
    94     if (eqPos == std::string::npos)
    95     { key = parm ; }
    96     else
    97     { key = parm.substr(0,eqPos) ;
    98       value = parm.substr(eqPos+1) ; }
    99 /*
    100   Is the specifed key valid?
    101 */
    102     if (definedKeyWords.find(key) == definedKeyWords.end())
    103     { std::cerr << "Undefined parameter \"" << key << "\"." << std::endl ;
    104       std::cerr
    105         << "Usage: " << argv[0]
    106         << " [-nobuf] [-mpsDir=V1] [-netlibDir=V2] "
    107         << "[-testOsiSolverInterface] " << std::endl ;
    108       std::cerr << "  where:" << std::endl ;
    109       std::cerr
    110         << "    "
    111         << "-cerr2cout: redirect cerr to cout; sometimes useful." << std::endl
    112         << "\t" << "to synchronise cout & cerr." << std::endl ;
    113       std::cerr
    114         << "    "
    115         << "-mpsDir: directory containing mps test files." << std::endl
    116         << "\t" << "Default value V1=\"../../Data/Sample\"" << std::endl ;
    117       std::cerr
    118         << "    "
    119         << "-netlibDir: directory containing netlib files." << std::endl
    120         << "\t" << "Default value V2=\"../../Data/Netlib\"" << std::endl ;
    121       std::cerr
    122         << "    "
    123         << "-testOsiSolverInterface: "
    124         << "run each OSI on the netlib problem set." << std::endl
    125         << "\t"
    126         << "Default is to not run the netlib problem set." << std::endl ;
    127       std::cerr
    128         << "    "
    129         << "-nobuf: use unbuffered output." << std::endl
    130         << "\t" << "Default is buffered output." << std::endl ;
    131      
    132       return (false) ; }
    133 /*
    134   Valid keyword; stash the value for later reference.
    135 */
    136     parms[key]=value ; }
    137 /*
    138   Tack the directory separator onto the data directories so we don't have to
    139   worry about it later.
    140 */
    141   parms["-mpsDir"] += dirsep ;
    142   parms["-netlibDir"] += dirsep ;
    143 /*
    144   Did the user request unbuffered i/o? It seems we need to go after this
    145   through stdio --- using pubsetbuf(0,0) on the C++ streams has no
    146   discernible affect. Nor, for that matter, did setting the unitbuf flag on
    147   the streams. Why? At a guess, sync_with_stdio connects the streams to the
    148   stdio buffers, and the C++ side isn't programmed to change them?
    149 */
    150   if (parms.find("-nobuf") != parms.end())
    151   { // std::streambuf *coutBuf, *cerrBuf ;
    152     // coutBuf = std::cout.rdbuf() ;
    153     // coutBuf->pubsetbuf(0,0) ;
    154     // cerrBuf = std::cerr.rdbuf() ;
    155     // cerrBuf->pubsetbuf(0,0) ;
    156     setbuf(stderr,0) ;
    157     setbuf(stdout,0) ; }
    158 /*
    159   Did the user request a redirect for cerr? This must occur before any i/o is
    160   performed.
    161 */
    162   if (parms.find("-cerr2cout") != parms.end())
    163   { std::cerr.rdbuf(std::cout.rdbuf()) ; }
    164 
    165   return (true) ; }
    166 
    167 
    168 }       // end file-local namespace
    169 
    170 
     21using namespace OsiUnitTest;
    17122
    17223//----------------------------------------------------------------
    17324// unitTest [-nobuf] [-mpsDir=V1] [-netlibDir=V2] [-testOsiSolverInterface]
     25//      [-cutsOnly]
    17426//
    17527// where:
    17628//   -nobuf: remove buffering on cout (stdout); useful to keep cout and cerr
    177 //      messages synchronised when redirecting output to a file or pipe.
     29//  messages synchronised when redirecting output to a file or pipe.
    17830//   -mpsDir: directory containing mps test files
    17931//       Default value V1="../../Data/Sample"   
     
    18335//       If specified, then OsiSolveInterface::unitTest
    18436//       is skipped over and not run.
     37//   -cutsOnly
     38//   If specified, only OsiCut tests are run.
    18539//
    18640// All parameters are optional.
     
    18842
    18943int main (int argc, const char *argv[])
    190 
    191 { int totalErrCnt = 0;
     44{
     45  bool exception = false;
     46  outcomes.clear();
    19247
    19348/*
     
    20964  Process command line parameters.
    21065*/
    211   std::map<std::string,std::string> parms ;
    212 
     66  std::map<std::string,std::string> parms;
    21367  if (processParameters(argc,argv,parms) == false)
    21468  { return (1) ; }
     
    21771  std::string netlibDir = parms["-netlibDir"] ;
    21872
    219 try {
    220 /*
    221   Test Osi{Row,Col}Cut routines.
    222 */
    223   {
    224     OsiClpSolverInterface clpSi;
    225     testingMessage( "Testing OsiRowCut with OsiClpSolverInterface\n" );
    226     OsiRowCutUnitTest(&clpSi,mpsDir);
    227   }
    228   {
    229     OsiClpSolverInterface clpSi;
    230     testingMessage( "Testing OsiColCut with OsiClpSolverInterface\n" );
    231     OsiColCutUnitTest(&clpSi,mpsDir);
    232   }
    233   {
    234     OsiClpSolverInterface clpSi;
    235     testingMessage( "Testing OsiRowCutDebugger with OsiClpSolverInterface\n" );
    236     OsiRowCutDebuggerUnitTest(&clpSi,mpsDir);
     73  try {
     74    /*
     75      Test Osi{Row,Col}Cut routines.
     76    */
     77    {
     78      OsiClpSolverInterface clpSi;
     79      testingMessage( "Testing OsiRowCut with OsiClpSolverInterface\n" );
     80      OsiRowCutUnitTest(&clpSi,mpsDir);
     81    }
     82    {
     83      OsiClpSolverInterface clpSi;
     84      testingMessage( "Testing OsiColCut with OsiClpSolverInterface\n" );
     85      OsiColCutUnitTest(&clpSi,mpsDir);
     86    }
     87    {
     88      OsiClpSolverInterface clpSi;
     89      testingMessage( "Testing OsiRowCutDebugger with OsiClpSolverInterface\n" );
     90      OsiRowCutDebuggerUnitTest(&clpSi,mpsDir);
     91    }
     92
     93    /*
     94      Run the OsiXXX class test. It's up to the OsiClp implementor
     95      to decide whether or not to run OsiSolverInterfaceCommonUnitTest. Arguably
     96      this should be required.
     97    */
     98    testingMessage( "Testing OsiClpSolverInterface\n" );
     99    OsiClpSolverInterfaceUnitTest(mpsDir,netlibDir);
     100
     101    /*
     102      We have run the specialised unit test. Check now to see if we need to
     103      run through the Netlib problems.
     104    */
     105    if (parms.find("-testOsiSolverInterface") != parms.end())
     106    {
     107      // Create vector of solver interfaces
     108      std::vector<OsiSolverInterface*> vecSi(1, new OsiClpSolverInterface);
     109
     110      testingMessage( "Testing OsiSolverInterface on Netlib problems.\n" );
     111      OsiSolverInterfaceMpsUnitTest(vecSi,netlibDir);
     112
     113      delete vecSi[0];
     114    }
     115    else {
     116      testingMessage( "***Skipped Testing of OsiClpSolverInterface on Netlib problems***\n" );
     117      testingMessage( "***use -testOsiSolverInterface to run them.***\n" );
     118    }
     119  } catch (CoinError& error) {
     120    std::cout.flush();
     121    std::cerr << "Caught CoinError exception: ";
     122    error.print(true);
     123    exception = true;
    237124  }
    238125
    239 /*
    240   Run the OsiXXX class test. It's up to the OsiClp implementor
    241   to decide whether or not to run OsiSolverInterfaceCommonUnitTest. Arguably
    242   this should be required.
    243 */
    244   testingMessage( "Testing OsiClpSolverInterface\n" );
    245   OsiClpSolverInterfaceUnitTest(mpsDir,netlibDir);
     126  /*
     127    We're done. Report on the results.
     128  */
     129  std::cout.flush();
     130  outcomes.print();
    246131
    247 /*
    248   We have run the specialised unit test. Check now to see if we need to
    249   run through the Netlib problems.
    250 */
    251   if (parms.find("-testOsiSolverInterface") != parms.end())
    252   {
    253     // Create vector of solver interfaces
    254     std::vector<OsiSolverInterface*> vecSi(1, new OsiClpSolverInterface);
     132  int nerrors;
     133  int nerrors_expected;
     134  outcomes.getCountBySeverity(TestOutcome::ERROR, nerrors, nerrors_expected);
    255135
    256     testingMessage( "Testing OsiSolverInterface on Netlib problems.\n" );
    257     OsiSolverInterfaceMpsUnitTest(vecSi,netlibDir);
     136  if (nerrors > nerrors_expected)
     137    std::cerr << "Tests completed with " << nerrors - nerrors_expected << " unexpected errors." << std::endl ;
     138  else
     139    std::cerr << "All tests completed successfully\n";
    258140
    259     delete vecSi[0];
    260   }
    261   else {
    262     testingMessage( "***Skipped Testing of OsiClpSolverInterface on Netlib problems***\n" );
    263     testingMessage( "***use -testOsiSolverInterface to run them.***\n" );
    264   }
    265 } catch (CoinError& error) {
    266   std::cout.flush();
    267   std::cerr << "Caught CoinError exception: ";
    268   error.print(true);
    269   totalErrCnt += 1;
     141  return (nerrors - nerrors_expected) + (exception ? 1 : 0);
    270142}
    271 /*
    272   We're done. Report on the results.
    273 */
    274   if (totalErrCnt)
    275   { std::cout.flush() ;
    276     std::cerr
    277       << "Tests completed with " << totalErrCnt << " errors." << std::endl ;
    278   } else
    279   { testingMessage("All tests completed successfully\n") ; }
    280   return totalErrCnt;
    281 }
Note: See TracChangeset for help on using the changeset viewer.