UNPKG

reliable-zeromq

Version:

A collection of reliable zeromq messaging constructs

182 lines (140 loc) 6.58 kB
/* tslint:disable: no-string-literal */ import anyTest, { ExecutionContext } from "ava"; import type { TestInterface } from "ava"; import * as sinon from "sinon"; import ExpiryMap from "../../../Src/Utils/ExpiryMap"; type TTestContext = { ExpiryBuffer: number; ExpiryMap: ExpiryMap<string, string>; DummyValues: [string, string][]; FilledMap: ExpiryMap<string, string>; }; const test: TestInterface<TTestContext> = anyTest as TestInterface<TTestContext> ; test.before(async(t: ExecutionContext<TTestContext>): Promise<void> => { // No setup necessary }); test.beforeEach((t: ExecutionContext<TTestContext>): void => { t.context.ExpiryBuffer = 500; t.context.ExpiryMap = new ExpiryMap(0); t.context.DummyValues = [ ["0", "myFunc()"], ["1", "d"], ["2", "200n"], ["3", "[ { \"_id\": \"5ef6d0a87fe78748b57ea948\", \"index\": 0, \"guid\": \"4332a763-53e5-4e3d-a978-d22ab6fe976c\", \"isActive\": false, \"balance\": \"$2,443.19\", \"tags\": [ \"pariatur\", \"duis\", \"commodo\", \"velit\", \"eiusmod\", \"minim\", \"eu\" ], \"greeting\": \"Hello, undefined! You have 7 unread messages.\" }, { \"_id\": \"5ef6d0a8e260872db7a55744\", \"index\": 1, \"guid\": \"c1ad2a72-2550-4a85-8556-d591af31041f\", \"isActive\": false, \"balance\": \"$3,257.61\", \"tags\": [ \"eu\", \"laborum\", \"aliquip\", \"tempor\", \"id\", \"ut\", \"consectetur\" ], \"greeting\": \"Hello, undefined! You have 2 unread messages.\" }, { \"_id\": \"5ef6d0a8a64a4201ebe17add\", \"index\": 2, \"guid\": \"ece7aabc-79dc-4286-abc1-25473a2a830e\", \"isActive\": false, \"balance\": \"$3,869.75\", \"tags\": [ \"fugiat\", \"qui\", \"irure\", \"esse\", \"ut\", \"ut\", \"consectetur\" ], \"greeting\": \"Hello, undefined! You have 3 unread messages.\" }, { \"_id\": \"5ef6d0a85fe8e68ca3af8b52\", \"index\": 3, \"guid\": \"0e9fc60a-a75b-4bd6-95f7-bed9fd514a69\", \"isActive\": true, \"balance\": \"$2,195.14\", \"tags\": [ \"aute\", \"ad\", \"irure\", \"et\", \"ea\", \"exercitation\", \"ipsum\" ], \"greeting\": \"Hello, undefined! You have 8 unread messages.\" }, { \"_id\": \"5ef6d0a86c98c87f8447bc85\", \"index\": 4, \"guid\": \"ae607bec-4a42-4884-b801-13fd04712b2e\", \"isActive\": false, \"balance\": \"$1,837.78\", \"tags\": [ \"irure\", \"occaecat\", \"nulla\", \"amet\", \"ut\", \"pariatur\", \"dolor\" ], \"greeting\": \"Hello, undefined! You have 10 unread messages.\" } ]"], ["4", "cat"], ]; }); test.afterEach((t: ExecutionContext<TTestContext>): void => { sinon.restore(); }); test("Constructor", (t: ExecutionContext<TTestContext>): void => { const lNewMap: ExpiryMap<string, string> = new ExpiryMap<string, string>(0); t.is(lNewMap["mExpiryMS"], 0); t.is(lNewMap["mNextExpiry"], undefined); t.is(lNewMap.size, 0); }); test("Constructor with Entries", (t: ExecutionContext<TTestContext>): void => { const lDummyEntries: [string, string][] = t.context.DummyValues; const lNewMap: ExpiryMap<string, string> = new ExpiryMap<string, string>(0, lDummyEntries); t.is(lNewMap["mExpiryMS"], 0); t.not(lNewMap["mNextExpiry"], undefined); t.is(lNewMap.size, t.context.DummyValues.length); }); test("Set, Get, and Clear", async(t: ExecutionContext<TTestContext>): Promise<void> => { const clock: sinon.SinonFakeTimers = sinon.useFakeTimers(); const lMap: ExpiryMap<string, string> = t.context.ExpiryMap; const lDummyValues: [string, string][] = t.context.DummyValues; lMap.set(lDummyValues[0][0], lDummyValues[0][1]); t.is(lMap.get(lDummyValues[0][0]), lDummyValues[0][1]); lMap.set(lDummyValues[1][0], lDummyValues[1][1]); lMap.set(lDummyValues[2][0], lDummyValues[2][1]); lMap.set(lDummyValues[3][0], lDummyValues[3][1]); lMap.set(lDummyValues[4][0], lDummyValues[4][1]); t.is(lMap.size, t.context.DummyValues.length); t.is(lMap.get(lDummyValues[1][0]), lDummyValues[1][1]); t.is(lMap.get(lDummyValues[2][0]), lDummyValues[2][1]); t.is(lMap.get(lDummyValues[3][0]), lDummyValues[3][1]); t.is(lMap.get(lDummyValues[4][0]), lDummyValues[4][1]); clock.tick(t.context.ExpiryBuffer); t.is(lMap.size, 0); }); test("5s Expiry", (t: ExecutionContext<TTestContext>): void => { const clock: sinon.SinonFakeTimers = sinon.useFakeTimers(); const lMap: Map<string, string> = new ExpiryMap(5000, t.context.DummyValues); clock.tick(5000 + t.context.ExpiryBuffer - 1); t.is(lMap.size, t.context.DummyValues.length); clock.tick(1); t.is(lMap.size, 0); }); test("Staggered Insertion & Pruning", (t: ExecutionContext<TTestContext>): void => { const clock: sinon.SinonFakeTimers = sinon.useFakeTimers(); const lMap: ExpiryMap<bigint, number> = new ExpiryMap<bigint, number>(2000); lMap.set(0n, 0); // 0,1,2 at 0s. Expire 2s, Timer 2.5s lMap.set(1n, 1); lMap.set(2n, 2); clock.tick(1000); // 3,4,5 at 1s. Expire 3s lMap.set(3n, 3); lMap.set(4n, 4); lMap.set(5n, 5); clock.tick(900); // 6,7,8 at 1.9s. Expire 3.9s lMap.set(6n, 6); lMap.set(7n, 7); lMap.set(8n, 8); t.is(lMap.size, 9); clock.tick(600); // 2.5s, timer triggered, first 3 cleared t.is(lMap.size, 6); clock.tick(1000); // 3.5s, 2nd timer triggered, next 3 cleared t.is(lMap.size, 3); clock.tick(900); // 4.4s 3rd timer triggered, final 3 cleared t.is(lMap.size, 0); t.is(lMap.size, 0); t.is(lMap["mNextExpiry"], undefined); lMap.clear(); lMap.set(10n, 10); lMap.set(11n, 11); lMap.set(12n, 12); t.is(lMap.size, 3); clock.tick(100); // Cleared timeout theoretical expiry t.is(lMap.size, 3); clock.tick(1900); // 2s into new timeout t.is(lMap.size, 3); clock.tick(1000); // 2.5s New timeout expiry t.is(lMap.size, 0); }); test("Staggered Insertion, Batched Pruning", (t: ExecutionContext<TTestContext>): void => { const clock: sinon.SinonFakeTimers = sinon.useFakeTimers(); const lMap: ExpiryMap<number, boolean> = new ExpiryMap<number, boolean>(2000); lMap.set(0, true); lMap.set(1, true); clock.tick(100); lMap.set(2, true); lMap.set(3, true); clock.tick(200); lMap.set(4, true); lMap.set(5, true); clock.tick(200); lMap.set(6, true); lMap.set(7, true); clock.tick(100); lMap.set(8, true); lMap.set(9, true); t.is(lMap.size, 10); clock.tick(1899); t.is(lMap.size, 10); clock.tick(1); t.is(lMap.size, 2); clock.tick(599); t.is(lMap.size, 2); clock.tick(1); t.is(lMap.size, 0); });