Browse Source

Tests: Convert remaining LibC tests to LibTest

Convert them to using outln instead of printf at the same time.
Andrew Kaster 3 years ago
parent
commit
b3e3e4d45d

+ 19 - 23
Tests/LibC/CMakeLists.txt

@@ -1,28 +1,24 @@
 set(TEST_SOURCES
-    ${CMAKE_CURRENT_SOURCE_DIR}/snprintf-correctness.cpp
-    ${CMAKE_CURRENT_SOURCE_DIR}/strlcpy-correctness.cpp
-    ${CMAKE_CURRENT_SOURCE_DIR}/TestLibCTime.cpp
-    ${CMAKE_CURRENT_SOURCE_DIR}/TestLibCMkTemp.cpp
-    ${CMAKE_CURRENT_SOURCE_DIR}/TestLibCExec.cpp
-    ${CMAKE_CURRENT_SOURCE_DIR}/TestLibCDirEnt.cpp
-    ${CMAKE_CURRENT_SOURCE_DIR}/TestLibCInodeWatcher.cpp
-    ${CMAKE_CURRENT_SOURCE_DIR}/TestLibCSetjmp.cpp
-    ${CMAKE_CURRENT_SOURCE_DIR}/TestLibCString.cpp
-    ${CMAKE_CURRENT_SOURCE_DIR}/TestStackSmash.cpp
-    ${CMAKE_CURRENT_SOURCE_DIR}/TestIo.cpp
+    TestIo.cpp
+    TestLibCExec.cpp
+    TestLibCDirEnt.cpp
+    TestLibCInodeWatcher.cpp
+    TestLibCMkTemp.cpp
+    TestLibCSetjmp.cpp
+    TestLibCString.cpp
+    TestLibCTime.cpp
+    TestMemmem.cpp
+    TestQsort.cpp
+    TestRealpath.cpp
+    TestScanf.cpp
+    TestSnprintf.cpp
+    TestStackSmash.cpp
+    TestStrlcpy.cpp
+    TestStrtodAccuracy.cpp
 )
 
-file(GLOB CMD_SOURCES  CONFIGURE_DEPENDS "*.cpp")
-list(REMOVE_ITEM CMD_SOURCES ${TEST_SOURCES})
+set_source_files_properties(TestStrtodAccuracy.cpp PROPERTIES COMPILE_FLAGS "-fno-builtin-strtod")
 
-# FIXME: These tests do not use LibTest
-foreach(CMD_SRC ${CMD_SOURCES})
-    get_filename_component(CMD_NAME ${CMD_SRC} NAME_WE)
-    add_executable(${CMD_NAME} ${CMD_SRC})
-    target_link_libraries(${CMD_NAME} LibCore)
-    install(TARGETS ${CMD_NAME} RUNTIME DESTINATION usr/Tests/LibC)
-endforeach()
-
-foreach(source ${TEST_SOURCES})
-    serenity_test(${source} LibC)
+foreach(source IN LISTS TEST_SOURCES)
+    serenity_test("${source}" LibC)
 endforeach()

+ 4 - 11
Tests/LibC/memmem-tests.cpp → Tests/LibC/TestMemmem.cpp

@@ -4,12 +4,10 @@
  * SPDX-License-Identifier: BSD-2-Clause
  */
 
+#include <LibTest/TestCase.h>
+
 #include <AK/Types.h>
-#include <assert.h>
-#include <stdio.h>
-#include <stdlib.h>
 #include <string.h>
-#include <unistd.h>
 
 struct TestCase {
     const u8* haystack;
@@ -32,20 +30,15 @@ const static TestCase g_test_cases[] = {
     { (const u8[64]) { 0, 1, 1, 2 }, 64u, (const u8[33]) { 1, 1 }, 2u, 1 },
 };
 
-int main()
+TEST_CASE(memmem_search)
 {
-    bool failed = false;
     size_t i = 0;
     for (const auto& test_case : g_test_cases) {
         auto expected = test_case.matching_offset >= 0 ? test_case.haystack + test_case.matching_offset : nullptr;
         auto result = memmem(test_case.haystack, test_case.haystack_length, test_case.needle, test_case.needle_length);
         if (result != expected) {
-            failed = true;
-            fprintf(stderr, "Test %zu FAILED! expected %p, got %p\n", i, expected, result);
+            FAIL(String::formatted("Test {} FAILED! expected {:p}, got {:p}", i, expected, result));
         }
         ++i;
     }
-
-    printf(failed ? "FAIL\n" : "PASS\n");
-    return failed ? 1 : 0;
 }

+ 8 - 10
Tests/LibC/qsort-sorts-and-copies.cpp → Tests/LibC/TestQsort.cpp

@@ -4,10 +4,12 @@
  * SPDX-License-Identifier: BSD-2-Clause
  */
 
+#include <LibTest/TestCase.h>
+
 #include <AK/QuickSort.h>
+#include <AK/Random.h>
 #include <AK/String.h>
 #include <AK/Vector.h>
-#include <stdio.h>
 #include <stdlib.h>
 
 const size_t NUM_RUNS = 100;
@@ -39,13 +41,13 @@ static int calc_payload_for_pos(size_t pos)
 static void shuffle_vec(Vector<SortableObject>& test_objects)
 {
     for (size_t i = 0; i < test_objects.size() * 3; ++i) {
-        auto i1 = rand() % test_objects.size();
-        auto i2 = rand() % test_objects.size();
+        auto i1 = get_random_uniform(test_objects.size());
+        auto i2 = get_random_uniform(test_objects.size());
         swap(test_objects[i1], test_objects[i2]);
     }
 }
 
-int main()
+TEST_CASE(quick_sort)
 {
     // Generate vector of SortableObjects in sorted order, with payloads determined by their sorted positions
     Vector<SortableObject> test_objects;
@@ -61,8 +63,7 @@ int main()
             const auto& key1 = test_objects[i].m_key;
             const auto& key2 = test_objects[i + 1].m_key;
             if (key1 > key2) {
-                printf("\x1b[01;35mTests failed: saw key %d before key %d\n", key1, key2);
-                return 1;
+                FAIL(String::formatted("saw key {} before key {}\n", key1, key2));
             }
         }
         // Check that the object's payloads have not been corrupted
@@ -70,11 +71,8 @@ int main()
             const auto expected = calc_payload_for_pos(i);
             const auto payload = test_objects[i].m_payload;
             if (payload != expected) {
-                printf("\x1b[01;35mTests failed: expected payload %d for pos %u, got payload %d\n", expected, i, payload);
-                return 1;
+                FAIL(String::formatted("Expected payload {} for pos {}, got payload {}", expected, i, payload));
             }
         }
     }
-    printf("PASS\n");
-    return 0;
 }

+ 85 - 0
Tests/LibC/TestRealpath.cpp

@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2021, Ben Wiederhake <BenWiederhake.GitHub@gmx.de>
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#include <LibTest/TestCase.h>
+
+#include <AK/String.h>
+#include <AK/StringBuilder.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+static constexpr char TMPDIR_PATTERN[] = "/tmp/overlong_realpath_XXXXXX";
+static constexpr char PATH_LOREM_250[] = "This-is-an-annoyingly-long-name-that-should-take-up-exactly-two-hundred-and-fifty-characters-and-is-surprisingly-difficult-to-fill-with-reasonably-meaningful-text-which-is-necessary-because-that-makes-it-easier-for-my-eyes-to-spot-any-corruption-fast";
+
+static constexpr size_t ITERATION_DEPTH = 17;
+
+static void check_result(const char* what, const String& expected, const char* actual)
+{
+    if (expected != actual)
+        FAIL(String::formatted("Expected {} to be \"{}\" ({} characters)", what, actual, actual ? strlen(actual) : 0));
+}
+
+TEST_CASE(overlong_realpath)
+{
+    // We want to construct a path that is over PATH_MAX characters long.
+    // This cannot be done in a single step.
+
+    // First, switch to a known environment:
+    char tmp_dir[] = "/tmp/overlong_realpath_XXXXXX";
+
+    errno = 0;
+    auto* new_dir = mkdtemp(tmp_dir);
+    VERIFY(new_dir != nullptr);
+    VERIFY(errno == 0);
+
+    errno = 0;
+    auto ret = chdir(tmp_dir);
+    VERIFY(ret >= 0);
+    VERIFY(errno == 0);
+
+    // Then, create a long path.
+    StringBuilder expected;
+    expected.append(tmp_dir);
+
+    // But first, demonstrate the functionality at a reasonable depth:
+    auto expected_str = expected.build();
+    check_result("getwd", expected_str, getwd(static_cast<char*>(calloc(1, PATH_MAX))));
+    check_result("getcwd", expected_str, getcwd(nullptr, 0));
+    check_result("realpath", expected_str, realpath(".", nullptr));
+
+    for (size_t i = 0; i < ITERATION_DEPTH; ++i) {
+        ret = mkdir(PATH_LOREM_250, S_IRWXU);
+        if (ret < 0) {
+            perror("mkdir iter");
+            FAIL(String::formatted("Unable to mkdir the overlong path fragment in iteration {}", i));
+            return;
+        }
+        expected.append('/');
+        expected.append(PATH_LOREM_250);
+        ret = chdir(PATH_LOREM_250);
+        if (ret < 0) {
+            perror("chdir iter");
+            FAIL(String::formatted("Unable to chdir to the overlong path fragment in iteration {}", i));
+            return;
+        }
+    }
+    outln("cwd should now be ridiculously large");
+
+    // Evaluate
+    expected_str = expected.build();
+
+    check_result("getwd", {}, getwd(static_cast<char*>(calloc(1, PATH_MAX))));
+    check_result("getcwd", expected_str, getcwd(nullptr, 0));
+    check_result("realpath", expected_str, realpath(".", nullptr));
+
+    VERIFY(strlen(PATH_LOREM_250) == 250);
+    VERIFY(strlen(TMPDIR_PATTERN) + ITERATION_DEPTH * (1 + strlen(PATH_LOREM_250)) == expected_str.length());
+    VERIFY(expected_str.length() > PATH_MAX);
+}

+ 4 - 4
Tests/LibC/scanf.cpp → Tests/LibC/TestScanf.cpp

@@ -4,6 +4,8 @@
  * SPDX-License-Identifier: BSD-2-Clause
  */
 
+#include <LibTest/TestCase.h>
+
 #include <AK/Array.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -233,13 +235,11 @@ static void do_one_test(const TestSuite& test)
     else
         printf("    overall FAIL\n");
 
-    g_any_failed = g_any_failed || !overall;
+    VERIFY(overall);
 }
 
-int main()
+TEST_CASE(scanf)
 {
     for (auto& test : test_suites)
         do_one_test(test);
-
-    return g_any_failed ? 1 : 0;
 }

+ 0 - 0
Tests/LibC/snprintf-correctness.cpp → Tests/LibC/TestSnprintf.cpp


+ 0 - 17
Tests/LibC/strlcpy-correctness.cpp → Tests/LibC/TestStrlcpy.cpp

@@ -107,23 +107,6 @@ static bool test_single(const Testcase& testcase)
 // Drop the NUL terminator added by the C++ compiler.
 #define LITERAL(x) x, (sizeof(x) - 1)
 
-//static Testcase TESTCASES[] = {
-//    // Golden path:
-
-//    // Hitting the border:
-
-//    // Too long:
-//    { LITERAL("Hello World!\0"), LITERAL("Hello Friend!"), LITERAL("Hello Friend\0") },
-//    { LITERAL("Hello World!\0"), LITERAL("This source is just *way* too long!"), LITERAL("This source \0") },
-//    { LITERAL("x"), LITERAL("This source is just *way* too long!"), LITERAL("\0") },
-//    // Other special cases:
-//    { LITERAL(""), LITERAL(""), LITERAL("") },
-//    { LITERAL(""), LITERAL("Empty test"), LITERAL("") },
-//    { LITERAL("x"), LITERAL(""), LITERAL("\0") },
-//    { LITERAL("xx"), LITERAL(""), LITERAL("\0x") },
-//    { LITERAL("xxx"), LITERAL(""), LITERAL("\0xx") },
-//};
-
 TEST_CASE(golden_path)
 {
     EXPECT(test_single({ LITERAL("Hello World!\0\0\0"), LITERAL("Hello Friend!"), LITERAL("Hello Friend!\0\0") }));

+ 15 - 19
Tests/LibC/accuracy-strtod.cpp → Tests/LibC/TestStrtodAccuracy.cpp

@@ -4,13 +4,12 @@
  * SPDX-License-Identifier: BSD-2-Clause
  */
 
-#include <assert.h>
-#include <signal.h>
-#include <stdio.h>
+#include <LibTest/TestCase.h>
+
+#include <AK/Format.h>
+#include <AK/String.h>
 #include <stdlib.h>
 #include <string.h>
-#include <time.h>
-#include <unistd.h>
 
 static constexpr char TEXT_ERROR[] = "\x1b[01;35m";
 static constexpr char TEXT_WRONG[] = "\x1b[01;31m";
@@ -291,7 +290,7 @@ static bool is_strtod_close(strtod_fn_t strtod_fn, const char* test_string, cons
     bool error_cns = !actual_consume_possible;
     bool wrong_cns = !error_cns && (actual_consume != expect_consume);
 
-    printf(" %s%s%s(%s%2u%s)",
+    out(" {}{}{}({}{:2}{})",
         ofby1_hex ? TEXT_OFBY1 : wrong_hex ? TEXT_WRONG
                                            : "",
         actual_hex,
@@ -315,8 +314,8 @@ static long long hex_to_ll(const char* hex)
         } else if ('a' <= ch && ch <= 'f') {
             digit = ch - 'a' + 10;
         } else {
-            printf("\n!!! Encountered char %02x at %d.\n", ch, i);
-            assert(false);
+            FAIL(String::formatted("\n!!! Encountered char {:02x} at {}", ch, i));
+            return result;
         }
         result <<= 4;
         result += digit;
@@ -324,10 +323,10 @@ static long long hex_to_ll(const char* hex)
     return result;
 }
 
-int main()
+TEST_CASE(strtod_accuracy)
 {
-    printf("Running %zu testcases...\n", NUM_TESTCASES);
-    printf("%3s(%-5s): %16s(%2s) %16s(%2s) %16s(%2s) %16s(%2s) – %s\n", "num", "name", "correct", "cs", "builtin", "cs", "old_strtod", "cs", "new_strtod", "cs", "teststring");
+    outln("Running {} testcases...", NUM_TESTCASES);
+    outln("{:3}({:-5}): {:16}({:2}) {:16}({:2}) - {}", "num", "name", "correct", "cs", "strtod", "cs", "teststring");
 
     int successes = 0;
     int fails = 0;
@@ -336,13 +335,12 @@ int main()
         if (tc.should_consume == -1) {
             tc.should_consume = strlen(tc.test_string);
         }
-        printf("%3zu(%-5s):", i, tc.test_name);
-        printf(" %s(%2d)", tc.hex, tc.should_consume);
+        out("{:3}({:-5}): {}({:2})", i, tc.test_name, tc.hex, tc.should_consume);
         long long expect_ll = hex_to_ll(tc.hex);
 
         bool success = false;
         success = is_strtod_close(strtod, tc.test_string, tc.hex, tc.should_consume, expect_ll);
-        printf(" from %s\n", tc.test_string);
+        outln(" from {}", tc.test_string);
 
         if (success) {
             successes += 1;
@@ -350,12 +348,10 @@ int main()
             fails += 1;
         }
     }
-    printf("Out of %zu tests, saw %d successes and %d fails.\n", NUM_TESTCASES, successes, fails);
+    outln("Out of {} tests, saw {} successes and {} fails.", NUM_TESTCASES, successes, fails);
     if (fails != 0) {
-        printf("FAIL\n");
-        return 1;
+        FAIL(String::formatted("{} strtod tests failed", fails));
     }
 
-    printf("PASS (with leniency up to %lld ULP from the exact solution.\n", LENIENCY);
-    return 0;
+    outln("PASS (with leniency up to {} ULP from the exact solution)", LENIENCY);
 }

+ 0 - 94
Tests/LibC/overlong_realpath.cpp

@@ -1,94 +0,0 @@
-/*
- * Copyright (c) 2021, Ben Wiederhake <BenWiederhake.GitHub@gmx.de>
- *
- * SPDX-License-Identifier: BSD-2-Clause
- */
-
-#include <AK/String.h>
-#include <AK/StringBuilder.h>
-#include <assert.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/stat.h>
-#include <unistd.h>
-
-// FIXME
-static constexpr char TEXT_FAIL[] = "\x1b[01;31m";
-static constexpr char TEXT_PASS[] = "\x1b[01;32m";
-static constexpr char TEXT_RESET[] = "\x1b[0m";
-
-static constexpr char TMPDIR_PATTERN[] = "/tmp/overlong_realpath_XXXXXX";
-static constexpr char PATH_LOREM_250[] = "This-is-an-annoyingly-long-name-that-should-take-up-exactly-two-hundred-and-fifty-characters-and-is-surprisingly-difficult-to-fill-with-reasonably-meaningful-text-which-is-necessary-because-that-makes-it-easier-for-my-eyes-to-spot-any-corruption-fast";
-
-static constexpr size_t ITERATION_DEPTH = 17;
-
-static bool check_result(const char* what, const String& expected, const char* actual)
-{
-    bool good = expected == actual;
-    printf("%s%s%s: %s = \"%s\" (%zu characters)\n", good ? TEXT_PASS : TEXT_FAIL, good ? "GOOD" : "FAIL", TEXT_RESET, what, actual, actual ? strlen(actual) : 0);
-    return good;
-}
-
-int main()
-{
-    // We want to construct a path that is over PATH_MAX characters long.
-    // This cannot be done in a single step.
-
-    // First, switch to a known environment:
-    char* tmp_dir = strdup("/tmp/overlong_realpath_XXXXXX");
-    if (!mkdtemp(tmp_dir)) {
-        perror("mkdtmp");
-        return 1;
-    }
-    if (chdir(tmp_dir) < 0) {
-        perror("chdir tmpdir");
-        return 1;
-    }
-
-    // Then, create a long path.
-    StringBuilder expected;
-    expected.append(tmp_dir);
-
-    // But first, demonstrate the functionality at a reasonable depth:
-    bool all_good = true;
-    auto expected_str = expected.build();
-    all_good &= check_result("getwd", expected_str, getwd(static_cast<char*>(calloc(1, PATH_MAX))));
-    all_good &= check_result("getcwd", expected_str, getcwd(nullptr, 0));
-    all_good &= check_result("realpath", expected_str, realpath(".", nullptr));
-
-    for (size_t i = 0; i < ITERATION_DEPTH; ++i) {
-        if (mkdir(PATH_LOREM_250, 0700) < 0) {
-            perror("mkdir iter");
-            printf("%sFAILED%s in iteration %zu.\n", TEXT_FAIL, TEXT_RESET, i);
-            return 1;
-        }
-        expected.append('/');
-        expected.append(PATH_LOREM_250);
-        if (chdir(PATH_LOREM_250) < 0) {
-            perror("chdir iter");
-            printf("%sFAILED%s in iteration %zu.\n", TEXT_FAIL, TEXT_RESET, i);
-            return 1;
-        }
-    }
-    printf("cwd should now be ridiculously large.\n");
-
-    // Evaluate
-    expected_str = expected.build();
-
-    all_good &= check_result("getwd", {}, getwd(static_cast<char*>(calloc(1, PATH_MAX))));
-    all_good &= check_result("getcwd", expected_str, getcwd(nullptr, 0));
-    all_good &= check_result("realpath", expected_str, realpath(".", nullptr));
-
-    VERIFY(strlen(PATH_LOREM_250) == 250);
-    VERIFY(strlen(TMPDIR_PATTERN) + ITERATION_DEPTH * (1 + strlen(PATH_LOREM_250)) == expected_str.length());
-    VERIFY(expected_str.length() > PATH_MAX);
-
-    if (all_good) {
-        printf("Overall: %sPASS%s\n", TEXT_PASS, TEXT_RESET);
-        return 0;
-    } else {
-        printf("Overall: %sFAIL%s\n", TEXT_FAIL, TEXT_RESET);
-        return 2;
-    }
-}