OSSIM - Open Source Software Image Map  Version 1.9.0 (20180803)
Public Types | Public Member Functions | Private Member Functions | Private Attributes | List of all members
ossimBatchTest Class Reference

#include <ossimBatchTest.h>

Inheritance diagram for ossimBatchTest:
ossimReferenced

Public Types

enum  TEST_STATUS {
  TEST_TBD = 0x00, TEST_PASSED = 0x01, TEST_FAILED = 0x02, TEST_ERROR = 0x04,
  TEST_DISABLED = 0x08
}
 

Public Member Functions

 ossimBatchTest ()
 This constructor only initializes data members to null/defaults. More...
 
bool initialize (ossimArgumentParser &ap)
 Initializes the test session given the command line. More...
 
ossim_uint8 execute ()
 Performs the actual test with the config filename previously set in initialize() or processConfigList() when config is a list of subordinate test config files. More...
 
- Public Member Functions inherited from ossimReferenced
 ossimReferenced ()
 
 ossimReferenced (const ossimReferenced &)
 
ossimReferencedoperator= (const ossimReferenced &)
 
void ref () const
 increment the reference count by one, indicating that this object has another pointer which is referencing it. More...
 
void unref () const
 decrement the reference count by one, indicating that a pointer to this object is referencing it. More...
 
void unref_nodelete () const
 decrement the reference count by one, indicating that a pointer to this object is referencing it. More...
 
int referenceCount () const
 

Private Member Functions

void writeTemplate (const ossimFilename &templateFile, bool long_form)
 Writes template test config file, either exhaustive long form for flexibility, or simple short-form for easier test creation. More...
 
void getDateString (ossimString &date)
 Fetches string from OS for naming and tagging the log file. More...
 
void getLogFilename (ossimFilename &logFile)
 Establishes name of output log file. More...
 
ossim_uint8 processConfigList (const ossimKeywordlist &kwl)
 When the config file consists of a list of subordinate test config files, this method manages processing multiple configs. More...
 
ossim_uint8 processTest (const ossimString &prefix, const ossimKeywordlist &kwl)
 Within a single config file can be multiple tests, distinguished by the "test*." prefix. More...
 
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. More...
 
void preprocessKwl (const std::vector< std::string > &testList, const std::string &testCommand, ossimKeywordlist &kwl)
 Modifies the config's KWL to explicitly declare implied keywords. More...
 
bool makeDefaultResultsDir ()
 Default preprocessing step makes expected and output results directories. More...
 
bool doDefaultClean ()
 Default clean step deletes all files in out and exp dirs. More...
 
bool getTempFileName (const ossimString &prefix, const ossimKeywordlist &kwl, ossimFilename &tempFile) const
 Gets the temp file name. More...
 
bool getDefaultTempFileDir (ossimFilename &tempDir) const
 Gets the default temp directory /data1/test/results/linux/tmp. More...
 
void usage (ossimArgumentParser &ap)
 Initializes arg parser and outputs usage. More...
 
std::string convertToNative (const char *lookup) const
 Converts string slashes to either forward or backward taking into account that windows commands with forward slashes in them. More...
 

Private Attributes

std::vector< std::string > m_acceptTestList
 
std::vector< std::string > m_cleanTestList
 
std::vector< std::string > m_preprocessTestList
 
std::vector< std::string > m_runTestList
 
std::map< ossim_uint32, std::string > m_statusLabels
 
bool m_templateModeActive
 
ossimFilename m_configFileName
 
ossimFilename m_outDir
 
ossimFilename m_expDir
 
std::ofstream m_logStr
 

Additional Inherited Members

- Protected Member Functions inherited from ossimReferenced
virtual ~ossimReferenced ()
 

Detailed Description

Definition at line 34 of file ossimBatchTest.h.

Member Enumeration Documentation

◆ TEST_STATUS

Enumerator
TEST_TBD 
TEST_PASSED 
TEST_FAILED 
TEST_ERROR 
TEST_DISABLED 

Definition at line 37 of file ossimBatchTest.h.

38  {
39  TEST_TBD = 0x00, // initial state: no test yet attempted
40  TEST_PASSED = 0x01,
41  TEST_FAILED = 0x02,
42  TEST_ERROR = 0x04,
43  TEST_DISABLED = 0x08
44  };

Constructor & Destructor Documentation

◆ ossimBatchTest()

ossimBatchTest::ossimBatchTest ( )

This constructor only initializes data members to null/defaults.

Definition at line 37 of file ossimBatchTest.cpp.

References m_statusLabels, TEST_DISABLED, TEST_ERROR, TEST_FAILED, TEST_PASSED, and TEST_TBD.

38  :
42  m_runTestList(),
43  m_templateModeActive(false),
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 }
ossimFilename m_expDir
std::vector< std::string > m_cleanTestList
std::vector< std::string > m_runTestList
std::ofstream m_logStr
std::vector< std::string > m_acceptTestList
ossimFilename m_configFileName
std::map< ossim_uint32, std::string > m_statusLabels
std::vector< std::string > m_preprocessTestList
ossimFilename m_outDir

Member Function Documentation

◆ convertToNative()

std::string ossimBatchTest::convertToNative ( const char *  lookup) const
private

Converts string slashes to either forward or backward taking into account that windows commands with forward slashes in them.

Parameters
sString to convert.

Definition at line 1209 of file ossimBatchTest.cpp.

Referenced by execute(), and processCommands().

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 }

◆ doDefaultClean()

bool ossimBatchTest::doDefaultClean ( )
private

Default clean step deletes all files in out and exp dirs.

Default clean step deletes all files in out and exp dirs. Returns TRUE if successful.

Returns
TRUE if successful.

Definition at line 1091 of file ossimBatchTest.cpp.

References ossimFilename::exists(), getDefaultTempFileDir(), ossimEnvironmentUtility::getEnvironmentVariable(), ossimEnvironmentUtility::instance(), m_logStr, and m_outDir.

Referenced by processCommands().

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 }
std::ofstream m_logStr
bool exists() const
static ossimEnvironmentUtility * instance()
bool getDefaultTempFileDir(ossimFilename &tempDir) const
Gets the default temp directory /data1/test/results/linux/tmp.
ossimFilename m_outDir
ossimString getEnvironmentVariable(const ossimString &variable) const

◆ execute()

ossim_uint8 ossimBatchTest::execute ( )

Performs the actual test with the config filename previously set in initialize() or processConfigList() when config is a list of subordinate test config files.

Returns
The overall bit-wise status of all tests (see TEST_STATUS enum for bit definitions).

Definition at line 418 of file ossimBatchTest.cpp.

References ossimKeywordlist::addFile(), ossimString::c_str(), ossimString::chars(), convertToNative(), ossimFilename::createDirectory(), ossimFilename::dirCat(), ossimString::empty(), ossimFilename::exists(), ossimFilename::fileNoExtension(), ossimKeywordlist::find(), ossimEnvironmentUtility::getCurrentWorkingDir(), getDateString(), ossimEnvironmentUtility::getEnvironmentVariable(), getLogFilename(), ossimKeywordlist::getSubstringKeyList(), ossimEnvironmentUtility::instance(), ossimTimer::instance(), m_acceptTestList, m_cleanTestList, m_configFileName, m_expDir, m_logStr, m_outDir, m_preprocessTestList, m_runTestList, m_statusLabels, m_templateModeActive, ossimSetLogFilename(), preprocessKwl(), processConfigList(), processTest(), ossimEnvironmentUtility::setEnvironmentVariable(), ossimKeywordlist::setExpandEnvVarsFlag(), ossimTimer::setStartTick(), status, TEST_ERROR, TEST_PASSED, TEST_TBD, ossimTimer::time_s(), and ossimException::what().

Referenced by processConfigList().

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 }
ossimFilename m_expDir
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
void setStartTick()
Set the start.
Definition: ossimTimer.h:27
Represents serializable keyword/value map.
bool addFile(const char *file)
const char * find(const char *key) const
ossim_uint8 processConfigList(const ossimKeywordlist &kwl)
When the config file consists of a list of subordinate test config files, this method manages process...
std::vector< std::string > m_cleanTestList
std::vector< std::string > m_runTestList
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.
std::ofstream m_logStr
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.
void getLogFilename(ossimFilename &logFile)
Establishes name of output log file.
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
std::vector< ossimString > getSubstringKeyList(const ossimString &regularExpression) const
return status
std::map< ossim_uint32, std::string > m_statusLabels
static ossimEnvironmentUtility * instance()
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
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
void setEnvironmentVariable(const char *variable, const char *value) const
bool createDirectory(bool recurseFlag=true, int perm=0775) const
void getDateString(ossimString &date)
Fetches string from OS for naming and tagging the log file.
void setExpandEnvVarsFlag(bool flag)
unsigned char ossim_uint8

◆ getDateString()

void ossimBatchTest::getDateString ( ossimString date)
private

Fetches string from OS for naming and tagging the log file.

Definition at line 641 of file ossimBatchTest.cpp.

References ossimString::clear().

Referenced by execute(), getLogFilename(), and processCommands().

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 }
void clear()
Erases the entire container.
Definition: ossimString.h:432

◆ getDefaultTempFileDir()

bool ossimBatchTest::getDefaultTempFileDir ( ossimFilename tempDir) const
private

Gets the default temp directory /data1/test/results/linux/tmp.

Parameters
tempDirInitialized by this.
Returns
true on success, false on error.

Definition at line 1159 of file ossimBatchTest.cpp.

References ossimFilename::dirCat(), ossimString::empty(), ossimEnvironmentUtility::getEnvironmentVariable(), ossimEnvironmentUtility::instance(), and ossimString::size().

Referenced by doDefaultClean(), and getTempFileName().

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 }
static ossimEnvironmentUtility * instance()
ossimString getEnvironmentVariable(const ossimString &variable) const

◆ getLogFilename()

void ossimBatchTest::getLogFilename ( ossimFilename logFile)
private

Establishes name of output log file.

Definition at line 661 of file ossimBatchTest.cpp.

References getDateString().

Referenced by execute().

662 {
663  logFile = "obt-log-";
664  ossimString date;
665  getDateString(date);
666  logFile += date;
667  logFile += ".txt";
668 }
void getDateString(ossimString &date)
Fetches string from OS for naming and tagging the log file.

◆ getTempFileName()

bool ossimBatchTest::getTempFileName ( const ossimString prefix,
const ossimKeywordlist kwl,
ossimFilename tempFile 
) const
private

Gets the temp file name.

This will either be from the config file lookup of "temp_file" or derived under /data1/test/results/linux/tmp if the lookup fails. Note that this will create the /data1/test/results/linux/tmp directory if needed.

Parameters
prefixLike "test1."
kwlKeyword list to look for temp_file in.
tempFileInitialized by this.
Returns
true on success. False if derived temp file directory could not be created.

Definition at line 1130 of file ossimBatchTest.cpp.

References ossimString::c_str(), ossimString::clear(), ossimString::contains(), ossimFilename::createDirectory(), ossimFilename::dirCat(), ossimFilename::expand(), ossimKeywordlist::find(), getDefaultTempFileDir(), and ossimString::size().

Referenced by processTest().

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 }
void clear()
Erases the entire container.
Definition: ossimString.h:432
const char * find(const char *key) const
ossimFilename expand() const
Method to do file name expansion.
bool contains(char aChar) const
Definition: ossimString.h:58
std::string::size_type size() const
Definition: ossimString.h:405
bool getDefaultTempFileDir(ossimFilename &tempDir) const
Gets the default temp directory /data1/test/results/linux/tmp.
ossimFilename dirCat(const ossimFilename &file) 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 createDirectory(bool recurseFlag=true, int perm=0775) const

◆ initialize()

bool ossimBatchTest::initialize ( ossimArgumentParser ap)

Initializes the test session given the command line.

Definition at line 64 of file ossimBatchTest.cpp.

References ossimArgumentParser::argc(), ossimArgumentParser::argv(), ossimArgumentParser::errors(), m_acceptTestList, m_cleanTestList, m_configFileName, m_preprocessTestList, m_runTestList, m_templateModeActive, ossimNotify(), ossimNotifyLevel_NOTICE, ossimArgumentParser::read(), ossimArgumentParser::reportRemainingOptionsAsUnrecognized(), ossimString::size(), ossimString::split(), usage(), ossimArgumentParser::writeErrorMessages(), and writeTemplate().

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 }
void usage(ossimArgumentParser &ap)
Initializes arg parser and outputs usage.
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
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.
std::vector< std::string > m_runTestList
void reportRemainingOptionsAsUnrecognized(ossimErrorSeverity severity=OSSIM_BENIGN)
for each remaining option report it as an unrecongnized.
bool errors(ossimErrorSeverity severity=OSSIM_BENIGN) const
std::vector< std::string > m_acceptTestList
ossimFilename m_configFileName
std::string::size_type size() const
Definition: ossimString.h:405
void writeTemplate(const ossimFilename &templateFile, bool long_form)
Writes template test config file, either exhaustive long form for flexibility, or simple short-form f...
std::vector< std::string > m_preprocessTestList
char ** argv()
return the argument array.
int & argc()
return the argument count.
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 .

◆ makeDefaultResultsDir()

bool ossimBatchTest::makeDefaultResultsDir ( )
private

Default preprocessing step makes expected and output results directories.

Returns

Returns
TRUE if successful.

Returns TRUE if successful.

Definition at line 1073 of file ossimBatchTest.cpp.

References ossimFilename::createDirectory(), ossimFilename::exists(), m_expDir, and m_outDir.

Referenced by processCommands().

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 }
ossimFilename m_expDir
bool exists() const
ossimFilename m_outDir
bool createDirectory(bool recurseFlag=true, int perm=0775) const

◆ preprocessKwl()

void ossimBatchTest::preprocessKwl ( const std::vector< std::string > &  testList,
const std::string &  testCommand,
ossimKeywordlist kwl 
)
private

Modifies the config's KWL to explicitly declare implied keywords.

Definition at line 974 of file ossimBatchTest.cpp.

References ossimKeywordlist::add(), ossimString::c_str(), ossimString::downcase(), ossimKeywordlist::getNumberOfSubstringKeys(), ossimKeywordlist::getSize(), and ossimString::toString().

Referenced by execute().

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
ossim_uint32 getNumberOfSubstringKeys(const ossimString &regularExpression) const
static ossimString toString(bool aValue)
Numeric to string methods.
void add(const char *prefix, const ossimKeywordlist &kwl, bool overwrite=true)
unsigned int ossim_uint32
ossim_uint32 getSize() const

◆ processCommands()

ossim_uint8 ossimBatchTest::processCommands ( const ossimString prefix,
const ossimKeywordlist kwl,
const ossimString testName,
bool  logTime,
const ossimFilename tempFile = ossimFilename("") 
)
private

Runs a single command within a test.

Returns
The bit-wise status of command (see TEST_STATUS enum for bit definitions).

Definition at line 820 of file ossimBatchTest.cpp.

References ossimString::c_str(), ossimString::contains(), convertToNative(), doDefaultClean(), ossimString::empty(), ossimKeywordlist::find(), getDateString(), ossimKeywordlist::getNumberOfSubstringKeys(), ossimTimer::instance(), m_logStr, makeDefaultResultsDir(), ossimString::size(), status, TEST_ERROR, TEST_FAILED, TEST_PASSED, TEST_TBD, ossimTimer::time_s(), and ossimString::toString().

Referenced by processTest().

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 }
std::basic_ostringstream< char > ostringstream
Class for char output memory streams.
Definition: ossimIosFwd.h:35
ossim_uint32 getNumberOfSubstringKeys(const ossimString &regularExpression) const
std::basic_ifstream< char > ifstream
Class for char input file streams.
Definition: ossimIosFwd.h:44
const char * find(const char *key) const
static ossimString toString(bool aValue)
Numeric to string methods.
std::ofstream m_logStr
static ossimTimer * instance()
Definition: ossimTimer.cpp:19
double time_s() const
Get elapsed time in seconds.
Definition: ossimTimer.h:33
unsigned int ossim_uint32
return status
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::string convertToNative(const char *lookup) const
Converts string slashes to either forward or backward taking into account that windows commands with ...
void getDateString(ossimString &date)
Fetches string from OS for naming and tagging the log file.
unsigned char ossim_uint8

◆ processConfigList()

ossim_uint8 ossimBatchTest::processConfigList ( const ossimKeywordlist kwl)
private

When the config file consists of a list of subordinate test config files, this method manages processing multiple configs.

Returns
The overall bit-wise status of all configs (see TEST_STATUS enum for bit definitions).

Definition at line 603 of file ossimBatchTest.cpp.

References ossimString::contains(), ossimString::empty(), execute(), ossimFilename::expand(), ossimKeywordlist::findKey(), ossimKeywordlist::getSubstringKeyList(), ossimFilename::isReadable(), m_configFileName, ossimFilename::path(), ossimFilename::setPath(), and TEST_TBD.

Referenced by execute().

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 }
const std::string & findKey(const std::string &key) const
Find methods that take std::string(s).
ossimFilename expand() const
Method to do file name expansion.
bool contains(char aChar) const
Definition: ossimString.h:58
ossimFilename & setPath(const ossimString &p)
ossim_uint8 execute()
Performs the actual test with the config filename previously set in initialize() or processConfigList...
ossimFilename m_configFileName
unsigned int ossim_uint32
bool isReadable() const
std::vector< ossimString > getSubstringKeyList(const ossimString &regularExpression) const
bool empty() const
Definition: ossimString.h:411
ossimFilename path() const
unsigned char ossim_uint8

◆ processTest()

ossim_uint8 ossimBatchTest::processTest ( const ossimString prefix,
const ossimKeywordlist kwl 
)
private

Within a single config file can be multiple tests, distinguished by the "test*." prefix.

This method manages the execution of a single test.

Returns
The overall bit-wise status of test (see TEST_STATUS enum for bit definitions).

This method manages the execution of a single test.

Definition at line 674 of file ossimBatchTest.cpp.

References ossimString::c_str(), ossimString::empty(), ossimFilename::fileNoExtension(), ossimKeywordlist::find(), ossimKeywordlist::getNumberOfSubstringKeys(), getTempFileName(), m_configFileName, m_logStr, processCommands(), ossimString::size(), TEST_DISABLED, TEST_ERROR, TEST_TBD, ossimString::toBool(), and ossimString::trim().

Referenced by execute().

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 }
ossim_uint32 getNumberOfSubstringKeys(const ossimString &regularExpression) const
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.
const char * find(const char *key) const
bool getTempFileName(const ossimString &prefix, const ossimKeywordlist &kwl, ossimFilename &tempFile) const
Gets the temp file name.
std::ofstream m_logStr
ossimFilename m_configFileName
std::string::size_type size() const
Definition: ossimString.h:405
bool toBool() const
String to numeric methods.
ossimString trim(const ossimString &valueToTrim=ossimString(" \\)) const
this will strip lead and trailing character passed in.
ossimFilename fileNoExtension() 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
unsigned char ossim_uint8

◆ usage()

void ossimBatchTest::usage ( ossimArgumentParser ap)
private

Initializes arg parser and outputs usage.

Definition at line 1171 of file ossimBatchTest.cpp.

References ossimApplicationUsage::addCommandLineOption(), ossimArgumentParser::getApplicationUsage(), ossimNotify(), ossimNotifyLevel_INFO, and ossimApplicationUsage::write().

Referenced by initialize().

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 }
void write(std::ostream &output, const UsageMap &um, unsigned int widthOfOutput=80)
void addCommandLineOption(const ossimString &option, const ossimString &explanation)
ossimApplicationUsage * getApplicationUsage()
OSSIMDLLEXPORT std::ostream & ossimNotify(ossimNotifyLevel level=ossimNotifyLevel_WARN)

◆ writeTemplate()

void ossimBatchTest::writeTemplate ( const ossimFilename templateFile,
bool  long_form 
)
private

Writes template test config file, either exhaustive long form for flexibility, or simple short-form for easier test creation.

Definition at line 217 of file ossimBatchTest.cpp.

References ossimString::c_str(), ossimString::chars(), ossimFilename::exists(), ossimString::expandEnvironmentVariable(), ossimNotify(), and ossimNotifyLevel_NOTICE.

Referenced by initialize().

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 }
ossimString expandEnvironmentVariable() const
If the variable "$(env_var_name)" is found in the string, where "env_var_name" is any system environm...
bool exists() 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
std::basic_ofstream< char > ofstream
Class for char output file streams.
Definition: ossimIosFwd.h:47
OSSIMDLLEXPORT std::ostream & ossimNotify(ossimNotifyLevel level=ossimNotifyLevel_WARN)

Member Data Documentation

◆ m_acceptTestList

std::vector<std::string> ossimBatchTest::m_acceptTestList
private

Definition at line 135 of file ossimBatchTest.h.

Referenced by execute(), and initialize().

◆ m_cleanTestList

std::vector<std::string> ossimBatchTest::m_cleanTestList
private

Definition at line 136 of file ossimBatchTest.h.

Referenced by execute(), and initialize().

◆ m_configFileName

ossimFilename ossimBatchTest::m_configFileName
private

Definition at line 142 of file ossimBatchTest.h.

Referenced by execute(), initialize(), processConfigList(), and processTest().

◆ m_expDir

ossimFilename ossimBatchTest::m_expDir
private

Definition at line 144 of file ossimBatchTest.h.

Referenced by execute(), and makeDefaultResultsDir().

◆ m_logStr

std::ofstream ossimBatchTest::m_logStr
private

Definition at line 145 of file ossimBatchTest.h.

Referenced by doDefaultClean(), execute(), processCommands(), and processTest().

◆ m_outDir

ossimFilename ossimBatchTest::m_outDir
private

Definition at line 143 of file ossimBatchTest.h.

Referenced by doDefaultClean(), execute(), and makeDefaultResultsDir().

◆ m_preprocessTestList

std::vector<std::string> ossimBatchTest::m_preprocessTestList
private

Definition at line 137 of file ossimBatchTest.h.

Referenced by execute(), and initialize().

◆ m_runTestList

std::vector<std::string> ossimBatchTest::m_runTestList
private

Definition at line 138 of file ossimBatchTest.h.

Referenced by execute(), and initialize().

◆ m_statusLabels

std::map<ossim_uint32, std::string> ossimBatchTest::m_statusLabels
private

Definition at line 139 of file ossimBatchTest.h.

Referenced by execute(), and ossimBatchTest().

◆ m_templateModeActive

bool ossimBatchTest::m_templateModeActive
private

Definition at line 141 of file ossimBatchTest.h.

Referenced by execute(), and initialize().


The documentation for this class was generated from the following files: