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

test: fix parser split race condition #1791

Merged
1 commit merged into from
Aug 6, 2020
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 24 additions & 24 deletions test/unit/Parser.spec.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
import chai, { expect } from 'chai';
import chaiAsPromised from 'chai-as-promised';
import { randomBytes } from 'crypto';
import Parser from '../../lib/p2p/Parser';
import { DisconnectionReason, SwapFailureReason, XuNetwork } from '../../lib/constants/enums';
import { errorCodes } from '../../lib/p2p/errors';
import Framer from '../../lib/p2p/Framer';
import Network from '../../lib/p2p/Network';
import { Packet, PacketType } from '../../lib/p2p/packets';
import * as packets from '../../lib/p2p/packets/types';
import { SessionInitPacketBody } from '../../lib/p2p/packets/types/SessionInitPacket';
import Parser from '../../lib/p2p/Parser';
import { Address, NodeState } from '../../lib/p2p/types';
import { removeUndefinedProps as removeUndefinedPropsTyped } from '../../lib/utils/utils';
import { DisconnectionReason, SwapFailureReason, XuNetwork } from '../../lib/constants/enums';
import uuid = require('uuid');
import { Address, NodeState } from '../../lib/p2p/types';
import { SessionInitPacketBody } from '../../lib/p2p/packets/types/SessionInitPacket';
import Network from '../../lib/p2p/Network';
import Framer from '../../lib/p2p/Framer';
import { errorCodes } from '../../lib/p2p/errors';
import stringify = require('json-stable-stringify');

const removeUndefinedProps = (obj: any): any => { return removeUndefinedPropsTyped(obj); };
Expand All @@ -30,7 +30,7 @@ describe('Parser', () => {
parser = new Parser(framer);
});

function wait(num = 1): Promise<Packet[]> {
function waitForPackets(num = 1): Promise<Packet[]> {
return new Promise((resolve, reject) => {
setTimeout(() => reject(timeoutError), 50);
const parsedPackets: Packet[] = [];
Expand All @@ -46,7 +46,7 @@ describe('Parser', () => {

function verify(packets: Packet[]): Promise<Packet[]> {
return new Promise((resolve, reject) => {
wait(packets.length)
waitForPackets(packets.length)
.then((parsedPackets) => {
for (let i = 0; i < packets.length; i += 1) {
expect(stringify(packets[i])).to.equal(stringify(parsedPackets[i]));
Expand All @@ -64,7 +64,7 @@ describe('Parser', () => {
.then(done)
.catch(done);

framer.frame(packet).then(parser.feed);
framer.frame(packet).then(parser.feed).catch(done);
});

it(`should parse an encrypted valid ${PacketType[packet.type]} packet`, (done) => {
Expand All @@ -74,7 +74,7 @@ describe('Parser', () => {

parser.setEncryptionKey(encryptionKey);

framer.frame(packet, encryptionKey).then(parser.feed);
framer.frame(packet, encryptionKey).then(parser.feed).catch(done);
});
}

Expand All @@ -84,7 +84,7 @@ describe('Parser', () => {
.then(() => done('err: packet is valid'))
.catch(() => done());

framer.frame(packet).then(parser.feed);
framer.frame(packet).then(parser.feed).catch(done);
});
}

Expand All @@ -98,7 +98,7 @@ describe('Parser', () => {
const middleIndex = data.length >> 1;
parser.feed(data.slice(0, middleIndex));
parser.feed(data.slice(middleIndex));
});
}).catch(done);
});

it(`should parse encrypted ${PacketType[packet.type]} packet split`, (done) => {
Expand All @@ -112,7 +112,7 @@ describe('Parser', () => {
const middleIndex = data.length >> 1;
parser.feed(data.slice(0, middleIndex));
parser.feed(data.slice(middleIndex));
});
}).catch(done);
});
}

Expand All @@ -126,7 +126,7 @@ describe('Parser', () => {
return framer.frame(packet);
})).then((buffers) => {
parser.feed(Buffer.concat(buffers));
});
}).catch(done);
});

it(`should parse encrypted ${packets.map(packet => PacketType[packet.type]).join(' ')} concatenated`, (done) => {
Expand All @@ -140,15 +140,14 @@ describe('Parser', () => {
return framer.frame(packet, encryptionKey);
})).then((buffers) => {
parser.feed(Buffer.concat(buffers));
});
}).catch(done);
});
}

function testConcatenatedAndSplit(packets: Packet[], splitByte: number) {
const packetsStr = packets.map(packet => PacketType[packet.type]).join(' ');
it(`should parse ${packetsStr} concatenated and split on byte ${splitByte} from each packet beginning`, (done) => {
verify(packets)
.then(done)
.catch(done);

let remaining = Buffer.alloc(0);
Expand All @@ -163,7 +162,8 @@ describe('Parser', () => {
});
Promise.all(framerPromises).then(() => {
parser.feed(remaining);
});
done();
}).catch(done);
});

it(`should parse encrypted ${packetsStr} concatenated and split on byte ${splitByte} from each packet beginning`, (done) => {
Expand All @@ -185,7 +185,7 @@ describe('Parser', () => {
});
Promise.all(framerPromises).then(() => {
parser.feed(remaining);
});
}).catch(done);
});
}

Expand Down Expand Up @@ -372,12 +372,12 @@ describe('Parser', () => {

describe('test more edge-cases', () => {
it('should not try to parse an empty buffer', async () => {
await expect(wait()).to.be.rejectedWith(timeoutError);
await expect(waitForPackets()).to.be.rejectedWith(timeoutError);
parser.feed(Buffer.alloc(0));
});

it('should not try parse just the header as a packet', (done) => {
wait()
waitForPackets()
.then(() => done('err: packet should not be parsed'))
.catch((err) => {
if (err === timeoutError) {
Expand All @@ -391,13 +391,13 @@ describe('Parser', () => {
framer.frame(sessionInitPacket).then((data) => {
const header = data.slice(0, Framer.MSG_HEADER_LENGTH);
parser.feed(header);
});
}).catch(done);
});

it('should buffer a max buffer length', (done) => {
parser = new Parser(framer, Framer.MSG_HEADER_LENGTH, 10);

wait()
waitForPackets()
.then(() => done('err: packet should not be parsed'))
.catch((err) => {
if (err === timeoutError) {
Expand All @@ -413,7 +413,7 @@ describe('Parser', () => {
it('should not buffer when max buffer size exceeds', (done) => {
parser = new Parser(framer, Framer.MSG_HEADER_LENGTH, 10);

wait()
waitForPackets()
.then(() => done('err: packet should not be parsed'))
.catch((err) => {
if (err && err.code === errorCodes.PARSER_MAX_BUFFER_SIZE_EXCEEDED) {
Expand Down