pocket-messaging
Version:
A small cryptographic messaging library written in TypeScript both for browser and nodejs supporting TCP and WebSockets
1,067 lines (955 loc) • 36.8 kB
text/typescript
//@ts-nocheck disable check for now since access modifiers have been set in Messaging.
//
import { TestSuite, Test, AfterAll, expect } from 'testyts';
import EventEmitter from "eventemitter3";
import {Messaging, once, Header, EventType, SentMessage, TimeoutEvent, EncryptedClient} from "../";
import {CreatePair, Client} from "pocket-sockets";
const assert = require("assert");
export class MessagingSpec {
socket1: Client;
socket2: Client;
messaging1: Messaging;
messaging2: Messaging;
eventEmitter1: EventEmitter;
eventEmitter2: EventEmitter;
constructor() {
[this.socket1, this.socket2] = CreatePair();
this.messaging1 = new Messaging(this.socket1, 0);
this.messaging2 = new Messaging(this.socket2, 0);
this.eventEmitter1 = this.messaging1.getEventEmitter();
this.eventEmitter2 = this.messaging1.getEventEmitter();
}
public shutdown() {
this.messaging1.close();
expect.toBeTrue(this.messaging1.isOpen() === false);
this.messaging2.close();
expect.toBeTrue(this.messaging2.isOpen() === false);
}
public basics() {
expect.toBeTrue(this.eventEmitter1 != null);
//@ts-ignore protected function
const allEMs: EventEmitter[] = this.messaging1.getAllEventEmitters();
expect.toBeTrue(allEMs.length === 1);
expect.toBeTrue(allEMs[0] === this.eventEmitter1);
expect.toBeTrue(this.messaging1.isOpen() === false);
this.messaging1.open();
expect.toBeTrue(this.messaging1.isOpen());
//@ts-ignore protected function
const msgId1 = Messaging.GenerateMsgId();
expect.toBeTrue(msgId1.length === 4);
//@ts-ignore protected function
const msgId2 = Messaging.GenerateMsgId();
expect.toBeTrue(msgId2.length === 4);
expect.toBeTrue(msgId1.compare(msgId2) !== 0);
const header: Header = {
version: 0,
target: Buffer.from("ping"),
msgId: msgId1,
dataLength: 33,
config: 2
};
//@ts-ignore protected function
const headerBuffer = Messaging.EncodeHeader(header);
expect.toBeTrue(headerBuffer.length === 11 + header.target.length);
const messageBuffer = Buffer.concat([headerBuffer, Buffer.alloc(33).fill(33)]);
//@ts-ignore protected function
const ret = Messaging.DecodeHeader(messageBuffer);
expect.toBeTrue(ret !== undefined);
if (!ret) return; //@ts-chillax trust me on this one
const [header2, data2] = ret;
expect.toBeTrue(header2 !== undefined);
expect.toBeTrue(header2.version === 0);
expect.toBeTrue(header2.target.length === 4);
expect.toBeTrue(data2 !== undefined);
expect.toBeTrue(data2.length === 33);
expect.toBeTrue(data2.compare(Buffer.alloc(33).fill(33)) === 0);
let buffers: Buffer[] = [];
//@ts-ignore protected function
let extracted = this.messaging1.extractBuffer(buffers, 100);
expect.toBeTrue(extracted === undefined);
buffers = [Buffer.from("abc"), Buffer.from("def")];
//@ts-ignore protected function
extracted = this.messaging1.extractBuffer(buffers, 100);
expect.toBeTrue(extracted === undefined);
//@ts-ignore protected function
extracted = this.messaging1.extractBuffer(buffers, 1);
expect.toBeTrue(extracted !== undefined);
if (!extracted) return; //@ts-chillax trust me on this one
expect.toBeTrue(extracted.compare(Buffer.from("a")) === 0);
expect.toBeTrue(buffers.length === 2);
expect.toBeTrue(buffers[0].length === 2);
//@ts-ignore protected function
extracted = this.messaging1.extractBuffer(buffers, 5);
expect.toBeTrue(extracted !== undefined);
if (!extracted) return; //@ts-chillax trust me on this one
expect.toBeTrue(extracted.compare(Buffer.from("bcdef")) === 0);
expect.toBeTrue(buffers.length === 0);
}
/**
* Poke and test the eventsystem on single messaging instance.
*/
public async events() {
process.nextTick( () => {
//@ts-ignore protected function
this.messaging1.emitEvent([this.eventEmitter1], "error", 111);
});
let value = await once(this.eventEmitter1, "error");
expect.toBeTrue(value === 111);
process.nextTick( () => {
//@ts-ignore protected function
this.messaging1.emitEvent([this.eventEmitter1], "error", 112);
//@ts-ignore protected function
this.messaging1.emitEvent([this.eventEmitter1], "reply", 113);
});
value = await once(this.eventEmitter1, "reply");
expect.toBeTrue(value === 113);
process.nextTick( () => {
//@ts-ignore protected function
this.messaging1.emitError(Buffer.from("hello"));
});
let accept: Function;
const p = new Promise( (accept2) => {
accept = accept2;
});
this.eventEmitter1.on("error", (err) => {
expect.toBeTrue(err !== undefined);
expect.toBeTrue(err.error.length === 5);
accept();
});
let buf = await once(this.eventEmitter1, "any");
await p;
}
/**
* Try communicating between two Messaging instances using leveraging the virtual socket pair.
*/
public async communication() {
const data = Buffer.from("Hello World!");
this.messaging1.open();
this.messaging2.open();
const ee2 = this.messaging2.getEventEmitter();
expect.toBeTrue(ee2 !== undefined, "Expecting eventemitter returned");
process.nextTick( async () => {
const ee1a = this.messaging1.send("ping", Buffer.from("A"), 10000, true);
expect.toBeTrue(ee1a !== undefined, "Expecting eventemitter returned");
if (!ee1a || !ee1a.eventEmitter) return; //@ts-chillax
const reply = await once(ee1a.eventEmitter, "reply");
// This will emit a close event
this.messaging1.close();
});
const event = await once(ee2, "route");
const ee2a = this.messaging2.send(event.fromMsgId, Buffer.from("B"), 10000);
expect.toBeTrue(ee2a !== undefined, "Expecting eventemitter returned");
if (!ee2a || !ee2a.eventEmitter) return;
const reply = await once(ee2a.eventEmitter, "any"); // this also catched close event
expect.toBeTrue(reply !== undefined);
expect.toBeTrue(reply.type === "close");
}
}
export class MessagingConstructor {
public default_state() {
let [socket, _] = CreatePair();
let messaging = new Messaging(socket, 0);
assert(Object.keys(messaging.pendingReply).length == 0);
assert(!messaging.isOpened());
assert(!messaging.isClosed());
assert(messaging.dispatchLimit == -1);
assert(messaging.isBusyOut == 0);
assert(messaging.isBusyIn == 0);
assert(messaging.instanceId.length == (8 * 2));
assert(messaging.incomingQueue.chunks.length == 0);
assert(messaging.incomingQueue.messages.length == 0);
assert(messaging.outgoingQueue.chunks.length == 0);
assert(messaging.eventEmitter);
}
}
export class MessagingSetEncrypted {
public successful_call() {
let [socket, _] = CreatePair();
let messaging = new Messaging(socket, 0);
assert.doesNotThrow(async function() {
const outKey = Buffer.alloc(32);
const outNonce = Buffer.alloc(24);
const inKey = Buffer.alloc(32);
const inNonce = Buffer.alloc(24);
const peerPubKey = Buffer.alloc(32);
let encryptedClient = new EncryptedClient(messaging.getClient(), outKey, outNonce, inKey, inNonce, peerPubKey);
await encryptedClient.init();
assert(encryptedClient.getPeerPublicKey());
});
}
}
export class MessagingSetUnencrypted {
public successful_call() {
let [socket, _] = CreatePair();
let messaging = new Messaging(socket, 0);
assert.doesNotThrow(async function() {
const outKey = Buffer.alloc(32);
const outNonce = Buffer.alloc(24);
const inKey = Buffer.alloc(32);
const inNonce = Buffer.alloc(24);
const peerPubKey = Buffer.alloc(32);
let encryptedClient = new EncryptedClient(messaging.getClient(), outKey, outNonce, inKey, inNonce, peerPubKey);
await encryptedClient.init();
});
}
}
export class MessagingOpen {
public already_closed() {
let [socket, _] = CreatePair();
let messaging = new Messaging(socket, 0);
assert.doesNotThrow(function() {
messaging._isClosed = true;
assert(messaging.isOpened() == false);
messaging.open();
assert(messaging.isOpened() == false);
});
}
public already_opened() {
let [socket, _] = CreatePair();
let messaging = new Messaging(socket, 0);
assert.doesNotThrow(function() {
messaging._isOpened = true;
let flag = false;
// Expected to be called only on success
// @ts-ignore: protected method
messaging.checkTimeouts = function() {
flag = true;
};
messaging.open();
assert(messaging.isOpened() == true);
assert(flag == false); // No change
});
}
public successful_call() {
let [socket, _] = CreatePair();
let messaging = new Messaging(socket, 0);
assert.doesNotThrow(function() {
let flag = false;
// Expected to be called only on success
// @ts-ignore: protected method
messaging.checkTimeouts = function() {
flag = true;
};
assert(messaging.isOpened() == false);
assert(flag == false);
messaging.open();
assert(messaging.isOpened() == true);
// @ts-ignore: expected to be modified by custom checkTimeouts
assert(flag == true);
});
}
}
export class MessagingClose {
public already_closed() {
let [socket, _] = CreatePair();
let messaging = new Messaging(socket, 0);
assert.doesNotThrow(function() {
let flag = false;
messaging.socket.close = function() {
flag = true;
}
assert(flag == false);
messaging.close();
//@ts-ignore
assert(flag == true);
});
}
public successful_call() {
let [socket, _] = CreatePair();
let messaging = new Messaging(socket, 0);
assert.doesNotThrow(function() {
assert(messaging.isClosed() == false);
assert(messaging.isOpened() == false);
messaging.open();
assert(messaging.isOpened() == true);
messaging.close();
assert(messaging.isClosed() == true);
});
}
}
export class MessagingCorkUncork {
public successful_call() {
let [socket, _] = CreatePair();
let messaging = new Messaging(socket, 0);
assert.doesNotThrow(function() {
messaging.uncork(30);
assert(messaging.dispatchLimit == 30);
messaging.cork();
assert(messaging.dispatchLimit == 0);
});
}
public uncork_without_parameters() {
let [socket, _] = CreatePair();
let messaging = new Messaging(socket, 0);
assert.doesNotThrow(function() {
assert(messaging.dispatchLimit == -1);
messaging.uncork(30);
assert(messaging.dispatchLimit == 30);
messaging.uncork();
assert(messaging.dispatchLimit == -1);
});
}
}
export class MessagingSend {
public not_open_noop() {
let [socket, _] = CreatePair();
let messaging = new Messaging(socket, 0);
assert.doesNotThrow(function() {
assert(messaging.isOpened() == false);
assert(Object.keys(messaging.pendingReply).length == 0);
messaging.send(Buffer.from(""));
assert(Object.keys(messaging.pendingReply).length == 0);
});
}
public isClosed_noop() {
let [socket, _] = CreatePair();
let messaging = new Messaging(socket, 0);
assert.doesNotThrow(function() {
messaging._isClosed = true;
assert(Object.keys(messaging.pendingReply).length == 0);
messaging.send(Buffer.from(""));
assert(Object.keys(messaging.pendingReply).length == 0);
});
}
public exceed_target_length() {
let [socket, _] = CreatePair();
let messaging = new Messaging(socket, 0);
assert.throws(function() {
assert(Object.keys(messaging.pendingReply).length == 0);
messaging._isOpened = true;
messaging._isClosed = false;
messaging.send(Buffer.alloc(256).fill(256));
assert(Object.keys(messaging.pendingReply).length == 0);
}, /target length cannot exceed 255 bytes/);
}
public successful_call_no_reply() {
let [socket, _] = CreatePair();
let messaging = new Messaging(socket, 0);
assert.doesNotThrow(function() {
assert(messaging.outgoingQueue.chunks.length == 0);
assert(Object.keys(messaging.pendingReply).length == 0);
messaging._isOpened = true;
messaging._isClosed = false;
const replyStatus = messaging.send(Buffer.alloc(255).fill(255));
assert(messaging.outgoingQueue.chunks.length == 1 + 1);
assert(Object.keys(messaging.pendingReply).length == 0);
assert(replyStatus !== undefined);
assert(replyStatus && replyStatus.msgId !== undefined);
});
}
public successful_call_expectingReply() {
let [socket, _] = CreatePair();
let messaging = new Messaging(socket, 0);
assert.doesNotThrow(function() {
assert(messaging.outgoingQueue.chunks.length == 0);
assert(Object.keys(messaging.pendingReply).length == 0);
messaging._isOpened = true;
messaging._isClosed = false;
const replyStatus = messaging.send(Buffer.alloc(255).fill(255), undefined, 1);
assert(messaging.outgoingQueue.chunks.length == 1 + 1);
assert(Object.keys(messaging.pendingReply).length == 1);
assert(replyStatus?.eventEmitter instanceof EventEmitter);
});
}
}
export class MessagingEncodeHeader {
public target_length_exceeded() {
let [socket, _] = CreatePair();
let messaging = new Messaging(socket, 0);
assert.throws(function() {
//@ts-ignore protected function
const id = Messaging.GenerateMsgId();
const header: Header = {
version: 0,
target: Buffer.alloc(256).fill(256),
msgId: id,
dataLength: 33,
config: 2
};
//@ts-ignore protected function
Messaging.EncodeHeader(header);
}, /Target length cannot exceed 255 bytes/);
}
public msgId_length_exceeded() {
let [socket, _] = CreatePair();
let messaging = new Messaging(socket, 0);
assert.throws(function() {
const header: Header = {
version: 0,
target: Buffer.alloc(255).fill(255),
msgId: Buffer.from(""),
dataLength: 33,
config: 2
};
//@ts-ignore protected function
Messaging.EncodeHeader(header);
}, /msgId length must be exactly 4 bytes long/);
}
}
export class MessagingDecodeHeader {
public unsupported_version() {
let [socket, _] = CreatePair();
let messaging = new Messaging(socket, 0);
assert.throws(function() {
//@ts-ignore protected function
const id = Messaging.GenerateMsgId();
const header: Header = {
version: 0,
target: Buffer.alloc(255).fill(255),
msgId: id,
dataLength: 33,
config: 2
};
//@ts-ignore protected function
let encodedHeader = Messaging.EncodeHeader(header);
encodedHeader.writeUInt8(255);
//@ts-ignore protected function
Messaging.DecodeHeader(encodedHeader);
}, /Unexpected version nr, only supporting version 0/);
}
public buffer_length_mismatch() {
let [socket, _] = CreatePair();
let messaging = new Messaging(socket, 0);
assert.throws(function() {
//@ts-ignore protected function
const id = Messaging.GenerateMsgId();
const header: Header = {
version: 0,
target: Buffer.alloc(255).fill(255),
msgId: id,
dataLength: 33,
config: 2
};
//@ts-ignore protected function
let encodedHeader = Messaging.EncodeHeader(header);
encodedHeader.writeUInt32LE(234, 1);
//@ts-ignore protected function
Messaging.DecodeHeader(encodedHeader);
}, /Mismatch in expected length and provided buffer length/);
}
}
export class MessagingSocketClose {
public alreadyClosed_noop() {
let [socket, _] = CreatePair();
let messaging = new Messaging(socket, 0);
assert.doesNotThrow(function() {
messaging._isClosed = true;
//@ts-ignore protected function
messaging.socketClose();
assert(messaging.isClosed() == true);
});
}
public successful_call() {
let [socket, _] = CreatePair();
let messaging = new Messaging(socket, 0);
assert.doesNotThrow(function() {
//@ts-ignore protected function
messaging.emitEvent = function(emitters: EventEmitter[], type: EventType, arg: any) {
assert(emitters)
assert(type == EventType.CLOSE || type == EventType.ANY);
assert(arg);
};
assert(messaging.isClosed() == false);
//@ts-ignore protected function
messaging.socketClose();
assert(messaging.isClosed() == true);
});
}
}
export class MessagingSocketData {
public successful_call() {
let [socket, _] = CreatePair();
let messaging = new Messaging(socket, 0);
assert.doesNotThrow(function() {
let flag = false;
//@ts-ignore custom signature
messaging.processInqueue = function() {
flag = true;
}
assert(messaging.incomingQueue.chunks.length == 0);
assert(messaging.isBusyIn == 0);
assert(flag == false);
//@ts-ignore protected function
messaging.socketData(Buffer.from(""));
assert(messaging.incomingQueue.chunks.length == 1);
assert(messaging.isBusyIn == 1);
//@ts-ignore: expected to be changed by custom processInqueue
assert(flag == true);
});
}
}
export class MessagingProcessInqueue {
public not_busy_noop() {
let [socket, _] = CreatePair();
let messaging = new Messaging(socket, 0);
assert.doesNotThrow(function() {
let flag = false;
assert(flag == false);
messaging.isBusyIn = 0;
//@ts-ignore protected function
messaging.processInqueue();
assert(messaging.isBusyIn == 0);
assert(flag == false);
});
}
public successful_call() {
let [socket, _] = CreatePair();
let messaging = new Messaging(socket, 0);
assert.doesNotThrow(async function() {
let counter = 0;
//@ts-ignore custom signature
messaging.assembleIncoming = function() {
counter++;
}
//@ts-ignore custom signature
messaging.dispatchIncoming = function() {
counter++;
}
messaging.isBusyIn = 1;
//@ts-ignore protected function
await messaging.processInqueue();
assert(counter == 1);
});
}
}
export class MessagingAssembleIncoming {
public no_data_noop() {
let [socket, _] = CreatePair();
let messaging = new Messaging(socket, 0);
assert.doesNotThrow(async function() {
messaging.incomingQueue.chunks.push(Buffer.from(""));
assert(messaging.incomingQueue.chunks.length == 1);
//@ts-ignore protected function
messaging.assembleIncoming();
});
}
public not_enough_data() {
let [socket, _] = CreatePair();
let messaging = new Messaging(socket, 0);
assert.doesNotThrow(async function() {
messaging.incomingQueue.chunks.push(Buffer.from("1234"));
//@ts-ignore protected function
messaging.assembleIncoming();
});
}
public bad_version() {
let [socket, _] = CreatePair();
let messaging = new Messaging(socket, 0);
assert.doesNotThrow(async function() {
messaging.incomingQueue.chunks.push(Buffer.from("12345"));
// Set custom version
messaging.incomingQueue.chunks[0].writeUInt8(244);
//@ts-ignore protected function
messaging.assembleIncoming();
});
}
public not_enough_data_extractBuffer() {
let [socket, _] = CreatePair();
let messaging = new Messaging(socket, 0);
assert.doesNotThrow(async function() {
messaging.incomingQueue.chunks.push(Buffer.from("12345"));
messaging.incomingQueue.chunks[0].writeUInt8(0);
//@ts-ignore protected function
messaging.extractBuffer = function() {
return undefined;
}
//@ts-ignore protected function
messaging.assembleIncoming();
});
}
public bad_stream_decodeHeader() {
let [socket, _] = CreatePair();
let messaging = new Messaging(socket, 0);
assert.doesNotThrow(async function() {
messaging.incomingQueue.chunks.push(Buffer.from("12345"));
messaging.incomingQueue.chunks[0].writeUInt8(0);
//@ts-ignore protected function
messaging.extractBuffer = function() {
return Buffer.from("");
}
//@ts-ignore protected function
Messaging.DecodeHeader = function() {
return undefined;
}
//@ts-ignore protected function
messaging.assembleIncoming();
});
}
public successful_call() {
let [socket, _] = CreatePair();
let messaging = new Messaging(socket, 0);
assert.doesNotThrow(async function() {
messaging.incomingQueue.chunks.push(Buffer.from("12345"));
messaging.incomingQueue.chunks[0].writeUInt8(0);
//@ts-ignore protected function
messaging.extractBuffer = function() {
return Buffer.from("");
}
//@ts-ignore protected function
Messaging.DecodeHeader = function() {
messaging.incomingQueue.chunks.length = 0;
return [{version: 0, target: "tgt", dataLength: 3, config: false}, Buffer.from("")];
}
assert(messaging.incomingQueue.messages.length == 0);
//@ts-ignore protected function
messaging.assembleIncoming();
assert(messaging.incomingQueue.messages.length == 1);
});
}
}
export class MessagingDispatchIncoming {
public no_data_noop() {
let [socket, _] = CreatePair();
let messaging = new Messaging(socket, 0);
assert.doesNotThrow(async function() {
messaging.incomingQueue.chunks.push(Buffer.from(""));
assert(messaging.incomingQueue.messages.length == 0);
//@ts-ignore protected function
messaging.dispatchIncoming();
assert(messaging.incomingQueue.messages.length == 0);
});
}
public dispatchLimit_is_zero() {
let [socket, _] = CreatePair();
let messaging = new Messaging(socket, 0);
assert.doesNotThrow(async function() {
messaging.incomingQueue.chunks.push(Buffer.from("12345"));
messaging.incomingQueue.chunks[0].writeUInt8(0);
//@ts-ignore protected function
messaging.extractBuffer = function() {
return Buffer.from("");
}
//@ts-ignore protected function
Messaging.DecodeHeader = function() {
messaging.incomingQueue.chunks.length = 0;
return [{version: 0, target: Buffer.from("tgt"), dataLength: 3, config: false}, Buffer.from("")];
}
//@ts-ignore protected function
messaging.assembleIncoming();
assert(messaging.incomingQueue.messages.length == 1);
messaging.dispatchLimit = 0;
//@ts-ignore protected function
messaging.dispatchIncoming();
assert(messaging.incomingQueue.messages.length == 1);
});
}
public dispatchLimit_is_one() {
let [socket, _] = CreatePair();
let messaging = new Messaging(socket, 0);
assert.doesNotThrow(async function() {
messaging.incomingQueue.chunks.push(Buffer.from("12345"));
messaging.incomingQueue.chunks[0].writeUInt8(0);
//@ts-ignore protected function
messaging.extractBuffer = function() {
return Buffer.from("");
}
//@ts-ignore protected function
Messaging.DecodeHeader = function() {
messaging.incomingQueue.chunks.length = 0;
return [{version: 0, target: Buffer.from("tgt"), dataLength: 3, config: false}, Buffer.from("")];
}
//@ts-ignore protected function
messaging.assembleIncoming();
assert(messaging.incomingQueue.messages.length == 1);
messaging.dispatchLimit = 1;
//@ts-ignore protected function
messaging.dispatchIncoming();
assert(messaging.incomingQueue.messages.length == 0);
});
}
public successful_call() {
let [socket, _] = CreatePair();
let messaging = new Messaging(socket, 0);
assert.doesNotThrow(async function() {
messaging.incomingQueue.chunks.push(Buffer.from("12345"));
messaging.incomingQueue.chunks[0].writeUInt8(0);
//@ts-ignore protected function
messaging.extractBuffer = function() {
return Buffer.from("");
}
//@ts-ignore protected function
Messaging.DecodeHeader = function() {
messaging.incomingQueue.chunks.length = 0;
return [{version: 0, target: Buffer.from("tgt"), dataLength: 3, config: false}, Buffer.from("")];
}
//@ts-ignore protected function
messaging.assembleIncoming();
assert(messaging.incomingQueue.messages.length == 1);
//@ts-ignore protected function
messaging.dispatchIncoming();
assert(messaging.incomingQueue.messages.length == 0);
});
}
}
export class MessagingProcessOutqueue {
public isBusyOut_noop() {
let [socket, _] = CreatePair();
let messaging = new Messaging(socket, 0);
assert.doesNotThrow(async function() {
messaging.isBusyOut = 0;
let counter = 0;
//@ts-ignore protected function
messaging.dispatchOutgoing = function() {
counter++;
}
assert(counter == 0);
//@ts-ignore protected function
messaging.processOutqueue();
assert(counter == 0);
});
}
public successful_call() {
let [socket, _] = CreatePair();
let messaging = new Messaging(socket, 0);
assert.doesNotThrow(async function() {
messaging.isBusyOut = 1;
let encryptFlag = false;
let dispatchFlag = false;
//@ts-ignore protected function
messaging.dispatchOutgoing = function() {
dispatchFlag = true;
}
//@ts-ignore protected function
await messaging.processOutqueue();
//@ts-ignore expected to be set by custom function
assert(dispatchFlag == true);
});
}
}
export class MessagingEncryptOutgoing {
public unencrypted_successful_call() {
let [socket, _] = CreatePair();
let messaging = new Messaging(socket, 0);
assert.doesNotThrow(async function() {
messaging._isOpened = true;
messaging._isClosed = false;
const replyStatus = messaging.send(Buffer.alloc(255).fill(255));
assert(messaging.outgoingQueue.chunks.length == 1 + 1);
});
}
public encrypted_successful_call() {
let [socket, _] = CreatePair();
let messaging = new Messaging(socket, 0);
assert.doesNotThrow(async function() {
messaging._isOpened = true;
messaging._isClosed = false;
const outKey = Buffer.alloc(32);
const outNonce = Buffer.alloc(24);
const inKey = Buffer.alloc(32);
const inNonce = Buffer.alloc(24);
const peerPubKey = Buffer.alloc(32);
let encryptedClient = new EncryptedClient(messaging.getClient(), outKey, outNonce, inKey, inNonce, peerPubKey);
await encryptedClient.init();
const replyStatus = messaging.send(Buffer.alloc(255).fill(255));
assert(messaging.outgoingQueue.chunks.length == 1 + 1);
});
}
}
export class MessagingDispatchOutgoing {
public no_encrypted_data_noop() {
let [socket, _] = CreatePair();
let messaging = new Messaging(socket, 0);
assert.doesNotThrow(async function() {
assert(messaging.outgoingQueue.chunks.length == 0);
//@ts-ignore: protected function
await messaging.dispatchOutgoing();
assert(messaging.outgoingQueue.chunks.length == 0);
});
}
public successful_call() {
let [socket, _] = CreatePair();
let messaging = new Messaging(socket, 0);
assert.doesNotThrow(async function() {
messaging._isOpened = true;
messaging._isClosed = false;
const outKey = Buffer.alloc(32);
const outNonce = Buffer.alloc(24);
const inKey = Buffer.alloc(32);
const inNonce = Buffer.alloc(24);
const peerPubKey = Buffer.alloc(32);
let encryptedClient = new EncryptedClient(messaging.getClient(), outKey, outNonce, inKey, inNonce, peerPubKey);
await encryptedClient.init();
const replyStatus = messaging.send(Buffer.alloc(255).fill(255));
let flag = false;
messaging.socket.send = function() {
flag = true;
}
assert(flag == false);
assert(messaging.outgoingQueue.chunks.length == 2);
//@ts-ignore: protected function
await messaging.dispatchOutgoing();
//@ts-ignore: flag expected to be toggled by custom socket send procedure
assert(flag == true);
assert(messaging.outgoingQueue.chunks.length == 0);
});
}
}
export class MessagingCheckTimeouts {
public unset_isOpened_noop() {
let [socket, _] = CreatePair();
let messaging = new Messaging(socket, 0);
assert.doesNotThrow(async function() {
messaging._isOpened = false;
//@ts-ignore: protected function
messaging.checkTimeouts();
});
}
public set_isClosed_noop() {
let [socket, _] = CreatePair();
let messaging = new Messaging(socket, 0);
assert.doesNotThrow(async function() {
messaging._isClosed = true;
//@ts-ignore: protected function
messaging.checkTimeouts();
});
}
public successful_call() {
let [socket, _] = CreatePair();
let messaging = new Messaging(socket, 0);
assert.doesNotThrow(async function() {
messaging.open();
assert(messaging.isOpened() == true);
assert(messaging.isClosed() == false);
//@ts-ignore: protected function
messaging.getTimeoutedPendingMessages = function() {
let messages: SentMessage[] = [];
messages.push({
timestamp: 0,
msgId: Buffer.from("10"),
timeout: 0,
timeoutStream: 0,
replyCounter: 0,
stream: false,
eventEmitter: new EventEmitter(),
isCleared: false,
});
return messages;
}
messaging.cancelPendingMessage = function(id: Buffer) {
assert(id.toString() == "10");
}
//@ts-ignore: protected function
messaging.emitEvent = function(emitter: EventEmitter[], type: EventType, timeout: TimeoutEvent) {
assert(type == EventType.TIMEOUT);
//@ts-ignore: protected function
messaging.emitEvent = () => {}; // We need to cancel this because a "close" event would else reach this function and the assert will trigger.
messaging.close();
}
//@ts-ignore: protected function
messaging.checkTimeouts();
});
}
}
export class MessagingGetTimeoutedPendingMessages {
public successful_call_timeout() {
let [socket, _] = CreatePair();
let messaging = new Messaging(socket, 0);
assert.doesNotThrow(async function() {
messaging._isOpened = true;
messaging._isClosed = false;
//@ts-ignore: protected function
messaging.pendingReply["20"] = {
timestamp: 0,
msgId: Buffer.from("20"),
timeout: 1,
timeoutStream: 0,
replyCounter: 0,
stream: false,
eventEmitter: new EventEmitter()
};
//@ts-ignore: protected function
let data = messaging.getTimeoutedPendingMessages();
assert(data.length == 1);
});
}
public successful_call_no_timeout() {
let [socket, _] = CreatePair();
let messaging = new Messaging(socket, 0);
assert.doesNotThrow(async function() {
messaging._isOpened = true;
messaging._isClosed = false;
//@ts-ignore: protected function
messaging.pendingReply["20"] = {
timestamp: 0,
msgId: Buffer.from("20"),
timeout: 0,
timeoutStream: 0,
replyCounter: 0,
stream: false,
eventEmitter: new EventEmitter()
};
//@ts-ignore: protected function
let data = messaging.getTimeoutedPendingMessages();
assert(data.length == 0);
});
}
}