blob: 254a25ed14aa5b06c1597c051001dd94c97c813e [file]
/*
* Copyright DataStax, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
'use strict';
const assert = require('assert');
const Protocol = require('../../lib/streams').Protocol;
const types = require('../../lib/types');
const utils = require('../../lib/utils');
describe('Protocol', function () {
it('should emit a single frame with 0-length body', function (done) {
const p = newInstance();
const items = [];
p.on('readable', function () {
let item;
while ((item = p.read())) {
items.push(item);
}
});
const buffer = generateBuffer(4, [ 0 ]);
p.readItems(buffer);
process.nextTick(() => {
assert.strictEqual(items.length, 1);
assert.strictEqual(items[0].header.bodyLength, 0);
done();
});
});
it('should emit a single frame with 0-length body chunked', function (done) {
const p = newInstance();
const items = [];
p.on('readable', function () {
let item;
while ((item = p.read())) {
items.push(item);
}
});
const buffer = generateBuffer(4, [ 0 ]);
p.readItems(buffer.slice(0, 2));
p.readItems(buffer.slice(2));
process.nextTick(() => {
assert.strictEqual(items.length, 1);
assert.strictEqual(items[0].header.bodyLength, 0);
done();
});
});
it('should emit multiple frames from a single chunk', function (done) {
const p = newInstance();
const items = [];
p.on('readable', function () {
let item;
while ((item = p.read())) {
items.push(item);
}
});
const bodyLengths = [ 0, 10, 0, 20, 30, 0];
const buffer = generateBuffer(4, bodyLengths);
p.readItems(buffer);
process.nextTick(() => {
assert.strictEqual(items.length, bodyLengths.length);
bodyLengths.forEach(function (length, index) {
assert.strictEqual(items[index].header.bodyLength, length);
});
done();
});
});
it('should emit multiple frames from multiples chunks', function (done) {
const p = newInstance();
const items = {};
p.on('readable', function () {
let item;
while ((item = p.read())) {
items[item.header.streamId] = items[item.header.streamId] || [];
items[item.header.streamId].push(item);
}
});
const bodyLengths = [ 0, 10, 0, 20, 30, 0];
const buffer = generateBuffer(4, bodyLengths);
p.readItems(buffer.slice(0, 9));
p.readItems(buffer.slice(9, 31));
p.readItems(buffer.slice(31, 33));
p.readItems(buffer.slice(33, 45));
p.readItems(buffer.slice(45, 65));
p.readItems(buffer.slice(65));
process.nextTick(() => {
bodyLengths.forEach(function (length, index) {
const item = items[index];
assert.ok(item);
assert.ok(item.length);
const sumLength = item.reduce(function (previousValue, subItem) {
return previousValue + subItem.chunk.length - subItem.offset;
}, 0);
assert.ok(sumLength >= length, sumLength + ' >= ' + length + ' failed');
});
done();
});
});
it('should emit multiple frames from multiples small chunks', function (done) {
const p = newInstance();
const items = {};
p.on('readable', function () {
let item;
while ((item = p.read())) {
items[item.header.streamId] = items[item.header.streamId] || [];
items[item.header.streamId].push(item);
}
});
const bodyLengths = [ 0, 10, 15, 15, 20, 12, 0, 6];
const buffer = generateBuffer(4, bodyLengths);
for (let i = 0; i < buffer.length; i = i + 2) {
if (i + 2 > buffer.length) {
p.readItems(buffer.slice(i));
break;
}
p.readItems(buffer.slice(i, i + 2));
}
process.nextTick(() => {
bodyLengths.forEach(function (length, index) {
const item = items[index];
assert.ok(item);
assert.ok(item.length);
const sumLength = item.reduce(function (previousValue, subItem) {
return previousValue + subItem.chunk.length - subItem.offset;
}, 0);
assert.ok(sumLength >= length, sumLength + ' >= ' + length + ' failed');
});
done();
});
});
});
/**
* @param {Number} version
* @param {Array.<Number>} frameBodyLengths
* @returns {Buffer}
*/
function generateBuffer(version, frameBodyLengths) {
const buffers = frameBodyLengths.map(function (bodyLength, index) {
const header = new types.FrameHeader(version, 0, index, 0, bodyLength);
return Buffer.concat([ header.toBuffer(), utils.allocBuffer(bodyLength) ]);
});
return Buffer.concat(buffers);
}
/** @returns {Protocol} */
function newInstance() {
return new Protocol({ objectMode: true });
}