From c9d3215b0f1f685c78b7570b03ceedaa8d583dd9 Mon Sep 17 00:00:00 2001 From: Jonathan Hui Date: Thu, 13 Aug 2026 10:51:48 -0700 Subject: [PATCH] [otci] drain pending lines in OtCliCommandRunner before timing out (#13494) In `OtCliCommandRunner.__expect_line()`, asynchronous commands loop for `timeout` iterations, calling `self.wait(1)` in each step. Under virtual-time simulation (`VIRTUAL_TIME=1`), `VirtualTime.go()` advances simulation time without delay when no timer events or radio traffic are scheduled on the node. In each iteration, `self.wait(1)` calls `__pending_lines.get_nowait()`. Because the background reader thread (`__otcli_reader`) transfers output asynchronously from the subprocess stdout pipe to the queue, a fast-forwarding simulation can exhaust all timeout iterations in sub-millisecond wall-clock time before the reader thread has pushed the buffered lines (such as `Done`) into `__pending_lines`. This results in an intermittent and spurious `ExpectLineTimeoutError`. This commit updates `__expect_line()` to drain `__pending_lines` with a short timeout (0.1s total deadline) after the timeout loop concludes, giving the reader thread sufficient time to process any remaining stdout lines before raising `ExpectLineTimeoutError`. TAG=agy CONV=9ffc5984-d5ce-4533-ae04-87de08ed9ba7 --- tools/otci/otci/command_handlers.py | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/tools/otci/otci/command_handlers.py b/tools/otci/otci/command_handlers.py index 6c531a786..5101de47b 100644 --- a/tools/otci/otci/command_handlers.py +++ b/tools/otci/otci/command_handlers.py @@ -213,6 +213,24 @@ class OtCliCommandRunner(OTCommandHandler): done = True break + if not done: + deadline = time.monotonic() + 0.1 + while True: + remaining = deadline - time.monotonic() + if remaining <= 0: + break + + try: + line = self.__pending_lines.get(timeout=remaining) + except queue.Empty: + break + + output.append(line) + + if match_line(line, expect_line): + done = True + break + if not done: raise ExpectLineTimeoutError(expect_line)