source: stable/2.6/Cbc/test/osiUnitTest.cpp @ 1553

Last change on this file since 1553 was 1553, checked in by stefan, 9 years ago

sync with trunk rev1551, except for chgsets 1539,1540

File size: 7.9 KB
Line 
1// Copyright (C) 2000, International Business Machines
2// Corporation and others.  All Rights Reserved.
3
4#include "CoinPragma.hpp"
5
6#include "OsiConfig.h"
7
8#ifdef NDEBUG
9#undef NDEBUG
10#endif
11
12#include <cassert>
13#include <cstdio>
14#include <iostream>
15#include <map>
16
17#include "OsiUnitTests.hpp"
18
19#include "CoinError.hpp"
20
21#include "OsiCbcSolverInterface.hpp"
22
23namespace {
24
25// Display message on stdout and stderr. Flush cout buffer before printing the
26// message, so that output comes out in order in spite of buffered cout.
27
28void testingMessage( const char * const msg )
29{
30  std::cout.flush() ;
31  std::cerr <<msg;
32  //cout <<endl <<"*****************************************"
33  //     <<endl <<msg <<endl;
34}
35
36
37/*
38  Utility routine to process command line parameters. An unrecognised parameter
39  will trigger the help message and a return value of false.
40 
41  This should be replaced with the one of the standard CoinUtils parameter
42  mechanisms.
43*/
44bool processParameters (int argc, const char **argv,
45                        std::map<std::string,std::string> &parms)
46
47{
48  assert(argc >= 1);
49  assert(argv != NULL);
50/*
51  Initialise the parameter keywords.
52*/
53  std::set<std::string> definedKeyWords;
54  definedKeyWords.insert("-cerr2cout");
55  definedKeyWords.insert("-mpsDir");
56  definedKeyWords.insert("-netlibDir");
57  definedKeyWords.insert("-testOsiSolverInterface");
58  definedKeyWords.insert("-nobuf");
59/*
60  Set default values for data directories.
61*/
62  std::string dirsep(1,CoinFindDirSeparator()) ;
63  std::string upOne = ".."+dirsep ;
64  std::string pathTmp ;
65/*
66  Establish likely defaults for the Sample and Miplib directories.
67*/
68# ifdef SAMPLEDIR
69    pathTmp = SAMPLEDIR ;
70# else
71    pathTmp = upOne+upOne+"Data"+dirsep+"Sample" ;
72# endif
73  parms["-mpsDir"] = pathTmp  ;
74# ifdef NETLIBDIR
75    pathTmp = NETLIBDIR ;
76# else
77    pathTmp = upOne+upOne+"Data"+dirsep+"Netlib" ;
78# endif
79  parms["-netlibDir"] = pathTmp ;
80/*
81  Read the command line parameters and fill a map of parameter keys and
82  associated data. The parser allows for parameters which are only a keyword,
83  or parameters of the form keyword=value (no spaces).
84*/
85  for (int i = 1 ; i < argc ; i++)
86  { std::string parm(argv[i]) ;
87    std::string key,value ;
88    std::string::size_type eqPos = parm.find('=');
89
90    if (eqPos == std::string::npos)
91    { key = parm ; }
92    else
93    { key = parm.substr(0,eqPos) ;
94      value = parm.substr(eqPos+1) ; }
95/*
96  Is the specifed key valid?
97*/
98    if (definedKeyWords.find(key) == definedKeyWords.end())
99    { std::cerr << "Undefined parameter \"" << key << "\"." << std::endl ;
100      std::cerr
101        << "Usage: " << argv[0]
102        << " [-nobuf] [-mpsDir=V1] [-netlibDir=V2] "
103        << "[-testOsiSolverInterface] " << std::endl ;
104      std::cerr << "  where:" << std::endl ;
105      std::cerr
106        << "    "
107        << "-cerr2cout: redirect cerr to cout; sometimes useful." << std::endl
108        << "\t" << "to synchronise cout & cerr." << std::endl ;
109      std::cerr
110        << "    "
111        << "-mpsDir: directory containing mps test files." << std::endl
112        << "\t" << "Default value V1=\"../../Data/Sample\"" << std::endl ;
113      std::cerr
114        << "    "
115        << "-netlibDir: directory containing netlib files." << std::endl
116        << "\t" << "Default value V2=\"../../Data/Netlib\"" << std::endl ;
117      std::cerr
118        << "    "
119        << "-testOsiSolverInterface: "
120        << "run each OSI on the netlib problem set." << std::endl
121        << "\t"
122        << "Default is to not run the netlib problem set." << std::endl ;
123      std::cerr
124        << "    "
125        << "-nobuf: use unbuffered output." << std::endl
126        << "\t" << "Default is buffered output." << std::endl ;
127     
128      return (false) ; }
129/*
130  Valid keyword; stash the value for later reference.
131*/
132    parms[key]=value ; }
133/*
134  Tack the directory separator onto the data directories so we don't have to
135  worry about it later.
136*/
137  parms["-mpsDir"] += dirsep ;
138  parms["-netlibDir"] += dirsep ;
139/*
140  Did the user request unbuffered i/o? It seems we need to go after this
141  through stdio --- using pubsetbuf(0,0) on the C++ streams has no
142  discernible affect. Nor, for that matter, did setting the unitbuf flag on
143  the streams. Why? At a guess, sync_with_stdio connects the streams to the
144  stdio buffers, and the C++ side isn't programmed to change them?
145*/
146  if (parms.find("-nobuf") != parms.end())
147  { // std::streambuf *coutBuf, *cerrBuf ;
148    // coutBuf = std::cout.rdbuf() ;
149    // coutBuf->pubsetbuf(0,0) ;
150    // cerrBuf = std::cerr.rdbuf() ;
151    // cerrBuf->pubsetbuf(0,0) ;
152    setbuf(stderr,0) ;
153    setbuf(stdout,0) ; }
154/*
155  Did the user request a redirect for cerr? This must occur before any i/o is
156  performed.
157*/
158  if (parms.find("-cerr2cout") != parms.end())
159  { std::cerr.rdbuf(std::cout.rdbuf()) ; }
160
161  return (true) ; }
162
163
164}       // end file-local namespace
165
166
167
168//----------------------------------------------------------------
169// unitTest [-nobuf] [-mpsDir=V1] [-netlibDir=V2] [-testOsiSolverInterface]
170//
171// where:
172//   -nobuf: remove buffering on cout (stdout); useful to keep cout and cerr
173//       messages synchronised when redirecting output to a file or pipe.
174//   -mpsDir: directory containing mps test files
175//       Default value V1="../../Data/Sample"   
176//   -netlibDir: directory containing netlib files
177//       Default value V2="../../Data/Netlib"
178//   -testOsiSolverInterface
179//       If specified, then OsiSolveInterface::unitTest
180//       is skipped over and not run.
181//
182// All parameters are optional.
183//----------------------------------------------------------------
184
185int main (int argc, const char *argv[])
186
187{ int totalErrCnt = 0;
188
189/*
190  Start off with various bits of initialisation that don't really belong
191  anywhere else.
192
193  First off, synchronise C++ stream i/o with C stdio. This makes debugging
194  output a bit more comprehensible. It still suffers from interleave of cout
195  (stdout) and cerr (stderr), but -nobuf deals with that.
196*/
197  std::ios::sync_with_stdio() ;
198/*
199  Suppress an popup window that Windows shows in response to a crash. See
200  note at head of file.
201*/
202  WindowsErrorPopupBlocker();
203/*
204  Process command line parameters.
205*/
206  std::map<std::string,std::string> parms ;
207
208  if (processParameters(argc,argv,parms) == false)
209  { return (1) ; }
210
211  std::string mpsDir = parms["-mpsDir"] ;
212  std::string netlibDir = parms["-netlibDir"] ;
213
214try {
215/*
216  Test Osi{Row,Col}Cut routines.
217*/
218  {
219    OsiCbcSolverInterface cbcSi;
220    testingMessage( "Testing OsiRowCut with OsiCbcSolverInterface\n" );
221    OsiRowCutUnitTest(&cbcSi,mpsDir);
222  }
223  {
224    OsiCbcSolverInterface cbcSi;
225    testingMessage( "Testing OsiColCut with OsiCbcSolverInterface\n" );
226    OsiColCutUnitTest(&cbcSi,mpsDir);
227  }
228  {
229    OsiCbcSolverInterface cbcSi;
230    testingMessage( "Testing OsiRowCutDebugger with OsiCbcSolverInterface\n" );
231    OsiRowCutDebuggerUnitTest(&cbcSi,mpsDir);
232  }
233
234/*
235  Run the OsiXXX class test. It's up to the OsiCbc implementor
236  to decide whether or not to run OsiSolverInterfaceCommonUnitTest. Arguably
237  this should be required.
238*/
239  testingMessage( "Testing OsiCbcSolverInterface\n" );
240  OsiCbcSolverInterfaceUnitTest(mpsDir,netlibDir);
241
242/*
243  We have run the specialised unit test. Check now to see if we need to
244  run through the Netlib problems.
245*/
246  if (parms.find("-testOsiSolverInterface") != parms.end())
247  {
248    // Create vector of solver interfaces
249    std::vector<OsiSolverInterface*> vecSi(1, new OsiCbcSolverInterface);
250
251    testingMessage( "Testing OsiSolverInterface on Netlib problems.\n" );
252    OsiSolverInterfaceMpsUnitTest(vecSi,netlibDir);
253
254    delete vecSi[0];
255  }
256  else {
257    testingMessage( "***Skipped Testing of OsiCbcSolverInterface on Netlib problems***\n" );
258    testingMessage( "***use -testOsiSolverInterface to run them.***\n" );
259  }
260} catch (CoinError& error) {
261  std::cout.flush();
262  std::cerr << "Caught CoinError exception: ";
263  error.print(true);
264  totalErrCnt += 1;
265}
266/*
267  We're done. Report on the results.
268*/
269  if (totalErrCnt)
270  { std::cout.flush() ;
271    std::cerr
272      << "Tests completed with " << totalErrCnt << " errors." << std::endl ; 
273  } else
274  { testingMessage("All tests completed successfully\n") ; }
275  return totalErrCnt;
276}
Note: See TracBrowser for help on using the repository browser.