row 281 b4a: the M1 hang was T6c's held web1:add loop, which only the fire's abort ends; setup's t.after clears held and failing, and T6c and T10 release their Gitea gate; test only, no code change (mos-1273, sage-2636, #1786)

This commit is contained in:
jason.woltje committed 2026-10-22 07:08:21 -05:00
1 parent 06ee5ed6b6
commit 3f29375a8a
2 files changed
+24

No files matched your search

+19
View File
@@ -734,6 +734,25 @@ no code:
`#grantSet` adds no `gitea` entry (`#giteaPending` and `#giteaUnfired` read only the store), and step G
never reaches `#stepGGitea`. A delete with no Gitea grant reads no Gitea credential file.
### b4a: the M1 hang's cause (mos-1273, sage-2636)
The first M1-M21 run on 06ee5ed6b hung on M1. All 22 tests ended in about 80 s (16 fail, 5 pass, 1
cancelled), but the file's process stayed alive until the harness killed it at 1762 s. This is a test fault,
and no code changed.
- Cause: T6c holds `web1:add`, and the fake `install` loops in `pause()` on `sleep(5)` while the key is
held. Only the fire's abort signal can end that loop, and M1 removes the host revoke that sends the
abort. In M1's log, T6c fails at its `until` on line 683, before it deletes the key on line 691. So the loop keeps a
timer alive forever. That reading comes from the log and the file. The rerun checks it: before M1-M21 it runs M1
once without `--test-force-exit`, and that run must exit by itself inside 180 s.
- Fix: setup's `t.after` clears `held` and `failing` before it closes the store, so any held loop ends
with its test. The base is unchanged because every passing test already releases its keys.
- Sage's second candidate, the Gitea `gate` in T6c and T10, isn't a live handle. The fake server's
`t.after` closes all its connections, and a parked promise with no timer doesn't keep node alive. Both
tests now also release the gate in `t.after` (`go()` only, not `off()`: a second `off()` would splice
index -1 and remove another rule).
- The runner's 180 s timeout with `--test-force-exit` (sage-2633) still caps any future hang.
## Runs
(after the gate)
@@ -88,6 +88,9 @@ async function setup(t) {
const store = new Store(join(dir, 'data'));
const credentials = new Credentials({ references: {}, storeRoot, dataRoot: join(dir, 'data') });
t.after(() => {
// A test that fails while a host step is held must not leave pause() looping after it ends.
held.clear();
failing.clear();
credentials.close();
store.close();
});
@@ -666,6 +669,7 @@ test('row 281 T6c: a host executor in flight aborts and ends revoked; a Gitea ex
// Gitea: held at the token create.
let go;
const gate = new Promise((r) => (go = r));
t.after(() => go());
let reached = false;
const off = f.gitea.rule(
(e) => e.method === 'POST' && e.path === '/api/v1/users/demo-coder/tokens',
@@ -795,6 +799,7 @@ test('row 281 T10 (B2): the fire and the delete answer while their jobs are held
await f.approveHost('ops', 'web2');
let go;
const gate = new Promise((r) => (go = r));
t.after(() => go());
let reached = false;
const off = f.gitea.rule(
(e) => e.method === 'DELETE' && e.path.startsWith('/api/v1/users/demo-coder/tokens/'),