one more test on real sysiphus packets

This commit is contained in:
2026-08-17 04:48:19 +03:00
parent f72d345f0d
commit 452190b8c4
12 changed files with 578801 additions and 0 deletions
@@ -0,0 +1,195 @@
#!/usr/bin/env python3
"""Behavior tests for extract_provided_symbols.py."""
from __future__ import annotations
import stat
import subprocess
import sys
import tempfile
import unittest
from pathlib import Path
ROOT = Path(__file__).resolve().parents[1]
SCRIPT = ROOT / "extract_provided_symbols.py"
def newc_entry(name: str, data: bytes, mode: int = stat.S_IFREG | 0o644) -> bytes:
encoded_name = name.encode("utf-8") + b"\0"
fields = (
1,
mode,
0,
0,
1,
0,
len(data),
0,
0,
0,
0,
len(encoded_name),
0,
)
header = b"070701" + b"".join(f"{value:08x}".encode() for value in fields)
record = header + encoded_name
record += b"\0" * (-len(record) % 4)
record += data
record += b"\0" * (-len(data) % 4)
return record
def newc_archive(entries: list[tuple[str, bytes, int]]) -> bytes:
payload = b"".join(newc_entry(*entry) for entry in entries)
return payload + newc_entry("TRAILER!!!", b"", 0)
class ExtractProvidedSymbolsTests(unittest.TestCase):
def setUp(self) -> None:
self.temporary_directory = tempfile.TemporaryDirectory()
self.work = Path(self.temporary_directory.name)
self.rpm2cpio = self.work / "rpm2cpio"
self.provided_symbols = self.work / "provided_symbols"
self.file_command = self.work / "file"
self.rpm2cpio.write_text(
"#!/usr/bin/env python3\n"
"import pathlib, sys\n"
"sys.stdout.buffer.write(pathlib.Path(sys.argv[1]).read_bytes())\n"
)
self.provided_symbols.write_text(
"#!/usr/bin/env python3\n"
"import pathlib, sys\n"
"symbols = set()\n"
"for name in sys.argv[1:]:\n"
" symbols.update(pathlib.Path(name).read_bytes()[4:].decode().splitlines())\n"
"print(*sorted(symbols), sep='\\n')\n"
)
self.file_command.write_text(
"#!/usr/bin/env python3\n"
"import pathlib, sys\n"
"data = pathlib.Path(sys.argv[-1]).read_bytes()\n"
"kind = 'pie executable' if b'EXECUTABLE' in data else 'shared object'\n"
"print(f'ELF 64-bit LSB {kind}, x86-64, version 1 (SYSV)')\n"
)
self.rpm2cpio.chmod(0o755)
self.provided_symbols.chmod(0o755)
self.file_command.chmod(0o755)
def tearDown(self) -> None:
self.temporary_directory.cleanup()
def run_script(self, *arguments: str) -> subprocess.CompletedProcess[str]:
return subprocess.run(
[
sys.executable,
str(SCRIPT),
"--rpm2cpio",
str(self.rpm2cpio),
"--provided-symbols",
str(self.provided_symbols),
"--file-command",
str(self.file_command),
*arguments,
],
capture_output=True,
text=True,
check=False,
)
def test_combines_unique_cpp_symbols_from_multiple_packages(self) -> None:
first = self.work / "first.rpm"
second = self.work / "second.rpm"
output = self.work / "symbols.txt"
first.write_bytes(
newc_archive(
[
("./usr/lib64/libfirst.so", b"\x7fELF_ZN3Foo3barEv\nplain_c_symbol\n", stat.S_IFREG | 0o755),
("./usr/share/doc/readme", b"not ELF", stat.S_IFREG | 0o644),
("./usr/lib64/libalias.so", b"libfirst.so", stat.S_IFLNK | 0o777),
]
)
)
second.write_bytes(
newc_archive(
[
(
"./usr/lib64/libsecond.so",
b"\x7fELF_ZN3Foo3barEv\n_ZN3Foo3bazEv\nanother_c_symbol\n",
stat.S_IFREG | 0o755,
),
]
)
)
result = self.run_script(
"--cpp-only", "--output", str(output), str(first), str(second)
)
self.assertEqual(result.returncode, 0, result.stderr)
self.assertEqual(
output.read_text().splitlines(),
["_ZN3Foo3barEv", "_ZN3Foo3bazEv"],
)
self.assertIn("package=first.rpm elf_files=1 symbols=2 selected=1", result.stderr)
self.assertIn("package=second.rpm elf_files=1 symbols=3 selected=2", result.stderr)
self.assertIn("unique_symbols=2", result.stderr)
self.assertEqual(result.stdout, "")
def test_without_cpp_filter_preserves_all_provided_symbols(self) -> None:
package = self.work / "all.rpm"
package.write_bytes(
newc_archive(
[
(
"./usr/lib64/liball.so",
b"\x7fELF_ZN3Foo3barEv\nplain_c_symbol\n",
stat.S_IFREG | 0o755,
)
]
)
)
result = self.run_script(str(package))
self.assertEqual(result.returncode, 0, result.stderr)
self.assertEqual(result.stdout.splitlines(), ["_ZN3Foo3barEv", "plain_c_symbol"])
def test_excludes_elf_executables_that_do_not_generate_library_provides(self) -> None:
package = self.work / "mixed.rpm"
package.write_bytes(
newc_archive(
[
(
"./usr/lib64/libmixed.so",
b"\x7fELF_ZN3Lib3runEv\n",
stat.S_IFREG | 0o755,
),
(
"./usr/bin/mixed",
b"\x7fELFEXECUTABLE\n_ZN4Exec3runEv\n",
stat.S_IFREG | 0o755,
),
]
)
)
result = self.run_script("--cpp-only", str(package))
self.assertEqual(result.returncode, 0, result.stderr)
self.assertEqual(result.stdout.splitlines(), ["_ZN3Lib3runEv"])
self.assertIn("elf_files=1", result.stderr)
def test_rejects_malformed_cpio_stream(self) -> None:
package = self.work / "broken.rpm"
package.write_bytes(b"not a newc archive")
result = self.run_script(str(package))
self.assertNotEqual(result.returncode, 0)
self.assertIn("newc", result.stderr)
if __name__ == "__main__":
unittest.main()