test(fba): verify signed delivery ACK loss and original event recovery

This commit is contained in:
2026-10-03 08:13:04 +08:00
parent ef1eef3278
commit 51bf4e5558
11 changed files with 499 additions and 57 deletions
+43 -1
View File
@@ -3,7 +3,7 @@ import { spawn, spawnSync } from 'node:child_process'
import { createServer } from 'node:http'
import { mkdtemp, readFile, rm } from 'node:fs/promises'
import { tmpdir } from 'node:os'
import { join } from 'node:path'
import { join, dirname, basename, resolve } from 'node:path'
import { fileURLToPath } from 'node:url'
import test from 'node:test'
@@ -78,6 +78,8 @@ async function fixture(selector = ['--loading-plan-id', '2100000000000000001'],
child.kill(); await exited
}
await close(consumer)
assert.equal(dirname(resolve(directory)), resolve(tmpdir()))
assert.ok(basename(directory).startsWith('event-fault-offline-'))
await rm(directory, { recursive: true })
},
}
@@ -218,3 +220,43 @@ test('booking selector rejects malformed identities and mixed selection before s
assert.ok(!result.stdout.includes('"ready"'))
}
})
test('delivery selector isolates the first exact delivery event and preserves its ACK-loss recovery', async t => {
const deliveryId = '2100000000000000088'
const proxy = await fixture(['--delivery-id', deliveryId], 'OverseasDeliveryCompleted')
t.after(() => proxy.stop())
await proxy.control('/mode', { mode: 'FAULT' })
const signed = { ...event(), eventType: 'OverseasDeliveryCompleted',
payload: { deliveryOrderId: deliveryId, sourceInboundId: '2100000000000000099' } }
for (const unrelated of [
{ ...signed, eventId: otherId, payload: { deliveryOrderId: '2100000000000000089' } },
{ ...signed, eventId: otherId, payload: { deliveryId } },
{ ...signed, eventId: otherId, payload: { loadingPlanId: deliveryId } },
{ ...signed, eventId: otherId, eventType: 'OverseasContainerUnloaded' },
]) assert.equal((await proxy.send(unrelated)).status, 200)
assert.equal((await proxy.send(signed)).status, 503)
assert.equal((await proxy.send(signed)).status, 503)
assert.equal((await proxy.send({ ...signed, eventId: samePlanOtherId })).status, 200)
const calls = proxy.calls.length
assert.equal((await proxy.send({ ...signed, payload: { deliveryOrderId: '2100000000000000089' } })).status, 409)
assert.equal(proxy.calls.length, calls)
await proxy.control('/mode', { mode: 'PASS' })
const recovered = await proxy.send(signed)
assert.equal(recovered.status, 200)
assert.equal(JSON.parse(recovered.raw).data.outcome, 'DUPLICATE')
const status = await (await proxy.control('/status')).json()
assert.equal(status.eventId, targetId)
assert.deepEqual(status.records.filter(row => row.errorCode !== 'TARGET_EVENT_HASH_CONFLICT').map(row => row.outcome), ['APPLIED', 'DUPLICATE', 'DUPLICATE'])
assert.ok(!(await readFile(proxy.log, 'utf8')).includes('sourceInboundId'))
})
test('delivery selection rejects malformed IDs or a second selector before opening a listener', () => {
for (const args of [['--delivery-id', '0'], ['--delivery-id', '../88'], ['--delivery-id', '88', '--event-id', targetId],
['--delivery-id', '88', '--container-booking-id', '66'], ['--delivery-id', '88', '--loading-plan-id', '77']]) {
const result = spawnSync(process.env.PYTHON || 'python', [script, '--upstream', 'http://127.0.0.1:1/internal/events',
'--event-type', 'OverseasDeliveryCompleted', ...args], { encoding: 'utf8', timeout: 5000,
env: { ...process.env, EVENT_FAULT_CONTROL_TOKEN: controlToken } })
assert.equal(result.status, 2)
assert.ok(!result.stdout.includes('"ready"'))
}
})