Tell a refused PDU apart from a session that failed (#82)
* Regression tests for telling a refused PDU from a failed session * Export PduRefusedError so a refusal can be told from a session failure * Document telling a refused PDU from a session failure * Share the malformed-PDU fixtures and pin that a dead stream is no refusal * Say once what a refusal is, and why the header type is published * Fold the refused-response test into the one that already staged it * Drop the refusal-rate claim the interop finding does not support * Build a raw PDU one way, sequence number included * Follow PduRefusedError into pdu-refusal.ts
This commit is contained in:
@@ -6,6 +6,8 @@ import type { Sms } from '../src/sms.ts';
|
||||
import type { SmppLog } from '../src/log.ts';
|
||||
import type { SmppServer } from '../src/server.ts';
|
||||
import type { TestContext } from 'node:test';
|
||||
import { PduRefusedError } from '../src/pdu-refusal.ts';
|
||||
import { objToPdu } from '../src/pdu.ts';
|
||||
import { client } from '../src/client.ts';
|
||||
import { closeAfter } from './teardown.ts';
|
||||
import { server } from '../src/server.ts';
|
||||
@@ -258,4 +260,52 @@ describe('README: Errors', () => {
|
||||
assert.ok(err instanceof Error);
|
||||
assert.equal(session, undefined);
|
||||
});
|
||||
|
||||
test('telling a refused PDU from a session that failed', async t => {
|
||||
const smpp = await answeringServer(t);
|
||||
const bound = once<Session>(resolve => { smpp.on('session', resolve); });
|
||||
const { err, session } = await client();
|
||||
if (err) throw err;
|
||||
|
||||
closeAfter(t, session);
|
||||
|
||||
const warned: Record<string, boolean | number | string>[] = [];
|
||||
const log: SmppLog = {
|
||||
debug: () => undefined,
|
||||
error: () => undefined,
|
||||
info: () => undefined,
|
||||
verbose: () => undefined,
|
||||
warn: (msg, metadata) => { warned.push({ msg, ...metadata }); },
|
||||
};
|
||||
|
||||
session.on('sessionError', err => {
|
||||
if (err instanceof PduRefusedError) {
|
||||
log.warn('the peer sent a PDU that could not be read', {
|
||||
cmdName: err.header.cmdName ?? err.header.cmdId,
|
||||
reason: err.reason,
|
||||
});
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
log.error('the session failed', { message: err.message });
|
||||
});
|
||||
|
||||
const reported = once<Error>(resolve => { session.on('sessionError', resolve); });
|
||||
const peer = await bound;
|
||||
const { buffer } = objToPdu({ cmdName: 'enquire_link', seqNr: 5 });
|
||||
|
||||
assert.ok(buffer);
|
||||
// A command id no command is defined for: refused on its own, with the link untouched.
|
||||
buffer.writeUInt32BE(0x00010001, 4);
|
||||
peer.sock.write(buffer);
|
||||
|
||||
await reported;
|
||||
|
||||
assert.deepEqual(warned, [{
|
||||
cmdName: 0x00010001,
|
||||
msg: 'the peer sent a PDU that could not be read',
|
||||
reason: 'command',
|
||||
}]);
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user