From 62c578dc31a6705515c30e0434980461af8401b1 Mon Sep 17 00:00:00 2001 From: Roger Qiu Date: Fri, 10 Nov 2023 09:07:55 +1100 Subject: [PATCH] WIP [ci skip] --- tests/nodes/NodeGraph.test.ts | 45 ++++++++++++++++++++++++++++------- tests/nodes/utils.ts | 13 ++++++++-- 2 files changed, 47 insertions(+), 11 deletions(-) diff --git a/tests/nodes/NodeGraph.test.ts b/tests/nodes/NodeGraph.test.ts index ab235df551..65d948644e 100644 --- a/tests/nodes/NodeGraph.test.ts +++ b/tests/nodes/NodeGraph.test.ts @@ -5,6 +5,7 @@ import type { NodeBucket, NodeBucketIndex, } from '@/nodes/types'; +import type { Host, Port } from '@/network/types'; import type { Key } from '@/keys/types'; import os from 'os'; import path from 'path'; @@ -272,7 +273,7 @@ describe(`${NodeGraph.name} test`, () => { }); await nodeGraph.stop(); }); - test('get bucket with multiple nodes', async () => { + test.only('get bucket with multiple nodes', async () => { const nodeBucketLimit = 25; const nodeGraph = await NodeGraph.createNodeGraph({ db, @@ -297,12 +298,25 @@ describe(`${NodeGraph.name} test`, () => { await nodeGraph.setNode( nodeId, { - host: '127.0.0.1', - port: 55555, - } as NodeAddress, + host: '127.0.0.1' as Host, + port: 55555 as Port, + scopes: [], + }, lastUpdated ); } + // Setting one more node would trigger the bucket limit error + const nodeIdExtra = IdInternal.create( + utils.bigInt2Bytes(BigInt(nodeBucketLimit), keyRing.getNodeId().byteLength), + ); + await expect(nodeGraph.setNode( + nodeIdExtra, + { + host: '127.0.0.1' as Host, + port: 55555 as Port, + scopes: [] + }, + )).rejects.toThrow(nodesErrors.ErrorNodeGraphBucketLimit); // Use first and last buckets because node IDs may be split between buckets const bucketIndexFirst = nodesUtils.bucketIndex( keyRing.getNodeId(), @@ -392,11 +406,24 @@ describe(`${NodeGraph.name} test`, () => { }); const now = utils.getUnixtime(); for (let i = 0; i < 50; i++) { - await utils.sleep(50); - await nodeGraph.setNode(testNodesUtils.generateRandomNodeId(), { - host: '127.0.0.1', - port: utils.getRandomInt(0, 2 ** 16), - } as NodeAddress); + try { + await nodeGraph.setNode( + testNodesUtils.generateRandomNodeId(), + { + host: '127.0.0.1' as Host, + port: utils.getRandomInt(0, 2 ** 16) as Port, + scopes: ['local'] + }, + testNodesUtils.generateRandomUnixtime(), + ); + } catch (e) { + // 50% of all randomly generate NodeIds will be in the farthest bucket + // So there is a high chance of this exception, just skip it + if (e instanceof nodesErrors.ErrorNodeGraphBucketLimit) { + continue; + } + throw e; + } } let bucketIndex_ = -1; // Ascending order diff --git a/tests/nodes/utils.ts b/tests/nodes/utils.ts index 40fcb96463..0ce10e8f6b 100644 --- a/tests/nodes/utils.ts +++ b/tests/nodes/utils.ts @@ -4,7 +4,7 @@ import { webcrypto } from 'crypto'; import { IdInternal } from '@matrixai/id'; import * as fc from 'fast-check'; import * as keysUtils from '@/keys/utils'; -import { bigInt2Bytes } from '@/utils'; +import * as utils from '@/utils'; /** * Generate random `NodeId` @@ -24,6 +24,14 @@ function generateRandomNodeId(readable: boolean = false): NodeId { } } +/** + * Generates a random unix timestamp between 0 and now. + */ +function generateRandomUnixtime() { + const now = utils.getUnixtime() + 1; + return Math.random() * (now - 0) + now; +} + /** * Generate a deterministic NodeId for a specific bucket given an existing NodeId * This requires solving the bucket index (`i`) and distance equation: @@ -49,7 +57,7 @@ function generateNodeIdForBucket( throw new RangeError('bucketOffset is beyond bucket size'); } // Offset position within the bucket - const distance = bigInt2Bytes( + const distance = utils.bigInt2Bytes( lowerBoundDistance + BigInt(bucketOffset), nodeId.byteLength, ); @@ -174,6 +182,7 @@ function createReasonConverters() { export { generateRandomNodeId, + generateRandomUnixtime, generateNodeIdForBucket, nodesConnect, nodeIdArb,