source: trunk/Cbc/test/osiUnitTest.cpp @ 1620

Last change on this file since 1620 was 1620, checked in by stefan, 10 years ago

add include to cope with changes in Osi/trunk unittest

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