/******************************************************************************** * Copyright (C) 2017 Ericsson and others. * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v. 2.0 which is available at * http://www.eclipse.org/legal/epl-2.0. * * This Source Code may also be made available under the following Secondary * Licenses when the conditions for such availability set forth in the Eclipse * Public License v. 2.0 are satisfied: GNU General Public License, version 2 * with the GNU Classpath Exception which is available at * https://www.gnu.org/software/classpath/license.html. * * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 ********************************************************************************/ import * as chai from 'chai'; import { MultiRingBuffer } from './multi-ring-buffer'; const expect = chai.expect; describe('MultiRingBuffer', function () { it('expect buffer to be empty initialized', function () { const size = 2; const compareTo = new Buffer('0000', 'hex'); const ringBuffer = new MultiRingBuffer({ size }); // tslint:disable-next-line:no-unused-expression expect(ringBuffer['buffer'].equals(compareTo)).to.be.true; }); it('expect enq and deq a string with unicode characters > 1 byte and no wrap around', function () { const ringBufferSize = 15; const ringBuffer = new MultiRingBuffer({ size: ringBufferSize }); const buffer = '\u00bd + \u00bc = \u00be'; const bufferByteLength = Buffer.byteLength(buffer, 'utf8'); ringBuffer.enq(buffer); expect(ringBuffer.size()).to.be.equal(bufferByteLength); }); it('expect enq and deq a string with unicode characters > 1 byte and wrap around', function () { const buffer = '\u00bd + \u00bc = \u00be'; const ringBufferSize = Buffer.byteLength(buffer[buffer.length - 1]); const ringBuffer = new MultiRingBuffer({ size: ringBufferSize }); ringBuffer.enq(buffer); expect(ringBuffer.size()).to.be.equal(ringBufferSize); const reader = ringBuffer.getReader(); const readBuffer = ringBuffer.deq(reader); expect(ringBuffer).to.not.be.equal(undefined); if (readBuffer !== undefined) { expect(readBuffer).to.be.equal(buffer[buffer.length - 1].toString()); } }); it('expect enq a string < ring buffer size ', function () { const size = 5; const ringBuffer = new MultiRingBuffer({ size }); const buffer = 'test'; ringBuffer.enq(buffer); expect(ringBuffer.size()).to.be.equal(buffer.length); expect(ringBuffer.empty()).to.be.equal(false); const reader = ringBuffer.getReader(); expect(ringBuffer.sizeForReader(reader)).to.be.equal(buffer.length); expect(ringBuffer.emptyForReader(reader)).to.be.equal(false); }); it('expect deq a string < ring buffer size ', function () { const ringBuffer = new MultiRingBuffer({ size: 5 }); const buffer = 'test'; ringBuffer.enq(buffer); expect(ringBuffer.size()).to.be.equal(4); const reader = ringBuffer.getReader(); const readBuffer = ringBuffer.deq(reader); expect(ringBuffer.size()).to.be.equal(4); expect(ringBuffer.sizeForReader(reader)).to.be.equal(0); expect(readBuffer).to.equal(buffer); }); it('expect deq a string > ring buffer size ', function () { const size = 5; const ringBuffer = new MultiRingBuffer({ size }); const buffer = 'testabcd'; ringBuffer.enq(buffer); expect(ringBuffer.size()).to.be.equal(size); const reader = ringBuffer.getReader(); const readBuffer = ringBuffer.deq(reader); expect(ringBuffer.size()).to.be.equal(size); expect(ringBuffer.sizeForReader(reader)).to.be.equal(0); expect(readBuffer).to.equal(buffer.substr(buffer.length - size)); }); it('expect enq deq enq deq a string > ring buffer size ', function () { const size = 5; const ringBuffer = new MultiRingBuffer({ size }); const buffer = '12345678'; for (let i = 0; i < 2; i++) { ringBuffer.enq(buffer); expect(ringBuffer.size()).to.be.equal(size); const reader = ringBuffer.getReader(); const readBuffer = ringBuffer.deq(reader); expect(ringBuffer.size()).to.be.equal(size); expect(ringBuffer.sizeForReader(reader)).to.be.equal(0); expect(readBuffer).to.equal(buffer.substr(buffer.length - size)); } }); it('expect enq a string == ring buffer size then one > ring buffer size and dequeue them ', function () { const size = 5; const ringBuffer = new MultiRingBuffer({ size }); const buffers = ['12345', '12345678']; for (const buffer of buffers) { ringBuffer.enq(buffer); expect(ringBuffer.size()).to.be.equal(size); } const reader = ringBuffer.getReader(); let i = 0; for (const _ of buffers) { const readBuffer = ringBuffer.deq(reader); if (i === 0) { expect(readBuffer).to.equal(buffers[buffers.length - 1].substr(buffers[buffers.length - 1].length - size)); } else { expect(readBuffer).to.equal(undefined); } i++; } expect(ringBuffer.sizeForReader(reader)).to.be.equal(0); }); it('expect enq a string == ring buffer size then one < ring buffer size and dequeue them ', function () { const size = 5; const ringBuffer = new MultiRingBuffer({ size }); const buffers = ['12345', '123']; for (const buffer of buffers) { ringBuffer.enq(buffer); expect(ringBuffer.size()).to.be.equal(size); } const reader = ringBuffer.getReader(); let i = 0; for (const _ of buffers) { const readBuffer = ringBuffer.deq(reader); if (i === 0) { expect(readBuffer).to.equal('45123'); } else { expect(readBuffer).to.equal(undefined); } i++; } expect(ringBuffer.sizeForReader(reader)).to.be.equal(0); }); it('expect enq a string == ring buffer size then one < ring buffer then one < buffer size and deque ', function () { const size = 5; const ringBuffer = new MultiRingBuffer({ size }); const buffers = ['12345', '123', '678']; for (const buffer of buffers) { ringBuffer.enq(buffer); expect(ringBuffer.size()).to.be.equal(size); } const reader = ringBuffer.getReader(); let i = 0; for (const _ of buffers) { const readBuffer = ringBuffer.deq(reader); if (i === 0) { expect(readBuffer).to.equal('23678'); } else { expect(readBuffer).to.equal(undefined); } i++; } expect(ringBuffer.sizeForReader(reader)).to.be.equal(0); }); it('expect enq buffer size then enq 1 to dequeue the right value', function () { const size = 5; const ringBuffer = new MultiRingBuffer({ size }); const buffers = ['12345', '1']; for (const buffer of buffers) { ringBuffer.enq(buffer); expect(ringBuffer.size()).to.be.equal(size); } const reader = ringBuffer.getReader(); let i = 0; for (const _ of buffers) { const readBuffer = ringBuffer.deq(reader); if (i === 0) { expect(readBuffer).to.equal('23451'); } else { expect(readBuffer).to.equal(undefined); } i++; } expect(ringBuffer.sizeForReader(reader)).to.be.equal(0); }); it('expect enq buffer size then enq 1 twice to dequeue the right value', function () { const size = 5; const ringBuffer = new MultiRingBuffer({ size }); const buffers = ['12345', '1', '12345', '1']; for (const buffer of buffers) { ringBuffer.enq(buffer); expect(ringBuffer.size()).to.be.equal(size); } const reader = ringBuffer.getReader(); let i = 0; for (const _ of buffers) { const readBuffer = ringBuffer.deq(reader); if (i === 0) { expect(readBuffer).to.equal('23451'); } else { expect(readBuffer).to.equal(undefined); } i++; } expect(ringBuffer.sizeForReader(reader)).to.be.equal(0); }); it('expect enq buffer size of various sizes dequeue the right value', function () { const size = 5; const ringBuffer = new MultiRingBuffer({ size }); const buffers = ['12345', '123', '678', '12345', '1', '12345', '123', '12', '12', '1', '12', '123', '1234', '12345', '1', '12']; for (const buffer of buffers) { ringBuffer.enq(buffer); expect(ringBuffer.size()).to.be.equal(size); } const reader = ringBuffer.getReader(); let i = 0; for (const _ of buffers) { const readBuffer = ringBuffer.deq(reader); if (i === 0) { expect(readBuffer).to.equal('45112'); } else { expect(readBuffer).to.equal(undefined); } i++; } expect(ringBuffer.sizeForReader(reader)).to.be.equal(0); }); it('expect enq buffer sizes < buffer size to dequeue normally', function () { const size = 5; const ringBuffer = new MultiRingBuffer({ size }); const buffers = ['1', '1']; for (const buffer of buffers) { ringBuffer.enq(buffer); } expect(ringBuffer.size()).to.be.equal(2); const reader = ringBuffer.getReader(); let i = 0; for (const _ of buffers) { const readBuffer = ringBuffer.deq(reader); if (i === 0) { expect(readBuffer).to.equal('11'); } else { expect(readBuffer).to.equal(undefined); } i++; } expect(ringBuffer.sizeForReader(reader)).to.be.equal(0); }); it('expect enq buffer size of various sizes dequeue the right value', function () { const size = 5; const ringBuffer = new MultiRingBuffer({ size }); const buffers = ['1', '1', '12', '12']; for (const buffer of buffers) { ringBuffer.enq(buffer); } expect(ringBuffer.size()).to.be.equal(size); const reader = ringBuffer.getReader(); let i = 0; for (const _ of buffers) { const readBuffer = ringBuffer.deq(reader); if (i === 0) { expect(readBuffer).to.equal('11212'); } else { expect(readBuffer).to.equal(undefined); } i++; } expect(ringBuffer.sizeForReader(reader)).to.be.equal(0); }); it('expect multiple enq and deq to deq the right values', function () { const size = 5; const ringBuffer = new MultiRingBuffer({ size }); ringBuffer.enq('12345'); expect(ringBuffer.size()).to.be.equal(size); const reader = ringBuffer.getReader(); let readBuffer = ringBuffer.deq(reader); expect(readBuffer).to.equal('12345'); ringBuffer.enq('123'); readBuffer = ringBuffer.deq(reader); expect(readBuffer).to.equal('123'); ringBuffer.enq('12345'); readBuffer = ringBuffer.deq(reader); expect(readBuffer).to.equal('12345'); expect(ringBuffer.sizeForReader(reader)).to.be.equal(0); }); it('expect data from stream on enq', async function () { const size = 5; const ringBuffer = new MultiRingBuffer({ size }); const buffer = 'abc'; const astream = ringBuffer.getStream(); const p = new Promise(resolve => { astream.on('data', (chunk: string) => { expect(chunk).to.be.equal(buffer); resolve(); }); }); ringBuffer.enq(buffer); await p; }); it('expect data from stream when data is already enqed', async function () { const size = 5; const ringBuffer = new MultiRingBuffer({ size }); const buffer = 'abc'; ringBuffer.enq(buffer); const astream = ringBuffer.getStream(); const p = new Promise(resolve => { astream.on('data', (chunk: string) => { expect(chunk).to.be.equal(buffer); resolve(); }); }); await p; }); it('expect disposing of a stream to delete it from the ringbuffer', function () { const size = 5; const ringBuffer = new MultiRingBuffer({ size }); const astream = ringBuffer.getStream(); astream.dispose(); expect(ringBuffer.streamsSize()).to.be.equal(0); expect(ringBuffer.readersSize()).to.be.equal(0); }); it('expect disposing of a reader to delete it from the ringbuffer', function () { const size = 5; const ringBuffer = new MultiRingBuffer({ size }); const reader = ringBuffer.getReader(); ringBuffer.closeReader(reader); expect(ringBuffer.readersSize()).to.be.equal(0); }); it('expect enq a string in utf8 and get it in hex', function () { const ringBuffer = new MultiRingBuffer({ size: 5 }); const buffer = 'test'; ringBuffer.enq(buffer); expect(ringBuffer.size()).to.be.equal(4); const reader = ringBuffer.getReader(); const readBuffer = ringBuffer.deq(reader, -1, 'hex'); expect(readBuffer).to.equal('74657374'); }); it('expect enq a string in hex and get it in utf8', function () { const ringBuffer = new MultiRingBuffer({ size: 5 }); const buffer = '74657374'; ringBuffer.enq(buffer, 'hex'); expect(ringBuffer.size()).to.be.equal(4); const reader = ringBuffer.getReader(); const readBuffer = ringBuffer.deq(reader); expect(readBuffer).to.equal('test'); }); it('expect data from stream in hex when enq in uf8', async function () { const size = 5; const ringBuffer = new MultiRingBuffer({ size }); const buffer = 'test'; ringBuffer.enq(buffer); const astream = ringBuffer.getStream('hex'); const p = new Promise(resolve => { astream.on('data', (chunk: string) => { expect(chunk).to.be.equal('74657374'); resolve(); }); }); await p; }); it('expect deq a string < ring buffer size with the internal encoding in hex ', function () { const ringBuffer = new MultiRingBuffer({ size: 5, encoding: 'hex' }); const buffer = 'test'; ringBuffer.enq(buffer); expect(ringBuffer.size()).to.be.equal(4); const reader = ringBuffer.getReader(); const readBuffer = ringBuffer.deq(reader); expect(ringBuffer.size()).to.be.equal(4); expect(ringBuffer.sizeForReader(reader)).to.be.equal(0); expect(readBuffer).to.equal(buffer); }); it('expect the ringbuffer to be empty if we enq an empty string', function () { const ringBuffer = new MultiRingBuffer({ size: 5 }); const buffer = ''; ringBuffer.enq(buffer); expect(ringBuffer.size()).to.be.equal(0); expect(ringBuffer.empty()).to.be.equal(true); }); it('expect an invalid reader count to be zero', function () { const ringBuffer = new MultiRingBuffer({ size: 5 }); expect(ringBuffer.sizeForReader(1)).to.be.equal(0); }); it('expect an invalid reader to be empty', function () { const ringBuffer = new MultiRingBuffer({ size: 5 }); expect(ringBuffer.emptyForReader(1)).to.be.equal(true); }); it('expect partially deq a string < ring buffer size ', function () { const ringBuffer = new MultiRingBuffer({ size: 5 }); const buffer = 'test'; ringBuffer.enq(buffer); expect(ringBuffer.size()).to.be.equal(4); const reader = ringBuffer.getReader(); let readBuffer = ringBuffer.deq(reader, 2); expect(ringBuffer.size()).to.be.equal(4); expect(ringBuffer.sizeForReader(reader)).to.be.equal(2); expect(readBuffer).to.equal('te'); readBuffer = ringBuffer.deq(reader, 2); expect(ringBuffer.size()).to.be.equal(4); expect(ringBuffer.sizeForReader(reader)).to.be.equal(0); expect(readBuffer).to.equal('st'); }); it('expect partially deq a string < ring buffer size then enq and deq again ', function () { const ringBuffer = new MultiRingBuffer({ size: 5 }); const buffer = 'test'; const secondBuffer = 'abcd'; ringBuffer.enq(buffer); expect(ringBuffer.size()).to.be.equal(4); const reader = ringBuffer.getReader(); let readBuffer = ringBuffer.deq(reader, 2); expect(ringBuffer.size()).to.be.equal(4); expect(ringBuffer.sizeForReader(reader)).to.be.equal(2); expect(readBuffer).to.equal('te'); ringBuffer.enq(secondBuffer); readBuffer = ringBuffer.deq(reader, 4); expect(ringBuffer.size()).to.be.equal(5); expect(readBuffer).to.equal('tabc'); expect(ringBuffer.sizeForReader(reader)).to.be.equal(1); }); });