Skip to content

test(proxy/db): treat zombies as gone when checking the killed prisma grandchild - #40296

Closed
cursor[bot] wants to merge 1 commit into
mainfrom
cursor/ci-autofix-automation-cd43
Closed

cursor[bot] wants to merge 1 commit into
mainfrom
cursor/ci-autofix-automation-cd43

Conversation

@cursor

@cursor cursor Bot commented Sep 8, 2026

Copy link
Copy Markdown
Contributor

TLDR

Problem this solves:

How it solves it:

  • Add a /proc/<pid>/status read to the conftest helper and treat State: Z or State: X as gone
  • Same fixture backs test_db_push_timeout_takes_its_process_tree_with_it, so both tests are covered by one change

User Flow

Before: an engineer opens any PR that touches proxy code and their CI dashboard shows proxy-infra / Run tests red even though nothing in the PR touched migration code

  1. They open a PR on github.com/BerriAI/litellm targeting litellm_internal_staging
  2. GitHub Actions runs the proxy-infra shard from .github/workflows/test-unit.yml, on the merged staging tip that already contains fix(proxy): kill the whole prisma process group when a boot migration command times out #39509
  3. Actions reports proxy-infra / Run tests fail, with FAILED tests/test_litellm/proxy/db/test_check_migration.py::test_migrate_diff_stops_at_its_budget_and_takes_its_process_tree_with_it - AssertionError: assert False, and the same failure repeats through both automatic reruns
  4. They cannot merge without an admin override even though their diff has nothing to do with the failing test

After: the same PR runs the same shard against staging that includes this fix, and CI reflects the actual PR content

  1. They open a PR on github.com/BerriAI/litellm targeting litellm_internal_staging
  2. GitHub Actions runs the proxy-infra shard from .github/workflows/test-unit.yml, on the merged staging tip that includes this change
  3. test_migrate_diff_stops_at_its_budget_and_takes_its_process_tree_with_it and test_db_push_timeout_takes_its_process_tree_with_it both pass on the first attempt, so the shard finishes green
  4. Reviews focus on the diff, not on a shared flake

Relevant issues

Linear ticket

Pre-Submission checklist

  • I have added meaningful tests
  • The handful of test files covering my change pass locally, e.g. uv run pytest tests/test_litellm/<your_test_file>.py -v. Leave the suites (make test-unit-*, make test-unit) to CI: it finishes in ~15 minutes where a laptop takes an hour or more
  • My PR passes all required CI/CD checks (e.g., lint, schema.d.ts sync check, etc.)
  • My PR's scope is as isolated as possible; it only solves 1 specific problem
  • I have received a Greptile Confidence Score of at least 4/5 before requesting a maintainer review (Greptile reviews automatically once the PR is opened; only comment @greptileai to re-request a review after pushing changes)

Screenshots / Proof of Fix

The test lives inside pytest-xdist and cannot be curled, so proof is a standalone reproduction that mirrors the exact conditions on the failing GHA proxy-infra shard: a parent that is a subreaper (via prctl(PR_SET_CHILD_SUBREAPER, 1)) spawns a fake prisma CLI with start_new_session=True, the fake CLI spawns a time.sleep(600) grandchild and records its pid, and we then killpg(SIGKILL) the whole group. This is what pytest-xdist workers end up looking like once they mark themselves as subreapers, which is why the grandchild lingers as a zombie under the worker instead of getting reaped by PID 1.

Before (staging tip 9fffda4)

  1. Run the standalone reproduction using only the check that ships in conftest.py today (os.kill(pid, 0) polled up to 5s)
  2. Observe:
parent pid=3830 is now a subreaper
fake_cli pid=3831, grandchild pid=3832
OLD helper (kill(pid,0) only): gone=False after 5.01s
  1. Cross-check against real CI: the exact same signature shows up on every failing shard, e.g. https://github.com/BerriAI/litellm/actions/runs/34277003868/job/102232382571 (PR feat(xai): add x_search as a native Search API provider #40289, initial + both reruns fail identically with AssertionError: assert False from grandchild_is_gone(within_seconds=5))

After (3dd3430)

  1. Run the same standalone reproduction, this time importing the updated helper (adds a State: Z/State: X /proc read)
  2. Observe:
fake_cli pid=3833, grandchild pid=3834
NEW helper (kill(pid,0) + zombie check): gone=True after 0.05s
  1. The helper returns True in one poll interval instead of exhausting the 5s window, which is exactly the shape the two affected tests assert against

Type

🐛 Bug Fix
✅ Test

Caveats

Low

  • The /proc/<pid>/status read is Linux-only, which is fine because os.killpg in the code under test is already POSIX-only and CI runs on Linux
  • tests/proxy_migration_tests/test_prisma_toolchain.py::test_a_timed_out_migrate_deploy_takes_its_process_tree_with_it has a similar _process_is_gone helper but it is scoped to the test-postgres job, uses the real prisma toolchain, and is not showing this flake today, so it stays untouched

Final Attestation

  • The tests check the right things, including the edge cases, and regressions in the respective real-world customer use-cases are not possible after this PR
Open in Web View Automation 

… grandchild

When pytest-xdist runs the proxy-infra shard, each worker inherits the
CPython interpreter's default behaviour and no explicit prctl. On CI
runners the nearest subreaper for a killed grandchild is a process that
never wait()s for it, so `os.kill(pid, 0)` reports the zombie as alive
past the 5-second window and the test times out with an ambiguous
`assert False`. Zombie state means the process has exited, which is
exactly what the process-group kill contract guarantees; treating a Z or
X /proc entry as gone makes the check reflect what the test is really
verifying instead of racing pid reaping.

Co-authored-by: Krrish Dholakia <krrish-berri-2@users.noreply.github.com>
@CLAassistant

Copy link
Copy Markdown

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.
You have signed the CLA already but the status is still pending? Let us recheck it.

@codecov

codecov Bot commented Sep 8, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@yuneng-berri
yuneng-berri deleted the branch main September 13, 2026 04:51
@mateo-berri mateo-berri reopened this Sep 13, 2026
@mateo-berri
mateo-berri changed the base branch from litellm_internal_staging to main September 13, 2026 05:40
@mateo-berri

Copy link
Copy Markdown
Contributor

Closing as superseded: main already carries this fix via #40333 and #39895, verified with a container repro on the merge base and main.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants