-
Notifications
You must be signed in to change notification settings - Fork 162
Expand file tree
/
Copy pathtest_repair.py
More file actions
141 lines (126 loc) · 5.63 KB
/
test_repair.py
File metadata and controls
141 lines (126 loc) · 5.63 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
from __future__ import annotations
from pathlib import Path
from unittest.mock import call, patch
from auditwheel.patcher import Patchelf
from auditwheel.repair import append_rpath_within_wheel, copylib
@patch("auditwheel.patcher._verify_patchelf")
@patch("auditwheel.patcher.check_output")
@patch("auditwheel.patcher.check_call")
class TestRepair:
def test_append_rpath(self, check_call, check_output, _): # noqa: PT019
patcher = Patchelf()
# When a library has an existing RPATH entry within wheel_dir
existing_rpath = b"$ORIGIN/.existinglibdir"
check_output.return_value = existing_rpath
wheel_dir = Path.cwd()
lib_name = Path("test.so")
full_lib_name = lib_name.absolute()
append_rpath_within_wheel(lib_name, "$ORIGIN/.lib", wheel_dir, patcher)
check_output_expected_args = [
call(["patchelf", "--print-rpath", full_lib_name]),
]
# Then that entry is preserved when updating the RPATH
check_call_expected_args = [
call(["patchelf", "--remove-rpath", full_lib_name]),
call(
[
"patchelf",
"--force-rpath",
"--set-rpath",
f"{existing_rpath.decode()}:$ORIGIN/.lib",
full_lib_name,
],
),
]
assert check_output.call_args_list == check_output_expected_args
assert check_call.call_args_list == check_call_expected_args
def test_append_rpath_reject_outside_wheel(self, check_call, check_output, _): # noqa: PT019
patcher = Patchelf()
# When a library has an existing RPATH entry outside wheel_dir
existing_rpath = b"/outside/wheel/dir"
check_output.return_value = existing_rpath
wheel_dir = Path("/not/outside")
lib_name = Path("test.so")
full_lib_name = lib_name.absolute()
append_rpath_within_wheel(lib_name, "$ORIGIN/.lib", wheel_dir, patcher)
check_output_expected_args = [
call(["patchelf", "--print-rpath", full_lib_name]),
]
# Then that entry is eliminated when updating the RPATH
check_call_expected_args = [
call(["patchelf", "--remove-rpath", full_lib_name]),
call(
[
"patchelf",
"--force-rpath",
"--set-rpath",
"$ORIGIN/.lib",
full_lib_name,
],
),
]
assert check_output.call_args_list == check_output_expected_args
assert check_call.call_args_list == check_call_expected_args
def test_append_rpath_ignore_duplicates(self, check_call, check_output, _): # noqa: PT019
patcher = Patchelf()
# When a library has an existing RPATH entry and we try and append it again
existing_rpath = b"$ORIGIN"
check_output.return_value = existing_rpath
wheel_dir = Path.cwd()
lib_name = Path("test.so")
full_lib_name = lib_name.absolute()
append_rpath_within_wheel(lib_name, "$ORIGIN", wheel_dir, patcher)
check_output_expected_args = [
call(["patchelf", "--print-rpath", full_lib_name]),
]
# Then that entry is ignored when updating the RPATH
check_call_expected_args = [
call(["patchelf", "--remove-rpath", full_lib_name]),
call(
["patchelf", "--force-rpath", "--set-rpath", "$ORIGIN", full_lib_name],
),
]
assert check_output.call_args_list == check_output_expected_args
assert check_call.call_args_list == check_call_expected_args
def test_append_rpath_ignore_relative(self, check_call, check_output, _): # noqa: PT019
patcher = Patchelf()
# When a library has an existing RPATH entry but it cannot be resolved
# to an absolute path, it is eliminated
existing_rpath = b"not/absolute"
check_output.return_value = existing_rpath
wheel_dir = Path.cwd()
lib_name = Path("test.so")
full_lib_name = lib_name.absolute()
append_rpath_within_wheel(lib_name, "$ORIGIN", wheel_dir, patcher)
check_output_expected_args = [
call(["patchelf", "--print-rpath", full_lib_name]),
]
# Then that entry is ignored when updating the RPATH
check_call_expected_args = [
call(["patchelf", "--remove-rpath", full_lib_name]),
call(
["patchelf", "--force-rpath", "--set-rpath", "$ORIGIN", full_lib_name],
),
]
assert check_output.call_args_list == check_output_expected_args
assert check_call.call_args_list == check_call_expected_args
@patch("auditwheel.patcher._verify_patchelf")
@patch("auditwheel.patcher.check_output")
@patch("auditwheel.patcher.check_call")
class TestCopylib:
@patch("auditwheel.repair.elf_read_rpaths")
def test_nonexistent_rpath(self, elf_read_rpaths, check_call, _0, _1, tmp_path): # noqa: PT019
# When a library has a non-existent runpath, copylib should still
# call set_rpath to replace it with $ORIGIN
patcher = Patchelf()
src_path = tmp_path / "b.so"
src_path.write_bytes(b"\x00")
dest_dir = tmp_path / "dest"
dest_dir.mkdir()
elf_read_rpaths.return_value = {"rpaths": [], "runpaths": ["/nonexistent/path"]}
copylib(src_path, dest_dir, patcher)
elf_read_rpaths.assert_called_once_with(src_path)
dest_path = next(dest_dir.iterdir())
check_call.assert_any_call(
["patchelf", "--force-rpath", "--set-rpath", "$ORIGIN", dest_path],
)