Skip to content

Commit c1425d2

Browse files
committed
ci: write the shard manifest before any suite runs; warn on absent upload
The manifest content (leg, slice, list hash) is fully determined at slicing time, so write it up front: a red run's manifest is exactly as load-bearing for the cross-shard union proof as a green one's. With that, a missing manifest at upload time can only mean the job died before the harness started (contract step / build failure) — that failure is already the job's red, so the upload warns instead of stacking a second error on top (the recurring 'No files were found with the provided path: build/c/test-logs/shard-manifest.txt' annotation). The shard-completeness job still gates the union. Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
1 parent a5f9a6d commit c1425d2

2 files changed

Lines changed: 28 additions & 16 deletions

File tree

.github/workflows/_test.yml

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,12 @@ jobs:
154154
with:
155155
name: shard-manifest-${{ matrix.os }}-${{ matrix.cc }}-${{ strategy.job-index }}
156156
path: build/c/test-logs/shard-manifest.txt
157-
if-no-files-found: error
157+
# The harness writes the manifest BEFORE any suite runs, so a
158+
# missing file here means the job died before the harness started
159+
# (contract step / build) — that failure is already the job's red;
160+
# warn instead of stacking a second error on top of it. The
161+
# shard-completeness job still gates the cross-shard union.
162+
if-no-files-found: warn
158163

159164
- name: Compiler cache (save)
160165
if: always() && (matrix.shard == null || startsWith(matrix.shard, '1/'))
@@ -330,7 +335,12 @@ jobs:
330335
with:
331336
name: shard-manifest-${{ matrix.os }}-${{ matrix.msystem }}-${{ strategy.job-index }}
332337
path: build/c/test-logs/shard-manifest.txt
333-
if-no-files-found: error
338+
# The harness writes the manifest BEFORE any suite runs, so a
339+
# missing file here means the job died before the harness started
340+
# (contract step / build) — that failure is already the job's red;
341+
# warn instead of stacking a second error on top of it. The
342+
# shard-completeness job still gates the cross-shard union.
343+
if-no-files-found: warn
334344

335345
# Shard 1 (or the unsharded job) saves the compiler cache; every shard
336346
# builds the identical runner, so one cache carries the full object set.

scripts/run-tests-parallel.sh

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,22 @@ shard_filter < "$SER_FILE" > "$SER_FILE.shard" && mv "$SER_FILE.shard" "$SER_FIL
195195
SHARD_EXPECT="$LOGDIR/suites-shard.txt"
196196
cat "$PAR_FILE" "$SER_FILE" > "$SHARD_EXPECT"
197197
NSHARD=$(wc -l < "$SHARD_EXPECT" | tr -d ' ')
198+
199+
# Machine-checkable manifest for CI's cross-shard completeness job: it
200+
# proves at runtime that the shards of one leg agree on N and on the full
201+
# suite list, and that the union of their slices IS that list — the guard
202+
# against a mis-plumbed CBM_TEST_SHARD (two jobs running the same slice
203+
# passes every per-shard check but silently drops a slice; only a
204+
# cross-shard view catches it). Written BEFORE any suite runs: the slice is
205+
# fully determined here, and a red run's manifest is exactly as load-bearing
206+
# as a green one's — CI uploads it if: always().
207+
{
208+
echo "leg=${CBM_TEST_LEG:-local}"
209+
echo "shard=${SHARD_INDEX}/${SHARD_TOTAL}"
210+
echo "list_sha256=$(sort "$SUITES_FILE" | { sha256sum 2>/dev/null || shasum -a 256; } | awk '{print $1}')"
211+
echo "--- slice ---"
212+
cat "$SHARD_EXPECT"
213+
} > "$LOGDIR/shard-manifest.txt"
198214
echo "=== parallel test run: $NSHARD of $NSUITES suites (shard ${SHARD_INDEX}/${SHARD_TOTAL}, $(wc -l < "$SER_FILE" | tr -d ' ') serial-tail), $JOBS jobs ==="
199215

200216
# Per-suite wall-clock ceilings make a wedged child fail loudly. The
@@ -255,20 +271,6 @@ stamp_windows_build_dir pre-tail
255271
run_wave "$FLEX_FILE" "${CBM_TAIL_JOBS:-2}"
256272
run_wave "$EXCL_FILE" 1
257273

258-
# Machine-checkable manifest for CI's cross-shard completeness job: it
259-
# proves at runtime that the shards of one leg agree on N and on the full
260-
# suite list, and that the union of their slices IS that list — the guard
261-
# against a mis-plumbed CBM_TEST_SHARD (two jobs running the same slice
262-
# passes every per-shard check but silently drops a slice; only a
263-
# cross-shard view catches it).
264-
{
265-
echo "leg=${CBM_TEST_LEG:-local}"
266-
echo "shard=${SHARD_INDEX}/${SHARD_TOTAL}"
267-
echo "list_sha256=$(sort "$SUITES_FILE" | { sha256sum 2>/dev/null || shasum -a 256; } | awk '{print $1}')"
268-
echo "--- slice ---"
269-
cat "$SHARD_EXPECT"
270-
} > "$LOGDIR/shard-manifest.txt"
271-
272274
# ── Union guard: every suite in this shard's slice produced exactly one
273275
# result. The slice is deterministic, so N green shard jobs = full coverage;
274276
# a shard that ran anything more, less, or twice fails here. ──

0 commit comments

Comments
 (0)