class v5 harness: the previous run's survivors (two nodes of the known-failed case were still bound at 08:49Z and the flip run read a stranger's chain): a pid file per data dir killed at start, a node whose log says a port was in use fails the run at once, a port base per case (IGNEUM_V5_BASE, BASE= in harness-remote.sh)
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
parent
76b7cee8d6
commit
3a9bd0873a
2 changed files with 14 additions and 2 deletions
|
|
@ -39,7 +39,7 @@ const IGNEUMD = process.env.IGNEUMD || `${BIN}/igneumd`;
|
|||
const CPU_MINER = process.env.IGNEUM_MINER || `${BIN}/igneum-miner`;
|
||||
const IGNEUM_POW = process.env.IGNEUM_POW || `${ROOT}igneum-pow/target/release/igneum-pow`;
|
||||
const TMP = process.env.IGNEUM_V5_TMP || '/tmp/igneum-fast-time-v5s';
|
||||
const BASE = 29760, SUFFIX = 976;
|
||||
const BASE = +(process.env.IGNEUM_V5_BASE || 29760), SUFFIX = 976;
|
||||
const NEVER = '18446744073709551615';
|
||||
const args = process.argv.slice(2);
|
||||
const flag = (name, dflt) => { const i = args.indexOf(`--${name}`); return i >= 0 ? +args[i + 1] : dflt; };
|
||||
|
|
@ -63,7 +63,13 @@ const log = (...a) => console.log(new Date().toISOString().slice(11, 23), ...a);
|
|||
const sleep = (ms) => new Promise(r => setTimeout(r, ms));
|
||||
for (const b of [IGNEUMD, CPU_MINER]) if (!existsSync(b)) { console.error(`missing ${b}`); process.exit(2); }
|
||||
|
||||
// the previous run's survivors (the flip-stale run of 7 October 2026, 08:49Z: two nodes of the earlier case were still bound
|
||||
// to the ports and the harness read a stranger's chain): the pid file of this data dir is killed first, by pid, and a node
|
||||
// whose log says a port was in use fails the run at once
|
||||
const PIDS = `${TMP}/pids`;
|
||||
try { for (const pid of readFileSync(PIDS, 'utf8').split('\n').map(Number).filter(Boolean)) { try { process.kill(pid, 'SIGKILL'); console.log(`killed survivor pid ${pid} of the previous run`); } catch { } } } catch { }
|
||||
rmSync(TMP, { recursive: true, force: true }); mkdirSync(TMP, { recursive: true });
|
||||
const recordPid = (p) => { try { writeFileSync(PIDS, `${readFileSync(PIDS, 'utf8')}${p.pid}\n`); } catch { writeFileSync(PIDS, `${p.pid}\n`); } };
|
||||
const baseText = readFileSync(FILE, 'utf8');
|
||||
const field = (name) => { const m = new RegExp(`"${name}":\\s*([0-9]+)`).exec(baseText); return m ? +m[1] : undefined; };
|
||||
const EPOCH = field('pow_epoch_blocks');
|
||||
|
|
@ -108,7 +114,9 @@ class Node {
|
|||
const byte = this.i < SIGNAL.length ? SIGNAL[this.i] : Math.max(...SIGNAL);
|
||||
this.proc = spawn(IGNEUMD, a, { stdio: ['ignore', out, out], env: { ...process.env, IGNEUM_CLASS_SIGNAL: String(byte) } });
|
||||
started.push(this.proc);
|
||||
recordPid(this.proc);
|
||||
await sleep(1200);
|
||||
if (this.grepLog(/Address already in use|AddrInUse/).length) { log(`FAILED: n${this.i} could not bind its ports (a previous run's node is still alive): ${this.grepLog(/AddrInUse|Address already in use/)[0].slice(0, 160)}`); await stopAll(); process.exit(4); }
|
||||
this.rpc = await connectRpc(`ws://127.0.0.1:${this.jsonPort}`);
|
||||
log(`n${this.i} up pid ${this.proc.pid} json ${this.jsonPort} p2p ${this.p2pPort} exec ${this.stateless ? 'disabled' : this.execPort}, signals ${byte}`);
|
||||
return this;
|
||||
|
|
@ -119,6 +127,7 @@ function miner(bin, argv, name, env = {}) {
|
|||
const out = openSync(`${TMP}/${name}.log`, 'a');
|
||||
const p = spawn(bin, argv, { stdio: ['ignore', out, out], env: { ...process.env, ...env } });
|
||||
started.push(p);
|
||||
recordPid(p);
|
||||
return p;
|
||||
}
|
||||
async function stopAll() {
|
||||
|
|
|
|||
|
|
@ -8,6 +8,8 @@
|
|||
#
|
||||
# tools/class-v5/harness-remote.sh <case-name> -- <class-v5-signal.mjs arguments>
|
||||
# tools/class-v5/harness-remote.sh failed-case -- --signal 5,5,4 --expect flip
|
||||
# BASE=29830 tools/class-v5/harness-remote.sh flip-stale -- --signal 5,5,5 --expect flip --stale 2 (another port base per
|
||||
# case, so two cases never share ports; the harness kills the previous run's pids of its own data dir first)
|
||||
set -euo pipefail
|
||||
HERE="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
ROOT="$(cd "$HERE/../.." && pwd)"
|
||||
|
|
@ -21,9 +23,10 @@ REMOTE_LOG="/srv/builds/_log/v5-class/harness"
|
|||
OUT="$ROOT/docs/design/class-v5-harness"
|
||||
mkdir -p "$OUT"
|
||||
ARGS="$*"
|
||||
BASE="${BASE:-29760}"
|
||||
echo "harness-remote: case $CASE on $HOST: node $REMOTE_ROOT/infra/fast-time/class-v5-signal.mjs $ARGS"
|
||||
# the harness file travels by rsync (the mirror carries HEAD; an uncommitted change rides along, re-stamped: the copied-sources rule)
|
||||
rsync -a -e "ssh -i $KEY" "$ROOT/infra/fast-time/class-v5-signal.mjs" "$ROOT/infra/fast-time/override-60x.json" "$HOST:$REMOTE_ROOT/infra/fast-time/"
|
||||
ssh -i "$KEY" "$HOST" "touch $REMOTE_ROOT/infra/fast-time/class-v5-signal.mjs $REMOTE_ROOT/infra/fast-time/override-60x.json; mkdir -p $REMOTE_LOG; cd $REMOTE_ROOT && IGNEUM_V5_TMP=/tmp/igneum-fast-time-v5s-$CASE IGNEUM_V5_BIN=$REMOTE_ROOT/vendor/igneum-node-class-v5/target/release IGNEUM_POW=$REMOTE_ROOT/igneum-pow/target/release/igneum-pow node infra/fast-time/class-v5-signal.mjs $ARGS > $REMOTE_LOG/$CASE.log 2>&1; rc=\$?; cp /tmp/igneum-fast-time-v5s-$CASE/summary.json $REMOTE_LOG/$CASE.json 2>/dev/null || true; echo \"harness-remote: rc \$rc\"; exit \$rc" || true
|
||||
ssh -i "$KEY" "$HOST" "touch $REMOTE_ROOT/infra/fast-time/class-v5-signal.mjs $REMOTE_ROOT/infra/fast-time/override-60x.json; mkdir -p $REMOTE_LOG; cd $REMOTE_ROOT && IGNEUM_V5_BASE=$BASE IGNEUM_V5_TMP=/tmp/igneum-fast-time-v5s-$CASE IGNEUM_V5_BIN=$REMOTE_ROOT/vendor/igneum-node-class-v5/target/release IGNEUM_POW=$REMOTE_ROOT/igneum-pow/target/release/igneum-pow node infra/fast-time/class-v5-signal.mjs $ARGS > $REMOTE_LOG/$CASE.log 2>&1; rc=\$?; cp /tmp/igneum-fast-time-v5s-$CASE/summary.json $REMOTE_LOG/$CASE.json 2>/dev/null || true; echo \"harness-remote: rc \$rc\"; exit \$rc" || true
|
||||
rsync -a -e "ssh -i $KEY" "$HOST:$REMOTE_LOG/$CASE.log" "$HOST:$REMOTE_LOG/$CASE.json" "$OUT/" 2>/dev/null || true
|
||||
grep -E "SUMMARY|FAILED CHECK|PROGRAM ID|CLASS SWITCH" "$OUT/$CASE.log" || tail -20 "$OUT/$CASE.log"
|
||||
|
|
|
|||
Loading…
Reference in a new issue