From 5f1985f9ab597cd7bbda98cf7f04ef5348ce5760 Mon Sep 17 00:00:00 2001 From: evgeny Date: Mon, 19 Oct 2026 17:37:24 +0200 Subject: [PATCH] Verify RX drain and explicit decoder rejection semantics --- tests/test_call.c | 2 +- tests/test_call_video_port.c | 21 ++++++++++++++------- 2 files changed, 15 insertions(+), 8 deletions(-) diff --git a/tests/test_call.c b/tests/test_call.c index 7fbbba29..2658922a 100644 --- a/tests/test_call.c +++ b/tests/test_call.c @@ -725,7 +725,7 @@ static void call_tick(void* arg) { if (call_video_port_status(t->call_id, &status) || status.decoded_generation != 1 || status.decoded_accepted) break; if (++t->phase_ticks < 10) break; // Регулятор не должен отменять запрет decoder на следующем tick. struct call_video_frame f = video_test_frame(t->call_id, 1); f.frame_id = 4; f.pts_us += 99999; - if (call_video_send_frame(B, &f) != 0) { DEBUG_ERROR(DEBUG_CATEGORY_CALL, "video ignored decoder rejection"); t->result = 2; break; } + if (call_video_send_frame(B, &f) != -1) { DEBUG_ERROR(DEBUG_CATEGORY_CALL, "video ignored decoder rejection"); t->result = 2; break; } // Все команды попадут в uasync после синхронного ENDED; TX ещё принадлежит mailbox. struct call_video_frame closing[2] = {f, f}; ++closing[1].frame_id; closing[1].pts_us += 33333; if (call_video_port_format(t->call_id, &f.format, 500000) diff --git a/tests/test_call_video_port.c b/tests/test_call_video_port.c index 31eb8e1c..4d4b3cee 100644 --- a/tests/test_call_video_port.c +++ b/tests/test_call_video_port.c @@ -44,7 +44,7 @@ int main(void) { session = (struct call_session){.ctx = &ctx, .call_id = 7, .state = CALL_ST_ACTIVE}; assert(!call_video_port_attach(&inst)); struct call_video_caps caps = {0}; - assert(!call_video_port_open(7, &caps)); uasync_drain_immediate(ua); + assert(!call_video_port_open(7, &caps)); uasync_poll(ua, 0); assert(callbacks && callbacks->writable); callbacks->writable(callback_arg, 1); uint8_t data[8][16]; struct call_video_frame frames[8]; for (unsigned i = 0; i < 8; ++i) { @@ -56,20 +56,27 @@ int main(void) { extra = frames[7]; concurrent = 1; allowance = 2; assert(call_video_port_send(frames, 8) == 1); memset(data, 0, sizeof(data)); // Порт обязан владеть собственной копией. - uasync_drain_immediate(ua); + uasync_poll(ua, 0); assert(accepted == 2 && port.tx_count == 6 && !port.tx_processing && !port.pending); - unsigned before = offered; uasync_drain_immediate(ua); assert(offered == before); // Нет busy loop. + unsigned before = offered; uasync_poll(ua, 0); assert(offered == before); // Нет busy loop. struct call_video_port_status status; assert(!call_video_port_status(7, &status) && !status.can_encode && !status.key_serial); for (unsigned i = 0; i < 3; ++i) { - callbacks->writable(callback_arg, 0); uasync_drain_immediate(ua); + callbacks->writable(callback_arg, 0); uasync_poll(ua, 0); assert(accepted == 2 && port.tx_count == 6 && !port.pending); } - allowance = 8; callbacks->writable(callback_arg, 1); uasync_drain_immediate(ua); + allowance = 8; callbacks->writable(callback_arg, 1); uasync_poll(ua, 0); assert(accepted == 8 && !port.tx_count); assert(!call_video_port_status(7, &status) && status.can_encode && !status.key_serial); DEBUG_INFO(DEBUG_CATEGORY_CALL, "PASS video port: all 8 frames preserved across partial send and repeated busy; no KEY or spin"); - call_video_port_close(7); uasync_drain_immediate(ua); - call_video_port_detach(&inst); uasync_drain_immediate(ua); + for (unsigned i = 0; i < 8; ++i) { assert(callbacks->receive_ready(callback_arg, 16)); callbacks->frame(callback_arg, &frames[i]); } + assert(!callbacks->receive_ready(callback_arg, 16)); + for (unsigned i = 0; i < 8; ++i) { + struct call_video_frame f; assert(call_video_port_pull(7, &f) == 1 && f.frame_id == i + 1); u_free((void *)f.data); + assert(callbacks->receive_ready(callback_arg, 16) == (i == 7)); + } + DEBUG_INFO(DEBUG_CATEGORY_CALL, "PASS video port: full RX drains completely before resuming producer admission"); + call_video_port_close(7); uasync_poll(ua, 0); + call_video_port_detach(&inst); uasync_poll(ua, 0); uasync_destroy(ua, 0); return 0; }