mirror of
https://github.com/bytedance/deer-flow.git
synced 2026-09-14 16:08:41 +00:00
* feat(ci): split backend unit tests into parallel CI shards Split the single offline backend `make test` job into four GitHub Actions matrix shards (SPLITS=4, GROUP=1..4) via pytest-split, so the ~12k-test suite runs in parallel instead of in one 15-minute job. Each shard runs on its own runner with its own Postgres/Redis services; fail-fast: false lets a failing shard report its owned tests without cancelling its peers. `make test` stays the canonical full-suite entry point; CI now calls the new `make test-shard SPLITS=4 GROUP=N`. tests/blocking_io remains owned solely by the dedicated blocking-I/O workflow (excluded via --ignore), extending #5105. Fixes #5088 * test(ci): make backend test shards duration-aware and pin the contract Make `make test-shard` an explicit least_duration split that READS backend/.test_durations (read-only for shards, so concurrent CI jobs never race writes on it), and add `make test-shard-durations` to regenerate that file from the full offline suite. Update the CI unit-test workflow contract to call `make test-shard SPLITS=4 GROUP=<n>` and assert the shard command carries --splits 4, --group 2, -m "not live", --ignore=tests/blocking_io and --splitting-algorithm least_duration. Verified on the real 13,140-test normal suite that the four shards are pairwise disjoint and their union equals the unsplit suite. Refs #5088 * test(ci): fail fast when the duration baseline is missing `make test-shard` now requires backend/.test_durations and exits with a clear error instead of letting pytest-split silently degrade to an even (count-based) split. Harden the CI contract test to pin `--durations-path=.test_durations` and to assert the repo ships the committed duration baseline. Refs #5088 * docs: trim backend/AGENTS.md within guidance budget * test(ci): add backend test duration baseline Add the duration baseline generated by a full offline backend run on a GitHub-hosted ubuntu-latest runner (the same runner type the shards use), so `make test-shard` balances the four matrix shards by real wall-clock cost. Refs #5088 * test(ci): make the duration writer honor DURATIONS_FILE `test-shard-durations` now writes `--durations-path=$(DURATIONS_FILE)` instead of a hard-coded .test_durations, so the reader and writer stay consistent when the path is overridden. Refs #5088 * test(ci): address sharding review feedback * test: isolate subagent execution capacity state --------- Co-authored-by: Willem Jiang <willem.jiang@gmail.com>
117 lines
3.5 KiB
YAML
117 lines
3.5 KiB
YAML
name: Unit Tests
|
|
|
|
on:
|
|
push:
|
|
branches: [ 'main', '2.0.x-dev' ]
|
|
pull_request:
|
|
types: [opened, synchronize, reopened, ready_for_review]
|
|
|
|
concurrency:
|
|
group: unit-tests-${{ github.event.pull_request.number || github.ref }}
|
|
cancel-in-progress: true
|
|
|
|
permissions:
|
|
contents: read
|
|
|
|
jobs:
|
|
default-install-collection:
|
|
# The main job installs --extra postgres; this job proves the documented
|
|
# contributor path (uv sync --group dev, no extras) still collects the
|
|
# whole suite, so optional-dependency imports must stay lazy.
|
|
if: github.event.pull_request.draft == false
|
|
runs-on: ubuntu-latest
|
|
timeout-minutes: 10
|
|
|
|
steps:
|
|
- name: Checkout
|
|
uses: actions/checkout@v6
|
|
|
|
- name: Set up Python
|
|
uses: actions/setup-python@v6
|
|
with:
|
|
python-version: '3.12'
|
|
|
|
- name: Install uv
|
|
uses: astral-sh/setup-uv@v7
|
|
with:
|
|
# Must match backend/Dockerfile's UV_IMAGE tag; pinned by backend/tests/test_ci_uv_version_pin.py
|
|
version: "0.11.1"
|
|
|
|
- name: Install backend dependencies (documented default)
|
|
working-directory: backend
|
|
run: uv sync --group dev
|
|
|
|
- name: Collect backend tests
|
|
working-directory: backend
|
|
run: uv run pytest --collect-only -q
|
|
|
|
backend-unit-tests:
|
|
if: github.event.pull_request.draft == false
|
|
runs-on: ubuntu-latest
|
|
timeout-minutes: 15
|
|
strategy:
|
|
# Duration-aware split: `make test-shard` balances the shards by real
|
|
# wall-clock cost from backend/.test_durations (read-only for shards, so
|
|
# concurrent jobs never race writes on it). Every test runs exactly once.
|
|
# Fail-fast is off so a failing shard reports its tests without cancelling
|
|
# its peers.
|
|
fail-fast: false
|
|
matrix:
|
|
shard: [1, 2, 3, 4]
|
|
|
|
services:
|
|
postgres:
|
|
image: postgres:17
|
|
env:
|
|
POSTGRES_USER: deerflow
|
|
POSTGRES_PASSWORD: deerflow
|
|
POSTGRES_DB: deerflow_test
|
|
ports:
|
|
- 5432:5432
|
|
options: >-
|
|
--health-cmd pg_isready
|
|
--health-interval 10s
|
|
--health-timeout 5s
|
|
--health-retries 5
|
|
redis:
|
|
image: redis:7-alpine
|
|
ports:
|
|
- 6379:6379
|
|
options: >-
|
|
--health-cmd "redis-cli ping"
|
|
--health-interval 10s
|
|
--health-timeout 5s
|
|
--health-retries 5
|
|
|
|
env:
|
|
TEST_POSTGRES_URI: postgresql://deerflow:deerflow@localhost:5432/deerflow_test?sslmode=disable
|
|
|
|
steps:
|
|
- name: Checkout
|
|
uses: actions/checkout@v6
|
|
|
|
- name: Set up Python
|
|
uses: actions/setup-python@v6
|
|
with:
|
|
python-version: '3.12'
|
|
|
|
- name: Install uv
|
|
uses: astral-sh/setup-uv@v7
|
|
with:
|
|
# Must match backend/Dockerfile's UV_IMAGE tag; pinned by backend/tests/test_ci_uv_version_pin.py
|
|
version: "0.11.1"
|
|
|
|
- name: Install backend dependencies
|
|
working-directory: backend
|
|
run: uv sync --group dev --extra postgres
|
|
|
|
- name: Run unit tests of backend (shard ${{ matrix.shard }} of 4)
|
|
working-directory: backend
|
|
env:
|
|
# Expose the job's Postgres service to the cross-pod dedupe integration
|
|
# tests (issue #4120), which read DEDUPE_TEST_POSTGRES_URL. Without this
|
|
# mapping those tests silently skip and the headline capability is never
|
|
# exercised in CI.
|
|
DEDUPE_TEST_POSTGRES_URL: ${{ env.TEST_POSTGRES_URI }}
|
|
run: make test-shard SPLITS=4 GROUP=${{ matrix.shard }}
|