Tests/LibELF: Add basic test checking initializer ordering

This commit is contained in:
Dan Klishch 2024-04-21 22:37:35 -04:00 committed by Andrew Kaster
parent d988b6facc
commit 6894faac1f
Notes: sideshowbarker 2024-07-17 03:59:29 +09:00
6 changed files with 140 additions and 5 deletions

View file

@ -2,7 +2,7 @@
SkipDirectories=Kernel/Legacy Shell
SkipRegex=^ue-.*$
SkipTests=TestCommonmark function.sh
NotTestsPattern=^.*(txt|frm|inc)$
NotTestsPattern=^.*(txt|frm|inc|so|elf)$
[test-js]
Arguments=--show-progress=false

View file

@ -3,10 +3,13 @@ set(CMAKE_SKIP_RPATH FALSE)
macro(add_test_lib NAME FILE)
add_library(${NAME} SHARED ${FILE})
serenity_set_implicit_links(${NAME})
# Avoid execution by the test runner
install(TARGETS ${NAME}
DESTINATION usr/Tests/LibELF
PERMISSIONS OWNER_READ GROUP_READ WORLD_READ OWNER_WRITE GROUP_WRITE)
install(TARGETS ${NAME} DESTINATION usr/Tests/LibELF)
endmacro()
macro(add_test_exe NAME FILE)
add_executable(${NAME} ${FILE})
serenity_set_implicit_links(${NAME})
install(TARGETS ${NAME} DESTINATION usr/Tests/LibELF)
endmacro()
macro(add_dlopen_lib NAME FUNCTION)
@ -28,6 +31,7 @@ unset(CMAKE_INSTALL_RPATH)
set(TEST_SOURCES
test-elf.cpp
TestDlOpen.cpp
TestOrder.cpp
TestTLS.cpp
TestWeakSymbolResolution.cpp
)
@ -48,3 +52,20 @@ add_test_lib(TestWeakSymbolResolution1 TestWeakSymbolResolution1.cpp)
add_test_lib(TestWeakSymbolResolution2 TestWeakSymbolResolution2.cpp)
target_link_libraries(TestWeakSymbolResolution PRIVATE TestWeakSymbolResolution1 TestWeakSymbolResolution2)
set_target_properties(TestWeakSymbolResolution PROPERTIES INSTALL_RPATH "$ORIGIN")
add_test_lib(TestOrderLib1 TestOrderLib1.cpp)
add_test_lib(TestOrderLib2 TestOrderLib2.cpp)
target_link_libraries(TestOrderLib2 PRIVATE TestOrderLib1)
set_target_properties(TestOrderLib2 PROPERTIES INSTALL_RPATH "$ORIGIN")
# NOTE: This is so ugly because CMake sorts targets supplied to target_link_libraries.
# .elf extension here avoids direct invocations by SerenityOS's test runner.
add_test_exe(TestOrderExe1.elf TestOrderExe.cpp)
target_link_libraries(TestOrderExe1.elf PRIVATE $<TARGET_FILE:TestOrderLib1> $<TARGET_FILE:TestOrderLib2>)
add_dependencies(TestOrderExe1.elf TestOrderLib1 TestOrderLib2)
set_target_properties(TestOrderExe1.elf PROPERTIES INSTALL_RPATH "$ORIGIN")
add_test_exe(TestOrderExe2.elf TestOrderExe.cpp)
target_link_libraries(TestOrderExe2.elf PRIVATE $<TARGET_FILE:TestOrderLib2> $<TARGET_FILE:TestOrderLib1>)
add_dependencies(TestOrderExe2.elf TestOrderLib1 TestOrderLib2)
set_target_properties(TestOrderExe2.elf PROPERTIES INSTALL_RPATH "$ORIGIN")

View file

@ -0,0 +1,58 @@
/*
* Copyright (c) 2024, Dan Klishch <danilklishch@gmail.com>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#include <AK/LexicalPath.h>
#include <LibCore/Process.h>
#include <LibFileSystem/TempFile.h>
#include <LibTest/TestCase.h>
auto temp_directory = [] {
return MUST(FileSystem::TempFile::create_temp_directory());
}();
static ByteBuffer run(ByteString executable)
{
static auto path_to_captured_output = LexicalPath::join(temp_directory->path(), "output"sv);
auto process = MUST(Core::Process::spawn(Core::ProcessSpawnOptions {
.executable = move(executable),
.file_actions = {
Core::FileAction::OpenFile {
.path = path_to_captured_output.string(),
.mode = Core::File::OpenMode::Write,
.fd = 1,
},
},
}));
MUST(process.wait_for_termination());
auto output = MUST(Core::File::open(path_to_captured_output.string(), Core::File::OpenMode::Read));
return MUST(output->read_until_eof());
}
TEST_CASE(order)
{
{
auto expected = R"(TestOrderLib1.cpp:init
TestOrderLib2.cpp:init
TestOrderExe.cpp:init
TestOrderExe.cpp:main
f() returns: TestOrderLib1.cpp
)"sv;
auto output = run("TestOrderExe1.elf");
EXPECT_EQ(StringView(output.bytes()), expected);
}
{
auto expected = R"(TestOrderLib1.cpp:init
TestOrderLib2.cpp:init
TestOrderExe.cpp:init
TestOrderExe.cpp:main
f() returns: TestOrderLib2.cpp
)"sv;
auto output = run("TestOrderExe2.elf");
EXPECT_EQ(StringView(output.bytes()), expected);
}
}

View file

@ -0,0 +1,20 @@
/*
* Copyright (c) 2024, Dan Klishch <danilklishch@gmail.com>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#include <AK/Format.h>
[[gnu::constructor]] static void init()
{
outln("TestOrderExe.cpp:init");
}
StringView f();
int main()
{
outln("TestOrderExe.cpp:main");
outln("f() returns: {}", f());
}

View file

@ -0,0 +1,18 @@
/*
* Copyright (c) 2024, Dan Klishch <danilklishch@gmail.com>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#include <AK/Format.h>
[[gnu::constructor]] static void init()
{
outln("TestOrderLib1.cpp:init");
}
StringView f();
StringView f()
{
return "TestOrderLib1.cpp"sv;
}

View file

@ -0,0 +1,18 @@
/*
* Copyright (c) 2024, Dan Klishch <danilklishch@gmail.com>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#include <AK/Format.h>
[[gnu::constructor]] static void init()
{
outln("TestOrderLib2.cpp:init");
}
StringView f();
StringView f()
{
return "TestOrderLib2.cpp"sv;
}