716ea9d410
Project CI / AI game creator shell Rust crates (pull_request) Successful in 1m41s
Project CI / AI game creator shell Rust smoke (pull_request) Successful in 2m14s
Project CI / Backend tests (pull_request) Successful in 4m28s
Project CI / Native shell tests (pull_request) Successful in 6m4s
Project CI / Frontend tests (pull_request) Successful in 2m13s
Project CI / AI game creator shell web tests (pull_request) Successful in 1m53s
Project CI / AI game creator shell Rust lane 2/2 (pull_request) Successful in 10m23s
Project CI / Repository checks (pull_request) Successful in 2m24s
Project CI / AI game creator shell Rust lane 1/2 (pull_request) Successful in 10m57s
# Conflicts: # docs/project-memory/shared-memory/pitfalls.md
105 lines
3.4 KiB
JavaScript
105 lines
3.4 KiB
JavaScript
import assert from 'node:assert/strict';
|
|
import { spawnSync } from 'node:child_process';
|
|
import fs from 'node:fs';
|
|
import os from 'node:os';
|
|
import path from 'node:path';
|
|
import test from 'node:test';
|
|
import { fileURLToPath } from 'node:url';
|
|
|
|
const runner = fileURLToPath(
|
|
new URL('./run-rust-shell-test-shards.mjs', import.meta.url),
|
|
);
|
|
|
|
function runFixture(t, source) {
|
|
const root = fs.mkdtempSync(path.join(os.tmpdir(), 'agc-shard-output-'));
|
|
t.after(() => fs.rmSync(root, { recursive: true, force: true }));
|
|
fs.mkdirSync(path.join(root, 'src'));
|
|
fs.writeFileSync(
|
|
path.join(root, 'Cargo.toml'),
|
|
'[package]\nname = "shard-output-fixture"\nversion = "0.1.0"\nedition = "2021"\n',
|
|
);
|
|
fs.writeFileSync(path.join(root, 'src/lib.rs'), source);
|
|
const result = spawnSync(
|
|
process.execPath,
|
|
[
|
|
runner,
|
|
`--manifest=${path.join(root, 'Cargo.toml')}`,
|
|
'--target-kind=lib',
|
|
'--no-locked',
|
|
'--shards=1',
|
|
`--shard-tmp-root=${path.join(root, 'tmp')}`,
|
|
],
|
|
{
|
|
encoding: 'utf8',
|
|
timeout: 60_000,
|
|
windowsHide: true,
|
|
env: { ...process.env, CARGO_TARGET_DIR: path.join(root, 'target') },
|
|
},
|
|
);
|
|
assert.ifError(result.error);
|
|
return { status: result.status, output: result.stdout + result.stderr };
|
|
}
|
|
|
|
test('failed shard retains panic details and separates selected count from failures', (t) => {
|
|
const result = runFixture(
|
|
t,
|
|
`
|
|
#[test]
|
|
fn passing_case() {}
|
|
#[test]
|
|
fn failing_case() {
|
|
assert_eq!(1, 2, "shard panic evidence");
|
|
}
|
|
`,
|
|
);
|
|
assert.equal(result.status, 1, result.output);
|
|
assert.match(result.output, /FAILED \(selected 2 test\(s\)\)/);
|
|
assert.match(result.output, /failing_case/);
|
|
assert.match(result.output, /panicked at src[\\/]lib\.rs:/);
|
|
assert.match(result.output, /shard panic evidence/);
|
|
assert.match(result.output, /left: 1/);
|
|
assert.match(result.output, /right: 2/);
|
|
assert.match(result.output, /1 passed; 1 failed/);
|
|
});
|
|
|
|
test('compile failure retains the diagnostic code, source location and cause', (t) => {
|
|
const result = runFixture(
|
|
t,
|
|
'#[test]\nfn compile_failure() { let _: u32 = "not a number"; }\n',
|
|
);
|
|
assert.equal(result.status, 1, result.output);
|
|
assert.match(result.output, /error\[E0308\]/);
|
|
assert.match(result.output, /src[\\/]lib\.rs:2:/);
|
|
assert.match(result.output, /mismatched types/);
|
|
assert.match(result.output, /expected `u32`, found `&str`/);
|
|
});
|
|
|
|
test('successful shard keeps its compact summary', (t) => {
|
|
const result = runFixture(t, '#[test]\nfn passing_case() {}\n');
|
|
assert.equal(result.status, 0, result.output);
|
|
assert.match(result.output, /shard 1\/1 ok: 1 test\(s\)/);
|
|
assert.doesNotMatch(result.output, /test passing_case \.\.\. ok/);
|
|
});
|
|
|
|
// bin 目标的用例名带命名空间(`agent::thread_manager::tests::…`)。复核名单必须靠
|
|
// 「本片名单精确匹配」认用例,不能靠名字前缀白名单,否则这类用例永远进不了重跑。
|
|
test('namespaced failing test is re-run once before the shard is judged', (t) => {
|
|
const result = runFixture(
|
|
t,
|
|
`
|
|
mod agent {
|
|
pub mod thread_manager {
|
|
#[test]
|
|
fn flaky_case() {
|
|
assert_eq!(1, 2, "namespaced panic evidence");
|
|
}
|
|
}
|
|
}
|
|
`,
|
|
);
|
|
assert.equal(result.status, 1, result.output);
|
|
assert.match(result.output, /re-run of 1 failing test\(s\) also failed/);
|
|
assert.match(result.output, /agent::thread_manager::flaky_case/);
|
|
assert.match(result.output, /namespaced panic evidence/);
|
|
});
|