Skip to content

Commit 7ad6f76

Browse files
committed
add tests
1 parent 26e6bd0 commit 7ad6f76

File tree

4 files changed

+844
-2
lines changed

4 files changed

+844
-2
lines changed
Lines changed: 252 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,252 @@
1+
from __future__ import annotations
2+
3+
import argparse
4+
from pathlib import Path
5+
from unittest.mock import MagicMock, patch
6+
7+
import pytest
8+
9+
from auditwheel.main_repair import ( # type: ignore[import-not-found]
10+
configure_parser,
11+
execute,
12+
)
13+
from auditwheel.repair import StripLevel # type: ignore[import-not-found]
14+
15+
16+
class TestMainRepairDebugSymbols:
17+
"""Test CLI argument parsing for debug symbol functionality."""
18+
19+
def test_configure_parser_new_arguments(self):
20+
"""Test that new debug symbol arguments are configured correctly."""
21+
parser = argparse.ArgumentParser()
22+
subparsers = parser.add_subparsers()
23+
configure_parser(subparsers)
24+
25+
# Test parsing with new arguments
26+
args = parser.parse_args(
27+
[
28+
"repair",
29+
"--strip-level=debug",
30+
"--collect-debug-symbols",
31+
"--debug-symbols-output=/path/to/debug.zip",
32+
"test.whl",
33+
]
34+
)
35+
36+
assert args.STRIP_LEVEL == "debug"
37+
assert args.COLLECT_DEBUG_SYMBOLS is True
38+
assert Path("/path/to/debug.zip") == args.DEBUG_SYMBOLS_OUTPUT
39+
40+
def test_strip_level_choices(self):
41+
"""Test that strip-level accepts all valid choices."""
42+
parser = argparse.ArgumentParser()
43+
subparsers = parser.add_subparsers()
44+
configure_parser(subparsers)
45+
46+
for level in StripLevel:
47+
args = parser.parse_args(
48+
["repair", f"--strip-level={level.value}", "test.whl"]
49+
)
50+
assert level.value == args.STRIP_LEVEL
51+
52+
def test_strip_level_invalid_choice(self):
53+
"""Test that invalid strip-level raises error."""
54+
parser = argparse.ArgumentParser()
55+
subparsers = parser.add_subparsers()
56+
configure_parser(subparsers)
57+
58+
with pytest.raises(SystemExit):
59+
parser.parse_args(["repair", "--strip-level=invalid", "test.whl"])
60+
61+
def test_default_values(self):
62+
"""Test default values for new arguments."""
63+
parser = argparse.ArgumentParser()
64+
subparsers = parser.add_subparsers()
65+
configure_parser(subparsers)
66+
67+
args = parser.parse_args(["repair", "test.whl"])
68+
69+
assert args.STRIP_LEVEL == "none"
70+
assert args.COLLECT_DEBUG_SYMBOLS is False
71+
assert args.DEBUG_SYMBOLS_OUTPUT is None
72+
assert args.STRIP is False # Backward compatibility
73+
74+
def test_deprecated_strip_help_text(self):
75+
"""Test that deprecated strip option shows deprecation in help."""
76+
# Test by creating a standalone parser with just the repair subcommand
77+
main_parser = argparse.ArgumentParser()
78+
subparsers = main_parser.add_subparsers()
79+
configure_parser(subparsers)
80+
81+
# Alternative: Test that the deprecated argument is still accepted
82+
# and verify the help text is configured correctly by parsing arguments
83+
args = main_parser.parse_args(["repair", "--strip", "test.whl"])
84+
assert args.STRIP is True
85+
86+
# The deprecation text is in the help, but we'll just test functionality
87+
# since accessing subparser internals is brittle
88+
89+
90+
class TestMainRepairExecute:
91+
"""Test the execute function with debug symbol arguments."""
92+
93+
@patch("auditwheel.main_repair.repair_wheel")
94+
@patch("auditwheel.main_repair.analyze_wheel_abi")
95+
@patch("auditwheel.main_repair.Patchelf")
96+
def test_execute_with_strip_level_debug(self, mock_analyze, mock_repair):
97+
"""Test execute function with strip-level=debug."""
98+
99+
# Mock objects
100+
mock_wheel_abi = MagicMock()
101+
mock_wheel_abi.full_external_refs = {"ext.so": {}}
102+
mock_wheel_abi.policies = MagicMock()
103+
mock_wheel_abi.policies.lowest.name = "manylinux_2_17_x86_64"
104+
mock_wheel_abi.overall_policy = mock_wheel_abi.policies.lowest
105+
mock_wheel_abi.sym_policy = mock_wheel_abi.policies.lowest
106+
mock_wheel_abi.ucs_policy = mock_wheel_abi.policies.lowest
107+
mock_wheel_abi.blacklist_policy = mock_wheel_abi.policies.lowest
108+
mock_wheel_abi.machine_policy = mock_wheel_abi.policies.lowest
109+
110+
mock_analyze.return_value = mock_wheel_abi
111+
mock_repair.return_value = Path("output.whl")
112+
113+
# Create mock args
114+
args = MagicMock()
115+
args.WHEEL_FILE = [Path("test.whl")]
116+
args.WHEEL_DIR = Path("wheelhouse")
117+
args.LIB_SDIR = ".libs"
118+
args.PLAT = "auto"
119+
args.UPDATE_TAGS = True
120+
args.ONLY_PLAT = False
121+
args.EXCLUDE = []
122+
args.DISABLE_ISA_EXT_CHECK = False
123+
args.ZIP_COMPRESSION_LEVEL = 6
124+
args.STRIP = False
125+
args.STRIP_LEVEL = "debug"
126+
args.COLLECT_DEBUG_SYMBOLS = True
127+
args.DEBUG_SYMBOLS_OUTPUT = Path("debug.zip")
128+
129+
parser = MagicMock()
130+
131+
with (
132+
patch("auditwheel.main_repair.Path.mkdir"),
133+
patch("auditwheel.main_repair.Path.exists", return_value=True),
134+
patch("auditwheel.main_repair.Path.is_file", return_value=True),
135+
patch("auditwheel.main_repair.get_wheel_architecture"),
136+
patch("auditwheel.main_repair.get_wheel_libc"),
137+
):
138+
result = execute(args, parser)
139+
140+
assert result == 0
141+
mock_repair.assert_called_once()
142+
143+
# Verify repair_wheel was called with correct arguments
144+
call_args = mock_repair.call_args
145+
assert (
146+
call_args[1]["strip"] is None
147+
) # strip should be None when using strip_level
148+
assert call_args[1]["strip_level"] == StripLevel.DEBUG
149+
assert call_args[1]["collect_debug_symbols"] is True
150+
assert call_args[1]["debug_symbols_output"] == Path("debug.zip")
151+
152+
@patch("auditwheel.main_repair.repair_wheel")
153+
@patch("auditwheel.main_repair.analyze_wheel_abi")
154+
@patch("auditwheel.main_repair.Patchelf")
155+
def test_execute_with_deprecated_strip(self, mock_analyze, mock_repair):
156+
"""Test execute function with deprecated --strip flag."""
157+
158+
# Mock objects
159+
mock_wheel_abi = MagicMock()
160+
mock_wheel_abi.full_external_refs = {"ext.so": {}}
161+
mock_wheel_abi.policies = MagicMock()
162+
mock_wheel_abi.policies.lowest.name = "manylinux_2_17_x86_64"
163+
mock_wheel_abi.overall_policy = mock_wheel_abi.policies.lowest
164+
mock_wheel_abi.sym_policy = mock_wheel_abi.policies.lowest
165+
mock_wheel_abi.ucs_policy = mock_wheel_abi.policies.lowest
166+
mock_wheel_abi.blacklist_policy = mock_wheel_abi.policies.lowest
167+
mock_wheel_abi.machine_policy = mock_wheel_abi.policies.lowest
168+
169+
mock_analyze.return_value = mock_wheel_abi
170+
mock_repair.return_value = Path("output.whl")
171+
172+
# Create mock args
173+
args = MagicMock()
174+
args.WHEEL_FILE = [Path("test.whl")]
175+
args.WHEEL_DIR = Path("wheelhouse")
176+
args.LIB_SDIR = ".libs"
177+
args.PLAT = "auto"
178+
args.UPDATE_TAGS = True
179+
args.ONLY_PLAT = False
180+
args.EXCLUDE = []
181+
args.DISABLE_ISA_EXT_CHECK = False
182+
args.ZIP_COMPRESSION_LEVEL = 6
183+
args.STRIP = True
184+
args.STRIP_LEVEL = "none"
185+
args.COLLECT_DEBUG_SYMBOLS = False
186+
args.DEBUG_SYMBOLS_OUTPUT = None
187+
188+
parser = MagicMock()
189+
190+
with (
191+
patch("auditwheel.main_repair.Path.mkdir"),
192+
patch("auditwheel.main_repair.Path.exists", return_value=True),
193+
patch("auditwheel.main_repair.Path.is_file", return_value=True),
194+
patch("auditwheel.main_repair.get_wheel_architecture"),
195+
patch("auditwheel.main_repair.get_wheel_libc"),
196+
patch("auditwheel.main_repair.warnings.warn") as mock_warn,
197+
):
198+
result = execute(args, parser)
199+
200+
assert result == 0
201+
mock_repair.assert_called_once()
202+
203+
# Verify deprecation warning was issued
204+
mock_warn.assert_called_once_with(
205+
"The --strip option is deprecated. Use --strip-level=all instead.",
206+
DeprecationWarning,
207+
stacklevel=2,
208+
)
209+
210+
# Verify repair_wheel was called with correct arguments
211+
call_args = mock_repair.call_args
212+
assert call_args[1]["strip"] is True
213+
assert call_args[1]["strip_level"] == StripLevel("none")
214+
215+
def test_execute_conflicting_strip_arguments(self):
216+
"""Test that conflicting strip arguments cause an error."""
217+
218+
# Create mock args with conflicting strip options
219+
args = MagicMock()
220+
args.WHEEL_FILE = [Path("test.whl")]
221+
args.STRIP = True
222+
args.STRIP_LEVEL = "debug" # Conflicts with STRIP=True
223+
224+
parser = MagicMock()
225+
226+
with patch("auditwheel.main_repair.Path.is_file", return_value=True):
227+
execute(args, parser)
228+
229+
# Should call parser.error
230+
parser.error.assert_called_once_with(
231+
"Cannot specify both --strip and --strip-level"
232+
)
233+
234+
def test_execute_collect_debug_without_stripping(self):
235+
"""Test that collect-debug-symbols without stripping causes an error."""
236+
237+
# Create mock args
238+
args = MagicMock()
239+
args.WHEEL_FILE = [Path("test.whl")]
240+
args.STRIP = False
241+
args.STRIP_LEVEL = "none"
242+
args.COLLECT_DEBUG_SYMBOLS = True
243+
244+
parser = MagicMock()
245+
246+
with patch("auditwheel.main_repair.Path.is_file", return_value=True):
247+
execute(args, parser)
248+
249+
# Should call parser.error
250+
parser.error.assert_called_once_with(
251+
"--collect-debug-symbols requires stripping to be enabled. Use --strip-level or --strip."
252+
)

tests/unit/test_repair.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,10 @@
33
from pathlib import Path
44
from unittest.mock import call, patch
55

6-
from auditwheel.patcher import Patchelf
7-
from auditwheel.repair import append_rpath_within_wheel
6+
from auditwheel.patcher import Patchelf # type: ignore[import-not-found]
7+
from auditwheel.repair import ( # type: ignore[import-not-found]
8+
append_rpath_within_wheel,
9+
)
810

911

1012
@patch("auditwheel.patcher._verify_patchelf")

0 commit comments

Comments
 (0)