Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion flocks/cli/service_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -704,7 +704,10 @@ def wait_for_http(
) -> None:
"""Wait until any URL passes the provided startup validator."""
response_validator = validator or _is_reachable_response
with httpx.Client(timeout=2.0) as client:
# Local startup probes must never be routed through system proxy settings;
# otherwise localhost/127.0.0.1 checks can time out even when the service
# is already healthy.
with httpx.Client(timeout=2.0, trust_env=False) as client:
for _ in range(attempts):
for url in urls:
try:
Expand Down
49 changes: 46 additions & 3 deletions tests/cli/test_service_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -339,7 +339,11 @@ def __exit__(self, exc_type, exc, tb):
def get(self, _url):
return next(responses)

monkeypatch.setattr(service_manager.httpx, "Client", lambda timeout: _FakeClient())
monkeypatch.setattr(
service_manager.httpx,
"Client",
lambda *, timeout, trust_env: _FakeClient(),
)
monkeypatch.setattr(service_manager.time, "sleep", lambda _delay: None)

with pytest.raises(service_manager.ServiceError, match="启动超时"):
Expand Down Expand Up @@ -368,7 +372,11 @@ def __exit__(self, exc_type, exc, tb):
def get(self, _url):
return next(responses)

monkeypatch.setattr(service_manager.httpx, "Client", lambda timeout: _FakeClient())
monkeypatch.setattr(
service_manager.httpx,
"Client",
lambda *, timeout, trust_env: _FakeClient(),
)
monkeypatch.setattr(service_manager.time, "sleep", lambda _delay: None)

service_manager.wait_for_http(
Expand Down Expand Up @@ -396,12 +404,47 @@ def __exit__(self, exc_type, exc, tb):
def get(self, _url):
return next(responses)

monkeypatch.setattr(service_manager.httpx, "Client", lambda timeout: _FakeClient())
monkeypatch.setattr(
service_manager.httpx,
"Client",
lambda *, timeout, trust_env: _FakeClient(),
)
monkeypatch.setattr(service_manager.time, "sleep", lambda _delay: None)

service_manager.wait_for_http(["http://127.0.0.1:5173"], "WebUI", attempts=2, delay=0.0)


def test_wait_for_http_ignores_proxy_environment(monkeypatch) -> None:
captured: dict[str, object] = {}

class _FakeClient:
def __enter__(self):
return self

def __exit__(self, exc_type, exc, tb):
return False

def get(self, _url):
return httpx.Response(200, json={"status": "healthy", "version": "v1"})

def _client_factory(*, timeout, trust_env):
captured["timeout"] = timeout
captured["trust_env"] = trust_env
return _FakeClient()

monkeypatch.setattr(service_manager.httpx, "Client", _client_factory)

service_manager.wait_for_http(
["http://127.0.0.1:8000/api/health"],
"后端服务",
attempts=1,
delay=0.0,
validator=service_manager._is_expected_health_response,
)

assert captured == {"timeout": 2.0, "trust_env": False}


def test_resolve_python_subprocess_command_prefers_venv(
monkeypatch,
tmp_path: Path,
Expand Down
Loading