mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-11-22 15:40:19 +00:00
Tests: Convert remaining LibC tests to LibTest
Convert them to using outln instead of printf at the same time.
This commit is contained in:
parent
1d253880e6
commit
b3e3e4d45d
Notes:
sideshowbarker
2024-07-18 04:58:27 +09:00
Author: https://github.com/ADKaster Commit: https://github.com/SerenityOS/serenity/commit/b3e3e4d45d2 Pull-request: https://github.com/SerenityOS/serenity/pull/9724
9 changed files with 135 additions and 178 deletions
|
@ -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,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;
|
||||
}
|
|
@ -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
Tests/LibC/TestRealpath.cpp
Normal file
85
Tests/LibC/TestRealpath.cpp
Normal file
|
@ -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,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;
|
||||
}
|
|
@ -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") }));
|
|
@ -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);
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue