[libc] Add option to run specific tests
authorCaitlyn Cano <caitlyncano@google.com>
Mon, 12 Jul 2021 20:32:51 +0000 (20:32 +0000)
committerCaitlyn Cano <caitlyncano@google.com>
Fri, 23 Jul 2021 16:08:13 +0000 (16:08 +0000)
This addition reads command line input to run specific single tests
within a larger call to run all the tests for a particular function.
When the user adds a second argument to the command line, the code skips
all the tests that don't match the user's specified binary. If the user
doesn't specify a test correctly and/or no tests are run, a failure
message prints.

Reviewed By: sivachandra, aeubanks

Differential Revision: https://reviews.llvm.org/D105843

libc/cmake/modules/LLVMLibCTestRules.cmake
libc/test/utils/CMakeLists.txt
libc/test/utils/UnitTest/CMakeLists.txt [new file with mode: 0644]
libc/test/utils/UnitTest/testfilter_test.cpp [new file with mode: 0644]
libc/utils/UnitTest/CMakeLists.txt
libc/utils/UnitTest/LibcTest.cpp
libc/utils/UnitTest/LibcTest.h
libc/utils/UnitTest/LibcTestMain.cpp [new file with mode: 0644]

index 4a49981..e16a811 100644 (file)
@@ -74,6 +74,7 @@ function(add_libc_unittest target_name)
     "" # No optional arguments
     "SUITE" # Single value arguments
     "SRCS;HDRS;DEPENDS;COMPILE_OPTIONS" # Multi-value arguments
+    "NO_LIBC_UNITTEST_TEST_MAIN"
     ${ARGN}
   )
   if(NOT LIBC_UNITTEST_SRCS)
@@ -148,7 +149,11 @@ function(add_libc_unittest target_name)
     ${fq_deps_list}
   )
 
-  target_link_libraries(${fq_target_name} PRIVATE LibcUnitTest libc_test_utils)
+  if(NO_LIBC_UNITTEST_TEST_MAIN)
+    target_link_libraries(${fq_target_name} PRIVATE LibcUnitTest libc_test_utils)
+  else()
+    target_link_libraries(${fq_target_name} PRIVATE LibcUnitTest LibcUnitTestMain libc_test_utils)
+  endif()
 
   add_custom_command(
     TARGET ${fq_target_name}
index b658c82..ae00987 100644 (file)
@@ -1,5 +1,6 @@
 add_subdirectory(FPUtil)
 add_subdirectory(CPP)
+add_subdirectory(UnitTest)
 
 if(NOT LLVM_LIBC_FULL_BUILD)
   return()
diff --git a/libc/test/utils/UnitTest/CMakeLists.txt b/libc/test/utils/UnitTest/CMakeLists.txt
new file mode 100644 (file)
index 0000000..68b127a
--- /dev/null
@@ -0,0 +1,11 @@
+add_libc_testsuite(libc_unittest_tests)
+
+add_libc_unittest(
+  testfilter_test
+  SUITE
+    libc_unittest_tests
+  SRCS
+    testfilter_test.cpp
+  DEPENDS
+    libc.utils.CPP.standalone_cpp
+)
diff --git a/libc/test/utils/UnitTest/testfilter_test.cpp b/libc/test/utils/UnitTest/testfilter_test.cpp
new file mode 100644 (file)
index 0000000..8f3a310
--- /dev/null
@@ -0,0 +1,38 @@
+//===-- Tests for Test Filter functionality -------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "utils/UnitTest/LibcTest.h"
+
+TEST(LlvmLibcTestFilterTest, CorrectFilter) {}
+
+TEST(LlvmLibcTestFilterTest, CorrectFilter2) {}
+
+TEST(LlvmLibcTestFilterTest, IncorrectFilter) {}
+
+TEST(LlvmLibcTestFilterTest, NoFilter) {}
+
+TEST(LlvmLibcTestFilterTest, CheckCorrectFilter) {
+  ASSERT_EQ(
+      __llvm_libc::testing::Test::runTests("LlvmLibcTestFilterTest.NoFilter"),
+      0);
+  ASSERT_EQ(__llvm_libc::testing::Test::runTests(
+                "LlvmLibcTestFilterTest.IncorrFilter"),
+            1);
+  ASSERT_EQ(__llvm_libc::testing::Test::runTests(
+                "LlvmLibcTestFilterTest.CorrectFilter"),
+            0);
+  ASSERT_EQ(__llvm_libc::testing::Test::runTests(
+                "LlvmLibcTestFilterTest.CorrectFilter2"),
+            0);
+}
+
+int main() {
+  __llvm_libc::testing::Test::runTests(
+      "LlvmLibcTestFilterTest.CheckCorrectFilter");
+  return 0;
+}
index c0bffe3..b3d2677 100644 (file)
@@ -7,3 +7,13 @@ add_library(
 target_include_directories(LibcUnitTest PUBLIC ${LIBC_SOURCE_DIR})
 add_dependencies(LibcUnitTest libc.utils.CPP.standalone_cpp)
 target_link_libraries(LibcUnitTest PUBLIC libc_test_utils)
+
+add_library(
+  LibcUnitTestMain
+  LibcTestMain.cpp
+)
+
+target_include_directories(LibcUnitTestMain PUBLIC ${LIBC_SOURCE_DIR})
+add_dependencies(LibcUnitTestMain LibcUnitTest libc.utils.CPP.standalone_cpp)
+target_link_libraries(LibcUnitTestMain PUBLIC libc_test_utils)
+
index 016a4e5..dc5c0dd 100644 (file)
@@ -1,4 +1,4 @@
-//===-- Implementation of the base class for libc unittests ---------------===//
+//===-- Implementation of the base class for libc unittests----------------===//
 //
 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
 // See https://llvm.org/LICENSE.txt for license information.
@@ -143,14 +143,18 @@ void Test::addTest(Test *T) {
   End = T;
 }
 
-int Test::runTests() {
+int Test::runTests(const char *TestFilter) {
   int TestCount = 0;
   int FailCount = 0;
-  for (Test *T = Start; T != nullptr; T = T->Next, ++TestCount) {
+  for (Test *T = Start; T != nullptr; T = T->Next) {
     const char *TestName = T->getName();
+    std::string StrTestName(TestName);
     constexpr auto GREEN = "\033[32m";
     constexpr auto RED = "\033[31m";
     constexpr auto RESET = "\033[0m";
+    if ((TestFilter != nullptr) && (StrTestName != TestFilter)) {
+      continue;
+    }
     std::cout << GREEN << "[ RUN      ] " << RESET << TestName << '\n';
     RunContext Ctx;
     T->SetUp();
@@ -167,13 +171,21 @@ int Test::runTests() {
       std::cout << GREEN << "[       OK ] " << RESET << TestName << '\n';
       break;
     }
+    ++TestCount;
   }
 
-  std::cout << "Ran " << TestCount << " tests. "
-            << " PASS: " << TestCount - FailCount << ' '
-            << " FAIL: " << FailCount << '\n';
+  if (TestCount > 0) {
+    std::cout << "Ran " << TestCount << " tests. "
+              << " PASS: " << TestCount - FailCount << ' '
+              << " FAIL: " << FailCount << '\n';
+  } else {
+    std::cout << "No tests run.\n";
+    if (TestFilter) {
+      std::cout << "No matching test for " << TestFilter << '\n';
+    }
+  }
 
-  return FailCount > 0 ? 1 : 0;
+  return FailCount > 0 || TestCount == 0 ? 1 : 0;
 }
 
 template bool Test::test<char, 0>(TestCondition Cond, char LHS, char RHS,
@@ -349,5 +361,3 @@ bool Test::testProcessExits(testutils::FunctionCaller *Func, int ExitCode,
 #endif // ENABLE_SUBPROCESS_TESTS
 } // namespace testing
 } // namespace __llvm_libc
-
-int main() { return __llvm_libc::testing::Test::runTests(); }
index f72d6c1..8e2eec9 100644 (file)
@@ -70,7 +70,7 @@ public:
   virtual void SetUp() {}
   virtual void TearDown() {}
 
-  static int runTests();
+  static int runTests(const char *);
 
 protected:
   static void addTest(Test *T);
diff --git a/libc/utils/UnitTest/LibcTestMain.cpp b/libc/utils/UnitTest/LibcTestMain.cpp
new file mode 100644 (file)
index 0000000..46e19dd
--- /dev/null
@@ -0,0 +1,18 @@
+//===-- Main function for implementation of base class for libc unittests -===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "LibcTest.h"
+
+static const char *getTestFilter(int argc, char *argv[]) {
+  return argc > 1 ? argv[1] : nullptr;
+}
+
+int main(int argc, char *argv[]) {
+  const char *TestFilter = getTestFilter(argc, argv);
+  return __llvm_libc::testing::Test::runTests(TestFilter);
+}