mirror of
https://github.com/MervinPraison/PraisonAI.git
synced 2026-11-08 01:08:39 -10:00
fix: address reviewer feedback
- Generalize docstring references to avoid maintenance overhead - Improve test coverage for argv restoration by using discriminating values Co-authored-by: Mervin Praison <[email protected]>
This commit is contained in:
1 parent
c276c5baab
commit
79eec46776
3 files changed
+71
-4
No files matched your search
@@ -27,7 +27,7 @@ class _BackgroundLoop:
|
||||
The thread is marked ``daemon=True`` so that short-lived scripts
|
||||
(e.g. CLI commands, smoke tests) exit cleanly without waiting on
|
||||
the background loop to be shut down explicitly. Long-running
|
||||
servers (gateway, a2u, mcp_server) should call :func:`shutdown`
|
||||
server processes should call :func:`shutdown`
|
||||
explicitly to cancel in-flight tasks before process exit.
|
||||
"""
|
||||
if self._loop is None or self._loop.is_closed():
|
||||
@@ -110,5 +110,5 @@ def run_sync(coro: Awaitable[T], *, timeout: float | None = _DEFAULT_TIMEOUT) ->
|
||||
|
||||
|
||||
def shutdown() -> None:
|
||||
"""Public hook for servers (gateway, a2u, mcp_server) to stop the bridge cleanly."""
|
||||
"""Public hook for long-running server processes to stop the bridge cleanly."""
|
||||
_BG.shutdown()
|
||||
@@ -154,7 +154,8 @@ class TestLegacyRouting(unittest.TestCase):
|
||||
self.assertEqual(cm.exception.code, 1)
|
||||
|
||||
def test_legacy_path_restores_argv(self):
|
||||
original = ["praisonai", "Topic prompt"]
|
||||
# Use different argv to test that restoration actually happens
|
||||
original = ["praisonai", "Build weather app", "--extra-arg"]
|
||||
sys.argv = list(original)
|
||||
fake = mock.MagicMock()
|
||||
fake.main.return_value = None
|
||||
@@ -203,7 +204,8 @@ class TestTyperRouting(unittest.TestCase):
|
||||
legacy.assert_not_called()
|
||||
|
||||
def test_typer_path_restores_argv(self):
|
||||
original = ["praisonai", "chat"]
|
||||
# Use different argv to test that restoration actually happens
|
||||
original = ["praisonai", "chat", "--model", "gpt-4"]
|
||||
sys.argv = list(original)
|
||||
with mock.patch("praisonai.cli.app.app"), \
|
||||
mock.patch("praisonai.cli.app.register_commands"):
|
||||
|
||||
@@ -0,0 +1,65 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Smoke test for async bridge daemon thread fix."""
|
||||
|
||||
import asyncio
|
||||
import time
|
||||
import threading
|
||||
from src.praisonai.praisonai._async_bridge import run_sync, _BG
|
||||
|
||||
async def test_coro(value: int) -> int:
|
||||
"""Simple test coroutine."""
|
||||
await asyncio.sleep(0.001) # Brief sleep to exercise the async machinery
|
||||
return value * 2
|
||||
|
||||
def test_daemon_thread_fix():
|
||||
"""Verify that daemon threads allow clean exit."""
|
||||
print("[smoke] === STEP 1: run_sync from sync context ===")
|
||||
result = run_sync(test_coro(21))
|
||||
assert result == 42, f"Expected 42, got {result}"
|
||||
print(f" result={result}")
|
||||
|
||||
def test_runtime_error_guard():
|
||||
"""Verify that run_sync raises RuntimeError when called from async context."""
|
||||
print("[smoke] === STEP 2: run_sync inside running loop ===")
|
||||
|
||||
async def nested_call():
|
||||
try:
|
||||
run_sync(test_coro(1))
|
||||
return False # Should not reach here
|
||||
except RuntimeError:
|
||||
return True # Expected behavior
|
||||
|
||||
result = run_sync(nested_call())
|
||||
assert result is True, "run_sync should raise RuntimeError from async context"
|
||||
print(" OK raised RuntimeError")
|
||||
|
||||
def test_thread_properties():
|
||||
"""Verify the background thread is properly configured as daemon."""
|
||||
print("[smoke] === STEP 3: thread daemon property ===")
|
||||
# Force thread creation
|
||||
run_sync(test_coro(1))
|
||||
|
||||
# Check thread properties
|
||||
assert _BG._thread is not None, "Background thread should exist"
|
||||
assert _BG._thread.daemon is True, "Background thread should be daemon"
|
||||
assert _BG._thread.is_alive(), "Background thread should be alive"
|
||||
print(" daemon=True ✓")
|
||||
|
||||
def main():
|
||||
"""Run all smoke tests."""
|
||||
print("[smoke] === ASYNC BRIDGE SMOKE TEST ===")
|
||||
|
||||
try:
|
||||
test_daemon_thread_fix()
|
||||
test_runtime_error_guard()
|
||||
test_thread_properties()
|
||||
|
||||
print("[smoke] === ALL SMOKE STEPS PASSED ===")
|
||||
return True
|
||||
except Exception as e:
|
||||
print(f"[smoke] === FAILED: {e} ===")
|
||||
return False
|
||||
|
||||
if __name__ == "__main__":
|
||||
success = main()
|
||||
exit(0 if success else 1)
|
||||
Reference in new issue
Block a user