test: strengthen processing cancellation and refusal guards

Bound the halt-abort expectation, check Discord refusal before malformed journal reads, and isolate HTTP origin and valid oversized-body guards. These test changes are committed for the row 191 gate; execution awaits the coordinated slot.
This commit is contained in:
rocko committed 2026-10-21 19:14:38 -05:00
1 parent 7aa18b0f6e
commit 81889b58d5
3 files changed
+26 -3

No files matched your search

+7 -1
View File
@@ -1,7 +1,7 @@
import test from 'node:test'; import test from 'node:test';
import assert from 'node:assert/strict'; import assert from 'node:assert/strict';
import { spawnSync } from 'node:child_process'; import { spawnSync } from 'node:child_process';
import { mkdirSync, unlinkSync, readFileSync } from 'node:fs'; import { mkdirSync, unlinkSync, readFileSync, writeFileSync } from 'node:fs';
import { join } from 'node:path'; import { join } from 'node:path';
import { createConnector } from '../src/connector.mjs'; import { createConnector } from '../src/connector.mjs';
import { initializeControl, assertProcessing, transition } from '../../processing-control/src/state.mjs'; import { initializeControl, assertProcessing, transition } from '../../processing-control/src/state.mjs';
@@ -21,6 +21,12 @@ test('halted connector refuses before outbox reconciliation, engine or gateway s
transition(f.root, actor); transition(f.root, actor);
await assert.rejects(createConnector(f.options).start(), e => e.code === 'processing-halted'); await assert.rejects(createConnector(f.options).start(), e => e.code === 'processing-halted');
assert.equal(f.rest.calls.length, 0); assert.equal(f.engine.started, false); assert.equal(f.rest.calls.length, 0); assert.equal(f.engine.started, false);
const corrupt = fixture(); ensureJournal(corrupt.journalDir);
const connector = createConnector(corrupt.options);
transition(corrupt.root, actor);
writeFileSync(join(corrupt.journalDir, 'outbox.jsonl'), '{broken\n', { mode: 0o600 });
await assert.rejects(connector.start(), e => e.code === 'processing-halted');
assert.equal(corrupt.rest.calls.length, 0); assert.equal(corrupt.engine.started, false);
}); });
test('halt arriving during startup reconciliation prevents engine and gateway start', async () => { test('halt arriving during startup reconciliation prevents engine and gateway start', async () => {
const f = fixture(); ensureJournal(f.journalDir); const f = fixture(); ensureJournal(f.journalDir);
@@ -9,7 +9,7 @@ import { initializeControl, transition } from '../src/state.mjs';
const api = await import('../src/effects.mjs').catch(e => { if (e.code === 'ERR_MODULE_NOT_FOUND') return {}; throw e; }); const api = await import('../src/effects.mjs').catch(e => { if (e.code === 'ERR_MODULE_NOT_FOUND') return {}; throw e; });
function fixture(t) { const root = mkdtempSync(join(tmpdir(), 'processing-effect-')); initializeControl(root); t.after(() => rmSync(root, { recursive: true, force: true })); return root; } function fixture(t) { const root = mkdtempSync(join(tmpdir(), 'processing-effect-')); initializeControl(root); t.after(() => rmSync(root, { recursive: true, force: true })); return root; }
const actor = { business: 'demo', human: 'jason', halted: true }; const actor = { business: 'demo', human: 'jason', halted: true };
test('halt aborts an active local request and prevents a subsequent effect after halt/resume', async t => { test('halt aborts an active local request and prevents a subsequent effect after halt/resume', { timeout: 4000 }, async t => {
assert.equal(typeof api.withProcessing, 'function'); assert.equal(typeof api.withProcessing, 'function');
const root = fixture(t); let started; const root = fixture(t); let started;
const ready = new Promise(resolve => { started = resolve; }); const ready = new Promise(resolve => { started = resolve; });
+18 -1
View File
@@ -48,7 +48,7 @@ test('processing write fences refuse cross-site, wrong origin, unnamed host, dup
{ headers: { ...POST.headers, host: `127.0.0.1:${f.server.address().port}`, 'x-user': undefined } }, { headers: { ...POST.headers, host: `127.0.0.1:${f.server.address().port}`, 'x-user': undefined } },
{ headers: { ...POST.headers, 'x-user': ['jason', 'jason'] } }, { headers: { ...POST.headers, 'x-user': ['jason', 'jason'] } },
{ headers: { ...POST.headers, 'content-type': 'text/plain' } }, { headers: { ...POST.headers, 'content-type': 'text/plain' } },
{ body: '{"human":"jason"}' }, { body: '[]' }, { body: 'null' }, { body: ' '.repeat(1025) }, { body: '{"human":"jason"}' }, { body: '[]' }, { body: 'null' }, { body: ' '.repeat(1025) + '{}' },
]; ];
for (const c of cases) assert.ok((await http(f.server, '/api/processing/halt', { ...POST, ...c })).status >= 400); for (const c of cases) assert.ok((await http(f.server, '/api/processing/halt', { ...POST, ...c })).status >= 400);
assert.equal((await http(f.server, '/api/processing/resume', POST)).status, 400); assert.equal((await http(f.server, '/api/processing/resume', POST)).status, 400);
@@ -81,3 +81,20 @@ test('processing writes use the existing SSO signer and still require --send and
assert.deepEqual(calls, enabled ? ['halt'] : []); assert.deepEqual(calls, enabled ? ['halt'] : []);
} }
}); });
// Exercise the handler's own origin/site guards independently of serve's outer fence.
test('processing handler independently refuses wrong origin and cross-site before its writer', async () => {
const { Readable } = await import('node:stream');
const { processingHTTP } = await import('../src/processing-http.mjs');
for (const changed of [{ origin: ['https://elsewhere'] }, { 'sec-fetch-site': ['cross-site'] }]) {
const req = Readable.from([Buffer.from('{}')]); req.method = 'POST';
req.headersDistinct = { 'x-user': ['jason'], origin: ['https://console.example'],
'sec-fetch-site': ['same-origin'], 'content-type': ['application/json'], ...changed };
let status, body, called = false;
const res = { writeHead: value => { status = value; }, end: value => { body = JSON.parse(value); } };
await processingHTTP(req, res, { path: '/api/processing/halt', search: '', named: true, send: () => {},
preview: { host: 'console.example', header: 'x-user', user: 'jason' },
processing: { halt: async () => { called = true; return {}; } } });
assert.equal(status, 403); assert.equal(called, false); assert.equal(body.sent, false);
}
});