[Feature] Improve CLI Realtime Logs#100
Conversation
|
Tick the box to add this pull request to the merge queue (same as
|
There was a problem hiding this comment.
Code Review
This pull request introduces real-time log streaming and execution tree visualization to the test runner, updating the execution hierarchy dynamically and streaming updates to a web-based log viewer via Server-Sent Events (SSE). Key feedback highlights critical thread-safety issues where the shared tree_state dictionary is mutated and read across threads without synchronization, suggesting the introduction of a threading.Lock. Additionally, the reviewer noted that multiple concurrent clients will compete for the single shared log queue, recommending a broadcast pattern with client-specific queues. Other issues include potential event loss during reconnection status checks due to lack of buffering, and the use of the deprecated global window.event in the HTML log viewer.
…nnections Also, dropped events during reconnection are now buffered and replayed instead of silently lost.
da831de
into
project-chip:v2.16-cli-develop
Fix: project-chip/certification-tool#1026
Description
Extends the existing real-time log streaming feature with two new capabilities:
New execution notification
/api/status(every 3 s) after the current SSE stream ends, detecting when a new test run has started by comparingrun_titleandstart_time⚠ New execution started) with a Reload button that refreshes the page and a Dismiss button that stops polling and keeps the current viewconnectedSSE event and the/api/statusfetch by setting the flag preemptively before the fetch resolvesExecution Tree panel
TestRunExecutionWithChildreninLogStreamHandler.init_tree()and broadcast as atree_initSSE event; reconnecting clients receive the current snapshot directly from the sharedtree_statedicttree_updateSSE events, applied incrementally without re-rendering the whole tree"Executing Test Step: <title>"log entries and tags them as DOM anchors; clicking jumps directly to that entrytree_update(step, executing)event fires and scrolls to that index if no anchor is foundFiles Changed
log_stream_handler.pylogs_http_server.pywebsocket.pyget_log_stream_handler()on each test state update to forward tree eventslogging.pyget_log_stream_handler()accessorlog_viewer.htmlUnit Tests
Unit tests were updated to reflect the changes. Here's a summary of what changed in each file:
tests/test_run/test_log_stream_handler.py:
test_log_queue_is_queue→test_clients_is_empty_set— verifies _clients is an empty settest_puts_none_sentinel_into_queue→test_broadcasts_none_sentinel_on_stop— registers a real client queue in h._clients, asserts it receives None after stop()test_skips_sentinel_when_queue_full→test_stop_does_not_raise_when_client_queue_full— pre-fills a client queue to capacity, asserts no raiseTestAddLogEntrytests — replacedh.log_queuereads with either patch.object(h, "_broadcast") (for the no-op case) or a client queue registered in h._clients (for all data-content assertions)tests/test_run/test_logs_http_server.py:
_make_handler— now sets explicit defaults:active_clients=set(),clients_lock=threading.Lock(),tree_state={},tree_lock=Nonesostream_logs()never tries to deepcopy a MagicMock_pre_filled_queue(*items)helper — returns a pre-populated queue for use withpatch("...queue.Queue", return_value=...)TestStreamLogstests — removedserver_attrs={"log_queue": q}, now patchqueue.Queueto return a pre-filled queue instead;test_no_log_queue_on_server_returns_earlyrenamed totest_no_active_clients_on_server_returns_earlywith matchingserver_attrsTestLogsHTTPServerStart— all three tests now callstart(active_clients=..., clients_lock=..., tree_state={}, ...)instead ofstart(log_queue=...);test_sets_server_attributesassertsmock_ths.active_clientsandmock_ths.clients_lockinstead ofmock_ths.log_queueScreenshots