Skip to content

Commit 6894faa

Browse files
DanShadersADKaster
authored andcommitted
Tests/LibELF: Add basic test checking initializer ordering
1 parent d988b6f commit 6894faa

File tree

6 files changed

+140
-5
lines changed

6 files changed

+140
-5
lines changed

Base/home/anon/.config/Tests.ini

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
SkipDirectories=Kernel/Legacy Shell
33
SkipRegex=^ue-.*$
44
SkipTests=TestCommonmark function.sh
5-
NotTestsPattern=^.*(txt|frm|inc)$
5+
NotTestsPattern=^.*(txt|frm|inc|so|elf)$
66

77
[test-js]
88
Arguments=--show-progress=false

Tests/LibELF/CMakeLists.txt

+25-4
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,13 @@ set(CMAKE_SKIP_RPATH FALSE)
33
macro(add_test_lib NAME FILE)
44
add_library(${NAME} SHARED ${FILE})
55
serenity_set_implicit_links(${NAME})
6-
# Avoid execution by the test runner
7-
install(TARGETS ${NAME}
8-
DESTINATION usr/Tests/LibELF
9-
PERMISSIONS OWNER_READ GROUP_READ WORLD_READ OWNER_WRITE GROUP_WRITE)
6+
install(TARGETS ${NAME} DESTINATION usr/Tests/LibELF)
7+
endmacro()
8+
9+
macro(add_test_exe NAME FILE)
10+
add_executable(${NAME} ${FILE})
11+
serenity_set_implicit_links(${NAME})
12+
install(TARGETS ${NAME} DESTINATION usr/Tests/LibELF)
1013
endmacro()
1114

1215
macro(add_dlopen_lib NAME FUNCTION)
@@ -28,6 +31,7 @@ unset(CMAKE_INSTALL_RPATH)
2831
set(TEST_SOURCES
2932
test-elf.cpp
3033
TestDlOpen.cpp
34+
TestOrder.cpp
3135
TestTLS.cpp
3236
TestWeakSymbolResolution.cpp
3337
)
@@ -48,3 +52,20 @@ add_test_lib(TestWeakSymbolResolution1 TestWeakSymbolResolution1.cpp)
4852
add_test_lib(TestWeakSymbolResolution2 TestWeakSymbolResolution2.cpp)
4953
target_link_libraries(TestWeakSymbolResolution PRIVATE TestWeakSymbolResolution1 TestWeakSymbolResolution2)
5054
set_target_properties(TestWeakSymbolResolution PROPERTIES INSTALL_RPATH "$ORIGIN")
55+
56+
add_test_lib(TestOrderLib1 TestOrderLib1.cpp)
57+
add_test_lib(TestOrderLib2 TestOrderLib2.cpp)
58+
target_link_libraries(TestOrderLib2 PRIVATE TestOrderLib1)
59+
set_target_properties(TestOrderLib2 PROPERTIES INSTALL_RPATH "$ORIGIN")
60+
61+
# NOTE: This is so ugly because CMake sorts targets supplied to target_link_libraries.
62+
# .elf extension here avoids direct invocations by SerenityOS's test runner.
63+
add_test_exe(TestOrderExe1.elf TestOrderExe.cpp)
64+
target_link_libraries(TestOrderExe1.elf PRIVATE $<TARGET_FILE:TestOrderLib1> $<TARGET_FILE:TestOrderLib2>)
65+
add_dependencies(TestOrderExe1.elf TestOrderLib1 TestOrderLib2)
66+
set_target_properties(TestOrderExe1.elf PROPERTIES INSTALL_RPATH "$ORIGIN")
67+
68+
add_test_exe(TestOrderExe2.elf TestOrderExe.cpp)
69+
target_link_libraries(TestOrderExe2.elf PRIVATE $<TARGET_FILE:TestOrderLib2> $<TARGET_FILE:TestOrderLib1>)
70+
add_dependencies(TestOrderExe2.elf TestOrderLib1 TestOrderLib2)
71+
set_target_properties(TestOrderExe2.elf PROPERTIES INSTALL_RPATH "$ORIGIN")

Tests/LibELF/TestOrder.cpp

+58
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
/*
2+
* Copyright (c) 2024, Dan Klishch <[email protected]>
3+
*
4+
* SPDX-License-Identifier: BSD-2-Clause
5+
*/
6+
7+
#include <AK/LexicalPath.h>
8+
#include <LibCore/Process.h>
9+
#include <LibFileSystem/TempFile.h>
10+
#include <LibTest/TestCase.h>
11+
12+
auto temp_directory = [] {
13+
return MUST(FileSystem::TempFile::create_temp_directory());
14+
}();
15+
16+
static ByteBuffer run(ByteString executable)
17+
{
18+
static auto path_to_captured_output = LexicalPath::join(temp_directory->path(), "output"sv);
19+
20+
auto process = MUST(Core::Process::spawn(Core::ProcessSpawnOptions {
21+
.executable = move(executable),
22+
.file_actions = {
23+
Core::FileAction::OpenFile {
24+
.path = path_to_captured_output.string(),
25+
.mode = Core::File::OpenMode::Write,
26+
.fd = 1,
27+
},
28+
},
29+
}));
30+
MUST(process.wait_for_termination());
31+
auto output = MUST(Core::File::open(path_to_captured_output.string(), Core::File::OpenMode::Read));
32+
return MUST(output->read_until_eof());
33+
}
34+
35+
TEST_CASE(order)
36+
{
37+
{
38+
auto expected = R"(TestOrderLib1.cpp:init
39+
TestOrderLib2.cpp:init
40+
TestOrderExe.cpp:init
41+
TestOrderExe.cpp:main
42+
f() returns: TestOrderLib1.cpp
43+
)"sv;
44+
auto output = run("TestOrderExe1.elf");
45+
EXPECT_EQ(StringView(output.bytes()), expected);
46+
}
47+
48+
{
49+
auto expected = R"(TestOrderLib1.cpp:init
50+
TestOrderLib2.cpp:init
51+
TestOrderExe.cpp:init
52+
TestOrderExe.cpp:main
53+
f() returns: TestOrderLib2.cpp
54+
)"sv;
55+
auto output = run("TestOrderExe2.elf");
56+
EXPECT_EQ(StringView(output.bytes()), expected);
57+
}
58+
}

Tests/LibELF/TestOrderExe.cpp

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
/*
2+
* Copyright (c) 2024, Dan Klishch <[email protected]>
3+
*
4+
* SPDX-License-Identifier: BSD-2-Clause
5+
*/
6+
7+
#include <AK/Format.h>
8+
9+
[[gnu::constructor]] static void init()
10+
{
11+
outln("TestOrderExe.cpp:init");
12+
}
13+
14+
StringView f();
15+
16+
int main()
17+
{
18+
outln("TestOrderExe.cpp:main");
19+
outln("f() returns: {}", f());
20+
}

Tests/LibELF/TestOrderLib1.cpp

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
/*
2+
* Copyright (c) 2024, Dan Klishch <[email protected]>
3+
*
4+
* SPDX-License-Identifier: BSD-2-Clause
5+
*/
6+
7+
#include <AK/Format.h>
8+
9+
[[gnu::constructor]] static void init()
10+
{
11+
outln("TestOrderLib1.cpp:init");
12+
}
13+
14+
StringView f();
15+
StringView f()
16+
{
17+
return "TestOrderLib1.cpp"sv;
18+
}

Tests/LibELF/TestOrderLib2.cpp

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
/*
2+
* Copyright (c) 2024, Dan Klishch <[email protected]>
3+
*
4+
* SPDX-License-Identifier: BSD-2-Clause
5+
*/
6+
7+
#include <AK/Format.h>
8+
9+
[[gnu::constructor]] static void init()
10+
{
11+
outln("TestOrderLib2.cpp:init");
12+
}
13+
14+
StringView f();
15+
StringView f()
16+
{
17+
return "TestOrderLib2.cpp"sv;
18+
}

0 commit comments

Comments
 (0)