OSSIM - Open Source Software Image Map  Version 1.9.0 (20180803)
ossimBatchTest.cpp
Go to the documentation of this file.
1 //----------------------------------------------------------------------------
2 //
3 // File ossim-batch-test.cpp
4 //
5 // License: See top level LICENSE.txt file.
6 //
7 // Author: David Burken, Oscar Kramer
8 //
9 // Description: Test code application ossim batch test.
10 //
11 //----------------------------------------------------------------------------
12 // $Id: ossim-batch-test.cpp 3112 2012-01-26 17:28:00Z david.burken $
13 
20 #include <ossim/base/ossimNotify.h>
21 #include <ossim/base/ossimString.h>
22 #include <ossim/base/ossimTimer.h>
23 #include <ossim/init/ossimInit.h>
24 
25 #include <cstdlib> /* for system() */
26 #include <ctime>
27 #include <iomanip>
28 #include <iostream>
29 #include <string>
30 #include <sstream>
31 
32 using namespace std;
33 
34 //**************************************************************************************************
35 // Constructor
36 //**************************************************************************************************
38  :
39  m_acceptTestList(),
40  m_cleanTestList(),
41  m_preprocessTestList(),
42  m_runTestList(),
43  m_templateModeActive(false),
44  m_configFileName(),
45  m_outDir(),
46  m_expDir(),
47  m_logStr()
48 {
49  typedef std::map<ossim_uint32, std::string>::value_type map_item;
50  m_statusLabels.insert(map_item(TEST_TBD, "UNKNOWN"));
51  m_statusLabels.insert(map_item(TEST_PASSED, "PASSED"));
52  m_statusLabels.insert(map_item(TEST_FAILED, "FAILED"));
53  m_statusLabels.insert(map_item(TEST_ERROR, "ERROR"));
54  m_statusLabels.insert(map_item(TEST_DISABLED, "DISABLED"));
55  m_statusLabels.insert(map_item(TEST_PASSED|TEST_FAILED, "FAILURE ENCOUNTERED"));
56  m_statusLabels.insert(map_item(TEST_PASSED|TEST_ERROR, "ERROR ENCOUNTERED"));
57  m_statusLabels.insert(map_item(TEST_FAILED|TEST_ERROR, "FAILURE AND ERROR ENCOUNTERED"));
58  m_statusLabels.insert(map_item(TEST_PASSED|TEST_FAILED|TEST_ERROR, "FAILURE AND ERROR ENCOUNTERED"));
59 }
60 
61 //**************************************************************************************************
62 // Initialize parses the command line. Returns true if status OK.
63 //**************************************************************************************************
65 {
66  if ( (ap.argc() == 1) || ap.read("-h") || ap.read("--help") )
67  {
68  usage(ap);
69 
70  // continue_after_init to false
71  return false;
72  }
73 
74  // Initialize environment:
75 #if defined(_WIN32) || defined(_MSC_VER) && !defined(__CYGWIN__) && !defined(__MWERKS__)
76  _putenv("DEL_CMD=del /Q"); // For backwards compatiblity.
77  _putenv("DIFF_CMD=fc /W");
78  _putenv("COPY_CMD=copy /Y");
79  _putenv("MKDIR_CMD=mkdir");
80  _putenv("RM_CMD=del /Q");
81  _putenv("RMDIR_CMD=rmdir /S /Q");
82 
83 #else
84  setenv("DEL_CMD", "rm -rf", 1); // For backwards compatiblity.
85  setenv("DIFF_CMD", "diff -w", 1);
86  setenv("COPY_CMD", "cp", 1);
87  setenv("MKDIR_CMD", "mkdir -p", 1);
88  setenv("RM_CMD", "rm -f", 1);
89  setenv("RMDIR_CMD", "rm -rf", 1);
90 
91 #endif
92 
93  std::string tempString;
94  ossimArgumentParser::ossimParameter stringParam(tempString);
95 
96  if (ap.read("-W", stringParam) || ap.read("-W"))
97  {
98  ossimFilename templateFile (tempString.c_str());
99  if (templateFile.empty())
100  templateFile = "obt_config_long_template.kwl";
101  m_templateModeActive = true;
102  writeTemplate(templateFile, true);
103  return true;
104  }
105  if (ap.read("-w", stringParam) || ap.read("-w"))
106  {
107  ossimFilename templateFile(tempString.c_str());
108  if (templateFile.empty())
109  templateFile = "obt_config_short_template.kwl";
110  m_templateModeActive = true;
111  writeTemplate(templateFile, false);
112  return true;
113  }
114 
115  while ( ap.read("-a", stringParam) || ap.read("--accept-test", stringParam) )
116  {
117  if ( tempString.size() )
118  {
119  ossimString os = tempString;
120  ossimString separatorList = " ";
121  std::vector<ossimString> result;
122  os.split(result, separatorList);
123  std::vector<ossimString>::const_iterator i = result.begin();
124  while ( i != result.end() )
125  {
126  m_acceptTestList.push_back((*i));
127  ++i;
128  }
129  }
130  }
131 
132  while ( ap.read("-c", stringParam) || ap.read("--clean-test", stringParam) )
133  {
134  if ( tempString.size() )
135  {
136  ossimString os = tempString;
137  ossimString separatorList = " ";
138  std::vector<ossimString> result;
139  os.split(result, separatorList);
140  std::vector<ossimString>::const_iterator i = result.begin();
141  while ( i != result.end() )
142  {
143  m_cleanTestList.push_back((*i));
144  ++i;
145  }
146  }
147  }
148 
149  while ( ap.read("-p", stringParam) || ap.read("--preprocess-test", stringParam) )
150  {
151  if ( tempString.size() )
152  {
153  ossimString os = tempString;
154  ossimString separatorList = " ";
155  std::vector<ossimString> result;
156  os.split(result, separatorList);
157  std::vector<ossimString>::const_iterator i = result.begin();
158  while ( i != result.end() )
159  {
160  m_preprocessTestList.push_back((*i));
161  ++i;
162  }
163  }
164  }
165 
166  while ( ap.read("-r", stringParam) || ap.read("--run-test", stringParam) )
167  {
168  if ( tempString.size() )
169  {
170  ossimString os = tempString;
171  ossimString separatorList = " ";
172  std::vector<ossimString> result;
173  os.split(result, separatorList);
174  std::vector<ossimString>::const_iterator i = result.begin();
175  while ( i != result.end() )
176  {
177  m_runTestList.push_back((*i));
178  ++i;
179  }
180  }
181  }
182 
183  // End of arg parsing.
185  if ( ap.errors() )
186  {
188  return false;
189  }
190 
191  if (ap.argc() > 1 )
192  {
193  m_configFileName = ap.argv()[1];
194  }
195  else
196  {
197  usage(ap);
198 
199  // continue_after_init to false
200  return false;
201  }
202 
203  // Special command line case: When only a config filename is provided, this implies "run all
204  // tests".
205  if (m_cleanTestList.empty() && m_preprocessTestList.empty() &&
206  m_acceptTestList.empty() && m_runTestList.empty() && m_configFileName.size())
207  {
208  m_runTestList.push_back("all");
209  }
210 
211  return true;
212 }
213 
214 //---
215 // Writes a template (either long form or short) to the file name specified.
216 //---
217 void ossimBatchTest::writeTemplate(const ossimFilename& templateFile, bool write_long_form)
218 {
219  if (templateFile.exists())
220  {
221  ossimString del_cmd ("$(RM_CMD) ");
222  del_cmd += templateFile;
223  del_cmd = del_cmd.expandEnvironmentVariable();
224  if (system(del_cmd.chars()) != 0)
225  {
226  cerr << "ERROR: Could not delete existing template file before writing new template."
227  " Please delete the existing and rerun the command."<< endl;
228  return;
229  }
230  }
231 
232  std::ofstream out(templateFile.c_str());
233  if ( !out.good() )
234  {
236  << "Could not open: " << templateFile.c_str() << std::endl;
237  return;
238  }
239 
240  if (write_long_form)
241  {
242  out<< "//===================================================================================\n"
243  << "// \n"
244  << "// File: " << templateFile.c_str() << "\n"
245  << "// Generated by command: ossim-batch-test -W " << templateFile.c_str() << "\n"
246  << "// Description: ossim-batch-test template config file.\n"
247  << "// \n"
248  << "// Control flags:\n"
249  << "// Use 1 or true, 0 or false to turn on and off sections.\n"
250  << "// Typically preprocess and expected results only turned on for first run.\n"
251  << "// Clean commands should erase anything created by this test.\n"
252  << "// Command order if flag turned on:\n"
253  << "// 1) clean, 2) pre-process, 3) expected, 4) test, 5) post-process\n"
254  << "// \n"
255  << "// NOTES:\n"
256  << "// * The following environment variables must be set before running batch test:\n"
257  << "// OSSIM_BATCH_TEST_DATA Top-level dir containing all test source data\n"
258  << "// OSSIM_BATCH_TEST_EXPECTED Top-level dir containing all test expected results \n"
259  << "// OSSIM_BATCH_TEST_RESULTS Top-level dir containing all test results and logging output \n"
260  << "// \n"
261  << "// * The variables OBT_EXP_DIR and OBT_OUT_DIR are assigned during run-time to\n"
262  << "// the proper paths according to the config filename. It isn't required to replace\n"
263  << "// these nor predefine them in the environment. You can leave them as is or modify\n"
264  << "// the paths to your unconventional file paths.\n"
265  << "// \n"
266  << "// * In order to preserve platform independence, please utilize the following \n"
267  << "// variables for the common OS commands when adding new commands to the test\n"
268  << "// configuration KWL file. Examples are provided in this template\n"
269  << "// $(DIFF_CMD) Use this var for windows \"fc\" or linux \"diff\"\n"
270  << "// $(COPY_CMD) Use this var for windows \"copy\" or linux \"cp\"\n"
271  << "// $(MKDIR_CMD) Use this var for windows \"mkdir\" or linux \"mkdir\"\n"
272  << "// $(RM_CMD) Use this var for windows \"del /Q\" or linux \"rm -f\"\n"
273  << "// $(RMDIR_CMD) Use this var for windows \"rmdir /S /Q\" or linux \"rm -rf\"\n"
274  << "// This application will set the environment variables to the proper values at \n"
275  << "// runtime, so no need to worry about defining these.\n"
276  << "// \n"
277  << "// * Use forward slashes \"//\", at beginning of line for comments.\n"
278  << "// \n"
279  << "// * You can use existing environment variables as $(YOUR_VARIABLE). They will be \n"
280  << "// expanded at run time if valid.\n"
281  << "// \n"
282  << "// * Clean, preprocess, run, and accept test sections can be switched on or off\n"
283  << "// at run time. These override config file flags. Optional arguments are the \n"
284  << "// the following: \n"
285  << "// -c or --clean-test \n"
286  << "// -p or --preprocess-test\n"
287  << "// -r or --run-test \n"
288  << "// -a or --accept-test \n"
289  << "// Multiple tests can be entered by quoting string of space-separated\n"
290  << "// test names, e.g. \"test1 test2\". To do all tests use \"all\" or leave blank.\n"
291  << "// \n"
292  << "//===================================================================================\n"
293  << "\n"
294  << "// If the config file will contain only a list of subordinate config files to be\n"
295  << "// run as one consolidated \"super-test\", then use only the following suffixed\n"
296  << "// keywords. Otherwise, REMOVE THESE:\n"
297  << "test_config_file1: <my_first_test_config.kwl>\n"
298  << "test_config_file2: <my_second_test_config.kwl>\n"
299  << "// ... etc.\n"
300  << "\n"
301  << "// The remaining keywords are used exclusive of \"test_config_fileX\" above. The\n"
302  << "// config files must be either a list of subordinate configs, or a concrete, \n"
303  << "// low-level config file.\n"
304  << "\n"
305  << "// Where you want the top-level (inter-test) log files to go:\n"
306  << "log_directory: $(OBT_OUT_DIR)\\..\\log\n"
307  << "\n"
308  << "//===================================================================================\n"
309  << "// Begin Test 1\n"
310  << "// NOTE: If the config file contains just a single test, then the use of the \"test1\"\n"
311  << "// prefix is optional. Make sure the results directory spec reflects the proper path.\n"
312  << "\n"
313  << "test1.name: <YOUR_TEST_NAME>\n"
314  << "test1.description: Test height for the center of the image for test2 and test3.\n"
315  << "\n"
316  << "// Controls/turns on/off whole test (all sections):\n"
317  << "test1.enabled: 1\n"
318  << "\n"
319  << "// Individual control flags:\n"
320  << "test1.run_clean_commands: 0\n"
321  << "test1.run_preprocessing_commands: 0\n"
322  << "test1.run_expected_results_commands: 0\n"
323  << "test1.run_test_commands: 1\n"
324  << "test1.run_postprocessing_commands: 1\n"
325  << "\n"
326  << "// Temp file to catch diff output.\n"
327  << "test1.temp_file: $(TEMP)\\tmp.txt\n"
328  << "\n"
329  << "// Clean up commands\n"
330  << "test1.clean_command1: $(RMDIR_CMD) $(OBT_OUT_DIR)\n"
331  << "\n"
332  << "// Pre-process commands\n"
333  << "test1.preprocess_command1: $(MKDIR_CMD) $(OBT_OUT_DIR)\n"
334  << "test1.preprocess_command1: $(MKDIR_CMD) $(OBT_OUT_DIR)\\..\\log\n"
335  << "\n"
336  << "//---------------------------------------\n"
337  << "// Commands to generate expected results\n"
338  << "//---------------------------------------\n"
339  << "// Since test2 and test3 are dependent on elevation test the center of the image.\n"
340  << "test1.expected_results_command0: ossim-info --height -42.8508 147.2537 > $(OBT_EXP_DIR)\\height.txt\n"
341  << "test1.expected_results_command1: $(COPY_CMD) $(OBT_OUT_DIR)\\height.txt $(OBT_EXP_DIR)\\height.txt\n"
342  << "\n"
343  << "//---------------------------------------\n"
344  << "// The actual commands to test\n"
345  << "//---------------------------------------\n"
346  << "test1.test_command0: ossim-info --height -42.8508 147.2537 > $(OBT_OUT_DIR)\\height.txt\n"
347  << "\n"
348  << "//-------------------------------------------\n"
349  << "// Post process commands for diffs, etc.\n"
350  << "//-------------------------------------------\n"
351  << "test1.postprocess_command0: $(DIFF_CMD) $(OBT_EXP_DIR)\\height.txt $(OBT_OUT_DIR)\\height.txt\n"
352  << " \n"
353  << "\n"
354  << "// End <TEST_NAME>\n"
355  << "//===================================================================================\n"
356  << "// Begin <TEST2_NAME>...\n"
357  << "\n"
358  << "// You can specify additional tests by copying the test1 keywords and changing the\n"
359  << "// prefix indices to be unique. It is not necessary to be consecutive.\n"
360  << "\n"
361  << std::endl;
362  }
363  else
364  {
365  out<< "//===================================================================================\n"
366  << "// \n"
367  << "// File: " << templateFile.c_str() << "\n"
368  << "// Generated by command: ossim-batch-test -w " << templateFile.c_str() << "\n"
369  << "// Description: ossim-batch-test template config file.\n"
370  << "// \n"
371  << "// NOTES:\n"
372  << "// * The following environment variables must be set before running batch test:\n"
373  << "// OSSIM_BATCH_TEST_DATA Top-level dir containing all test source data\n"
374  << "// OSSIM_BATCH_TEST_EXPECTED Top-level dir containing all test expected results \n"
375  << "// OSSIM_BATCH_TEST_RESULTS Top-level dir containing all test results and logging output \n"
376  << "// \n"
377  << "// * You can use existing environment variables as $(YOUR_VARIABLE). They will be \n"
378  << "// expanded at run time if valid.\n"
379  << "// \n"
380  << "// * If the config file contains more than a single test, then it will be necessary \n"
381  << "// to prefix all test-specific keywords with \"testN.\"\n"
382  << "// \n"
383  << "// * The variables OBT_EXP_DIR and OBT_OUT_DIR are assigned during runtime to\n"
384  << "// the proper paths according to the config filename. It isn't required to replace\n"
385  << "// these nor predefine them in the environment. You can leave them as is or modify\n"
386  << "// the paths to your unconventional file paths.\n"
387  << "// \n"
388  << "//===================================================================================\n"
389  << "\n"
390  << "description: Test height for the center of the image for test2 and test3.\n"
391  << "\n"
392  << "//---------------------------------------\n"
393  << "// Commands to generate expected results.\n"
394  << "//---------------------------------------\n"
395  << "expected_results_command0: ossim-info --height -42.8508 147.2537 > $(OBT_OUT_DIR)\\height.txt\n"
396  << "expected_results_command1: $(COPY_CMD) $(OBT_OUT_DIR)\\height.txt $(OBT_EXP_DIR)\\height.txt\n"
397  << "\n"
398  << "//---------------------------------------\n"
399  << "// The actual commands to test.\n"
400  << "//---------------------------------------\n"
401  << "test_command0: ossim-info --height -42.8508 147.2537 > $(OBT_OUT_DIR)\\height.txt\n"
402  << "\n"
403  << "//---------------------------------------\n"
404  << "// The post-processing (comparison) commands. Typically these involve a file \n"
405  << "// comparison of last run command against expected results.\n"
406  << "//---------------------------------------\n"
407  << "postprocess_command0: $(DIFF_CMD) $(OBT_EXP_DIR)\\height.txt $(OBT_OUT_DIR)\\height.txt\n"
408  << std::endl;
409  }
410 
411  out.close();
412  ossimNotify(ossimNotifyLevel_NOTICE) << "Wrote file: " << templateFile.c_str() << std::endl;
413 }
414 
415 //**************************************************************************************************
416 // Processes a test config file
417 //**************************************************************************************************
419 {
421  {
422  return TEST_PASSED;
423  }
424 
426 
428  cout << "\nExecuting batch test for config: <" << configName << ">" << endl;
429 
430  try
431  {
433 
434  // Fetch possible existing env vars for the expected and output directories:
435  ossimFilename base_output_dir =
436  ossimEnv->getEnvironmentVariable(ossimString("OSSIM_BATCH_TEST_RESULTS"));
437  if (base_output_dir.empty())
438  {
439  // Need to establish the top-level test directory that will contain log and out subdirs:
440  cout<<"\nossimBatchTest WARNING: The environment variable OSSIM_BATCH_TEST_RESULTS is not "
441  "defined. Results will be written relative to the current working directory."<<endl;
442  base_output_dir = ossimEnv->getCurrentWorkingDir();
443  }
444 
445  // The base output directory is appended with the name of the test config file. Need to export
446  // the corresponding env var so that the KeywordList class can expand the same env var used
447  // in the config file:
448  base_output_dir = base_output_dir.dirCat(configName);
449  m_outDir = base_output_dir.dirCat("out");
450  ossimEnv->setEnvironmentVariable("OBT_OUT_DIR", m_outDir.chars());
451 
452  m_expDir = ossimEnv->getEnvironmentVariable(ossimString("OSSIM_BATCH_TEST_EXPECTED"));
453  if (m_expDir.empty())
454  {
455  // Need to establish the top-level test directory that will contain expected results:
456  m_expDir = base_output_dir.dirCat("exp");
457  }
458  else
459  {
460  m_expDir = m_expDir.dirCat(configName);
461  }
462  ossimEnv->setEnvironmentVariable("OBT_EXP_DIR", m_expDir.chars());
463 
464  // Turn expansion of for like: $(OBT_TEST_RESULTS)
465  ossimKeywordlist kwl;
466  kwl.setExpandEnvVarsFlag(true);
467  if (!kwl.addFile(m_configFileName))
468  {
469  ostringstream errmsg;
470  errmsg << "Error encountered reading test config at <"<<m_configFileName<<">."<<endl;
471  throw ossimException(errmsg.str());
472  }
473 
474  // The KWL may contain names of other test config files. Is this a list of config files? If the
475  // status returns anything other than TBD, then a list was present and processed:
476  status = processConfigList(kwl);
477  if (status != TEST_TBD)
478  {
479  cout<<"\nossimBatchTest: Exiting <"<<configName<<"> with overall status = "
480  <<m_statusLabels[status]<<"\n"<<endl;
481  return status;
482  }
483 
484  // Pick up individual test options passed in by user. These will adjust the keyword list
485  // flags loaded in memory.
486  if ( m_cleanTestList.size() ) // Do this first always...
487  {
488  std::string testCommand = "run_clean_commands";
489  preprocessKwl(m_cleanTestList, testCommand, kwl);
490  }
491 
492  if ( m_preprocessTestList.size() )
493  {
494  std::string testCommand = "run_preprocessing_commands";
495  preprocessKwl(m_preprocessTestList, testCommand, kwl);
496  }
497 
498  if ( m_acceptTestList.size() )
499  {
500  std::string testCommand = "run_expected_results_commands";
501  preprocessKwl(m_acceptTestList, testCommand, kwl);
502  }
503 
504  if ( m_runTestList.size() ) // Do this last always...
505  {
506  std::string testCommand = "run_test_commands";
507  preprocessKwl(m_runTestList, testCommand, kwl);
508  }
509 
510  ossimFilename logDir = base_output_dir.dirCat("log");
511  const char* lookup = kwl.find("log_directory");
512  if ( lookup )
513  {
514  logDir = convertToNative( lookup ).c_str();
515  }
516 
517  if (( logDir.exists() == false ) && ( logDir.createDirectory() == false ))
518  {
519  status = TEST_ERROR;
520  ostringstream errmsg;
521  errmsg << "Could not create: <" << logDir << ">."<< endl;
522  throw ossimException(errmsg.str());
523  }
524 
525  // Establish path to and active stream for the log file:
526  ossimFilename logFile;
527  getLogFilename(logFile);
528  logFile = logDir.dirCat(logFile);
529  ossimSetLogFilename(logFile);
530  m_logStr.open(logFile.c_str());
531  if ( m_logStr.fail() )
532  {
533  status = TEST_ERROR;
534  ostringstream errmsg;
535  errmsg << "Could not open: <" << logFile << ">."<< endl;
536  throw ossimException(errmsg.str());
537  }
538 
539  cout << "Logging to file: " << logFile << "\n";
540 
541  ossimString date;
542  getDateString(date);
543  m_logStr << "// ---\n"
544  << "// ossim-batch-test log:\n"
545  << "// date format = yyyymmddhhmmss\n"
546  << "//---\n"
547  << "start_time: " << date << "\n"
548  << "config_file: " << m_configFileName<< "\n";
549  // Start the timer.
551 
552  double startTime = ossimTimer::instance()->time_s();
553 
554 
555  ossimString regExpStr = "test[0-9]+\\.";
556  std::vector<ossimString> prefixes;
557  kwl.getSubstringKeyList(prefixes, regExpStr);
558 
559  // If no test prefix is used, this implies a single test:
560  if (prefixes.empty())
561  prefixes.push_back("");
562 
563  status = TEST_TBD;
564  for(ossim_uint32 idx = 0; idx < prefixes.size(); ++idx)
565  {
566  ossim_uint8 individual_test_status = processTest( prefixes[idx], kwl);
567  status |= individual_test_status;
568  }
569 
570  getDateString(date);
571  m_logStr << "\nstop_time: " << date << "\n";
572  double stopTime = ossimTimer::instance()->time_s();
573  m_logStr << "total elapsed time in seconds: "
574  << std::setiosflags(ios::fixed) << std::setprecision(4)
575  << (stopTime-startTime)
576  << endl; // flush
577  m_logStr.close();
578 
579  cout << "\ntotal elapsed time in seconds: "
580  << std::setiosflags(ios::fixed) << std::setprecision(4)
581  << (stopTime-startTime)
582  << "\nWrote log: " << logFile << "\n" << endl;
583  }
584  catch (ossimException& e)
585  {
586  status = TEST_ERROR;
587  cerr << "\nossimBatchTest::execute() caught exception: " << e.what() << endl;
588  }
589  catch ( ... )
590  {
591  cerr << "\nossimBatchTest::execute() caught unhandled exception: " << endl;
592  }
593 
594  cout<<"ossimBatchTest: Exiting <"<<configName<<"> with status = "
595  <<m_statusLabels[status]<<endl;
596 
597  return status;
598 }
599 
600 //************************************************************************************************
601 // Special handler for KWL containing list of test config files.
602 //************************************************************************************************
604 {
605  ossim_uint8 overall_test_status = TEST_TBD;
606  ossimFilename config_list_path = m_configFileName.path();
607 
608  ossimString keywordRegEx = "test_config_file[0-9]+";
609  std::vector<ossimString> keywords;
610  kwl.getSubstringKeyList(keywords, keywordRegEx);
611 
612  for(ossim_uint32 idx=0;idx < (ossim_uint32)keywords.size(); ++idx)
613  {
614  // Looping over each config file listed, performing an execute() on each:
615  m_configFileName = kwl.findKey(keywords[idx]);
616 
617  if (!m_configFileName.empty())
618  {
619  // Expand any environment variable:
620  if (m_configFileName.contains("$("))
622 
623  // Handle paths relative to the master config list file:
624  if (m_configFileName.path().empty())
625  m_configFileName = m_configFileName.setPath(config_list_path);
626  }
627 
628  // Execute this config file:
630  {
631  overall_test_status |= execute();
632  }
633  }
634 
635  return overall_test_status;
636 }
637 
638 //************************************************************************************************
640 //************************************************************************************************
642 {
643  time_t t;
644  time(&t);
645  tm* lt;
646  lt = localtime(&t);
647  std::string frmt = "%Y%m%d%H%M%S";
648  // yyyymmddhhmmss
649  char s[15];
650  size_t count = strftime(s, 15, frmt.c_str(), lt);
651  if ( count && (count < 15) )
652  date = s;
653  else
654  date.clear();
655 
656 }
657 
658 //**************************************************************************************************
660 //**************************************************************************************************
662 {
663  logFile = "obt-log-";
664  ossimString date;
665  getDateString(date);
666  logFile += date;
667  logFile += ".txt";
668 }
669 
670 //**************************************************************************************************
673 //**************************************************************************************************
675 {
676  ossim_uint8 testStatus = TEST_TBD;
677 
678  // Determine first if this test prefix is represented in the KWL:
679  if (kwl.getNumberOfSubstringKeys(prefix) == 0)
680  return testStatus;
681 
682  ossimString testName;
683  const char* lookup = kwl.find( prefix, "name" );
684  if ( lookup )
685  {
686  testName = lookup;
687  }
688  if (testName.empty())
689  {
690  if (prefix.empty())
691  testName = m_configFileName.fileNoExtension();
692  else
693  testName = prefix.trim(".");
694  }
695 
696  m_logStr << "\n----------------------------------------------------------------------\n";
697 
698  // See if test is disabled/enabled:
699 
700  bool enabled = true;
701  lookup = kwl.find( prefix, "enabled" );
702  if ( lookup )
703  {
704  enabled = ossimString(lookup).toBool();
705  }
706 
707  if ( !enabled )
708  {
709  testStatus = TEST_DISABLED;
710  ossimString statusString;
711  if ( prefix.size() )
712  {
713  statusString = prefix.trim(ossimString(".")) + ossimString(": disabled");
714  }
715  else
716  {
717  statusString = "test: disabled";
718  }
719  cout << "test_name: " << testName << "\n" << statusString << endl;
720  m_logStr << "test_name: " << testName << "\n" << statusString << endl;
721  return testStatus;
722  }
723 
724  cout << "\n\nbegin_test:\n" << prefix << "name: " << testName << "\n";
725  m_logStr << "\n\nbegin_test:\n" << prefix << "name: " << testName << "\n";
726  lookup = kwl.find( prefix, "description" );
727  if ( lookup )
728  m_logStr << "description: " << lookup << "\n";
729 
730  bool preProcessFlag = false;
731  bool expectedFlag = false;
732  bool testFlag = false;
733  bool postProcessFlag = false;
734  bool cleanFlag = false;
735  std::string date;
736 
737  lookup = kwl.find(prefix.c_str(), "run_clean_commands");
738  if ( lookup )
739  {
740  cleanFlag = ossimString(lookup).toBool();
741  }
742 
743  lookup = kwl.find(prefix.c_str(), "run_preprocessing_commands");
744  if ( lookup )
745  {
746  preProcessFlag = ossimString(lookup).toBool();
747  }
748 
749  lookup = kwl.find(prefix.c_str(), "run_expected_results_commands");
750  if ( lookup )
751  {
752  expectedFlag = ossimString(lookup).toBool();
753  }
754 
755  lookup = kwl.find(prefix.c_str(), "run_test_commands");
756  if ( lookup )
757  {
758  testFlag = ossimString(lookup).toBool();
759  }
760 
761  lookup = kwl.find(prefix.c_str(), "run_postprocessing_commands");
762  if ( lookup )
763  {
764  postProcessFlag = ossimString(lookup).toBool();
765  }
766 
767  m_logStr << "preProcessFlag: " << preProcessFlag
768  << "\nexpectedFlag: " <<expectedFlag
769  << "\ntestFlag: " <<testFlag
770  << "\npostProcessFlag: " <<postProcessFlag
771  << "\ncleanFlag: " <<cleanFlag
772  << "\n";
773 
774  // Run the clean first if set...
775  if ( cleanFlag )
776  {
777  ossimString prefixBase = prefix + "clean_command";
778  testStatus |= processCommands( prefixBase, kwl, testName, false );
779  }
780 
781  if ( preProcessFlag && !(testStatus & TEST_ERROR))
782  {
783  ossimString prefixBase = prefix + "preprocess_command";
784  testStatus |= processCommands( prefixBase, kwl, testName, false );
785  }
786  if ( expectedFlag && !(testStatus & TEST_ERROR))
787  {
788  ossimString prefixBase = prefix + "expected_results_command";
789  testStatus |= processCommands( prefixBase, kwl, testName, true );
790  }
791  if ( testFlag && !(testStatus & TEST_ERROR))
792  {
793  ossimString prefixBase = prefix + "test_command";
794  testStatus |= processCommands( prefixBase, kwl, testName, true );
795  }
796  if ( postProcessFlag && !(testStatus & TEST_ERROR))
797  {
798  ossimFilename tempFile;
799 
800  if ( getTempFileName( prefix, kwl, tempFile ) )
801  {
802  ossimString prefixBase = prefix + "postprocess_command";
803  testStatus |= processCommands( prefixBase, kwl, testName, false, tempFile );
804  }
805  else
806  {
807  m_logStr << testName << ": ERROR temp file could not be derived..." << endl;
808  testStatus |= TEST_ERROR; // Set an error bit...
809  }
810  }
811 
812  cout << "end_test:\n";
813  m_logStr << "end_test:\n";
814 
815  m_logStr << "----------------------------------------------------------------------\n";
816  return testStatus;
817 }
818 
819 //**************************************************************************************************
821  const ossimKeywordlist& kwl,
822  const ossimString& testName,
823  bool logTime,
824  const ossimFilename& tempFileName)
825 {
826  ossim_uint8 result = TEST_TBD;
827 
828  //---
829  // We must do these in order so we will use the
830  // ossimKeywordlist::getNumberOfSubstringKeys
831  // instead of: ossimKeywordlist::getSubstringKeyList
832  //
833  // MAX_INDEX is just so people can skip numbers in their config file like:
834  // test1.command
835  // test3.command oops...
836  //---
837  ossimString regExpStr = prefixBase + "[0-9]+";
838  const ossim_uint32 num_commands = kwl.getNumberOfSubstringKeys(regExpStr);
839  const ossim_uint32 MAX_INDEX = num_commands + 1000;
840 
841  // Hack to permit defaulted results paths and default clean operation:
842  if (num_commands == 0)
843  {
844  bool rtn_ok = true;
845  if (prefixBase.contains("preprocess"))
846  rtn_ok = makeDefaultResultsDir();
847  if (prefixBase.contains("clean"))
848  rtn_ok = doDefaultClean();
849  if (rtn_ok)
850  result = TEST_PASSED;
851  else
852  result = TEST_ERROR;
853  return result;
854  }
855 
856  ossimString date;
857  double startTime;
858  double stopTime;
859 
860  ossimString command;
861  ossim_uint32 index = 0;
862  ossim_uint32 processedIndexes = 0;
863  const char* lookup = 0;
864 
865  bool postprocessing = false;
866  if (prefixBase.contains("postprocess"))
867  postprocessing = true;
868 
869  while ( processedIndexes < num_commands )
870  {
871  ossimString cmd_kw = prefixBase + ossimString::toString(index);
872  lookup = kwl.find( cmd_kw );
873  if ( lookup )
874  {
875  ossimString command_line = convertToNative( lookup ).c_str();
876  if ( tempFileName.size() )
877  {
878  command_line += " > " + tempFileName;
879  }
880 
881  m_logStr << "executing command: " << command_line << "\n";
882 
883  if ( logTime )
884  {
885  getDateString(date);
886  m_logStr << "begin: " << date << "\n";
887 
888  // Start the clock:
889  startTime = ossimTimer::instance()->time_s();
890  }
891 
892  // Launch the command:
893  int status = system(command_line.chars());
894  if (status == 0)
895  result |= TEST_PASSED;
896  else if (postprocessing)
897  result |= TEST_FAILED;
898  else
899  result |= TEST_ERROR;
900 
901  if ( logTime )
902  {
903  // Log the time and status:
904  stopTime = ossimTimer::instance()->time_s();
905  getDateString(date);
906  m_logStr << "end: " << date << "\n"
907  << testName << "[" << index << "]: elapsed time in seconds: "
908  << std::setiosflags(ios::fixed)
909  << std::setprecision(4)
910  << (stopTime-startTime) << "\n";
911  }
912 
913  m_logStr << "return status: " << status << "\n";
914 
915  // Output the status.
916  // If failed write the temp file to the log. This should have the diffs in it.
917  ostringstream statusString;
918  if ( prefixBase.size() )
919  {
920  statusString << prefixBase;
921  }
922  else
923  {
924  statusString << "test";
925  }
926  statusString << "[" << index << "]: ";
927 
928  if ( status != 0 )
929  {
930  // A bad return status can be a test fail if the command was a postprocess:
931  if ( postprocessing )
932  {
933  statusString << "FAILED";
934  }
935  else
936  {
937  statusString << "ERROR";
938  }
939 
940  cout << statusString.str() << endl;
941  m_logStr << statusString.str() << endl;
942  m_logStr << command << "\noutput follows:\n";
943  std::ifstream in;
944  if (!tempFileName.empty())
945  {
946  in.open(tempFileName.c_str(), ios::in | ios::binary);
947  if ( in.is_open() )
948  {
949  char ch;
950  while ( in.get(ch) ) m_logStr.put(ch);
951  m_logStr << "\n";
952  in.close();
953  }
954  }
955  }
956  else
957  {
958  statusString << "PASSED";
959  cout << statusString.str() << endl;
960  m_logStr << statusString.str() << endl;
961  }
962 
963  ++processedIndexes;
964  }
965  ++index;
966 
967  if ( index >= MAX_INDEX )
968  break; // Config file has bad numbering...
969  }
970  return result;
971 }
972 
973 //**************************************************************************************************
974 void ossimBatchTest::preprocessKwl(const std::vector<std::string>& testList,
975  const std::string& testCommand,
976  ossimKeywordlist& kwl)
977 {
978  if ( testList.empty() || testCommand.empty() || (kwl.getSize()==0) )
979  return;
980 
981  // Check for user passed in "all" to option.
982  std::vector<std::string>::const_iterator testIter = testList.begin();
983  bool enableAllTestFlag = false;
984  ossimString firstTest(*testIter);
985  firstTest.downcase();
986  if ( firstTest == "all" )
987  {
988  enableAllTestFlag = true;
989  }
990 
991  while ( testIter != testList.end() )
992  {
993  // Get the number of test:
994  ossimString regExpStr = "test[0-9]+\\.";
995  ossim_uint32 num_tests = kwl.getNumberOfSubstringKeys(regExpStr);
996  const ossim_uint32 MAX_INDEX = num_tests + 1000;
997  ossimString prefixBase = "test";
998  ossim_uint32 index = 0;
999  ossim_uint32 processedIndexes = 0;
1000 
1001  // A count of 0 may indicate that the config file consists of a single, unprefixed test spec:
1002  bool is_single_test = false;
1003  if (num_tests == 0)
1004  {
1005  regExpStr = "test_command[0-9]+";
1006  const ossim_uint32 cmd_count = kwl.getNumberOfSubstringKeys(regExpStr);
1007  if (cmd_count != 0)
1008  {
1009  ++num_tests;
1010  is_single_test = true;
1011  }
1012  else
1013  break; // Nothing to do here:
1014  }
1015 
1016  while ( processedIndexes < num_tests )
1017  {
1018  ossimString prefix ("");
1019  bool test_name_matches = true;
1020  bool test_exists = true;
1021 
1022  if (!is_single_test)
1023  {
1024  // The tests are prefixed with "test*". Assign the prefix for this test set:
1025  prefix = prefixBase + ossimString::toString(index);
1026  test_name_matches = (prefix == (*testIter).c_str());
1027  prefix += ".";
1028 
1029  // With a valid prefix, check if this test even exists before doing any more
1030  // preprocessing:
1031  regExpStr = prefix + "test_command[0-9]+";
1032  const ossim_uint32 cmd_count = kwl.getNumberOfSubstringKeys(regExpStr);
1033  test_exists = cmd_count > 0;
1034  }
1035 
1036  if ( test_exists )
1037  {
1038  if ( test_name_matches || enableAllTestFlag )
1039  {
1040  //---
1041  // Removed adjustment of "enable" flag. Let the config file "enable" key
1042  // control this. drb - 20151202
1043  // kwl.add(prefix.c_str(), "enabled", "1", true);
1044  //---
1045  kwl.add(prefix.c_str(), testCommand.c_str(), "1", true);
1046  if ( testCommand == "run_expected_results_commands" )
1047  {
1048  // Need pre-processing if clean performed.
1049  kwl.add(prefix.c_str(), "run_preprocessing_commands", "1", true);
1050  }
1051  if ( testCommand == "run_test_commands" )
1052  {
1053  // Need pre/post-processing:
1054  kwl.add(prefix.c_str(), "run_preprocessing_commands", "1", true);
1055  kwl.add(prefix.c_str(), "run_postprocessing_commands", "1", true);
1056  }
1057  }
1058  ++processedIndexes;
1059  }
1060  ++index;
1061  if ( index >= MAX_INDEX ) break;
1062  }
1063  ++testIter;
1064 
1065  } // End: while ( testIter != testList.end() )
1066 
1067 } // End: preprocessKwl method
1068 
1069 //**************************************************************************************************
1072 //**************************************************************************************************
1074 {
1075  if ( !m_outDir.exists() && !m_outDir.createDirectory() )
1076  {
1077  cerr << "Could not create: " << m_outDir << endl;
1078  return false;
1079  }
1080  if ( !m_expDir.exists() && !m_expDir.createDirectory() )
1081  {
1082  cerr << "Could not create: " << m_expDir << endl;
1083  return false;
1084  }
1085  return true;
1086 }
1087 
1088 //**************************************************************************************************
1090 //**************************************************************************************************
1092 {
1093  bool result = true;
1094 
1096  ossimString("RMDIR_CMD") );
1097  ossimString command_line;
1098 
1099  if ( m_outDir.exists() )
1100  {
1101  command_line = del_cmd + " " + m_outDir;
1102  m_logStr << "executing command: " << command_line << "\n";
1103  if (system(command_line) != 0)
1104  {
1105  m_logStr << "ERROR: execution failed!\n";
1106  cerr << "ERROR: Could not delete <"<<m_outDir<<">. Clean operation failed."<< endl;
1107  result = false;
1108  }
1109  }
1110 
1111  ossimFilename tmpDir;
1112  if ( getDefaultTempFileDir( tmpDir ) )
1113  {
1114  if ( tmpDir.exists() )
1115  {
1116  command_line = del_cmd + " " + tmpDir;
1117  m_logStr << "executing command: " << command_line << "\n";
1118  if (system(command_line) != 0)
1119  {
1120  m_logStr << "ERROR: execution failed!\n";
1121  cerr << "ERROR: Could not delete <"<<m_outDir<<">. Clean operation failed."<< endl;
1122  result = false;
1123  }
1124  }
1125  }
1126 
1127  return result;
1128 }
1129 
1131  const ossimKeywordlist& kwl,
1132  ossimFilename& tempFile ) const
1133 {
1134  const char* lookup = kwl.find(prefix.c_str(), "temp_file");
1135  if ( lookup )
1136  {
1137  tempFile = ossimFilename(lookup);
1138  if (tempFile.contains("$("))
1139  tempFile = tempFile.expand();
1140  }
1141  else
1142  {
1143  if ( getDefaultTempFileDir( tempFile ) )
1144  {
1145  if ( tempFile.createDirectory( true, 0775 ) )
1146  {
1147  // Tack on the file name.
1148  tempFile = tempFile.dirCat("tmp.txt");
1149  }
1150  else
1151  {
1152  tempFile.clear();
1153  }
1154  }
1155  }
1156  return ( tempFile.size() > 0 );
1157 }
1158 
1160 {
1161  // Create a default tmp directory under OSSIM_BATCH_TEST_RESULTS.
1163  ossimString("OSSIM_BATCH_TEST_RESULTS") );
1164  if (!tempFile.empty())
1165  tempFile = tempFile.dirCat("tmp");
1166  else
1168  return ( tempFile.size() > 0 );
1169 }
1170 
1172 {
1174 
1175  au->addCommandLineOption("-a or --accept-test",
1176  "<testX> Runs \"run_expected_results_commands\" portion from test configuration file for "
1177  "testX where X is some test number, i.e. 1, 2, 3... This will turn off all other test in "
1178  "the test config file. Notes: Multiple tests can be entered by quoting string of space "
1179  "separated test, e.g. \"test1 test2\". To accept all tests use \"all\" for test.");
1180 
1181  au->addCommandLineOption("-c or --clean-test", "<testX> Runs \"run_clean_commands\" portion "
1182  "from test configuration file for testX where X is some test number, i.e. 1, 2, 3... This "
1183  "will turn off all other test in the test config file. Notes: Multiple tests can be entered "
1184  "by quoting string of space separated test, e.g. \"test1 test2\". To clean all tests use "
1185  "\"all\" for test.");
1186 
1187  au->addCommandLineOption("-p or --preprocess-test",
1188  "<testX> Runs \"run_preprocessing_commands\" portion from test configuration file for testX "
1189  "where X is some test number, i.e. 1, 2, 3... This will turn off all other test in the test "
1190  "config file. Notes: Multiple tests can be entered by quoting string of space separated "
1191  "test, e.g. \"test1 test2\". To preprocess all tests use \"all\" for test.");
1192 
1193  au->addCommandLineOption("-r or --run-test",
1194  "<testX> Runs \"run_test_commands\" portion from test configuration file for testX where X "
1195  "is some test number, i.e. 1, 2, 3... This will turn off all other test in the test config "
1196  "file. Notes: Multiple tests can be entered by quoting string of space separated test, e.g. "
1197  "\"test1 test2\". To run all tests use \"all\" for test.");
1198 
1199  au->addCommandLineOption("-h or --help", "Display usage.");
1200 
1201  au->addCommandLineOption("-W or -w",
1202  "<template_name.kwl> Writes a long-form (-W) or a short-form (-w) template test "
1203  "configuration file.");
1204 
1205  // Write usage.
1207 }
1208 
1209 std::string ossimBatchTest::convertToNative( const char* lookup ) const
1210 {
1211  std::string s;
1212 
1213  if ( lookup )
1214  {
1215  s = lookup;
1216  const std::string::size_type SIZE = s.size();
1217  std::string::size_type i = 0;
1218 
1219 #if defined(_WIN32)
1220  //---
1221  // Must not convert slashes for: "del /Q", "fc /W", and "copy /Y"
1222  //---
1223  while( i < SIZE )
1224  {
1225  if( s[i] == '/' )
1226  {
1227  bool replace = true;
1228  if ( (i+2) < SIZE ) // Could fit a window command and space like: "/Y "
1229  {
1230  if ( (s[i+1] == 'Q') || (s[i+1] == 'W') || (s[i+1] == 'Y') )
1231  {
1232  if ( s[i+2] == ' ' ) // Check for space after "/Q".
1233  {
1234  replace = false;
1235  }
1236  }
1237  }
1238  if ( replace )
1239  {
1240  s[i] = '\\';
1241  }
1242  }
1243  ++i;
1244  }
1245 #else
1246  while( i < SIZE )
1247  {
1248  if( s[i] == '\\' )
1249  {
1250  s[i] = '/';
1251  }
1252  ++i;
1253  }
1254 #endif
1255 
1256  } // Matches: if ( lookup )
1257 
1258  return s;
1259 }
1260 
1261 
void clear()
Erases the entire container.
Definition: ossimString.h:432
ossimFilename m_expDir
void write(std::ostream &output, const UsageMap &um, unsigned int widthOfOutput=80)
void addCommandLineOption(const ossimString &option, const ossimString &explanation)
ossim_uint8 processTest(const ossimString &prefix, const ossimKeywordlist &kwl)
Within a single config file can be multiple tests, distinguished by the "test*." prefix.
std::basic_ostringstream< char > ostringstream
Class for char output memory streams.
Definition: ossimIosFwd.h:35
ossim_uint32 getNumberOfSubstringKeys(const ossimString &regularExpression) const
void setStartTick()
Set the start.
Definition: ossimTimer.h:27
ossim_uint8 processCommands(const ossimString &prefix, const ossimKeywordlist &kwl, const ossimString &testName, bool logTime, const ossimFilename &tempFile=ossimFilename(""))
Runs a single command within a test.
void usage(ossimArgumentParser &ap)
Initializes arg parser and outputs usage.
Represents serializable keyword/value map.
bool addFile(const char *file)
const std::string & findKey(const std::string &key) const
Find methods that take std::string(s).
std::basic_ifstream< char > ifstream
Class for char input file streams.
Definition: ossimIosFwd.h:44
const char * find(const char *key) const
ossimFilename expand() const
Method to do file name expansion.
ossim_uint8 processConfigList(const ossimKeywordlist &kwl)
When the config file consists of a list of subordinate test config files, this method manages process...
bool read(const std::string &str)
search for an occurance of a string in the argument list, on sucess remove that occurance from the li...
std::vector< std::string > m_cleanTestList
bool contains(char aChar) const
Definition: ossimString.h:58
ossimFilename & setPath(const ossimString &p)
static ossimString toString(bool aValue)
Numeric to string methods.
void split(std::vector< ossimString > &result, const ossimString &separatorList, bool skipBlankFields=false) const
Splits this string into a vector of strings (fields) using the delimiter list specified.
ossim_uint8 execute()
Performs the actual test with the config filename previously set in initialize() or processConfigList...
ossimApplicationUsage * getApplicationUsage()
std::vector< std::string > m_runTestList
void reportRemainingOptionsAsUnrecognized(ossimErrorSeverity severity=OSSIM_BENIGN)
for each remaining option report it as an unrecongnized.
void add(const char *prefix, const ossimKeywordlist &kwl, bool overwrite=true)
ossimFilename getCurrentWorkingDir() const
void preprocessKwl(const std::vector< std::string > &testList, const std::string &testCommand, ossimKeywordlist &kwl)
Modifies the config&#39;s KWL to explicitly declare implied keywords.
bool getTempFileName(const ossimString &prefix, const ossimKeywordlist &kwl, ossimFilename &tempFile) const
Gets the temp file name.
ossimString expandEnvironmentVariable() const
If the variable "$(env_var_name)" is found in the string, where "env_var_name" is any system environm...
std::ofstream m_logStr
bool errors(ossimErrorSeverity severity=OSSIM_BENIGN) const
std::vector< std::string > m_acceptTestList
static ossimTimer * instance()
Definition: ossimTimer.cpp:19
bool exists() const
ossimFilename m_configFileName
virtual const char * what() const
Returns the error message.
std::string::size_type size() const
Definition: ossimString.h:405
void getLogFilename(ossimFilename &logFile)
Establishes name of output log file.
bool toBool() const
String to numeric methods.
double time_s() const
Get elapsed time in seconds.
Definition: ossimTimer.h:33
unsigned int ossim_uint32
const char * chars() const
For backward compatibility.
Definition: ossimString.h:77
ossimString trim(const ossimString &valueToTrim=ossimString(" \\)) const
this will strip lead and trailing character passed in.
void writeTemplate(const ossimFilename &templateFile, bool long_form)
Writes template test config file, either exhaustive long form for flexibility, or simple short-form f...
ossimBatchTest()
This constructor only initializes data members to null/defaults.
static ossimString downcase(const ossimString &aString)
Definition: ossimString.cpp:48
bool isReadable() const
std::vector< ossimString > getSubstringKeyList(const ossimString &regularExpression) const
return status
std::map< ossim_uint32, std::string > m_statusLabels
static ossimEnvironmentUtility * instance()
bool getDefaultTempFileDir(ossimFilename &tempDir) const
Gets the default temp directory /data1/test/results/linux/tmp.
bool makeDefaultResultsDir()
Default preprocessing step makes expected and output results directories.
bool doDefaultClean()
Default clean step deletes all files in out and exp dirs.
std::vector< std::string > m_preprocessTestList
ossimFilename fileNoExtension() const
ossimFilename m_outDir
OSSIMDLLEXPORT void ossimSetLogFilename(const ossimFilename &filename)
std::string convertToNative(const char *lookup) const
Converts string slashes to either forward or backward taking into account that windows commands with ...
ossimFilename dirCat(const ossimFilename &file) const
ossim_uint32 getSize() const
const char * c_str() const
Returns a pointer to a null-terminated array of characters representing the string&#39;s contents...
Definition: ossimString.h:396
bool empty() const
Definition: ossimString.h:411
ossimString getEnvironmentVariable(const ossimString &variable) const
std::basic_ofstream< char > ofstream
Class for char output file streams.
Definition: ossimIosFwd.h:47
bool initialize(ossimArgumentParser &ap)
Initializes the test session given the command line.
void setEnvironmentVariable(const char *variable, const char *value) const
char ** argv()
return the argument array.
bool createDirectory(bool recurseFlag=true, int perm=0775) const
void getDateString(ossimString &date)
Fetches string from OS for naming and tagging the log file.
int & argc()
return the argument count.
void setExpandEnvVarsFlag(bool flag)
ossimFilename path() const
unsigned char ossim_uint8
OSSIMDLLEXPORT std::ostream & ossimNotify(ossimNotifyLevel level=ossimNotifyLevel_WARN)
void writeErrorMessages(std::ostream &output, ossimErrorSeverity sevrity=OSSIM_BENIGN)
write out error messages at an above specified .