Narrow send_peers and REPEAT fan-out on inject-only proxies using a precomputed OPTIONS index, cache connected peer count, and debounce CONFIG_SND pushes to the monitor.pull/1/head
parent
f4d6843f94
commit
2235203e22
@ -0,0 +1,54 @@
|
||||
"""Inject-only MASTER: downlink index limits send_peer fan-out."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import pytest
|
||||
|
||||
from adn_server.domain import bytes_4
|
||||
from adn_server.infrastructure.hbp_constants import DMRD
|
||||
from tests.harness.deterministic import DeterministicScenario, PacketSpec
|
||||
from tests.support.hbp_repeat_stack import build_hbp_repeat_stack
|
||||
|
||||
pytestmark = pytest.mark.integration
|
||||
|
||||
_TG = 52090
|
||||
|
||||
|
||||
def _voice_burst(peer_id: bytes, rf_src: int = 7300444) -> bytes:
|
||||
spec = PacketSpec(
|
||||
peer_id=int.from_bytes(peer_id, "big"),
|
||||
rf_src=rf_src,
|
||||
dst_id=_TG,
|
||||
slot=2,
|
||||
stream_id=0x11223344,
|
||||
payload=b"\x00" * 33,
|
||||
)
|
||||
return DeterministicScenario.voice_burst_spec(spec, seq=1, dtype_vseq=1).data()
|
||||
|
||||
|
||||
def test_send_peers_scales_with_matching_options_not_total_peers() -> None:
|
||||
stack = build_hbp_repeat_stack(talker_alias=False, system_name="MASTER-A")
|
||||
stack.config["PROXY"] = {"TARGET_SYSTEM": "MASTER-A"}
|
||||
stack.hbp._CONFIG = stack.config
|
||||
|
||||
tx = bytes_4(730044401)
|
||||
match = bytes_4(730044402)
|
||||
stack.register_peer(tx, ("10.0.0.10", 62010), options=f"TS2={_TG};")
|
||||
stack.register_peer(match, ("10.0.0.11", 62011), options=f"TS2={_TG};")
|
||||
|
||||
extras = []
|
||||
for i in range(50):
|
||||
pid = bytes_4(730100000 + i)
|
||||
extras.append(pid)
|
||||
stack.register_peer(pid, (f"10.1.0.{i}", 62100 + i), options="TS2=91;")
|
||||
|
||||
stack.hbp._refresh_connected_peer_count()
|
||||
stack.hbp._mark_downlink_index_dirty()
|
||||
|
||||
burst = _voice_burst(tx)
|
||||
stack.transport.clear()
|
||||
stack.hbp.send_peers(burst)
|
||||
|
||||
dmrd_sends = [pkt for pkt, _ in stack.transport.sent if pkt[:4] == DMRD]
|
||||
# TX peer + one matching peer (not 50 unrelated hotspots).
|
||||
assert len(dmrd_sends) == 2
|
||||
@ -0,0 +1,45 @@
|
||||
"""Peer downlink index: inject-only fan-out narrowing."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from adn_server.application.routing.peer_downlink_index import (
|
||||
build_peer_downlink_index,
|
||||
cached_peer_static_tgs,
|
||||
invalidate_peer_options_cache,
|
||||
)
|
||||
from adn_server.domain import bytes_4
|
||||
|
||||
|
||||
def _peer(options: str) -> dict:
|
||||
return {"CONNECTION": "YES", "OPTIONS": options.encode()}
|
||||
|
||||
|
||||
def test_build_index_maps_static_tgs_per_slot() -> None:
|
||||
p1 = bytes_4(730044401)
|
||||
p2 = bytes_4(730044402)
|
||||
peers = {
|
||||
p1: _peer("TS2=52090,314569;"),
|
||||
p2: _peer("TS2=730170;"),
|
||||
}
|
||||
idx = build_peer_downlink_index(peers, {})
|
||||
assert p1 in idx.candidates(2, 52090, connected_count=5)
|
||||
assert p2 not in idx.candidates(2, 52090, connected_count=5)
|
||||
assert p2 in idx.candidates(2, 730170, connected_count=5)
|
||||
assert len(idx.candidates(2, 52090, connected_count=5)) == 1
|
||||
|
||||
|
||||
def test_single_connected_peer_returns_all() -> None:
|
||||
p1 = bytes_4(730044401)
|
||||
peers = {p1: _peer("TS2=91;")}
|
||||
idx = build_peer_downlink_index(peers, {})
|
||||
assert idx.candidates(2, 52090, connected_count=1) == frozenset({p1})
|
||||
|
||||
|
||||
def test_options_cache_invalidates_on_rpto() -> None:
|
||||
peer = _peer("TS2=52090;")
|
||||
cached_peer_static_tgs(peer)
|
||||
assert "_CACHED_OPTIONS_STATIC" in peer
|
||||
peer["OPTIONS"] = b"TS2=730170;"
|
||||
invalidate_peer_options_cache(peer)
|
||||
ts1, ts2 = cached_peer_static_tgs(peer)
|
||||
assert "730170" in ts2
|
||||
Loading…
Reference in new issue