feat(peer-manager): unit tests

This commit is contained in:
Danish Arora 2024-10-08 11:52:47 +05:30
parent d0714d9de4
commit 874d835117
No known key found for this signature in database
GPG Key ID: 1C6EF37CDAE1426E
6 changed files with 191 additions and 38 deletions

12
package-lock.json generated
View File

@ -33367,7 +33367,8 @@
"@waku/proto": "^0.0.8", "@waku/proto": "^0.0.8",
"@waku/utils": "0.0.20", "@waku/utils": "0.0.20",
"async-mutex": "^0.5.0", "async-mutex": "^0.5.0",
"libp2p": "^1.8.1" "libp2p": "^1.8.1",
"p-event": "^6.0.1"
}, },
"devDependencies": { "devDependencies": {
"@rollup/plugin-commonjs": "^25.0.7", "@rollup/plugin-commonjs": "^25.0.7",
@ -33375,15 +33376,16 @@
"@rollup/plugin-node-resolve": "^15.2.3", "@rollup/plugin-node-resolve": "^15.2.3",
"@rollup/plugin-replace": "^5.0.5", "@rollup/plugin-replace": "^5.0.5",
"@types/chai": "^4.3.11", "@types/chai": "^4.3.11",
"@types/mocha": "^10.0.6", "@types/mocha": "^10.0.9",
"@waku/build-utils": "*", "@waku/build-utils": "*",
"chai": "^4.3.10", "chai": "^5.1.1",
"cspell": "^8.6.1", "cspell": "^8.6.1",
"interface-datastore": "^8.2.10", "interface-datastore": "^8.2.10",
"mocha": "^10.3.0", "mocha": "^10.7.3",
"npm-run-all": "^4.1.5", "npm-run-all": "^4.1.5",
"rollup": "^4.12.0", "rollup": "^4.12.0",
"sinon": "^18.0.0" "sinon": "^19.0.2",
"ts-node": "^10.9.2"
}, },
"engines": { "engines": {
"node": ">=20" "node": ">=20"

View File

@ -1,26 +1,27 @@
const config = { const config = {
extension: ['ts'], extension: ['ts'],
spec: 'src/**/*.spec.ts', spec: 'src/**/*.spec.ts',
require: ['ts-node/register', 'isomorphic-fetch'], require: ['ts-node/register', 'isomorphic-fetch'],
loader: 'ts-node/esm', loader: 'ts-node/esm',
nodeOptions: [ nodeOptions: [
'experimental-specifier-resolution=node', 'experimental-specifier-resolution=node',
'loader=ts-node/esm' 'loader=ts-node/esm'
], ],
exit: true exit: true
};
if (process.env.CI) {
console.log("Running tests in parallel");
config.parallel = true;
config.jobs = 6;
console.log("Activating allure reporting");
config.reporter = 'mocha-multi-reporters';
config.reporterOptions = {
configFile: '.mocha.reporters.json'
}; };
} else {
console.log("Running tests serially. To enable parallel execution update mocha config");
}
module.exports = config; if (process.env.CI) {
console.log("Running tests in parallel");
config.parallel = true;
config.jobs = 6;
console.log("Activating allure reporting");
config.reporter = 'mocha-multi-reporters';
config.reporterOptions = {
configFile: '.mocha.reporters.json'
};
} else {
console.log("Running tests serially. To enable parallel execution update mocha config");
}
module.exports = config;

View File

@ -74,23 +74,25 @@
"@waku/utils": "0.0.20", "@waku/utils": "0.0.20",
"@waku/message-hash": "0.1.16", "@waku/message-hash": "0.1.16",
"async-mutex": "^0.5.0", "async-mutex": "^0.5.0",
"libp2p": "^1.8.1" "libp2p": "^1.8.1",
"p-event": "^6.0.1"
}, },
"devDependencies": { "devDependencies": {
"@types/mocha": "^10.0.6",
"@types/chai": "^4.3.11", "@types/chai": "^4.3.11",
"@rollup/plugin-commonjs": "^25.0.7", "@rollup/plugin-commonjs": "^25.0.7",
"@rollup/plugin-json": "^6.0.0", "@rollup/plugin-json": "^6.0.0",
"@rollup/plugin-node-resolve": "^15.2.3", "@rollup/plugin-node-resolve": "^15.2.3",
"@rollup/plugin-replace": "^5.0.5", "@rollup/plugin-replace": "^5.0.5",
"@types/mocha": "^10.0.9",
"@waku/build-utils": "*", "@waku/build-utils": "*",
"mocha": "^10.3.0", "chai": "^5.1.1",
"sinon": "^18.0.0",
"chai": "^4.3.10",
"cspell": "^8.6.1", "cspell": "^8.6.1",
"interface-datastore": "^8.2.10", "interface-datastore": "^8.2.10",
"mocha": "^10.7.3",
"npm-run-all": "^4.1.5", "npm-run-all": "^4.1.5",
"rollup": "^4.12.0" "rollup": "^4.12.0",
"sinon": "^19.0.2",
"ts-node": "^10.9.2"
}, },
"peerDependencies": { "peerDependencies": {
"@libp2p/bootstrap": "^10" "@libp2p/bootstrap": "^10"

View File

@ -0,0 +1,148 @@
import { Peer, PeerId } from "@libp2p/interface";
import { ConnectionManager, LightPushCodec } from "@waku/core";
import { BaseProtocol } from "@waku/core/lib/base_protocol";
import { Logger } from "@waku/utils";
import { expect } from "chai";
import sinon from "sinon";
import { PeerManager } from "./peer_manager.js";
describe("PeerManager", () => {
let peerManager: PeerManager;
let mockConnectionManager: sinon.SinonStubbedInstance<ConnectionManager>;
let mockCore: sinon.SinonStubbedInstance<BaseProtocol>;
let mockLogger: any;
beforeEach(() => {
mockConnectionManager = sinon.createStubInstance(ConnectionManager);
mockCore = sinon.createStubInstance(BaseProtocol);
mockLogger = {
info: sinon.stub(),
warn: sinon.stub(),
error: sinon.stub(),
debug: sinon.stub(),
extend: sinon.stub().returns({
info: sinon.stub(),
warn: sinon.stub(),
error: sinon.stub(),
debug: sinon.stub()
})
};
mockCore.multicodec = LightPushCodec;
peerManager = new PeerManager(
mockConnectionManager as any,
mockCore as any,
mockLogger as Logger
);
});
afterEach(() => {
sinon.restore();
});
const createMockPeer = (id: string): Peer =>
({
id: {
toString: () => id
} as PeerId
}) as Peer;
describe("addPeer", () => {
it("should add a peer", async () => {
const peer = createMockPeer("peer1");
await peerManager.addPeer(peer);
expect(mockConnectionManager.attemptDial.calledWith(peer.id)).to.be.true;
expect(
mockLogger.info.calledWith(sinon.match(/Added and dialed peer: peer1/))
).to.be.true;
expect(await peerManager.getPeerCount()).to.equal(1);
});
});
describe("removePeer", () => {
it("should remove a peer", async () => {
const peer = createMockPeer("peer1");
await peerManager.addPeer(peer);
await peerManager.removePeer(peer.id);
expect(mockLogger.info.calledWith(sinon.match(/Removed peer: peer1/))).to
.be.true;
expect(await peerManager.getPeerCount()).to.equal(0);
});
});
describe("getPeerCount", () => {
it("should return the correct number of peers", async () => {
await peerManager.addPeer(createMockPeer("peer1"));
await peerManager.addPeer(createMockPeer("peer2"));
const count = await peerManager.getPeerCount();
expect(count).to.equal(2);
});
});
describe("hasPeers", () => {
it("should return true when peers exist", async () => {
await peerManager.addPeer(createMockPeer("peer1"));
const result = await peerManager.hasPeers();
expect(result).to.be.true;
});
it("should return false when no peers exist", async () => {
const result = await peerManager.hasPeers();
expect(result).to.be.false;
});
});
describe("removeExcessPeers", () => {
it("should remove the specified number of excess peers", async () => {
await peerManager.addPeer(createMockPeer("peer1"));
await peerManager.addPeer(createMockPeer("peer2"));
await peerManager.addPeer(createMockPeer("peer3"));
await peerManager.removeExcessPeers(2);
const count = await peerManager.getPeerCount();
expect(count).to.equal(1);
expect(mockLogger.info.calledWith(`Removing 2 excess peer(s)`)).to.be
.true;
});
});
describe("findAndAddPeers", () => {
it("should find and add new peers", async () => {
const newPeers = [createMockPeer("peer1"), createMockPeer("peer2")];
mockCore.getPeers.resolves(newPeers);
const addedPeers = await peerManager.findAndAddPeers(2);
expect(addedPeers).to.have.lengthOf(2);
expect(mockConnectionManager.attemptDial.callCount).to.equal(2);
});
it("should not add existing peers", async () => {
const existingPeer = createMockPeer("existing");
await peerManager.addPeer(existingPeer);
const newPeers = [existingPeer, createMockPeer("new")];
mockCore.getPeers.resolves(newPeers);
const addedPeers = await peerManager.findAndAddPeers(2);
expect(addedPeers).to.have.lengthOf(1);
expect(mockConnectionManager.attemptDial.callCount).to.equal(2); // Once for existing, once for new
});
it("should log when no additional peers are found", async () => {
mockCore.getPeers.resolves([]);
await peerManager.findAndAddPeers(2);
expect(mockLogger.warn.calledWith("No additional peers found")).to.be
.true;
});
});
});

View File

@ -5,6 +5,6 @@
"rootDir": "src", "rootDir": "src",
"tsBuildInfoFile": "dist/.tsbuildinfo" "tsBuildInfoFile": "dist/.tsbuildinfo"
}, },
"include": ["src"], "include": ["src/**/*.ts"],
"exclude": ["src/**/*.spec.ts", "src/test_utils"] "exclude": ["src/test_utils"]
} }

View File

@ -17,7 +17,7 @@ import {
TestShardInfo TestShardInfo
} from "./utils.js"; } from "./utils.js";
describe.only("Node Health Status Matrix Tests", function () { describe("Node Health Status Matrix Tests", function () {
let waku: LightNode; let waku: LightNode;
let serviceNodes: ServiceNode[]; let serviceNodes: ServiceNode[];