Files
hermes-agent/tests/hermes_cli/test_plugins_loader.py
kshitijk4poor f7bbbc474e fix(plugins): abandon only nested plugin loads still running at outer timeout
Gate finding BN10.r1.2c (Low): the inline re-entrant branch appended the
nested ctx to the outer load's scope and never removed it, so a nested
load that had already finished (and was recorded enabled under its own
key) got fenced by _abandon_load() when the outer load later timed out.
Keep the ctx in scope only while its fn() runs.

The kept nested-inline test now times the outer load out with one finished
and one hung nested load, asserting only outer + hung are abandoned; this
also pins the nested-abandon behaviour of the previous commit.
2026-10-03 16:53:54 +05:30

37 lines
1.2 KiB
Python

import threading
import pytest
from hermes_cli import plugins_loader
def test_nested_plugin_load_runs_inline_on_deadline_worker(monkeypatch):
monkeypatch.setattr(plugins_loader, "_resolve_plugin_load_timeout", lambda: 0.3)
abandoned = []
class Context:
def __init__(self, name):
self.name = name
def _abandon_load(self):
abandoned.append(self.name)
observed_threads = []
release = threading.Event()
def outer_load():
observed_threads.append(threading.current_thread())
plugins_loader.run_with_load_deadline(
"done", Context("done"), lambda: observed_threads.append(threading.current_thread()),
)
plugins_loader.run_with_load_deadline("hung", Context("hung"), release.wait)
with pytest.raises(plugins_loader.PluginLoadTimeout):
plugins_loader.run_with_load_deadline("outer", Context("outer"), outer_load)
release.set()
assert len(observed_threads) == 2
assert observed_threads[0] is observed_threads[1]
# The outer timeout abandons only contexts still loading, not a nested load that already finished.
assert abandoned == ["outer", "hung"]