Skip to content

v0.2.49..v0.2.50 changeset main.cpp

Garret Voltz edited this page Nov 6, 2019 · 1 revision
diff --git a/hoot-test/src/main/cpp/hoot/test/main.cpp b/hoot-test/src/main/cpp/hoot/test/main.cpp
index b2bcdd8..fde2ae6 100644
--- a/hoot-test/src/main/cpp/hoot/test/main.cpp
+++ b/hoot-test/src/main/cpp/hoot/test/main.cpp
@@ -78,16 +78,17 @@ typedef std::shared_ptr<CppUnit::Test> TestPtr;
 
 enum _TestType
 {
+  NONE          = 0x00,
   CURRENT       = 0x01,
   QUICK_ONLY    = 0x02,
   QUICK         = 0x03,
-  SLOW_ONLY     = 0x04,
-  SLOW          = 0x07,
-  GLACIAL_ONLY  = 0x08,
-  GLACIAL       = 0x0f,
-  SERIAL        = 0x10,
-  CASE_ONLY     = 0x11,
-  ALL           = 0x1f
+  CASE_ONLY     = 0x04,
+  SLOW_ONLY     = 0x08,
+  SLOW          = 0x0f,
+  GLACIAL_ONLY  = 0x10,
+  GLACIAL       = 0x1f,
+  SERIAL        = 0x20,
+  ALL           = 0x3f
 };
 
 enum _TimeOutValue
@@ -223,6 +224,41 @@ void filterPattern(const std::vector<CppUnit::Test*>& from, std::vector<CppUnit:
   }
 }
 
+void includeExcludeTests(const QStringList& args, vector<CppUnit::Test*>& vTests)
+{
+  vector<CppUnit::Test*> vTestsToRun;
+  bool filtered = false;
+
+  for (int i = 0; i < args.size(); i++)
+  {
+    if (args[i].startsWith("--exclude="))
+    {
+      if (vTestsToRun.size() > 0)
+      {
+        //  On the second (or more) time around exclude from the excluded list
+        vTests.swap(vTestsToRun);
+        vTestsToRun.clear();
+      }
+      int equalsPos = args[i].indexOf('=');
+      QString regex = args[i].mid(equalsPos + 1);
+      LOG_INFO("Excluding pattern: " << regex);
+      filterPattern(vTests, vTestsToRun, regex, false);
+      filtered = true;
+    }
+    else if (args[i].startsWith("--include="))
+    {
+      int equalsPos = args[i].indexOf('=');
+      QString regex = args[i].mid(equalsPos + 1);
+      LOG_INFO("Including only tests that match: " << regex);
+      filterPattern(vTests, vTestsToRun, regex, true);
+      filtered = true;
+    }
+  }
+  //  Swap the filtered tests into the test list
+  if (filtered)
+    vTests.swap(vTestsToRun);
+}
+
 CppUnit::Test* findTest(CppUnit::Test* t, std::string name)
 {
   if (name == t->getName())
@@ -292,12 +328,12 @@ void getNames(vector<string>& names, CppUnit::Test* t)
   }
 }
 
-void getNames(vector<string>& names, const std::vector<TestPtr>& vTests)
+void getNames(vector<string>& names, const std::vector<CppUnit::Test*>& vTests)
 {
   for (size_t i = 0; i < vTests.size(); i++)
   {
     // See if our test is really a suite
-    CppUnit::TestSuite* suite = dynamic_cast<CppUnit::TestSuite*>(vTests[i].get());
+    CppUnit::TestSuite* suite = dynamic_cast<CppUnit::TestSuite*>(vTests[i]);
     if (suite != 0)
     {
       vector<CppUnit::Test*> children = suite->getTests();
@@ -313,13 +349,7 @@ void getNames(vector<string>& names, const std::vector<TestPtr>& vTests)
   }
 }
 
-void getNames(std::vector<string>& names, const std::vector<CppUnit::Test*>& vTests)
-{
-  for (size_t i = 0; i < vTests.size(); i++)
-    names.push_back(vTests[i]->getName());
-}
-
-void printNames(const std::vector<TestPtr>& vTests)
+void printNames(const std::vector<CppUnit::Test*>& vTests)
 {
   vector<string> names;
   getNames(names, vTests);
@@ -338,13 +368,17 @@ void runSingleTest(CppUnit::Test* pTest, QStringList& args, CppUnit::TextTestRes
 }
 
 void populateTests(_TestType t, std::vector<TestPtr>& vTests, bool printDiff,
-                   bool hideDisableTests = false)
+                   bool suppressFailureDetail, bool hideDisableTests = false)
 {
   //  Current tests are included in CURRENT, QUICK, SLOW, and GLACIAL
   //  Add current tests if the bit flag is set
   if (t & CURRENT)
   {
-    vTests.push_back(TestPtr(new ScriptTestSuite("test-files/cmd/current/", printDiff, QUICK_WAIT, hideDisableTests)));
+    vTests.push_back(
+      TestPtr(
+        new ScriptTestSuite(
+          "test-files/cmd/current/", printDiff, QUICK_WAIT, hideDisableTests,
+          suppressFailureDetail)));
     vTests.push_back(TestPtr(CppUnit::TestFactoryRegistry::getRegistry("current").makeTest()));
   }
   //  Quick tests are included in QUICK, SLOW, and GLACIAL
@@ -352,7 +386,10 @@ void populateTests(_TestType t, std::vector<TestPtr>& vTests, bool printDiff,
   if (t & QUICK_ONLY)
   {
     vTests.push_back(TestPtr(CppUnit::TestFactoryRegistry::getRegistry().makeTest()));
-    vTests.push_back(TestPtr(new ScriptTestSuite("test-files/cmd/quick/", printDiff, QUICK_WAIT, hideDisableTests)));
+    vTests.push_back(
+      TestPtr(
+        new ScriptTestSuite(
+          "test-files/cmd/quick/", printDiff, QUICK_WAIT, hideDisableTests, suppressFailureDetail)));
     vTests.push_back(TestPtr(CppUnit::TestFactoryRegistry::getRegistry("quick").makeTest()));
     vTests.push_back(TestPtr(CppUnit::TestFactoryRegistry::getRegistry("TgsTest").makeTest()));
   }
@@ -360,23 +397,46 @@ void populateTests(_TestType t, std::vector<TestPtr>& vTests, bool printDiff,
   //  Add slow tests if the bit flag is set
   if (t & SLOW_ONLY)
   {
-    vTests.push_back(TestPtr(new ScriptTestSuite("test-files/cmd/slow/", printDiff, SLOW_WAIT, hideDisableTests)));
-    vTests.push_back(TestPtr(new ScriptTestSuite("test-files/cmd/slow/serial/", printDiff, SLOW_WAIT, hideDisableTests)));
+    vTests.push_back(
+      TestPtr(
+        new ScriptTestSuite(
+          "test-files/cmd/slow/", printDiff, SLOW_WAIT, hideDisableTests, suppressFailureDetail)));
+    vTests.push_back(
+      TestPtr(
+        new ScriptTestSuite(
+          "test-files/cmd/slow/serial/", printDiff, SLOW_WAIT, hideDisableTests,
+          suppressFailureDetail)));
     vTests.push_back(TestPtr(new ConflateCaseTestSuite("test-files/cases", hideDisableTests)));
     vTests.push_back(TestPtr(CppUnit::TestFactoryRegistry::getRegistry("slow").makeTest()));
   }
   //  Add glacial tests if the bit flag is set
   if (t & GLACIAL_ONLY)
   {
-    vTests.push_back(TestPtr(new ScriptTestSuite("test-files/cmd/glacial/", printDiff, GLACIAL_WAIT, hideDisableTests)));
-    vTests.push_back(TestPtr(new ScriptTestSuite("test-files/cmd/glacial/serial/", printDiff, GLACIAL_WAIT, hideDisableTests)));
+    vTests.push_back(
+      TestPtr(
+        new ScriptTestSuite(
+          "test-files/cmd/glacial/", printDiff, GLACIAL_WAIT, hideDisableTests,
+          suppressFailureDetail)));
+    vTests.push_back(
+      TestPtr(
+        new ScriptTestSuite(
+          "test-files/cmd/glacial/serial/", printDiff, GLACIAL_WAIT, hideDisableTests,
+          suppressFailureDetail)));
     vTests.push_back(TestPtr(CppUnit::TestFactoryRegistry::getRegistry("glacial").makeTest()));
   }
   //  Add serial tests if the bit flag is set
   if (t == SERIAL)
   {
-    vTests.push_back(TestPtr(new ScriptTestSuite("test-files/cmd/glacial/serial/", printDiff, GLACIAL_WAIT, hideDisableTests)));
-    vTests.push_back(TestPtr(new ScriptTestSuite("test-files/cmd/slow/serial/", printDiff, SLOW_WAIT, hideDisableTests)));
+    vTests.push_back(
+      TestPtr(
+        new ScriptTestSuite(
+          "test-files/cmd/glacial/serial/", printDiff, GLACIAL_WAIT, hideDisableTests,
+          suppressFailureDetail)));
+    vTests.push_back(
+      TestPtr(
+        new ScriptTestSuite(
+          "test-files/cmd/slow/serial/", printDiff, SLOW_WAIT, hideDisableTests,
+          suppressFailureDetail)));
     vTests.push_back(TestPtr(CppUnit::TestFactoryRegistry::getRegistry("serial").makeTest()));
   }
 
@@ -386,38 +446,115 @@ void populateTests(_TestType t, std::vector<TestPtr>& vTests, bool printDiff,
   }
 }
 
+QMap<QString, QString> getAllowedOptions()
+{
+  // keep this list alphabetized
+  QMap<QString, QString> options;
+  options["--all"] = "Run all the tests";
+  options["--all-names"] = "Print the names of all the tests without running them";
+  options["--case-only"] = "Run the conflate case tests only";
+  options["--current"] = "Run the 'current' level tests";
+  options["--debug"] = "Show debug level log messages and above";
+  options["--diff"] = "Print a diff when a script test fails";
+  options["--error"] = "Show error log level messages and above";
+  options["--exclude=[regex]"] =
+    "Exclude tests that match the specified regex; e.g. HootTest '--exclude=.*building.*'";
+  options["--fatal"] = "Show fatal error log level messages only";
+  options["--glacial"] = "Run 'glacial' level tests and below";
+  options["--glacial-only"] = "Run the 'glacial' level tests only";
+  options["--include=[regex]"] =
+    "Include only tests that match the specified regex; e.g. HootTest '--include=.*building.*'";
+  options["--info"] = "Show info log level messages and above";
+  options["--quick"] = "Run the 'quick' level' tests";
+  options["--quick-only"] = "Run the 'quick' level tests only";
+  options["--names"] = "Show the names of all the tests as they run";
+  options["--parallel [process count]"] =
+    "Run the specified tests in parallel with the specified number of processes";
+  options["--single [test name]"] = "Run only the test specified";
+  options["--slow"] = "Run the 'slow' level tests and above";
+  options["--slow-only"] = "Run the 'slow' level tests only";
+  options["--status"] = "Show status log level messages and above";
+  options["--suppress-failure-detail"] =
+    "Do not show test failure detailed messages; disables --diff for script tests";
+  options["--trace"] = "Show trace log level messages and abov";
+  options["--verbose"] = "Show verbose log level messages and above";
+  options["--warn"] = "Show warning log level messages and above";
+  return options;
+}
+
+QStringList getAllowedOptionNames()
+{
+  QStringList optionNames;
+  const QMap<QString, QString> options = getAllowedOptions();
+  for (QMap<QString, QString>::const_iterator it = options.begin(); it != options.end(); ++it)
+  {
+    optionNames.append(it.key().split(QRegExp("\\s+|="))[0]);
+  }
+  return optionNames;
+}
+
+int largestOptionNameSize()
+{
+  int largest = 0;
+  const QMap<QString, QString> options = getAllowedOptions();
+  for (QMap<QString, QString>::const_iterator it = options.begin(); it != options.end(); ++it)
+  {
+    if (it.key().size() > largest)
+    {
+      largest = it.key().size();
+    }
+  }
+  return largest;
+}
+
 void usage(char* argv)
 {
-  // keep this alphabetized
-  cout << argv << " Usage:\n"
-          "  --all                      - Run all the tests.\n"
-          "  --all-names                - Print the names of all the tests without running them.\n"
-          "  --case-only                - Run the conflate case tests only.\n"
-          "  --current                  - Run the 'current' level tests.\n"
-          "  --debug                    - Show debug level log messages and above.\n"
-          "  --diff                     - Print a diff when a script test fails.\n"
-          "  --error                    - Show error log level messages and above.\n"
-          "  --exclude=[regex]          - Exclude tests that match the specified regex. e.g. HootTest '--exclude=.*building.*'\n"
-          "  --fatal                    - Show fatal error log level messages only.\n"
-          "  --glacial                  - Run 'glacial' level tests and below.\n"
-          "  --glacial-only             - Run the 'glacial' level tests only.\n"
-          "  --include=[regex]          - Include only tests that match the specified regex. e.g. HootTest '--include=.*building.*'\n"
-          "  --info                     - Show info log level messages and above.\n"
-          "  --quick                    - Run the 'quick' level' tests.\n"
-          "  --quick-only               - Run the 'quick' level tests only.\n"
-          "  --names                    - Show the names of all the tests as they run.\n"
-          "  --parallel [process count] - Run the specified tests in parallel with the specified number of processes. With no process count specified, all available CPU cores are used to launch processes.\n"
-          "  --single [test name]       - Run only the test specified.\n"
-          "  --slow                     - Run the 'slow' level tests and above.\n"
-          "  --slow-only                - Run the 'slow' level tests only.\n"
-          "  --status                   - Show status log level messages and above.\n"
-          "  --suppress-failure-detail  - If a test fails, only show the tests' name and do not show a detailed failure message.\n"
-          "  --trace                    - Show trace log level messages and above.\n"
-          "  --verbose                  - Show verbose log level messages and above.\n"
-          "  --warn                     - Show warning log level messages and above.\n"
-          "\n"
-          "See the Hootenanny Developer Guide for more information.\n"
-          ;
+  cout << argv << " Usage:" << endl;
+  const QMap<QString, QString> options = getAllowedOptions();
+  const int largestSize = largestOptionNameSize();
+  for (QMap<QString, QString>::const_iterator it = options.begin(); it != options.end(); ++it)
+  {
+    cout << "  " << it.key();
+    const int numSpaces = largestSize - it.key().size();
+    for (int i = 0; i < numSpaces; i++)
+    {
+      cout << " ";
+    }
+    cout << " - " << it.value() << endl;
+  }
+  cout << endl << "See the Hootenanny Developer Guide for more information." << endl;
+}
+
+_TestType getTestType(const QStringList& args)
+{
+  if (args.contains("--current"))
+    return CURRENT;
+  else if (args.contains("--quick"))
+    return QUICK;
+  else if (args.contains("--quick-only"))
+    return QUICK_ONLY;
+  else if (args.contains("--slow"))
+    return SLOW;
+  else if (args.contains("--slow-only"))
+    return SLOW_ONLY;
+  else if (args.contains("--all") || args.contains("--glacial"))
+    return GLACIAL;
+  else if (args.contains("--glacial-only"))
+    return GLACIAL_ONLY;
+  else if (args.contains("--case-only"))
+    return CASE_ONLY;
+  else
+    return ALL;
+}
+
+_TimeOutValue getTimeoutValue(_TestType type)
+{
+  if (type & GLACIAL)
+      return GLACIAL_WAIT;
+  else if (type & SLOW)
+    return SLOW_WAIT;
+  else
+    return QUICK_WAIT;
 }
 
 int main(int argc, char* argv[])
@@ -446,6 +583,17 @@ int main(int argc, char* argv[])
       args << argv[i];
     }
 
+    const QStringList allowedOptions = getAllowedOptionNames();
+    for (int i = 0; i < args.size(); i++)
+    {
+      const QString arg = args.at(i).split("=")[0];
+      if (arg.startsWith("--") && arg != "--listen" && !allowedOptions.contains(arg))
+      {
+        LOG_ERROR("Invalid HootTest option: " << arg);
+        return 1;
+      }
+    }
+
     Log::getInstance().setLevel(Log::Warn);
     std::vector<TestPtr> vAllTests;
     std::vector<CppUnit::Test*> vTestsToRun;
@@ -458,14 +606,6 @@ int main(int argc, char* argv[])
 
     bool printDiff = args.contains("--diff");
 
-    // Print all names & exit without running anything
-    if (args.contains("--all-names"))
-    {
-      populateTests(ALL, vAllTests, printDiff);
-      printNames(vAllTests);
-      return 0;
-    }
-
     bool suppressFailureDetail = false;
     if (args.contains("--suppress-failure-detail"))
     {
@@ -473,6 +613,17 @@ int main(int argc, char* argv[])
       Log::getInstance().setLevel(Log::Error);
     }
 
+    // Print all names & exit without running anything
+    if (args.contains("--all-names"))
+    {
+      populateTests(getTestType(args), vAllTests, printDiff, suppressFailureDetail);
+      getTestVector(vAllTests, vTestsToRun);
+      includeExcludeTests(args, vTestsToRun);
+      cout << "Test count: " << vTestsToRun.size() << endl;
+      printNames(vTestsToRun);
+      return 0;
+    }
+
     // Run a single test
     if (args.contains("--single"))
     {
@@ -486,7 +637,7 @@ int main(int argc, char* argv[])
       listener.reset(new HootTestListener(false, suppressFailureDetail, -1));
       result.addListener(listener.get());
       Log::getInstance().setLevel(Log::Info);
-      populateTests(ALL, vAllTests, printDiff);
+      populateTests(ALL, vAllTests, printDiff, suppressFailureDetail);
       CppUnit::Test* t = findTest(vAllTests, testName.toStdString());
       if (t == NULL)
       {
@@ -513,7 +664,7 @@ int main(int argc, char* argv[])
       cin >> testName;
       while (testName != HOOT_TEST_FINISHED)
       {
-        populateTests(ALL, vAllTests, printDiff, true);
+        populateTests(ALL, vAllTests, printDiff, suppressFailureDetail, true);
         CppUnit::Test* t = findTest(vAllTests, testName);
         if (t != 0)
         {
@@ -531,80 +682,23 @@ int main(int argc, char* argv[])
     }
     else
     {
-      if (args.contains("--current"))
+      _TestType type = getTestType(args);
+      _TimeOutValue timeout = getTimeoutValue(type);
+      if (type == CURRENT)
       {
-        listener.reset(new HootTestListener(true, suppressFailureDetail));
+        listener.reset(new HootTestListener(true, suppressFailureDetail, timeout));
         Log::getInstance().setLevel(Log::Info);
-        populateTests(CURRENT, vAllTests, printDiff);
-      }
-      else if (args.contains("--quick"))
-      {
-        listener.reset(new HootTestListener(false, suppressFailureDetail, QUICK_WAIT));
-        populateTests(QUICK, vAllTests, printDiff);
-      }
-      else if (args.contains("--quick-only"))
-      {
-        listener.reset(new HootTestListener(false, suppressFailureDetail, QUICK_WAIT));
-        populateTests(QUICK_ONLY, vAllTests, printDiff);
-      }
-      else if (args.contains("--slow"))
-      {
-        listener.reset(new HootTestListener(false, suppressFailureDetail, SLOW_WAIT));
-        populateTests(SLOW, vAllTests, printDiff);
-      }
-      else if (args.contains("--slow-only"))
-      {
-        listener.reset(new HootTestListener(false, suppressFailureDetail, SLOW_WAIT));
-        populateTests(SLOW_ONLY, vAllTests, printDiff);
-      }
-      else if (args.contains("--all") || args.contains("--glacial"))
-      {
-        listener.reset(new HootTestListener(false, suppressFailureDetail, GLACIAL_WAIT));
-        populateTests(GLACIAL, vAllTests, printDiff);
-      }
-      else if (args.contains("--glacial-only"))
-      {
-        listener.reset(new HootTestListener(false, suppressFailureDetail, GLACIAL_WAIT));
-        populateTests(GLACIAL_ONLY, vAllTests, printDiff);
-      }
-      else if (args.contains("--case-only"))
-      {
-        listener.reset(new HootTestListener(false, suppressFailureDetail, SLOW_WAIT));
-        populateTests(CASE_ONLY, vAllTests, printDiff);
       }
+      else
+        listener.reset(new HootTestListener(false, suppressFailureDetail, timeout));
+      //  Populate the list of tests
+      populateTests(type, vAllTests, printDiff, suppressFailureDetail);
 
       vector<CppUnit::Test*> vTests;
-      getTestVector(vAllTests, vTests);
-      bool filtered = false;
-
-      for (int i = 0; i < args.size(); i++)
-      {
-        if (args[i].startsWith("--exclude="))
-        {
-          if (vTestsToRun.size() > 0)
-          {
-            //  On the second (or more) time around exclude from the excluded list
-            vTests.swap(vTestsToRun);
-            vTestsToRun.clear();
-          }
-          int equalsPos = args[i].indexOf('=');
-          QString regex = args[i].mid(equalsPos + 1);
-          LOG_WARN("Excluding pattern: " << regex);
-          filterPattern(vTests, vTestsToRun, regex, false);
-          filtered = true;
-        }
-        else if (args[i].startsWith("--include="))
-        {
-          int equalsPos = args[i].indexOf('=');
-          QString regex = args[i].mid(equalsPos + 1);
-          LOG_WARN("Including only tests that match: " << regex);
-          filterPattern(vTests, vTestsToRun, regex, true);
-          filtered = true;
-        }
-      }
+      getTestVector(vAllTests, vTestsToRun);
+      //  Include or exclude tests
+      includeExcludeTests(args, vTestsToRun);
 
-      if (!filtered) // Do all tests
-        vTestsToRun.swap(vTests);
       cout << "Running core tests.  Test count: " << vTestsToRun.size() << endl;
     }
 
@@ -646,9 +740,11 @@ int main(int argc, char* argv[])
 
       //  Add all of the jobs that must be done serially and are a part of the selected tests
       vector<TestPtr> serialTests;
-      populateTests(SERIAL, serialTests, printDiff, true);
+      populateTests(SERIAL, serialTests, printDiff, suppressFailureDetail, true);
+      vector<CppUnit::Test*> vSerialTests;
+      getTestVector(serialTests, vSerialTests);
       vector<string> serialNames;
-      getNames(serialNames, serialTests);
+      getNames(serialNames, vSerialTests);
       for (vector<string>::iterator it = serialNames.begin(); it != serialNames.end(); ++it)
       {
         if (nameCheck.find(*it) != nameCheck.end())
Clone this wiki locally