Skip to content

ci: balance fixture-aware test groups#5810

Open
njzjz-bot wants to merge 6 commits into
deepmodeling:masterfrom
njzjz:ci/duration-based-test-split
Open

ci: balance fixture-aware test groups#5810
njzjz-bot wants to merge 6 commits into
deepmodeling:masterfrom
njzjz:ci/duration-based-test-split

Conversation

@njzjz-bot

@njzjz-bot njzjz-bot commented Jul 16, 2026

Copy link
Copy Markdown
Contributor

Summary

  • group complete test classes and module-level tests into indivisible fixture-sharing units
  • assign units to 12 shards with deterministic longest-processing-time bin packing
  • support @pytest.mark.ci_split_group("name") for merging complete classes/modules that share an expensive fixture; partial method-level markers are rejected
  • use version-controlled Python 3.10 and 3.13 seeds for historically expensive units, so the first run does not depend on any GitHub Actions cache
  • record the main, TF2, JAX-to-TF, and consistent-TF2 durations independently, then merge their partial maps without summing duplicate node IDs
  • use the test4 cache namespace only after a successful grouped run has produced combined runtime durations

Validation

  • 9 splitter unit tests passed on Python 3.10 and Python 3.13
  • two-shard pytest integration runs selected disjoint complete classes and stored all durations
  • real collection of source/tests/pt_expt/infer/test_deep_eval.py kept the 22 TestDeepEvalEnerPt2 methods in one unit
  • first-run seed replay against existing CI artifacts produced a 3145-second maximum shard, versus the 3426-second base maximum and the previous 5117-second PR maximum
  • malformed legacy cache lists produce a descriptive pytest.UsageError
  • workflow YAML and TF2 helper shell syntax validated
  • ruff check .
  • ruff format .

Live CI validation: https://github.com/deepmodeling/deepmd-kit/actions/runs/29637394120

Coding agent: Codex
Codex version: codex-cli 0.144.4
Model: gpt-5.6-sol
Reasoning effort: xhigh

Use duration-based contiguous chunks so neighboring tests and their expensive class-scoped setup are less likely to be dispersed across all CI shards.\n\nCoding-Agent: Codex\nCodex-Version: codex-cli 0.144.4\nModel: gpt-5.6-sol\nReasoning-Effort: xhigh
@dosubot dosubot Bot added the build label Jul 16, 2026
@coderabbitai

coderabbitai Bot commented Jul 16, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

The Python test workflow now invokes a pytest plugin that groups fixture-sharing tests, balances shards using cached durations, and selects a requested CI group. Tests validate grouping and deterministic balancing, while workflow cache keys move to the test4 prefix.

Changes

Python test sharding

Layer / File(s) Summary
Fixture-aware shard allocation
source/tests/ci_split.py
Adds pytest options and hooks that group tests by class, module, or explicit marker, load duration caches, assign units with deterministic LPT balancing, and select the requested shard.
Shard allocation tests
source/tests/test_ci_split.py
Tests indivisible units, cross-module explicit groups, marker validation, cached-duration balancing, empty-cache balancing, and deterministic ordering.
Workflow integration and cache versioning
.github/workflows/test_python.yml
Runs pytest through source.tests.ci_split with --ci-splits and --ci-group, and updates duration cache keys and restore keys to test4.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant CI as CI workflow
  participant Pytest
  participant Cache as Duration cache
  participant Plugin as ci_split plugin
  CI->>Pytest: Run with shard options
  Pytest->>Plugin: Collect tests and invoke hooks
  Plugin->>Cache: Load persisted durations
  Cache-->>Plugin: Return duration data
  Plugin->>Plugin: Group and balance test units
  Plugin->>Pytest: Select requested shard
Loading
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly reflects the main change: balancing fixture-aware test groups in CI.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

Start the contiguous splitting algorithm with a clean duration cache so setup costs recorded under least-duration sharding do not distort the new chunk boundaries.\n\nCoding-Agent: Codex\nCodex-Version: codex-cli 0.144.4\nModel: gpt-5.6-sol\nReasoning-Effort: xhigh

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.github/workflows/test_python.yml:
- Line 59: Update the cache key in the test workflow to include
github.run_attempt alongside the existing run identifiers, Python version, and
matrix group, ensuring reruns use distinct per-shard duration caches.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 1c7752db-b768-442a-80a3-b068954bf662

📥 Commits

Reviewing files that changed from the base of the PR and between 1377db8 and dd232a6.

📒 Files selected for processing (1)
  • .github/workflows/test_python.yml

Comment thread .github/workflows/test_python.yml Outdated
Include github.run_attempt in each per-shard cache key so workflow reruns cannot restore stale shard-local duration data from an earlier attempt.

Coding-Agent: Codex
Codex-Version: codex-cli 0.144.4
Model: gpt-5.6-sol
Reasoning-Effort: xhigh
@codecov

codecov Bot commented Jul 16, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 78.42%. Comparing base (1c5ff68) to head (0718753).
⚠️ Report is 11 commits behind head on master.

Additional details and impacted files
@@            Coverage Diff             @@
##           master    #5810      +/-   ##
==========================================
- Coverage   78.57%   78.42%   -0.16%     
==========================================
  Files        1049     1053       +4     
  Lines      120650   120891     +241     
  Branches     4348     4382      +34     
==========================================
- Hits        94806    94804       -2     
- Misses      24285    24544     +259     
+ Partials     1559     1543      -16     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

njzjz-bot and others added 2 commits July 18, 2026 15:31
Keep test classes and module-level tests together, then assign those units with deterministic duration-based LPT bin packing. Warm-start the new cache namespace from existing per-test timings so the first CI run remains balanced.

Coding-Agent: Codex

Codex-Version: codex-cli 0.144.4

Model: gpt-5.6-sol

Reasoning-Effort: xhigh

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

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.github/workflows/test_python.yml:
- Line 69: Append --store-durations to each TF2 test command in the workflow,
including the commands covering source/tests/tf2, source/jax2tf_tests, and
consistent TF2 tests. Do not add --clean-durations there, so those commands
append their timings to the duration file created by the source/tests step.

In `@source/tests/ci_split.py`:
- Around line 80-89: The explicit-group handling around _explicit_group_name
must preserve complete fixture units: a method-level marker must not separate
one method from the remaining methods in its class. Change grouping so explicit
groups merge the entire class or module unit, or reject markers that do not
cover that unit; add a regression covering a marked class with multiple methods
and verify all methods remain together.
- Around line 162-163: Update the legacy-list normalization in the cache restore
flow around the isinstance(data, list) check to catch TypeError and ValueError
from dict(data), and handle them through the existing cache usage error path.
Ensure malformed restored lists do not escape as unhandled collection failures.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 8c61f016-a08f-4964-b0ab-764dacbe312c

📥 Commits

Reviewing files that changed from the base of the PR and between b8b5d0f and f36adb7.

📒 Files selected for processing (3)
  • .github/workflows/test_python.yml
  • source/tests/ci_split.py
  • source/tests/test_ci_split.py

Comment thread .github/workflows/test_python.yml Outdated
Comment thread source/tests/ci_split.py Outdated
Comment thread source/tests/ci_split.py Outdated
@njzjz-bot njzjz-bot changed the title ci: preserve test order across duration shards ci: balance fixture-aware test groups Jul 18, 2026
Comment thread source/tests/ci_split.py Fixed
Use version-controlled Python 3.10 and 3.13 estimates for expensive fixture units instead of relying on a possibly missing test2 cache. Preserve complete class/module units for explicit markers, retain TF2 timings through independent duration files, and report malformed legacy caches as usage errors.

Coding-Agent: Codex

Codex-Version: codex-cli 0.144.4

Model: gpt-5.6-sol

Reasoning-Effort: xhigh
@njzjz-bot

Copy link
Copy Markdown
Contributor Author

CI timing result for the first committed-seed run: https://github.com/deepmodeling/deepmd-kit/actions/runs/29637394120

Group Main pytest TF2 Total job Queue
1 29:27 8:36 40:47 23:39
2 15:13 6:53 25:28 14:53
3 66:15 2:17 71:18 13:03
4 19:11 2:24 24:11 24:25
5 27:19 2:57 33:39 14:23
6 60:58 2:21 66:26 21:01
7 48:29 2:21 53:39 21:43
8 21:01 2:14 26:08 23:22
9 23:05 2:09 28:18 6:01
10 47:25 3:54 54:17 23:37
11 47:35 2:21 53:28 21:24
12 36:09 2:18 42:05 6:19

Compared with the base run (29456447617):

  • cumulative main-pytest time: 10:12:07 -> 7:22:07, 27.8% less runner time
  • cumulative full-job time: 11:31:41 -> 8:39:44, 24.9% less runner time
  • slowest main-pytest shard: 57:06 -> 66:15, 16.0% slower
  • slowest full job: 68:18 -> 71:18, 4.4% slower
  • workflow wall time: 1:13:21 -> 1:29:30, 22.0% slower, including runner queueing

Compared with the previous duration_based_chunks run (29513326076), the slowest main shard improved from 85:17 to 66:15 (22.3%), although cumulative main-pytest time increased by 5.0%.

Conclusion: this run reduced duplicated setup and total runner-minutes, but did not accelerate the CI critical path. The first-run seed remained imbalanced, especially groups 3 and 6. A second run using the newly generated test4 grouped-duration cache is needed to evaluate steady-state performance.

Coding agent: Codex
Codex version: codex-cli 0.144.4
Model: gpt-5.6-sol
Reasoning effort: xhigh

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants