Skip to content

ci: categorise the tests into tiers and run each tier where it belongs #1958

Closed

Description

@JarryShaw

An audit of every test module at b2cd14078. Timings are from Unit Tests run 39331834560. It proposes a target tier for each kind of test. Builds on #1954 / #1956.

Proposed tiers

Tier Runs on What belongs
ALL every CPython leg, KTLO, 3.14t, GraalPy unit, compat (version-gated behaviour), simple integration on generated captures
LATEST latest CPython only complex integration (multi-engine parity, large captures, subprocess), repo-text / workflow / docs pins, round-trip sweeps
PERIODIC cron only drift checks against external state; none found among the tests (the cron-* workflows already do this)
PR pull requests only diff-dependent checks; none found among the tests (Changelog drift is already its own job)

Of the module classifications, 385 land in ALL, about 30 of them borderline, and 144 in LATEST, about 40 borderline. The LATEST ones carry about 710 s of 3.15 test time. Today most of them also run on every leg.

Where today's placement disagrees

  1. The *roundtrip* glob (ci(python): the GraalPy experimental leg reaches 26% of the suite before its 25-minute cap #1732) is a name rule. It sends 30 small hand-picked round-trip unit modules to 3.15 only, e.g. test_tcp_ns_flag_roundtrip_unit and test_from_dict_roundtrip_unit. It also misses real sweeps under other names, e.g. test_dispatch_reachability_unit at 24–55 s and test_misc_short_read_1470_runtime.
  2. ci(unit-tests): run platform-independent project pins once per push (#1954) #1956's pin rule is conservative. It keeps on every leg 36 project modules whose answer does not vary by interpreter: those that load conf.py, test util/ scripts, or check workflow shapes. That is about 99 s per leg. Pins outside tests/project are not covered at all, e.g. tests/corekit/test_sentinel_exports_unit.py and tests/test_docstring_contract.py.
  3. Tests that never run on push or PR:
  4. Misfiled tiers. tests/integration/test_module_loading.py and two *_runtime.py modules read no capture. The parity job runs the round-trip sweeps on 3.10 and 3.11, against ci(python): the GraalPy experimental leg reaches 26% of the suite before its 25-minute cap #1732.
  5. Cost. A push costs about 300 runner-minutes. GraalPy runs into its 110-minute cap on most runs, about a third of that. PyPy runs no tests.

Decisions

  • A. Adopt the four tiers. Should one executable rule assign them, extending ci(unit-tests): run platform-independent project pins once per push (#1954) #1956's tests/_tiers.py beyond tests/project, or an explicit per-module marker?
  • B. Should hand-picked round trips run on ALL, and sweeps be found by behaviour rather than name?
  • C. Should the dark tests get a job: one latest-CPython leg with every engine plus Sphinx, on push or on PR?
  • D. GraalPy: keep it as is, trim it to the ALL tier, or move it to cron?
  • E. Should PyPy get an ALL leg?

The per-module tables (path, kind, tier, current placement, seconds, reason) are available, and a follow-up comment can carry them. A separate pass is checking the historical logs of the non-blocking legs that end green, for real failures to fix.

Activity

  1. added
    ciPull requests that change CI or workflow configuration (ci: subject prefix)
    needs: decisionWaiting on the maintainer to decide — not blocked by other work
    on Oct 20, 2026
  2. moved this to Needs decision in PyPCAPKiton Oct 20, 2026
  3. JarryShaw commented on Oct 20, 2026

    @JarryShaw
    OwnerAuthor

    A. I'd prefer executable rule assignment for single-place tracking but also comes with per-module marker for explicity.
    B. I'd say selected ones should run on ALL as part of the quality assurance.
    C. yes, and assign them to the corresponding tiers.
    D. depending on how we've tested it. if GraalPy support is generally validated, we can now promote it from experimental classes, free-threaded CPython as well.
    E. I'd say ALL implementations should get the same minimal tier of tailored test suite for quality assurance purposes. But latest CPython will have the whole suite for sanity check and gatekeeping.

  4. JarryShaw commented on Oct 20, 2026

    @JarryShaw
    OwnerAuthor

    The plan, in four PRs, each stacked on #1956 until it merges:

    1. Tier assignment (A, B).
      • tests/_tiers.py becomes the single source for every module under tests/. A module-level __tier__ constant ('ALL', 'LATEST', …), read by AST, overrides the executable rule where the rule's guess is wrong or worth stating outright. A constant works under plain unittest too, which a pytest marker would not.
      • The *roundtrip* name glob goes. The hand-picked round trips run on ALL; the real sweeps are marked LATEST.
      • The tier guard fails if any module resolves to no tier, or if the workflows disagree with the rule.
    2. Whole suite on latest CPython (C, E). The latest-CPython leg installs every engine, Sphinx and html5lib, and runs every tier. That brings the dark tests in.
    3. The ALL tier on every implementation (E). Add PyPy legs that run the ALL tier, as the other non-latest legs do.
    4. Promotion (D). GraalPy and 3.14t move out of experimental once their history shows they are validated. A separate pass over their recent logs is under way; its findings will be posted here before that PR.

    Starting on 1.

  5. added
    wipWork in flight - a covering PR is open or an agent is actively on it
    and removed
    needs: decisionWaiting on the maintainer to decide — not blocked by other work
    on Oct 20, 2026
  6. moved this from Needs decision to WIP in PyPCAPKiton Oct 20, 2026
  7. JarryShaw commented on Oct 20, 2026

    @JarryShaw
    OwnerAuthor

    After the review of #1971, the four *_edge_roundtrip_unit tables move to ALL, since their hand-written rows serve ruling B's purpose. test_short_read_roundtrip_unit and the deadline harness test stay LATEST. This lands as a test-only follow-up.

  8. JarryShaw commented on Oct 20, 2026

    @JarryShaw
    OwnerAuthor

    Blocked until #1973 merges. Phase 2 (the whole suite on latest CPython) rewrites the same unit-tests.yml test commands that #1973 wraps with the file-size cap.

  9. added
    blockedDeferred pending another issue or decision; see the last comment for what unblocks it
    and removed
    wipWork in flight - a covering PR is open or an agent is actively on it
    on Oct 20, 2026
  10. 24 remaining items

  11. moved this from WIP to Needs decision in PyPCAPKiton Oct 21, 2026
  12. JarryShaw commented on Oct 21, 2026

    @JarryShaw
    OwnerAuthor

    3.14t findings, from experimental.yml on main (2026-10-19 to d419d8c39). Each run is judged by its tests step's pytest summary, since the job itself always ends in success.

    The record supports promoting 3.14t. That leaves item 5 above: set PYTHON_GIL=0 on the leg, or keep lxml out of it, if the tier should run truly free-threaded.

  13. JarryShaw commented on Oct 21, 2026

    @JarryShaw
    OwnerAuthor
    1. take recommendations
    2. take recommendations and iirc, you can make rulesets update as well.
    3. good, promote 3.14t; and let's wait for GraalPy in this issue.
    4. good. go with your order
    5. i say we ensure GIL is not on. and if necessary, consider drop lxml from 3.14t tests.
  14. JarryShaw commented on Oct 21, 2026

    @JarryShaw
    OwnerAuthor

    Plan from these rulings:

  15. removed
    needs: decisionWaiting on the maintainer to decide — not blocked by other work
    on Oct 21, 2026
  16. moved this from Needs decision to WIP in PyPCAPKiton Oct 21, 2026
  17. JarryShaw commented on Oct 22, 2026

    @JarryShaw
    OwnerAuthor

    Phase 4 is dropped: 3.14t and GraalPy both stay experimental (ruling on #1967 at 02:05Z), so #2024 is closed and the ruleset is unchanged. Phases 1–3 landed in #1971, #1976, #1978 and #2006. Closing; I'll reopen this if promotion comes back.

  18. removed
    wipWork in flight - a covering PR is open or an agent is actively on it
    on Oct 22, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    ciPull requests that change CI or workflow configuration (ci: subject prefix)

    Projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions