Correct the one-controller claim: the drone takes over, it does not refuse

Tested on the aircraft. A second ARSDK handshake is accepted and telemetry is
redirected to it; the first session's frames stop while it still reports
connected = True. So the claim inherited from pyparrot's error text, which had
reached our error messages, tool descriptions, simulator behaviour and a test
name, was wrong in the most misleading direction: a refusal would be loud, and
this is silent.

The simulator now models the takeover by default; refusal stays available
because a client must handle a non-zero status anyway.
This commit is contained in:
Ryan Malloy
2026-10-02 03:44:05 -06:00
parent ad81cc6e38
commit 41a6cb107f
6 changed files with 86 additions and 12 deletions
+15 -4
View File
@@ -119,7 +119,14 @@ async def test_handshake_describes_this_controller(sim, session):
assert request["d2c_port"] == session.d2c_port != 0
async def test_second_controller_is_refused(sim, session):
async def test_second_controller_takes_the_link_over(sim, session):
"""The aircraft accepts a newcomer and stops talking to whoever had it.
Measured on the real drone 2026-10-02: the first session's frame count
froze while the second received, and the first went on reporting
connected = True. That silent failure is why a client should judge a link
by telemetry freshness rather than by its connected flag.
"""
other = DroneSession(
"127.0.0.1",
discovery_port=sim.discovery_port,
@@ -128,9 +135,13 @@ async def test_second_controller_is_refused(sim, session):
encoder=fake_encode,
decoder=fake_decode,
)
with pytest.raises(HandshakeError, match="one controller"):
await other.connect()
assert not other.connected
await other.connect()
try:
assert other.connected
# The loser keeps its socket and its optimism; only the data stops.
assert session.connected
finally:
await other.disconnect()
async def test_unreachable_address_fails_fast_rather_than_hanging():