diff --git a/libc/cmake/modules/LLVMLibCTestRules.cmake b/libc/cmake/modules/LLVMLibCTestRules.cmake --- a/libc/cmake/modules/LLVMLibCTestRules.cmake +++ b/libc/cmake/modules/LLVMLibCTestRules.cmake @@ -74,6 +74,7 @@ "" # No optional arguments "SUITE" # Single value arguments "SRCS;HDRS;DEPENDS;COMPILE_OPTIONS" # Multi-value arguments + "LIBC_UNITTEST_TEST_MAIN" ${ARGN} ) if(NOT LIBC_UNITTEST_SRCS) @@ -148,7 +149,11 @@ ${fq_deps_list} ) - target_link_libraries(${fq_target_name} PRIVATE LibcUnitTest libc_test_utils) + if(LIBC_UNITTEST_TEST_MAIN) + target_link_libraries(${fq_target_name} PRIVATE LibcUnitTest testfilter_test libc_test_utils) + else() + target_link_libraries(${fq_target_name} PRIVATE LibcUnitTest LibcUnitTestMain libc_test_utils) + endif() add_custom_command( TARGET ${fq_target_name} diff --git a/libc/test/utils/CMakeLists.txt b/libc/test/utils/CMakeLists.txt --- a/libc/test/utils/CMakeLists.txt +++ b/libc/test/utils/CMakeLists.txt @@ -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 --- /dev/null +++ b/libc/test/utils/UnitTest/CMakeLists.txt @@ -0,0 +1,11 @@ +add_libc_testsuite(libc_libctest_runtests_unittests) + +add_libc_unittest( + testfilter_test + SUITE + libc_libctest_runtests_unittests + 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 --- /dev/null +++ b/libc/test/utils/UnitTest/testfilter_test.cpp @@ -0,0 +1,40 @@ +// ===-- 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" + +const char *TestFilter; + +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; +} diff --git a/libc/utils/UnitTest/CMakeLists.txt b/libc/utils/UnitTest/CMakeLists.txt --- a/libc/utils/UnitTest/CMakeLists.txt +++ b/libc/utils/UnitTest/CMakeLists.txt @@ -7,3 +7,13 @@ 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 LibcUnitTest ${LIBC_SOURCE_DIR}) +add_dependencies(LibcUnitTestMain LibcUnitTest libc.utils.CPP.standalone_cpp) +target_link_libraries(LibcUnitTestMain PUBLIC libc_test_utils) + diff --git a/libc/utils/UnitTest/LibcTest.h b/libc/utils/UnitTest/LibcTest.h --- a/libc/utils/UnitTest/LibcTest.h +++ b/libc/utils/UnitTest/LibcTest.h @@ -70,7 +70,7 @@ 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/LibcTest.cpp b/libc/utils/UnitTest/LibcTest.cpp --- a/libc/utils/UnitTest/LibcTest.cpp +++ b/libc/utils/UnitTest/LibcTest.cpp @@ -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 @@ 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 != NULL) && (StrTestName != TestFilter)) { + continue; + } std::cout << GREEN << "[ RUN ] " << RESET << TestName << '\n'; RunContext Ctx; T->SetUp(); @@ -167,13 +171,21 @@ 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(TestCondition Cond, char LHS, char RHS, @@ -349,5 +361,3 @@ #endif // ENABLE_SUBPROCESS_TESTS } // namespace testing } // namespace __llvm_libc - -int main() { return __llvm_libc::testing::Test::runTests(); } diff --git a/libc/utils/UnitTest/LibcTestMain.cpp b/libc/utils/UnitTest/LibcTestMain.cpp new file mode 100644 --- /dev/null +++ b/libc/utils/UnitTest/LibcTestMain.cpp @@ -0,0 +1,20 @@ +//===Main function for 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. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "LibcTest.h" + +#include + +static const char *getTestFilter(int argc, char *argv[]) { + return argc > 1 ? argv[1] : NULL; +} + +int main(int argc, char *argv[]) { + const char *TestFilter = getTestFilter(argc, argv); + return __llvm_libc::testing::Test::runTests(TestFilter); +}