Skip to content

Commit 42eb3cb

Browse files
add tests
1 parent 0e46824 commit 42eb3cb

File tree

3 files changed

+142
-6
lines changed

3 files changed

+142
-6
lines changed

package-lock.json

+6-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/tests/package.json

+4-3
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@
5757
"@waku/interfaces": "*",
5858
"@waku/utils": "*",
5959
"app-root-path": "^3.1.0",
60+
"chai-as-promised": "^7.1.1",
6061
"debug": "^4.3.4",
6162
"dockerode": "^3.3.5",
6263
"p-timeout": "^6.1.0",
@@ -66,20 +67,20 @@
6667
},
6768
"devDependencies": {
6869
"@libp2p/bootstrap": "^9.0.2",
69-
"@types/sinon": "^10.0.16",
7070
"@types/chai": "^4.3.5",
7171
"@types/dockerode": "^3.3.19",
7272
"@types/mocha": "^10.0.1",
73+
"@types/sinon": "^10.0.16",
7374
"@types/tail": "^2.2.1",
7475
"@typescript-eslint/eslint-plugin": "^5.57.0",
7576
"@typescript-eslint/parser": "^6.6.0",
76-
"@waku/sdk": "*",
7777
"@waku/dns-discovery": "*",
7878
"@waku/message-encryption": "*",
7979
"@waku/peer-exchange": "*",
80+
"@waku/sdk": "*",
8081
"chai": "^4.3.7",
81-
"datastore-core": "^9.2.2",
8282
"cspell": "^7.3.2",
83+
"datastore-core": "^9.2.2",
8384
"debug": "^4.3.4",
8485
"interface-datastore": "^8.2.3",
8586
"libp2p": "^0.46.8",

packages/tests/tests/utils.spec.ts

+132-2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
import type { PeerStore } from "@libp2p/interface/peer-store";
2+
import type { Peer } from "@libp2p/interface/peer-store";
3+
import { createSecp256k1PeerId } from "@libp2p/peer-id-factory";
14
import {
25
createDecoder,
36
createEncoder,
@@ -9,11 +12,16 @@ import { Protocols } from "@waku/interfaces";
912
import { createLightNode } from "@waku/sdk";
1013
import { toAsyncIterator } from "@waku/utils";
1114
import { bytesToUtf8, utf8ToBytes } from "@waku/utils/bytes";
12-
import { expect } from "chai";
15+
import { selectPeerForProtocol } from "@waku/utils/libp2p";
16+
import chai, { expect } from "chai";
17+
import chaiAsPromised from "chai-as-promised";
18+
import sinon from "sinon";
1319

14-
import { makeLogFileName, NOISE_KEY_1 } from "../src/index.js";
20+
import { delay, makeLogFileName, NOISE_KEY_1 } from "../src/index.js";
1521
import { NimGoNode } from "../src/node/node.js";
1622

23+
chai.use(chaiAsPromised);
24+
1725
const TestContentTopic = "/test/1/waku-filter";
1826
const TestEncoder = createEncoder({ contentTopic: TestContentTopic });
1927
const TestDecoder = createDecoder(TestContentTopic);
@@ -106,3 +114,125 @@ describe("Util: toAsyncIterator: Filter", () => {
106114
expect(result.done).to.eq(true);
107115
});
108116
});
117+
118+
const TestCodec = "test/1";
119+
120+
describe("selectPeerForProtocol", () => {
121+
let peerStore: PeerStore;
122+
let peerPings: Map<string, number>;
123+
const protocols = [TestCodec];
124+
125+
beforeEach(async function () {
126+
this.timeout(10000);
127+
const waku = await createLightNode();
128+
await waku.start();
129+
await delay(3000);
130+
peerStore = waku.libp2p.peerStore;
131+
peerPings = new Map();
132+
});
133+
134+
afterEach(() => {
135+
sinon.restore();
136+
});
137+
138+
it("should return the peer with the lowest ping", async function () {
139+
const peer1 = await createSecp256k1PeerId();
140+
const peer2 = await createSecp256k1PeerId();
141+
const peer3 = await createSecp256k1PeerId();
142+
143+
const mockPeers = [
144+
{ id: peer1, protocols: [TestCodec] },
145+
{ id: peer2, protocols: [TestCodec] },
146+
{ id: peer3, protocols: [TestCodec] }
147+
] as Peer[];
148+
149+
sinon.stub(peerStore, "forEach").callsFake(async (callback) => {
150+
for (const peer of mockPeers) {
151+
callback(peer);
152+
}
153+
});
154+
155+
peerPings.set(peer1.toString(), 500);
156+
peerPings.set(peer2.toString(), 1000);
157+
peerPings.set(peer3.toString(), 100);
158+
159+
const result = await selectPeerForProtocol(peerStore, peerPings, protocols);
160+
161+
expect(result.peer).to.deep.equal(mockPeers[2]);
162+
expect(result.protocol).to.equal(TestCodec);
163+
});
164+
165+
it("should return the peer with the provided peerId", async function () {
166+
const targetPeer = await createSecp256k1PeerId();
167+
const mockPeer = { id: targetPeer, protocols: [TestCodec] } as Peer;
168+
sinon.stub(peerStore, "get").withArgs(targetPeer).resolves(mockPeer);
169+
170+
const result = await selectPeerForProtocol(
171+
peerStore,
172+
peerPings,
173+
protocols,
174+
targetPeer
175+
);
176+
expect(result.peer).to.deep.equal(mockPeer);
177+
});
178+
179+
it("should return a random peer when all peers have the same latency", async function () {
180+
const peer1 = await createSecp256k1PeerId();
181+
const peer2 = await createSecp256k1PeerId();
182+
const peer3 = await createSecp256k1PeerId();
183+
184+
const mockPeers = [
185+
{ id: peer1, protocols: [TestCodec] },
186+
{ id: peer2, protocols: [TestCodec] },
187+
{ id: peer3, protocols: [TestCodec] }
188+
] as Peer[];
189+
190+
sinon.stub(peerStore, "forEach").callsFake(async (callback) => {
191+
for (const peer of mockPeers) {
192+
callback(peer);
193+
}
194+
});
195+
196+
peerPings.set(peer1.toString(), 500);
197+
peerPings.set(peer2.toString(), 500);
198+
peerPings.set(peer3.toString(), 500);
199+
200+
const result = await selectPeerForProtocol(peerStore, peerPings, protocols);
201+
202+
expect(mockPeers).to.deep.include(result.peer);
203+
});
204+
205+
it("should throw an error when no peer matches the given protocols", async function () {
206+
const mockPeers = [
207+
{ id: await createSecp256k1PeerId(), protocols: ["DifferentCodec"] },
208+
{
209+
id: await createSecp256k1PeerId(),
210+
protocols: ["AnotherDifferentCodec"]
211+
}
212+
] as Peer[];
213+
214+
sinon.stub(peerStore, "forEach").callsFake(async (callback) => {
215+
for (const peer of mockPeers) {
216+
callback(peer);
217+
}
218+
});
219+
220+
await expect(
221+
selectPeerForProtocol(peerStore, peerPings, protocols)
222+
).to.be.rejectedWith(
223+
`Failed to find known peer that registers protocols: ${protocols}`
224+
);
225+
});
226+
227+
it("should throw an error when the selected peer does not register the required protocols", async function () {
228+
const targetPeer = await createSecp256k1PeerId();
229+
const mockPeer = { id: targetPeer, protocols: ["DifferentCodec"] } as Peer;
230+
sinon.stub(peerStore, "get").withArgs(targetPeer).resolves(mockPeer);
231+
232+
await expect(
233+
selectPeerForProtocol(peerStore, peerPings, protocols, targetPeer)
234+
).to.be.rejectedWith(
235+
`Peer does not register required protocols (${targetPeer.toString()}): ${protocols}`
236+
);
237+
});
238+
});

0 commit comments

Comments
 (0)