merge testing->tomerge/main #7

Open
anti wants to merge 242 commits from testing into tomerge/main
2 changed files with 21 additions and 14 deletions
Showing only changes of commit 3cc5ba36e8 - Show all commits

View File

@@ -106,19 +106,20 @@ def api(
# can signal the whole tree on Ctrl+C. Without this, only the supervisor
# receives SIGINT from the terminal and worker children may survive and
# be respawned — the "forkbomb" ANTI hit during testing.
proc = subprocess.Popen(_cmd, env=_env, start_new_session=True) # nosec B603 B404
try:
proc.wait()
except KeyboardInterrupt:
proc = subprocess.Popen(_cmd, env=_env, start_new_session=True) # nosec B603 B404
try:
os.killpg(proc.pid, signal.SIGTERM)
proc.wait()
except KeyboardInterrupt:
try:
proc.wait(timeout=10)
except subprocess.TimeoutExpired:
os.killpg(proc.pid, signal.SIGKILL)
proc.wait()
except ProcessLookupError:
pass
os.killpg(proc.pid, signal.SIGTERM)
try:
proc.wait(timeout=10)
except subprocess.TimeoutExpired:
os.killpg(proc.pid, signal.SIGKILL)
proc.wait()
except ProcessLookupError:
pass
except (FileNotFoundError, subprocess.SubprocessError):
console.print("[red]Failed to start API. Ensure 'uvicorn' is installed in the current environment.[/]")

View File

@@ -325,13 +325,19 @@ class TestCorrelateCommand:
# ── api command ───────────────────────────────────────────────────────────────
class TestApiCommand:
@patch("subprocess.run", side_effect=KeyboardInterrupt)
def test_api_keyboard_interrupt(self, mock_run):
@patch("os.killpg")
@patch("subprocess.Popen")
def test_api_keyboard_interrupt(self, mock_popen, mock_killpg):
proc = MagicMock()
proc.wait.side_effect = [KeyboardInterrupt, 0]
proc.pid = 4321
mock_popen.return_value = proc
result = runner.invoke(app, ["api"])
assert result.exit_code == 0
mock_killpg.assert_called()
@patch("subprocess.run", side_effect=FileNotFoundError)
def test_api_not_found(self, mock_run):
@patch("subprocess.Popen", side_effect=FileNotFoundError)
def test_api_not_found(self, mock_popen):
result = runner.invoke(app, ["api"])
assert result.exit_code == 0