Repository navigation
fix(ci): judge PR test growth by time and re-enable per-test alerts for 4 modules - #6053
mesakhcienet wants to merge 1 commit into
Conversation
|
🤖 Hi @mesakhcienet, I'm running an automatic MaxText review of this pull request. You can track my progress in the logs. To request another review later, add the |
Summary of ChangesHello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed! This pull request updates the CI test regression logic to shift from test-count-based alerts to a time-based suite growth check. This change addresses false positives caused by fluctuations in test counts and improves the reliability of performance monitoring. Additionally, it re-enables per-test alerts for specific modules that have been stabilized by the class-level shard split and introduces stricter data validation for test duration inputs. Highlights
New Features🧠 You can now enable Memory (public preview) to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console. Ignored Files
Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize the Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counterproductive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here. Footnotes
|
There was a problem hiding this comment.
📋 Review Summary
Verdict: Spec met; robust implementation with excellent test coverage. One minor edge case found.
Top issues:
- [Bug]
add_suite_sampleomits thebase_time > 0validation used elsewhere. If a baseline entry isNaNor negative, it poisons the flavor's base time and silently disables the suite check for that flavor. → Addand base_time > 0to the condition (see inline comment).
Inferred spec & validation
- Sources: PR description, code before/after.
- Problem: PR test growth was judged by test count, which failed PRs when many quick tests were added, causing false positive regressions on CI.
| Spec item | Implementation | Validating test |
|---|---|---|
| R1 (stated): PR test growth is judged by time, comparing passed tests to the baseline of existing tests | ✅ | test_suite_check_fails_a_pr_whose_new_tests_grow_a_flavor_past_both_limits ✅ |
| R2 (stated): PR fails if flavor time grows > 1.20x AND > 300s longer | ✅ | test_suite_check_fails_a_pr_whose_new_tests_grow_a_flavor_past_both_limits ✅ |
R3 (stated): New scheduled_only tests are not counted towards PR suite regression |
✅ | test_suite_check_leaves_out_new_scheduled_only_tests ✅ |
| R4 (stated): CPU, decoupled, partial, corrupt, and overlapping flavors are skipped | ✅ | test_suite_check_skips_cpu_and_partial_flavors_and_ignores_failed_tests ✅ |
| R5 (stated): Per-test alerts are enforced again for 4 modules | ✅ | test_process_testcase_regression_enforced_for_megablox_gmm_3d_test ✅ |
| C1 (stated): Dashboard keeps tracking test counts but does not fail PRs | ✅ preserved | N/A (Checked in GitHub workflow) |
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
24f8c4d to
32b94b6
Compare
32b94b6 to
6ad8b21
Compare
| EVENT_NAME: ${{ github.event_name }} | ||
| REF: ${{ github.ref }} | ||
| run: | | ||
| EXTRA_ARGS=() |
There was a problem hiding this comment.
Pass --warn-only for all non-PR events so release/manual runs log regressions without failing the pipeline. Also, only generate new_per_test_baseline.json and benchmark-results.json on schedule runs on refs/heads/main.
EXTRA_ARGS=()
if [ "$EVENT_NAME" != "pull_request" ]; then
EXTRA_ARGS+=("--warn-only")
fi
if [ "$EVENT_NAME" = "schedule" ] && [ "$REF" = "refs/heads/main" ]; then
EXTRA_ARGS+=(
"--save-baseline" "new_per_test_baseline.json"
"--output-benchmark" "benchmark-results.json"
)
fi
python3 tools/dev/process_test_results.py test-results \
--baseline per_test_baseline.json \
"${EXTRA_ARGS[@]}"
There was a problem hiding this comment.
Done, with your snippet. Every non-PR event now passes --warn-only, and only scheduled runs on main write new_per_test_baseline.json and benchmark-results.json. The dashboard step needs benchmark-results.json, so it now only runs on those runs. I kept fail-on-alert: false there so those runs only warn too; an alert still adds a commit comment.
| corrupt_jobs.add(job_name) | ||
| has_errors = True | ||
|
|
||
| # A test that ran in two shard files means the flavor's shards overlapped (e.g. a shard dealt the classes without |
There was a problem hiding this comment.
Can we simplify this by dropping the duplicate-shard detection?
Shards only overlap when the coordinator uploads the durations artifact and one worker fails to download it while other workers succeed. When that happens, other tests are silently skipped so we shouldn't let that test shard pass with a fallback split and try to filter out the aftermath during result processing.
Instead of adding extra post-processing logic and edge cases here, let's remove the duplicate-test handling from this PR and make the test runner require the durations download whenever the coordinator uploaded it so all shards are guaranteed to use the same split.
There was a problem hiding this comment.
Agreed, removed. The coordinator now outputs test_durations_uploaded (true when its upload step created the artifact) and passes it to run_tests_against_package.yml. Shards download the durations only in that case, and without continue-on-error. So a failed download fails the shard, instead of letting it use a different split. If the coordinator had no baseline, every shard uses the same fallback split, as before.
One related change: a re-run shard downloads the durations again, so with a 1-day retention a re-run the next day would now fail. The artifact is now kept 30 days, which is how long GitHub allows re-runs.
| return markers | ||
|
|
||
|
|
||
| def baseline_seconds(value): |
There was a problem hiding this comment.
Can we simplify this by removing the extra checks and tests for unrealistic duration values like booleans, NaN, infinity, negative test times, and 400-digit numbers? Both the XML test reports and the baseline JSON are generated automatically by pytest and this script, so test durations in CI are always normal non-negative numbers. If we still want a basic safety check when reading the baseline JSON, let's just filter out invalid entries once right when the file is loaded rather than adding separate validation helpers and edge-case tests across multiple files.
There was a problem hiding this comment.
Done. I removed baseline_seconds(), testcase_seconds(), the extra filtering in class_split.load_durations and the edge-case tests. Only one check is left: when the baseline JSON is loaded, it keeps the <flavor>::<test> keys whose value is a number ≥ 0. This replaces the old isinstance filter, which only applied to the saved copy. Test times from the XML are read with plain float() again.
6ad8b21 to
1d0a91c
Compare
…or 4 modules Follow-up to #5565 for the Track Test Duration regression alerts. - PR runs are no longer failed by the dashboard's test-count totals. A new suite check in process_test_results.py compares, per flavor, the time of all passed tests (new ones included) with the baseline time of the same existing tests, and fails a PR above 1.20x and +300 s, listing the costliest new tests and the existing tests that slowed down most. New scheduled_only tests and CPU, decoupled, partial or corrupt flavors are left out. A renamed or moved test counts as new until the next scheduled run. The check runs in process_testcase(), in the same pass as the per-test check. - Only PR runs fail on a regression: every other event passes --warn-only, and only scheduled runs on main write the new baseline and the dashboard data, so the dashboard step only runs there (it comments on an alert, it does not fail). - Per-test alerts are enforced again for megablox_gmm_3d_test, megablox_relayout_test, m3.qwen3_vl_comparison_test and tiling_test, which no longer swing with shard position under the class split. moe_test, attention_test and integration.pipeline_parallelism_test stay warn-only: their tests still reuse other classes' compiles depending on the deal. - When the coordinator uploads the converted test durations, every shard must download them (no continue-on-error), so all shards split the tests the same way instead of one falling back to another split and overlapping the others. The artifact is kept 30 days instead of 1, as a re-run shard downloads it again and GitHub allows re-runs for 30 days. - The baseline is filtered once when loaded ('<flavor>::<test>' keys with a number >= 0). The [class-split] lines print after the collection summary instead of after "collecting ...".
1d0a91c to
1a84635
Compare
Description
Background
The "Track Test Duration" CI job checks whether a PR makes tests slower. It compares the PR's test times with the times from the last scheduled run on
main. It had two problems:What this PR changes
mainsave the new test times and update the dashboard.Details for reviewers
tools/dev/process_test_results.py,tests/utils/class_split.py,.github/workflows/track_performance.yml,run_tests_coordinator.yml,run_tests_against_package.yml, and the tests.tpu-unit), it compares the time of all passed tests with the saved time of the same existing tests. The limits areSUITE_RATIO_LIMIT = 1.20andSUITE_FLOOR_SEC = 300. Newscheduled_onlytests, CPU groups and incomplete runs are skipped. A renamed test counts as new until the next scheduled run. The check runs insideprocess_testcase(), in the same pass as the per-test check.megablox_gmm_3d_test,megablox_relayout_test,m3.qwen3_vl_comparison_test,tiling_test. Still warning-only:moe_test,attention_test,integration.pipeline_parallelism_test.track_performance.yml): every event exceptpull_requestpasses--warn-only. Onlyscheduleonrefs/heads/mainpasses--save-baselineand--output-benchmark, so the baseline push and the dashboard step only run there. The dashboard step comments on an alert and doesn't fail the run..test_durations(test_durations_uploaded). If it did, the shard's download step is required (no morecontinue-on-error). If the coordinator had no baseline, every shard uses the same fallback split, as before. The artifact is kept 30 days instead of 1 (GitHub's re-run limit): a re-run shard downloads it again, and with 1 day a re-run the next day would now fail.<flavor>::<test>keys with a number ≥ 0);[class-split]log line prints on its own line.tpu-unittotal rose 1.28x (+1,494 s), well past both limits.Tests
tests/devpass.[SUITE]lines from 0.95x to 1.02x, no new tests) and, as a PR run, skipped the baseline push and the dashboard step.Checklist
Before submitting this PR, please make sure (put X in square brackets):
gemini-reviewlabel.skip-ci-testsso only CPU/lint/docs checks run during review; a bot removes it after 2 approvals on a 1-commit PR to run TPU/GPU suites, or remove it yourself / ask a maintainer on fork PRs to run them sooner.)