Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Check for the minimum size of the bytes read only once per frame [API-1546] #1411

Merged
merged 12 commits into from Dec 29, 2022
157 changes: 156 additions & 1 deletion test/unit/connection/ClientMessageReaderTest.js
Expand Up @@ -20,8 +20,9 @@ const { expect } = require('chai');

const { ClientMessageReader } = require('../../../lib/network/Connection');
const cm = require('../../../lib/protocol/ClientMessage');
const {Frame, ClientMessage} = require('../../../lib/protocol/ClientMessage');

describe('ClientMessageReaderTest', function () {
describe('OldClientMessageReaderTest', function () {
const HEADER_SIZE = cm.SIZE_OF_FRAME_LENGTH_AND_FLAGS;

let reader;
Expand Down Expand Up @@ -99,3 +100,157 @@ describe('ClientMessageReaderTest', function () {
expect(reader.read()).to.be.equal(null);
});
});

describe('ClientMessageReaderTest', function() {
let reader;

srknzl marked this conversation as resolved.
Show resolved Hide resolved
function createFrameWithRandomBytes(length) {
const buffer = Buffer.allocUnsafe(length);
for (let i = 0; i < length; i++) {
buffer.writeUInt8(Math.floor(Math.random() * 256), i);
}
return new Frame(buffer);
}

function writeToBuffer(message) {
const buffer = Buffer.allocUnsafe(message.getTotalLength());
message.writeTo(buffer);
return buffer;
}

beforeEach(function() {
reader = new ClientMessageReader();
});

it('testReadSingleFrameMessage', function() {
const frame = createFrameWithRandomBytes(42);
const message = ClientMessage.createForEncode();
message.addFrame(frame);
const buffer = writeToBuffer(message);
reader.append(buffer);

const messageRead = reader.read();
expect(messageRead).to.be.not.equal(null);
expect(messageRead.hasNextFrame()).to.be.true;

const frameRead = messageRead.nextFrame();
expect(frameRead.content).to.deep.equal(frame.content);

expect(messageRead.hasNextFrame()).to.be.false;
});

it('testReadMultiFrameMessage', function() {
const frame1 = createFrameWithRandomBytes(10);
const frame2 = createFrameWithRandomBytes(20);
const frame3 = createFrameWithRandomBytes(30);

const message = ClientMessage.createForEncode();
message.addFrame(frame1);
message.addFrame(frame2);
message.addFrame(frame3);

const buffer = writeToBuffer(message);
reader.append(buffer);

const messageRead = reader.read();
expect(messageRead).to.be.not.equal(null);
let frameRead = messageRead.nextFrame();
expect(frameRead.content).to.deep.equal(frame1.content);

expect(messageRead.hasNextFrame()).to.be.true;
frameRead = messageRead.nextFrame();
expect(frameRead.content).to.deep.equal(frame2.content);

expect(messageRead.hasNextFrame()).to.be.true;
frameRead = messageRead.nextFrame();
expect(frameRead.content).to.deep.equal(frame3.content);

expect(messageRead.hasNextFrame()).to.be.false;
});

it('testReadFramesInMultipleCallsToReadFrom', function() {
const frame = createFrameWithRandomBytes(1000);

const message = ClientMessage.createForEncode();
message.addFrame(frame);

const buffer = writeToBuffer(message);

const firstPartition = buffer.slice(0, 750);
const secondPartition = buffer.slice(750);

reader.append(firstPartition);
srknzl marked this conversation as resolved.
Show resolved Hide resolved
expect(reader.read()).to.be.null;
reader.append(secondPartition);

const messageRead = reader.read();
srknzl marked this conversation as resolved.
Show resolved Hide resolved
expect(messageRead).to.be.not.null;
expect(messageRead.hasNextFrame()).to.be.true;

const frameRead = messageRead.nextFrame();
expect(frameRead.content).to.deep.equal(frame.content);

expect(messageRead.hasNextFrame()).to.be.false;
});

it('testReadFramesInMultipleCallsToReadFrom_whenLastPieceIsSmall', function() {
const frame = createFrameWithRandomBytes(1000);

const message = ClientMessage.createForEncode();
message.addFrame(frame);

const buffer = writeToBuffer(message);

const firstPartition = buffer.slice(0, 750);
const secondPartition = buffer.slice(750, 1002);

// Message Length = 1000 + 6 bytes
// part1 = 750, part2 = 252, part3 = 4 bytes
const thirdPartition = buffer.slice(1002);

reader.append(firstPartition);
expect(reader.read()).to.be.null;
reader.append(secondPartition);
expect(reader.read()).to.be.null;
reader.append(thirdPartition);

const messageRead = reader.read();
expect(messageRead).not.to.be.null;
expect(messageRead.hasNextFrame()).to.be.true;
srknzl marked this conversation as resolved.
Show resolved Hide resolved

const frameRead = messageRead.nextFrame();
expect(frameRead.content).to.deep.equal(frame.content);

expect(messageRead.hasNextFrame()).to.be.false;
});

it('testRead_whenTheFrameLengthAndFlagsNotReceivedAtFirst', function() {
const frame = createFrameWithRandomBytes(100);

const message = ClientMessage.createForEncode();
message.addFrame(frame);

const buffer = writeToBuffer(message);

// Set limit to a small value so that we can simulate
// that the frame length and flags are not read yet.
const firstPartition = buffer.slice(0, 4);
reader.append(firstPartition);
let messageRead = reader.read();

// should not be able to read with just 4 bytes of data
expect(messageRead).to.be.null;
const secondPartition = buffer.slice(4, buffer.length);
reader.append(secondPartition);

messageRead = reader.read();
// should be able to read when the rest of the data comes
expect(messageRead).to.be.not.equal(null);
expect(messageRead.hasNextFrame()).to.be.true;

const frameRead = messageRead.nextFrame();
expect(frameRead.content).to.deep.equal(frame.content);

expect(messageRead.hasNextFrame()).to.be.false;
});
});