Answer every segment of an inbound concatenated message as it arrives (#83)

* Regression tests for answering every inbound segment as it arrives

* Answer every segment of an inbound concatenated message as it arrives

* Record the segment-by-segment answer in AGENTS.md and README

* Regression tests for an empty message_id on deliver_sm_resp

* Answer a deliver_sm with the empty message_id SMPP 3.4 makes it

* Record Jasmin's refusal of a deliver_sm_resp message_id

* Mark the Jasmin multipart deadlock fixed

* Regression tests for the architecture review's findings

* Give the segment id notation an owner, and every segment a status

* Correct what the ids reach and what a lost group tells the application

* Regression tests for a group lost to its own octet overrun

* Report a group lost to its own overrun, and refuse by the command it arrived on

* Keep the docs true about what a segment is answered with

* Count only the answered segments of a group lost to an overrun

* Report only what a lost group cost, and say which cap bit
This commit is contained in:
2026-09-06 04:16:11 +02:00
committed by GitHub
parent 66b49ebfb3
commit 5b7b563dc2
14 changed files with 824 additions and 160 deletions
+25 -1
View File
@@ -1,6 +1,6 @@
import assert from 'node:assert/strict';
import test, { describe } from 'node:test';
import { normaliseSmsId } from '../src/sms-id.ts';
import { normaliseSmsId, parseSegmentId, respIdParams, segmentId } from '../src/sms-id.ts';
describe('normaliseSmsId()', () => {
test('reads an id the length a message_id may be, and leaves a longer one alone', () => {
@@ -21,3 +21,27 @@ describe('normaliseSmsId()', () => {
assert.equal(normaliseSmsId('1a2B', 'hex'), normaliseSmsId('1A2b', 'hex'));
});
});
describe('the <base>-<n> a segment is answered with', () => {
const base = '0199e0ed-3a55-7e91-9c04-6b7f2d81a5e2';
// One writer, two readers: DlrMerger has to read back exactly what a segment was answered with.
test('reads back the base and the part it was written from', () => {
assert.equal(segmentId(base, 0, 1), base, 'a lone segment is the base itself');
assert.equal(segmentId(base, 2, 3), `${base}-3`);
assert.deepEqual(parseSegmentId(`${base}-3`), { base, part: 3 });
});
test('reads nothing out of an id no segment convention wrote', () => {
assert.equal(parseSegmentId(base), undefined);
assert.equal(parseSegmentId(`${base}-x`), undefined);
assert.equal(parseSegmentId(''), undefined);
});
});
describe('the id a response carries', () => {
test('leaves a deliver_sm_resp without one, and gives submit_sm_resp its own', () => {
assert.deepEqual(respIdParams('deliver_sm', 'x'), {});
assert.deepEqual(respIdParams('submit_sm', 'x'), { message_id: 'x' });
});
});