AGC Rust 分片改为失败用例有界复核

- run-rust-shell-test-shards.mjs 在分片失败后解析失败用例名,仅对这组用例在新进程内复核一次
- 复核通过按 flaky 明确记录并通过,复核仍失败则保留失败并标注 re-run 结果,避免洗掉真实回归
- 解析兼容 runner 输出的 [rust-shards] 前缀与 panic 头格式,已用一次性探针 crate 端到端验证重跑路径
This commit is contained in:
2026-09-21 02:42:27 +08:00
parent cc39045799
commit af4324a64d
@@ -371,6 +371,26 @@ async function runWithConcurrency(shards, runner) {
return results;
}
function extractFailingTestNames(result) {
const names = new Set();
for (const line of result.failures) {
const normalized = line
.trim()
.replace(/^\[rust-shards\]\s*/, '')
.replace(/^----\s*/, '')
.replace(/\s*stdout\s*----$/, '')
.replace(/\s*\(\d+\)\s*$/, '')
.trim();
const match = normalized.match(
/^(process_session::tests::[A-Za-z0-9_:]+|tests::[A-Za-z0-9_:]+)$/,
);
if (match) {
names.add(match[1]);
}
}
return [...names];
}
async function main() {
const executable = await resolveTestExecutable();
const testNames = await listTestNames(executable);
@@ -410,15 +430,55 @@ async function main() {
const results = await runWithConcurrency(
selectedShards,
({ index, shardTestNames }) =>
runShard(executable, index, shards.length, shardTestNames),
async ({ index, shardTestNames }) => {
const result = await runShard(
executable,
index,
shards.length,
shardTestNames,
);
if (result.ok) {
return result;
}
// 片内串行的时序型用例在高负载 CI 上会偶发假红。只对失败用例做一次
// 有界复核:复核通过按 flaky 记录,复核失败才判红,避免把真实回归洗掉。
const failingTestNames = extractFailingTestNames(result).filter((name) =>
shardTestNames.includes(name),
);
if (failingTestNames.length === 0) {
return result;
}
const retry = await runShard(
executable,
index,
shards.length,
failingTestNames,
);
if (!retry.ok) {
return {
...result,
failures: [
`re-run of ${failingTestNames.length} failing test(s) also failed`,
...retry.failures,
],
};
}
return {
...result,
ok: true,
retriedTestNames: failingTestNames,
};
},
);
let failed = false;
for (const result of results) {
if (result.ok) {
const retrySuffix = result.retriedTestNames
? ` (flaky: re-ran ${result.retriedTestNames.length} failing test(s) and passed: ${result.retriedTestNames.join(', ')})`
: '';
console.log(
`[rust-shards] ${result.label} ok: ${result.testCount} test(s) in ${formatDuration(result.durationMs)}`,
`[rust-shards] ${result.label} ok: ${result.testCount} test(s) in ${formatDuration(result.durationMs)}${retrySuffix}`,
);
continue;
}