Skip to content

Commit

Permalink
wip: adding tests
Browse files Browse the repository at this point in the history
[ci skip]
  • Loading branch information
tegefaulkes committed May 29, 2024
1 parent 8e6649c commit 75655ee
Show file tree
Hide file tree
Showing 3 changed files with 294 additions and 13 deletions.
7 changes: 2 additions & 5 deletions src/audit/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,7 @@ const topicPaths = [
discoveryCheckRediscoveryTopicPath,
] as const;

// @ts-ignore
// @ts-ignore: recursive definition for defining a tree
type TopicPathTreeNode = Record<string, TopicPathTreeNode>;

function generateTopicPathTree() {
Expand Down Expand Up @@ -261,7 +261,7 @@ function filterSubPaths(paths: Array<string>): Array<string> {
* This takes N generators that yield data in a sorted order and combines their outputs in a fully sorted order.
* This will only work on pre-sorted outputs from the generator.
*/
async function* genSort<T extends any = any>(
async function* genSort<T>(
sortFn: (a: T, b: T) => number,
...gens: Array<AsyncGenerator<T, void, void>>
): AsyncGenerator<T, void, void> {
Expand Down Expand Up @@ -308,9 +308,6 @@ async function* genSort<T extends any = any>(
// If the last head is done then we break
if (heads.length === 0) return;
}
} catch (e) {
console.error(e);
throw e;
} finally {
for (const { gen } of heads) {
await gen.return();
Expand Down
2 changes: 0 additions & 2 deletions tests/audit/utils.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,6 @@ describe('Audit Utils', () => {
expect(filtered).not.toInclude('e.f');
expect(filtered).not.toInclude('e.g');
});

test.prop([fc.array(orderedNumberArrayArb).noShrink()])(
'can combine strictly ordered iterators',
async (generatorData) => {
Expand Down Expand Up @@ -89,7 +88,6 @@ describe('Audit Utils', () => {
expect(acc).toMatchObject(expectedDataArray);
},
);

test('isAuditPath', async () => {
for (const topicPath of auditUtils.topicPaths) {
expect(auditUtils.isTopicPath(topicPath)).toBeTrue();
Expand Down
298 changes: 292 additions & 6 deletions tests/client/handlers/audit.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,6 @@ describe('auditEventGet', () => {
let rpcClient: OverrideRPClientType<
RPCClient<{
auditEventsGet: typeof auditEventsGet;
auditEventsMultiPathGet: typeof auditEventsMultiPathGet;
}>
>;
let tlsConfig: TLSConfig;
Expand Down Expand Up @@ -98,9 +97,6 @@ describe('auditEventGet', () => {
auditEventsGet: new AuditEventsGet({
audit,
}),
auditEventsMultiPathGet: new AuditEventsMultiPathGet({
audit,
}),
},
host: localhost,
});
Expand Down Expand Up @@ -251,8 +247,287 @@ describe('auditEventGet', () => {
}
expect(results).toHaveLength(6);
});
});

describe('auditEventMultiPathGet', () => {
const logger = new Logger('auditEventsGet test', LogLevel.WARN, [
new StreamHandler(
formatting.format`${formatting.level}:${formatting.keys}:${formatting.msg}`,
),
]);
const password = 'password';
const localhost = '127.0.0.1';
let audit: Audit;
let dataDir: string;
let db: DB;
let keyRing: KeyRing;
let clientService: ClientService;
let webSocketClient: WebSocketClient;
let rpcClient: OverrideRPClientType<
RPCClient<{
auditEventsMultiPathGet: typeof auditEventsMultiPathGet;
}>
>;
let tlsConfig: TLSConfig;
let nodeConnectionManager: NodeConnectionManager; // Event target pretending to be discovery
let discovery: Discovery; // Event target pretending to be discovery

const handleEvent = async (evt) => {
// @ts-ignore: kidnap protected handlerMap so we can send events in the foreground
const handlerMap = audit.eventHandlerMap;
await handlerMap.get(evt.constructor)?.handler(evt);
};

beforeEach(async () => {
dataDir = await fs.promises.mkdtemp(
path.join(os.tmpdir(), 'polykey-test-'),
);
const keysPath = path.join(dataDir, 'keys');
const dbPath = path.join(dataDir, 'db');
db = await DB.createDB({
dbPath,
logger,
});
keyRing = await KeyRing.createKeyRing({
password,
keysPath,
passwordOpsLimit: keysUtils.passwordOpsLimits.min,
passwordMemLimit: keysUtils.passwordMemLimits.min,
strictMemoryLock: false,
logger,
});
tlsConfig = await testsUtils.createTLSConfig(keyRing.keyPair);
clientService = new ClientService({
tlsConfig,
logger: logger.getChild(ClientService.name),
});
nodeConnectionManager = new EventTarget() as any;
discovery = new EventTarget() as any;
audit = await Audit.createAudit({
db,
nodeConnectionManager,
discovery,
logger: logger.getChild(Audit.name),
});
clientService = new ClientService({
tlsConfig,
logger: logger.getChild(ClientService.name),
});
await clientService.start({
manifest: {
auditEventsGet: new AuditEventsGet({
audit,
}),
auditEventsMultiPathGet: new AuditEventsMultiPathGet({
audit,
}),
},
host: localhost,
});
webSocketClient = await WebSocketClient.createWebSocketClient({
config: {
verifyPeer: false,
},
host: localhost,
logger: logger.getChild(WebSocketClient.name),
port: clientService.port,
});
rpcClient = new RPCClient({
manifest: {
auditEventsMultiPathGet,
},
streamFactory: () => webSocketClient.connection.newStream(),
toError: networkUtils.toError,
logger: logger.getChild(RPCClient.name),
}) as any;
});
afterEach(async () => {
await clientService.stop({ force: true });
await webSocketClient.destroy({ force: true });
await keyRing.stop();
await audit.stop();
await fs.promises.rm(dataDir, {
force: true,
recursive: true,
});
});

test('cancels', async () => {
let callerInterface = await rpcClient.methods.auditEventsMultiPathGet({
paths: [],
});
let reader = callerInterface.getReader();
await reader.cancel();
await expect(reader.closed).toResolve();
callerInterface = await rpcClient.methods.auditEventsMultiPathGet({
paths: [],
awaitFutureEvents: true,
});
reader = callerInterface.getReader();
await reader.cancel();
await expect(reader.closed).toResolve();
});
test('gets connection events', async () => {
const nodeId = testNodesUtils.generateRandomNodeId();
const eventDetail: ConnectionData = {
remoteHost: '::' as Host,
remoteNodeId: nodeId,
remotePort: 0 as Port,
};
const auditEventData = {
...eventDetail,
remoteNodeId: nodesUtils.encodeNodeId(eventDetail.remoteNodeId),
};
await handleEvent(
new nodesEvents.EventNodeConnectionManagerConnectionReverse({
detail: eventDetail,
}),
);
let callerInterface: any = await rpcClient.methods.auditEventsMultiPathGet({
paths: ['node.connection.reverse'],
});
let reader = callerInterface.getReader();
await expect(reader.read().then((e) => e.value!.data)).resolves.toEqual({
...auditEventData,
type: 'reverse',
});
callerInterface = await rpcClient.methods.auditEventsMultiPathGet({
paths: ['node.connection'],
awaitFutureEvents: true,
});
reader = callerInterface.getReader();
await expect(reader.read().then((e) => e.value!.data)).resolves.toEqual({
...auditEventData,
type: 'reverse',
});
await handleEvent(
new nodesEvents.EventNodeConnectionManagerConnectionForward({
detail: eventDetail,
}),
);
await expect(reader.read().then((e) => e.value!.data)).resolves.toEqual({
...auditEventData,
type: 'forward',
});
});
test('gets discovery events', async () => {
// Set up some events
await handleEvent(
new discoveryEvents.EventDiscoveryVertexQueued({
detail: {
vertex: 'vertex1' as GestaltIdEncoded,
},
}),
);
await handleEvent(
new discoveryEvents.EventDiscoveryVertexQueued({
detail: {
vertex: 'vertex2' as GestaltIdEncoded,
parent: 'vertex1' as GestaltIdEncoded,
},
}),
);
await handleEvent(
new discoveryEvents.EventDiscoveryVertexQueued({
detail: {
vertex: 'vertex3' as GestaltIdEncoded,
parent: 'vertex1' as GestaltIdEncoded,
},
}),
);
await handleEvent(
new discoveryEvents.EventDiscoveryVertexProcessed({
detail: {
vertex: 'vertex1' as GestaltIdEncoded,
},
}),
);
await handleEvent(
new discoveryEvents.EventDiscoveryVertexFailed({
detail: {
vertex: 'vertex2' as GestaltIdEncoded,
parent: 'vertex1' as GestaltIdEncoded,
code: 255,
message: 'some message',
},
}),
);
await handleEvent(
new discoveryEvents.EventDiscoveryVertexCancelled({
detail: {
vertex: 'vertex3' as GestaltIdEncoded,
parent: 'vertex1' as GestaltIdEncoded,
},
}),
);

test('testo', async () => {
const readableStream = await rpcClient.methods.auditEventsMultiPathGet({
paths: ['discovery.vertex'],
});
const results: Array<POJO> = [];
for await (const result of readableStream) {
results.push(result);
}
expect(results).toHaveLength(6);
});
test('can get multiple paths in ascending order', async () => {
const nodeId = testNodesUtils.generateRandomNodeId();
const eventDetail: ConnectionData = {
remoteHost: '::' as Host,
remoteNodeId: nodeId,
remotePort: 0 as Port,
};
await handleEvent(
new nodesEvents.EventNodeConnectionManagerConnectionReverse({
detail: {
...eventDetail,
remotePort: 1 as Port,
},
}),
);
await handleEvent(
new nodesEvents.EventNodeConnectionManagerConnectionForward({
detail: {
...eventDetail,
remotePort: 2 as Port,
},
}),
);
await handleEvent(
new nodesEvents.EventNodeConnectionManagerConnectionReverse({
detail: {
...eventDetail,
remotePort: 3 as Port,
},
}),
);
await handleEvent(
new nodesEvents.EventNodeConnectionManagerConnectionForward({
detail: {
...eventDetail,
remotePort: 4 as Port,
},
}),
);
const callerInterface: any =
await rpcClient.methods.auditEventsMultiPathGet({
paths: ['node.connection', 'node.connection.forward'],
order: 'asc',
});
const order: Array<number> = [];
const pathSet: Set<string> = new Set();
for await (const result of callerInterface) {
order.push(result.data.remotePort);
pathSet.add(result.path.join('.'));
}
expect(order).toMatchObject([1, 2, 3, 4]);
expect([...pathSet]).toIncludeAllMembers([
'node.connection.reverse',
'node.connection.forward',
]);
expect(pathSet.size).toBe(2);
});
test('can get multiple paths in descending order', async () => {
const nodeId = testNodesUtils.generateRandomNodeId();
const eventDetail: ConnectionData = {
remoteHost: '::' as Host,
Expand Down Expand Up @@ -296,7 +571,18 @@ describe('auditEventGet', () => {
paths: ['node.connection', 'node.connection.forward'],
order: 'desc',
});
for await (const result of callerInterface) console.log(result);
const order: Array<number> = [];
const pathSet: Set<string> = new Set();
for await (const result of callerInterface) {
order.push(result.data.remotePort);
pathSet.add(result.path.join('.'));
}
expect(order).toMatchObject([4, 3, 2, 1]);
expect([...pathSet]).toIncludeAllMembers([
'node.connection.reverse',
'node.connection.forward',
]);
expect(pathSet.size).toBe(2);
});
});

Expand Down

0 comments on commit 75655ee

Please sign in to comment.