1
0
Fork 0
liza/test/system/DeltaProcessorTest.ts

503 lines
17 KiB
TypeScript
Raw Normal View History

2019-11-12 15:07:37 -05:00
/**
* Delta Processor test
*
* Copyright (C) 2010-2019 R-T Specialty, LLC.
*
* This file is part of the Liza Data Collection Framework.
*
* liza is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
import { DeltaProcessor as Sut } from '../../src/system/DeltaProcessor';
import { AmqpPublisher } from '../../src/system/AmqpPublisher';
2019-11-12 15:07:37 -05:00
import { DeltaDao } from '../../src/system/db/DeltaDao';
import { DeltaType } from "../../src/bucket/delta";
import { EventEmitter } from 'events';
2019-11-12 15:07:37 -05:00
import { expect, use as chai_use } from 'chai';
chai_use( require( 'chai-as-promised' ) );
describe( 'system.DeltaProcessor', () =>
{
describe( '#getTimestampSortedDeltas', () =>
{
( <{ label: string, given: any, expected: any }[]>[
{
label: 'creates list',
given: {
rdelta: {
data: [
{
data: { foo: [ 'first_bar' ] },
2019-11-12 15:07:37 -05:00
timestamp: 123,
},
{
data: { foo: [ 'second_bar' ] },
2019-11-12 15:07:37 -05:00
timestamp: 234,
},
],
ratedata: [
{
data: { foo: [ 'third_bar' ] },
2019-11-12 15:07:37 -05:00
timestamp: 345,
},
{
data: { foo: [ 'fourth_bar' ] },
2019-11-12 15:07:37 -05:00
timestamp: 456,
},
]
}
},
expected: [
{
data: { foo: [ 'first_bar' ] },
2019-11-12 15:07:37 -05:00
timestamp: 123,
type: 'data',
},
{
data: { foo: [ 'second_bar' ] },
2019-11-12 15:07:37 -05:00
timestamp: 234,
type: 'data',
},
{
data: { foo: [ 'third_bar' ] },
2019-11-12 15:07:37 -05:00
timestamp: 345,
type: 'ratedata',
},
{
data: { foo: [ 'fourth_bar' ] },
2019-11-12 15:07:37 -05:00
timestamp: 456,
type: 'ratedata',
},
],
},
{
label: 'creates list with no ratedata',
given: {
rdelta: {
data: [
{
data: { foo: [ 'first_bar' ] },
2019-11-12 15:07:37 -05:00
timestamp: 123,
},
{
data: { foo: [ 'second_bar' ] },
2019-11-12 15:07:37 -05:00
timestamp: 234,
},
],
ratedata: []
}
},
expected: [
{
data: { foo: [ 'first_bar' ] },
2019-11-12 15:07:37 -05:00
timestamp: 123,
type: 'data',
},
{
data: { foo: [ 'second_bar' ] },
2019-11-12 15:07:37 -05:00
timestamp: 234,
type: 'data',
},
],
},
{
label: 'creates list when rate occurs between two saves',
given: {
rdelta: {
data: [
{
data: { foo: [ 'first_bar' ] },
2019-11-12 15:07:37 -05:00
timestamp: 123,
},
{
data: { foo: [ 'second_bar' ] },
2019-11-12 15:07:37 -05:00
timestamp: 234,
},
{
data: { foo: [ 'fourth_bar' ] },
2019-11-12 15:07:37 -05:00
timestamp: 456,
},
],
ratedata: [
{
data: { foo: [ 'third_bar' ] },
2019-11-12 15:07:37 -05:00
timestamp: 345,
},
],
},
},
expected: [
{
data: { foo: [ 'first_bar' ] },
2019-11-12 15:07:37 -05:00
timestamp: 123,
type: 'data',
},
{
data: { foo: [ 'second_bar' ] },
2019-11-12 15:07:37 -05:00
timestamp: 234,
type: 'data',
},
{
data: { foo: [ 'third_bar' ] },
2019-11-12 15:07:37 -05:00
timestamp: 345,
type: 'ratedata',
},
{
data: { foo: [ 'fourth_bar' ] },
2019-11-12 15:07:37 -05:00
timestamp: 456,
type: 'data',
},
],
},
] ).forEach( ( { given, expected, label } ) => it( label, () =>
{
const sut = new Sut(
createMockDeltaDao(),
createMockDeltaPublisher(),
new EventEmitter(),
);
2019-11-12 15:07:37 -05:00
const actual = sut.getTimestampSortedDeltas( given );
expect( actual ).to.deep.equal( expected );
} ) );
} );
describe( '#getDeltas', () =>
{
( <{
label: string,
type: DeltaType,
2019-11-12 15:07:37 -05:00
given: any,
expected: any
}[]>[
{
label: 'return empty array if no deltas are present',
type: 'data',
given: {
rdelta: {},
},
expected: [],
},
{
label: 'return full list if no lastPublished index is found',
type: 'data',
given: {
rdelta: {
data: [
{
data: { foo: [ 'first_bar' ] },
2019-11-12 15:07:37 -05:00
timestamp: 123,
},
{
data: { foo: [ 'second_bar' ] },
2019-11-12 15:07:37 -05:00
timestamp: 234,
},
],
},
},
expected: [
{
data: { foo: [ 'first_bar' ] },
2019-11-12 15:07:37 -05:00
timestamp: 123,
type: 'data',
},
{
data: { foo: [ 'second_bar' ] },
2019-11-12 15:07:37 -05:00
timestamp: 234,
type: 'data',
},
],
},
{
label: 'marks deltas with their type',
type: 'data',
given: {
rdelta: {
data: [
{
data: { foo: [ 'first_bar' ] },
2019-11-12 15:07:37 -05:00
timestamp: 123,
},
{
data: { foo: [ 'second_bar' ] },
2019-11-12 15:07:37 -05:00
timestamp: 234,
},
],
},
totalPublishDelta: {
2019-11-12 15:07:37 -05:00
data: 0,
},
},
expected: [
{
data: { foo: [ 'first_bar' ] },
2019-11-12 15:07:37 -05:00
timestamp: 123,
type: 'data',
},
{
data: { foo: [ 'second_bar' ] },
2019-11-12 15:07:37 -05:00
timestamp: 234,
type: 'data',
},
],
},
{
label: 'trims delta array based on index',
type: 'data',
given: {
rdelta: {
data: [
{
data: { foo: [ 'first_bar' ] },
2019-11-12 15:07:37 -05:00
timestamp: 123,
},
{
data: { foo: [ 'second_bar' ] },
2019-11-12 15:07:37 -05:00
timestamp: 234,
},
],
},
totalPublishDelta: {
2019-11-12 15:07:37 -05:00
data: 1,
},
},
expected: [
{
data: { foo: [ 'second_bar' ] },
2019-11-12 15:07:37 -05:00
timestamp: 234,
type: 'data',
},
],
},
] ).forEach( ( { type, given, expected, label } ) => it( label, () =>
{
const sut = new Sut(
createMockDeltaDao(),
createMockDeltaPublisher(),
new EventEmitter(),
);
2019-11-12 15:07:37 -05:00
const actual = sut.getDeltas( given, type );
expect( actual ).to.deep.equal( expected );
} ) );
} );
describe( '#process', () =>
{
( <{
label: string,
given: any[],
expected: any
}[]>[
{
label: 'No deltas are processed',
docs: [
{
id: 123,
lastUpdate: 123123123,
bucket: {},
rdelta: {},
},
],
expected: [],
},
{
label: 'Publishes deltas in order',
given: [
{
id: 123,
lastUpdate: 123123123,
bucket: { foo: [ 'start_bar' ] },
rdelta: {
data: [
{
data: { foo: [ 'first_bar' ] },
timestamp: 123123,
},
{
data: { foo: [ 'second_bar' ] },
timestamp: 234123,
},
],
},
},
],
expected: [
{
delta: { foo: [ 'first_bar' ] },
bucket: { foo: [ 'first_bar' ] },
doc_id: 123,
},
{
delta: { foo: [ 'second_bar' ] },
bucket: { foo: [ 'second_bar' ] },
doc_id: 123,
},
],
},
{
label: 'Publishes deltas in order for multiple documents',
given: [
{
id: 123,
lastUpdate: 123123123,
bucket: { foo: 'start_bar' },
rdelta: {
data: [
{
data: { foo: [ 'second_bar' ] },
timestamp: 234,
},
],
ratedata: [
{
data: { foo: [ 'first_bar' ] },
timestamp: 123,
},
],
},
},
{
id: 234,
lastUpdate: 123123123,
bucket: { foo: 'start_bar' },
rdelta: {
data: [
{
data: { foo: [ 'first_bar' ] },
timestamp: 123,
},
{
data: { foo: [ 'second_bar' ] },
timestamp: 234,
},
{
data: { foo: [ 'third_bar' ] },
timestamp: 345,
},
],
},
},
{
id: 345,
lastUpdate: 123123123,
bucket: { foo: 'start_bar' },
rdelta: {
ratedata: [
{
data: { foo: [ 'first_bar' ] },
timestamp: 123,
},
{
data: { foo: [ 'second_bar' ] },
timestamp: 234,
},
],
},
},
],
expected: [
{
delta: { foo: [ 'first_bar' ] },
bucket: { foo: [ 'first_bar' ] },
doc_id: 123,
},
{
delta: { foo: [ 'second_bar' ] },
bucket: { foo: [ 'second_bar' ] },
doc_id: 123,
},
{
delta: { foo: [ 'first_bar' ] },
bucket: { foo: [ 'first_bar' ] },
doc_id: 234,
},
{
delta: { foo: [ 'second_bar' ] },
bucket: { foo: [ 'second_bar' ] },
doc_id: 234,
},
{
delta: { foo: [ 'third_bar' ] },
bucket: { foo: [ 'third_bar' ] },
doc_id: 234,
},
{
delta: { foo: [ 'first_bar' ] },
bucket: { foo: [ 'first_bar' ] },
doc_id: 345,
},
{
delta: { foo: [ 'second_bar' ] },
bucket: { foo: [ 'second_bar' ] },
doc_id: 345,
},
],
},
] ).forEach( ( { given, expected, label } ) => it( label, () =>
{
let published: any = [];
const dao = createMockDeltaDao();
const publisher = createMockDeltaPublisher();
const emitter = new EventEmitter();
dao.getUnprocessedDocuments = (): Promise<Record<string, any>[]> =>
{
return Promise.resolve( given );
}
publisher.publish = ( delta, bucket, doc_id ): Promise<void> =>
{
published.push( {
delta: delta.data,
bucket: bucket,
doc_id: doc_id,
} );
return Promise.resolve();
}
return expect( new Sut( dao, publisher, emitter ).process() )
.to.eventually.deep.equal( undefined )
.then( _ => expect( published ).to.deep.equal( expected ) );
} ) );
} );
2019-11-12 15:07:37 -05:00
} );
function createMockDeltaDao(): DeltaDao
{
return <DeltaDao>{
getUnprocessedDocuments() { return Promise.resolve( [] ); },
advanceDeltaIndex() { return Promise.resolve(); },
markDocumentAsProcessed() { return Promise.resolve(); },
setErrorFlag() { return Promise.resolve(); },
getErrorCount() { return Promise.resolve( 0 ); },
2019-11-12 15:07:37 -05:00
};
}
function createMockDeltaPublisher(): AmqpPublisher
{
return <AmqpPublisher>{
publish() { return Promise.resolve(); },
};
}