source: trunk/Clp/test/osiUnitTest.cpp @ 1687

Last change on this file since 1687 was 1663, checked in by lou, 9 years ago

Add EPL license notice in test.

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