mirror of
https://github.com/lexmount/moli.git
synced 2026-10-06 08:00:59 +00:00
97 lines
3.5 KiB
Python
97 lines
3.5 KiB
Python
from __future__ import annotations
|
|
|
|
import importlib.util
|
|
import subprocess
|
|
import unittest
|
|
from pathlib import Path
|
|
from unittest.mock import patch
|
|
|
|
SCRIPT = Path(__file__).resolve().parents[1] / "check_linux_compat.py"
|
|
spec = importlib.util.spec_from_file_location("check_linux_compat", SCRIPT)
|
|
compat = importlib.util.module_from_spec(spec)
|
|
spec.loader.exec_module(compat)
|
|
|
|
|
|
def needs(*names: str) -> str:
|
|
return "Version needs section '.gnu.version_r' contains 2 entries:\n" + "\n".join(
|
|
f" 0x0010: Name: {name} Flags: none Version: 2" for name in names
|
|
)
|
|
|
|
|
|
class LinuxCompatibilityTests(unittest.TestCase):
|
|
def test_accepts_jammy_limits(self) -> None:
|
|
self.assertEqual(
|
|
compat.check_versions(
|
|
needs("GLIBC_2.35", "GLIBCXX_3.4.30", "CXXABI_1.3.13")
|
|
),
|
|
compat.MAX_VERSIONS,
|
|
)
|
|
|
|
def test_compares_versions_numerically(self) -> None:
|
|
self.assertEqual(
|
|
compat.check_versions(needs("GLIBC_2.9", "GLIBC_2.34", "GLIBCXX_3.4.9")),
|
|
{"GLIBC": (2, 34), "GLIBCXX": (3, 4, 9)},
|
|
)
|
|
|
|
def test_rejects_newer_abi_in_each_family(self) -> None:
|
|
for name in ["GLIBC_2.36", "GLIBC_2.38", "GLIBCXX_3.4.31", "CXXABI_1.3.14"]:
|
|
with self.subTest(name=name), self.assertRaisesRegex(ValueError, name):
|
|
compat.check_versions(needs("GLIBC_2.17", name))
|
|
|
|
def test_rejects_relr_and_private_abi(self) -> None:
|
|
for name in ["GLIBC_ABI_DT_RELR", "GLIBC_PRIVATE", "CXXABI_UNKNOWN"]:
|
|
with self.subTest(name=name), self.assertRaisesRegex(ValueError, name):
|
|
compat.check_versions(needs("GLIBC_2.17", name))
|
|
|
|
def test_accepts_jammy_named_cxx_abis(self) -> None:
|
|
compat.check_versions(needs("GLIBC_2.17", "CXXABI_TM_1", "CXXABI_FLOAT128"))
|
|
|
|
def test_ignores_version_definitions(self) -> None:
|
|
output = "Version definition section:\nName: GLIBC_9.99\n" + needs("GLIBC_2.35")
|
|
self.assertEqual(compat.check_versions(output), {"GLIBC": (2, 35)})
|
|
|
|
def test_fails_closed_without_glibc_requirements(self) -> None:
|
|
for output in [
|
|
"",
|
|
"No version information found in this file.",
|
|
needs("GCC_3.0"),
|
|
]:
|
|
with self.subTest(output=output), self.assertRaises(ValueError):
|
|
compat.check_versions(output)
|
|
|
|
def test_smoke_requires_version_and_javascript_execution(self) -> None:
|
|
with patch.object(
|
|
compat,
|
|
"run_checked",
|
|
side_effect=[
|
|
"moli 1.0.0\n",
|
|
'{"title":"jammy-smoke","text":"script-ran","answer":42}',
|
|
],
|
|
) as run:
|
|
compat.smoke_test(Path("/moli"))
|
|
self.assertEqual(run.call_count, 2)
|
|
self.assertEqual(run.call_args_list[0].args[0], ["/moli", "--version"])
|
|
self.assertIn("--eval", run.call_args_list[1].args[0])
|
|
|
|
def test_smoke_rejects_incorrect_result(self) -> None:
|
|
with (
|
|
patch.object(compat, "run_checked", side_effect=["moli 1.0.0", "{}"]),
|
|
self.assertRaisesRegex(ValueError, "unexpected output"),
|
|
):
|
|
compat.smoke_test(Path("/moli"))
|
|
|
|
def test_smoke_propagates_loader_failure(self) -> None:
|
|
with (
|
|
patch.object(
|
|
compat,
|
|
"run_checked",
|
|
side_effect=subprocess.CalledProcessError(1, "moli"),
|
|
),
|
|
self.assertRaises(subprocess.CalledProcessError),
|
|
):
|
|
compat.smoke_test(Path("/moli"))
|
|
|
|
|
|
if __name__ == "__main__":
|
|
unittest.main()
|