fix: emit arq-session-finished on IRS success again (lost April 2024)

The IRS success branch set ENDED and returned without the
session-finished event, while abort, failure and the ISS success path
all send one. A successful inbound raw transfer was invisible to every
websocket/REST consumer, and the received payload was dropped with it
(handle_raw returns the data into a call chain that discards it).

c2388a65 emitted exactly this event, data= included; it vanished by
ef18f4cc without that commit's IRS diff touching the lines, so this
looks like a merge casualty rather than a decision. Restore the event
and add a regression test: one finished event with success=True,
payload round-trips through the base64 data field.

The original also pushed session statistics gated on enable_stats, but
that key is no longer in the config schema (config.py STATION), so the
strict lookup raises KeyError; the two existing stats sites in the
failure and abort paths have the same latent problem. Restoring just
the event here; the stats question is worth its own look.

No setARQ(False) here: dispatch() already clears busy on this path.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
pull/1110/head
Steve Pinkham 2026-07-12 12:35:06 -04:00
parent 749b8de92e
commit f19c775a3a
2 changed files with 52 additions and 0 deletions

View File

@ -373,6 +373,17 @@ class ARQSessionIRS(arq_session.ARQSession):
self.session_ended = time.time()
self.set_state(IRS_State.ENDED)
session_stats = self.calculate_session_statistics(self.received_bytes, self.total_length)
self.ctx.event_manager.send_arq_session_finished(
False,
self.id,
self.dxcall,
True,
self.state.name,
data=self.received_data,
statistics=session_stats,
)
return self.received_data, self.type_byte
else:
ack = self.frame_factory.build_arq_burst_ack(

View File

@ -154,6 +154,47 @@ class TestARQSession(unittest.TestCase):
# self.ctx_IRS.shutdown()
# self.ctx_ISS.shutdown()
def testARQSessionIRSSuccessEmitsFinishedEvent(self):
# Gap 3 regression test: a completed IRS session must emit exactly
# one "arq-transfer-inbound" event with success=True, and the
# payload must round-trip through the event's base64 data field
# (previously the success branch in arq_session_irs.py never called
# send_arq_session_finished at all, so no such event was ever
# emitted -- only the abort/failure paths did).
self.loss_probability = 0
payload = np.random.bytes(200)
self.establishChannels()
params = {
"dxcall": "AA1AAA-1",
"data": base64.b64encode(payload),
# "raw" (not "raw_lzma"): the event's data field carries the
# bytes as received over the air, before ARQDataTypeHandler's
# separate decompression step -- "raw" keeps this an honest
# exact-match round-trip check instead of asserting equality
# against still-compressed bytes.
"type": "raw",
}
cmd = ARQRawCommand(self.ctx_ISS, params)
cmd.run()
self.waitForSession(self.ctx_ISS.TESTMODE_EVENTS, True)
self.channels_running = False
finished_events = []
while not self.ctx_IRS.TESTMODE_EVENTS.empty():
ev = self.ctx_IRS.TESTMODE_EVENTS.get()
if "arq-transfer-inbound" in ev:
finished_events.append(ev["arq-transfer-inbound"])
successes = [e for e in finished_events if e.get("success") is True]
self.assertEqual(
len(successes),
1,
f"expected exactly one successful arq-transfer-inbound event, got {finished_events}",
)
received = base64.b64decode(successes[0]["data"])
self.assertEqual(received, payload)
def DisabledtestARQSessionAbortTransmissionISS(self):
# set Packet Error Rate (PER) / frame loss probability
self.loss_probability = 0