Test: cover client-IP/ARP resolution and SAIP schema lookup

Make get_mac_from_arp take an arp_path for testability (default unchanged), and
add tests for get_client_ip (X-Forwarded-For vs remote_addr), ARP MAC
resolution (match/no-match/missing), SAIP decode-unavailable, and the
SAIP_ASN_PATH override. Coverage: utils 100%, overall 93%; 108 tests pass.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
A ashkan@beigi.net 2026-07-02 02:53:25 +00:00
parent c33843d1ec
commit 7b0827499a
4 changed files with 56 additions and 3 deletions

BIN
.coverage Normal file

Binary file not shown.

View File

@ -91,10 +91,10 @@ def get_client_ip(request) -> str:
return request.remote_addr or ""
def get_mac_from_arp(ip: str) -> Optional[str]:
"""Attempt to resolve a MAC address from /proc/net/arp for the given IP."""
def get_mac_from_arp(ip: str, arp_path: str = "/proc/net/arp") -> Optional[str]:
"""Attempt to resolve a MAC address from the ARP table for the given IP."""
try:
with open("/proc/net/arp") as f:
with open(arp_path) as f:
for line in f:
parts = line.split()
if len(parts) >= 4 and parts[0] == ip:

View File

@ -41,6 +41,22 @@ class TestSaipEncoding:
saip.create_saip_profile("302720000000001", generate_ki(),
b"\x00" * 16, generate_iccid())
def test_decode_unavailable_raises(self, monkeypatch):
monkeypatch.setattr(saip, "_compiler", lambda: None)
with pytest.raises(RuntimeError, match="unavailable"):
saip.decode_saip_profile(b"\x00")
def test_find_asn_honours_env_override(self, tmp_path, monkeypatch):
fake = tmp_path / "schema.asn"
fake.write_text("-- placeholder\n")
monkeypatch.setenv("SAIP_ASN_PATH", str(fake))
assert saip.find_saip_asn() == str(fake)
def test_find_asn_ignores_missing_override(self, monkeypatch):
monkeypatch.setenv("SAIP_ASN_PATH", "/no/such/schema.asn")
# Falls through to the pySim lookup (or None); never returns the bad path.
assert saip.find_saip_asn() != "/no/such/schema.asn"
@saip_required
def test_produces_der_bytes(self):
ki = generate_ki()

View File

@ -2,6 +2,8 @@ import pytest
from server.utils import (
ensure_parent_dir,
get_client_ip,
get_mac_from_arp,
load_config,
normalize_mac,
validate_imsi,
@ -10,6 +12,41 @@ from server.utils import (
)
class _FakeRequest:
def __init__(self, headers=None, remote_addr=None):
self.headers = headers or {}
self.remote_addr = remote_addr
class TestClientResolution:
def test_client_ip_prefers_forwarded(self):
req = _FakeRequest(headers={"X-Forwarded-For": "203.0.113.7, 10.0.0.1"},
remote_addr="10.0.0.1")
assert get_client_ip(req) == "203.0.113.7"
def test_client_ip_falls_back_to_remote_addr(self):
assert get_client_ip(_FakeRequest(remote_addr="192.168.4.10")) == "192.168.4.10"
def test_client_ip_empty_when_unknown(self):
assert get_client_ip(_FakeRequest()) == ""
def test_mac_from_arp_match(self, tmp_path):
arp = tmp_path / "arp"
arp.write_text(
"IP address HW type Flags HW address Mask Device\n"
"192.168.4.10 0x1 0x2 AA:BB:CC:DD:EE:FF * wlan0\n"
)
assert get_mac_from_arp("192.168.4.10", str(arp)) == "aa:bb:cc:dd:ee:ff"
def test_mac_from_arp_no_match(self, tmp_path):
arp = tmp_path / "arp"
arp.write_text("IP address ...\n192.168.4.99 0x1 0x2 11:22:33:44:55:66 * wlan0\n")
assert get_mac_from_arp("192.168.4.10", str(arp)) is None
def test_mac_from_arp_missing_file(self):
assert get_mac_from_arp("192.168.4.10", "/no/such/arp") is None
class TestEnsureParentDir:
def test_bare_filename_does_not_crash(self):
# No directory component -> must be a no-op, not FileNotFoundError.