Skip to content

test(ui): give the integration vitest tier a wait ceiling matching its cost - #43437

Open
devin-ai-integration[bot] wants to merge 1 commit into
mainfrom
litellm_deflake_20260927
Open

devin-ai-integration[bot] wants to merge 1 commit into
mainfrom
litellm_deflake_20260927

Conversation

@devin-ai-integration

Copy link
Copy Markdown
Contributor

TLDR

Problem this solves:

  • edit_auto_router_modal.integration.test.tsx threshold cases flaked twice on main in the last 24h
  • The integration Vitest tier used Testing Library's 1s waitFor default
  • A full modal rerender plus a 300ms debounce plus a query refetch can exceed 1s under CI load

How it solves it:

  • New tests/setup.integration.ts sets Testing Library asyncUtilTimeout to 5s
  • Only the integration Vitest project loads it; unit and component tiers keep the 1s default
  • No production code and no test assertions changed

User Flow

Before: a contributor's unrelated PR goes red on the UI integration shard and they have to re-run it

  1. They push a commit that touches nothing under ui/litellm-dashboard/src/components/edit_auto_router
  2. The ui-tests job fails on EditAutoRouterModal keyword matching > hydrates the saved threshold and saves an edit to '0' with Save Changes still disabled after 1000ms
  3. They re-run the job with no changes and it passes

After: the same commit gets a green UI integration shard on the first attempt

  1. They push the same commit
  2. The ui-tests job waits up to 5s for the availability check to finish and the Save button to enable, which it does well inside that budget
  3. The job passes on the first attempt

Flake evidence (run date 2026-09-26)

Test ids:
src/components/edit_auto_router/edit_auto_router_modal.integration.test.tsx > EditAutoRouterModal keyword matching > hydrates the saved threshold and saves an edit to '0' and the '' variant of the same it.each

Failed on main, attempt 1, with no change to the component or the test:
https://github.com/BerriAI/litellm/actions/runs/36280397180 and https://github.com/BerriAI/litellm/actions/runs/36294321344

Passed on the neighboring main commits 829cba1b, 491d4548, b831e9b4, 4274bdda, 8e6d99d7 and f4308bc1, so the result changed without the code under test changing

Mechanism: wall-clock dependence. fireEvent.change on the threshold field changes the serialized router config, the availability hook marks the form as checking, waits a 300ms debounce, refetches the mocked /auto_router/availability endpoint through React Query, and only then does the modal enable Save Changes. On a contended runner that whole chain runs past Testing Library's 1000ms asyncUtilTimeout, so waitFor(() => expect(saveButton).toBeEnabled()) gives up first. Locally the test never fails on an idle box, and fails 2 in 10 with 16 CPU busy loops alongside it

Why this is a timeout ceiling and not a longer sleep: waitFor polls a condition and returns the moment it holds, so the 5s value is only how long a real hang takes to surface. The integration tier is the one tier that renders whole component trees and stubs only the network boundary, so its steps legitimately cost more than a unit render. Dropping the hook's debounce to 0 was tried and did not remove the flake, and the hook itself is not racy, so no production change is warranted

Mutation check: forcing the hook to always report Checking availability makes both threshold cases fail after the change, so the test still catches a Save button that never enables

Not flakes in the window

Real breakage: a types refactor on main around 2101c860 broke unit shards and the coverage job deterministically on every attempt until fixed upstream. Several PR failures matched files those PRs modified. Infra: one Prisma generation timeout and a run whose log blob was missing. None of these were touched

Other open deflake PRs

#42936 and #41219 both carry an approval from a human reviewer, so they are left untouched under the human-reviewed exception and this PR is the new rolling PR

Pre-Submission checklist

  • I have added meaningful tests
  • The handful of test files covering my change pass locally, e.g. uv run pytest tests/unit/<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

There is no proxy or Admin UI surface for this change, so the proof is the flake reproduction itself: the same test file run under the same CPU contention at the merge base and at the tip, in ui/litellm-dashboard

Before (f4308bc)

  1. for i in $(seq 16); do (while :; do :; done) & done; for i in $(seq 10); do npx vitest run --project integration src/components/edit_auto_router/edit_auto_router_modal.integration.test.tsx -t "hydrates the saved threshold" 2>&1 | grep -E "Tests .*(passed|failed)"; done; kill $(jobs -p)
  2. 8 runs report Tests 2 passed, 2 runs report Tests 1 failed | 1 passed with expect(element).toBeEnabled() on Save Changes timing out after 1000ms

After (9887b2e)

  1. Same command
  2. 10 of 10 runs report Tests 2 passed, and the full file reports Tests 64 passed

Type

✅ Test

Caveats (if any)

Low

  • A genuinely hung integration assertion now takes 5s instead of 1s to fail
  • Component and unit tiers are unchanged, so they keep the tight 1s signal

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

Link to Devin session: https://app.devin.ai/sessions/a2edebd9f60d42e8baab982666464c52
Open in Devin Desktop: https://app.devin.ai/desktop/session/a2edebd9f60d42e8baab982666464c52?variant=devin

…s cost

Integration cases render a whole component tree and legitimately take about a second per availability round trip under load, so testing-library's 1000ms asyncUtilTimeout default flakes them. The ceiling is raised to 5s for the integration project only via a dedicated setup file; unit and component tiers keep the default

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
@devin-ai-integration
devin-ai-integration Bot requested a review from a team September 27, 2026 09:47
@devin-ai-integration

Copy link
Copy Markdown
Contributor Author

I'll fix CI failures and address comments from users with write access. I'll skip comments containing "(aside)".

  • Disable automatic comment, CI, and merge conflict monitoring

@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.

@greptile-apps

greptile-apps Bot commented Sep 27, 2026 •

Copy link
Copy Markdown
Contributor

RetriggerConfidence Score: 5/5

[Low risk] Adds test setup configuration for integration tests.

The PR appears safe to merge; the reported flaky assertion receives the intended longer wait without changing the other test tiers.

Summary

The PR raises Testing Library’s asynchronous wait ceiling from one to five seconds for dashboard integration tests only.

  • Adds an integration-specific setup file and loads it after the existing shared setup.
  • Leaves production code, assertions, and the unit and component test tiers unchanged.

Reviews (1) · Last reviewed commit: "test(ui): give the integration vitest ti..."

@mateo-berri mateo-berri left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

This branch has not been deployed

No deployments
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.

2 participants