test: fix two Windows-host failures (subprocess encoding, budget-boundary epsilon) (#6627)

* test: fix two Windows-host failures (subprocess encoding, budget-boundary epsilon)

- test_env_file: pin PYTHONIOENCODING=utf-8 in the stripped child env;
  without it the child writes stderr in the host's ANSI codepage while
  the UTF-8-mode parent decodes it, the reader thread dies on the first
  non-ASCII byte, and stderr comes back None;
- test_jina_retries: give the budget-cap assertion a 1e-9 tolerance —
  deadline = now + budget rounds, so the cap lands a few ulps above the
  exact 0.05 (observed 0.05000000000291038).

Fixes #6626

* test: pin both sides of the capture and use an uptime-proof budget tolerance

- test_env_file: the parent's capture decodes with the host locale when
  pytest runs without the Makefile's UTF-8 pins, so the child-side pin
  alone mirrored the crash rather than eliminating it. Pin the capture
  explicitly (encoding=utf-8, errors=replace, per the
  test_local_sandbox_encoding.py precedent) and carry both suite pins in
  the child env (PYTHONUTF8=1 + PYTHONIOENCODING=utf-8).
- test_jina_retries: the float error scales with loop-time magnitude
  (host uptime), not with 0.05; a 1e-9 absolute slack leaves a ~389-day-
  uptime flake window. Use a relative tolerance instead.

---------

Co-authored-by: xiaodu55 <xiaodu55@users.noreply.github.com>
This commit is contained in:
xiaodu55 2026-10-10 20:48:39 +08:00 committed by GitHub
parent 8377aa3d39
commit e3f21ce105
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 16 additions and 3 deletions

View File

@ -19,7 +19,15 @@ ENTRYPOINTS = {
def run_startup(tmp_path, entrypoint="config", selector=None, extra_env=None, prelude=""):
# Only propagate interpreter necessities, never ambient credentials/config.
env = {key: os.environ[key] for key in ("PATH", "SYSTEMROOT") if key in os.environ}
env.update(PYTHONPATH=os.pathsep.join((str(BACKEND), str(BACKEND / "packages/harness"))), AUTH_JWT_SECRET="test-only")
# The stripped env drops the suite's UTF-8 pins (PYTHONUTF8/PYTHONIOENCODING
# from `make test`), so the child's interpreter writes stderr in the host's
# ANSI codepage (cp936 on Chinese Windows) while a UTF-8-mode parent decodes
# it as UTF-8 — the reader thread dies on the first non-ASCII byte and
# stderr comes back None. Pin the child's interpreter to UTF-8 like the
# suite does, and pin the parent's capture explicitly so the round-trip is
# locale-independent even when pytest runs without the Makefile wrapper
# (bare `uv run pytest`, the bug class #6590 eliminated).
env.update(PYTHONPATH=os.pathsep.join((str(BACKEND), str(BACKEND / "packages/harness"))), AUTH_JWT_SECRET="test-only", PYTHONUTF8="1", PYTHONIOENCODING="utf-8")
if selector is not None:
env["DEER_FLOW_ENV_FILE"] = str(selector)
env.update(extra_env or {})
@ -37,7 +45,7 @@ dotenv.main.find_dotenv = lambda *args, **kwargs: {str(default)!r}
{ENTRYPOINTS[entrypoint]}
print(json.dumps([os.getenv('ENV_FILE_TEST_VALUE'), os.getenv('ENV_FILE_TEST_DEFAULT_ONLY')]))
"""
return subprocess.run([sys.executable, "-c", script], cwd=cwd, env=env, capture_output=True, text=True, timeout=30)
return subprocess.run([sys.executable, "-c", script], cwd=cwd, env=env, capture_output=True, text=True, encoding="utf-8", errors="replace", timeout=30)
@pytest.mark.parametrize("entrypoint", ENTRYPOINTS)

View File

@ -94,7 +94,12 @@ async def test_backoff_jitter_is_capped_by_remaining_budget(requests, monkeypatc
assert requests.await_count == 2
sleep.assert_awaited_once()
assert 0 < sleep.await_args.args[0] <= 0.05
# Tolerance, not an exact bound: deadline = now + budget rounds, so the
# remaining-budget cap can land above the exact 0.05 by ~ulp(loop.time())/4
# — the error scales with the host's uptime, not with 0.05. A relative
# tolerance covers any realistic uptime while a genuine regression
# overshoots the cap by >= 0.025.
assert 0 < sleep.await_args.args[0] <= 0.05 * (1 + 2**-24)
@pytest.mark.parametrize("during_backoff", [False, True])