chore: run tests in parallel (#1655)

* run tests in parallel

* small fixes

* small fixes

* fix setup of nodes

* fix relay tests

* fix Static Sharding: Running Nodes tests

* try with 5 threads

* try with 6 threads

* use startWithRetries as default start

* revert to 6

* set 10 jobs

* revert to back to 6

* add CI info in readme
This commit is contained in:
Florin Barbu 2023-10-13 12:36:43 +03:00 committed by GitHub
parent 9f14dab626
commit 347cbfa08a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
31 changed files with 259 additions and 221 deletions

View File

@ -7,5 +7,7 @@
"loader=ts-node/esm" "loader=ts-node/esm"
], ],
"exit": true, "exit": true,
"retries": 3 "retries": 4,
"parallel": true,
"jobs": 6
} }

View File

@ -39,3 +39,10 @@ Therefore, you need to have `docker` installed on your machine to run the tests.
```bash ```bash
WAKUNODE_IMAGE=image-name npm run test:node WAKUNODE_IMAGE=image-name npm run test:node
``` ```
# Running tests in the CI
- Tests are being run on standard Ubuntu GitHub Actions instances.
- To speed up execution, we run tests in parallel. After numerous attempts, we determined that using 6 threads strikes the best balance between execution speed and test reliability. Using more than this doesn't significantly decrease execution time and might even slow it down.
- To address occasional test flakiness, primarily due to Docker containers starting and stopping for each test and the concurrent execution of tests, we utilize the Mocha retry mechanism.

View File

@ -44,6 +44,7 @@ export class MessageCollector {
if (typeof message.payload === "string") { if (typeof message.payload === "string") {
return message.payload === text; return message.payload === text;
} else if (message.payload instanceof Uint8Array) { } else if (message.payload instanceof Uint8Array) {
log(`Checking payload: ${bytesToUtf8(message.payload)}`);
return isEqual(message.payload, utf8ToBytes(text)); return isEqual(message.payload, utf8ToBytes(text));
} }
return false; return false;

View File

@ -18,7 +18,6 @@ export default class Dockerode {
public containerId?: string; public containerId?: string;
private static network: Docker.Network; private static network: Docker.Network;
private static lastUsedIp = "172.18.0.1";
private containerIp: string; private containerIp: string;
private constructor(imageName: string, containerIp: string) { private constructor(imageName: string, containerIp: string) {
@ -70,15 +69,14 @@ export default class Dockerode {
} }
private static getNextIp(): string { private static getNextIp(): string {
const ipFragments = Dockerode.lastUsedIp.split("."); const baseIpFragments = "172.18".split(".");
let lastFragment = Number(ipFragments[3]); // Generate a random number between 0 and 255 for the last two fragments.
lastFragment++; const secondLastFragment = Math.floor(Math.random() * 256); // For the .0 fragment
if (lastFragment > 254) { const lastFragment = Math.floor(Math.random() * 256); // For the last fragment
throw new Error("IP Address Range Exhausted"); const newIp = [...baseIpFragments, secondLastFragment, lastFragment].join(
} "."
ipFragments[3] = lastFragment.toString(); );
Dockerode.lastUsedIp = ipFragments.join("."); return newIp;
return Dockerode.lastUsedIp;
} }
get container(): Docker.Container | undefined { get container(): Docker.Container | undefined {
@ -159,18 +157,19 @@ export default class Dockerode {
} }
async stop(): Promise<void> { async stop(): Promise<void> {
if (!this.container) throw "containerId not set"; if (!this.container) {
log("ContainerId not set");
} else {
log(
`Shutting down container ID ${
this.containerId
} at ${new Date().toLocaleTimeString()}`
);
log( await this.container.stop();
`Shutting down container ID ${
this.containerId
} at ${new Date().toLocaleTimeString()}`
);
await this.container.stop(); delete this.containerId;
await this.container.remove(); }
delete this.containerId;
} }
private async confirmImageExistsOrPull(): Promise<void> { private async confirmImageExistsOrPull(): Promise<void> {

View File

@ -86,86 +86,8 @@ export class NimGoNode {
return isGoWaku ? "go-waku" : "nwaku"; return isGoWaku ? "go-waku" : "nwaku";
} }
async start(args: Args = {}): Promise<void> { async start(
this.docker = await Dockerode.createInstance(DOCKER_IMAGE_NAME); args: Args = {},
try {
await existsAsync(LOG_DIR);
} catch (e) {
try {
await mkdirAsync(LOG_DIR);
} catch (e) {
// Looks like 2 tests tried to create the director at the same time,
// it can be ignored
}
}
await openAsync(this.logPath, "w");
const mergedArgs = defaultArgs();
// waku nodes takes some time to bind port so to decrease chances of conflict
// we also randomize the first port that portfinder will try
const startPort = Math.floor(Math.random() * (65535 - 1025) + 1025);
const ports: number[] = await new Promise((resolve, reject) => {
portfinder.getPorts(4, { port: startPort }, (err, ports) => {
if (err) reject(err);
resolve(ports);
});
});
if (isGoWaku && !args.logLevel) {
args.logLevel = LogLevel.Debug;
}
const [rpcPort, tcpPort, websocketPort, discv5UdpPort] = ports;
this.rpcPort = rpcPort;
this.websocketPort = websocketPort;
// `legacyFilter` is required to enable filter v1 with go-waku
const { legacyFilter = false, ..._args } = args;
// Object.assign overrides the properties with the source (if there are conflicts)
Object.assign(
mergedArgs,
{
rpcPort,
tcpPort,
websocketPort,
...(args?.peerExchange && { discv5UdpPort }),
...(isGoWaku && { minRelayPeersToPublish: 0, legacyFilter })
},
{ rpcAddress: "0.0.0.0" },
_args
);
process.env.WAKUNODE2_STORE_MESSAGE_DB_URL = "";
if (this.docker.container) {
await this.docker.stop();
}
await this.docker.startContainer(
ports,
mergedArgs,
this.logPath,
WAKU_SERVICE_NODE_PARAMS
);
try {
log(`Waiting to see '${NODE_READY_LOG_LINE}' in ${this.type} logs`);
await this.waitForLog(NODE_READY_LOG_LINE, 15000);
if (process.env.CI) await delay(100);
log(`${this.type} node has been started`);
} catch (error) {
log(`Error starting ${this.type}: ${error}`);
if (this.docker.container) await this.docker.stop();
throw error;
}
}
async startWithRetries(
args: Args,
options: { options: {
retries?: number; retries?: number;
} = { retries: 3 } } = { retries: 3 }
@ -173,9 +95,83 @@ export class NimGoNode {
await pRetry( await pRetry(
async () => { async () => {
try { try {
await this.start(args); this.docker = await Dockerode.createInstance(DOCKER_IMAGE_NAME);
try {
await existsAsync(LOG_DIR);
} catch (e) {
try {
await mkdirAsync(LOG_DIR);
} catch (e) {
// Looks like 2 tests tried to create the director at the same time,
// it can be ignored
}
}
await openAsync(this.logPath, "w");
const mergedArgs = defaultArgs();
// waku nodes takes some time to bind port so to decrease chances of conflict
// we also randomize the first port that portfinder will try
const startPort = Math.floor(Math.random() * (65535 - 1025) + 1025);
const ports: number[] = await new Promise((resolve, reject) => {
portfinder.getPorts(4, { port: startPort }, (err, ports) => {
if (err) reject(err);
resolve(ports);
});
});
if (isGoWaku && !args.logLevel) {
args.logLevel = LogLevel.Debug;
}
const [rpcPort, tcpPort, websocketPort, discv5UdpPort] = ports;
this.rpcPort = rpcPort;
this.websocketPort = websocketPort;
// `legacyFilter` is required to enable filter v1 with go-waku
const { legacyFilter = false, ..._args } = args;
// Object.assign overrides the properties with the source (if there are conflicts)
Object.assign(
mergedArgs,
{
rpcPort,
tcpPort,
websocketPort,
...(args?.peerExchange && { discv5UdpPort }),
...(isGoWaku && { minRelayPeersToPublish: 0, legacyFilter })
},
{ rpcAddress: "0.0.0.0" },
_args
);
process.env.WAKUNODE2_STORE_MESSAGE_DB_URL = "";
if (this.docker.container) {
await this.docker.stop();
}
await this.docker?.startContainer(
ports,
mergedArgs,
this.logPath,
WAKU_SERVICE_NODE_PARAMS
);
} catch (error) { } catch (error) {
log("Nwaku node failed to start:", error); log("Nwaku node failed to start:", error);
await this.stop();
throw error;
}
try {
log(`Waiting to see '${NODE_READY_LOG_LINE}' in ${this.type} logs`);
await this.waitForLog(NODE_READY_LOG_LINE, 15000);
if (process.env.CI) await delay(100);
log(`${this.type} node has been started`);
} catch (error) {
log(`Error starting ${this.type}: ${error}`);
if (this.docker.container) await this.docker.stop();
throw error; throw error;
} }
}, },
@ -184,7 +180,7 @@ export class NimGoNode {
} }
public async stop(): Promise<void> { public async stop(): Promise<void> {
await this.docker?.container?.stop(); await this.docker?.stop();
delete this.docker; delete this.docker;
} }
@ -381,20 +377,31 @@ export class NimGoNode {
method: string, method: string,
params: Array<string | number | unknown> params: Array<string | number | unknown>
): Promise<T> { ): Promise<T> {
log("RPC Query: ", method, params); return await pRetry(
const res = await fetch(this.rpcUrl, { async () => {
method: "POST", try {
body: JSON.stringify({ log("RPC Query: ", method, params);
jsonrpc: "2.0", const res = await fetch(this.rpcUrl, {
id: 1, method: "POST",
method, body: JSON.stringify({
params jsonrpc: "2.0",
}), id: 1,
headers: new Headers({ "Content-Type": "application/json" }) method,
}); params
const json = await res.json(); }),
log(`RPC Response: `, JSON.stringify(json)); headers: new Headers({ "Content-Type": "application/json" })
return json.result; });
const json = await res.json();
log(`RPC Response: `, JSON.stringify(json));
return json.result;
} catch (error) {
log(`${this.rpcUrl} failed with error:`, error);
await delay(10);
throw error;
}
},
{ retries: 5 }
);
} }
private checkProcess(): void { private checkProcess(): void {

View File

@ -1,4 +1,4 @@
import { LightNode } from "@waku/interfaces"; import { Waku } from "@waku/interfaces";
import debug from "debug"; import debug from "debug";
import pRetry from "p-retry"; import pRetry from "p-retry";
@ -8,7 +8,7 @@ const log = debug("waku:test");
export async function tearDownNodes( export async function tearDownNodes(
nwakuNodes: NimGoNode | NimGoNode[], nwakuNodes: NimGoNode | NimGoNode[],
wakuNodes: LightNode | LightNode[] wakuNodes: Waku | Waku[]
): Promise<void> { ): Promise<void> {
const nNodes = Array.isArray(nwakuNodes) ? nwakuNodes : [nwakuNodes]; const nNodes = Array.isArray(nwakuNodes) ? nwakuNodes : [nwakuNodes];
const wNodes = Array.isArray(wakuNodes) ? wakuNodes : [wakuNodes]; const wNodes = Array.isArray(wakuNodes) ? wakuNodes : [wakuNodes];

View File

@ -6,6 +6,7 @@ import { expect } from "chai";
import sinon, { SinonSpy, SinonStub } from "sinon"; import sinon, { SinonSpy, SinonStub } from "sinon";
import { delay } from "../dist/delay.js"; import { delay } from "../dist/delay.js";
import { tearDownNodes } from "../src/index.js";
const TEST_TIMEOUT = 10_000; const TEST_TIMEOUT = 10_000;
const DELAY_MS = 1_000; const DELAY_MS = 1_000;
@ -18,7 +19,8 @@ describe("ConnectionManager", function () {
}); });
afterEach(async () => { afterEach(async () => {
await waku.stop(); this.timeout(15000);
await tearDownNodes([], waku);
}); });
describe("Events", () => { describe("Events", () => {
@ -161,7 +163,7 @@ describe("ConnectionManager", function () {
afterEach(async () => { afterEach(async () => {
this.timeout(15000); this.timeout(15000);
await waku.stop(); await tearDownNodes([], waku);
isPeerTopicConfigured.restore(); isPeerTopicConfigured.restore();
sinon.restore(); sinon.restore();
}); });

View File

@ -5,7 +5,7 @@ import { Protocols } from "@waku/interfaces";
import { createRelayNode } from "@waku/sdk"; import { createRelayNode } from "@waku/sdk";
import { expect } from "chai"; import { expect } from "chai";
import { makeLogFileName, NOISE_KEY_1 } from "../src/index.js"; import { makeLogFileName, NOISE_KEY_1, tearDownNodes } from "../src/index.js";
import { NimGoNode } from "../src/node/node.js"; import { NimGoNode } from "../src/node/node.js";
describe("ENR Interop: NimGoNode", function () { describe("ENR Interop: NimGoNode", function () {
@ -13,9 +13,8 @@ describe("ENR Interop: NimGoNode", function () {
let nwaku: NimGoNode; let nwaku: NimGoNode;
afterEach(async function () { afterEach(async function () {
!!nwaku && this.timeout(15000);
nwaku.stop().catch((e) => console.log("Nwaku failed to stop", e)); await tearDownNodes(nwaku, waku);
!!waku && waku.stop().catch((e) => console.log("Waku failed to stop", e));
}); });
it("Relay", async function () { it("Relay", async function () {

View File

@ -26,7 +26,8 @@ import {
delay, delay,
makeLogFileName, makeLogFileName,
NOISE_KEY_1, NOISE_KEY_1,
NOISE_KEY_2 NOISE_KEY_2,
tearDownNodes
} from "../src/index.js"; } from "../src/index.js";
import { NimGoNode } from "../src/node/node.js"; import { NimGoNode } from "../src/node/node.js";
@ -45,9 +46,8 @@ describe("Waku Message Ephemeral field", () => {
let subscription: IFilterSubscription; let subscription: IFilterSubscription;
afterEach(async function () { afterEach(async function () {
!!nwaku && this.timeout(15000);
nwaku.stop().catch((e) => console.log("Nwaku failed to stop", e)); await tearDownNodes(nwaku, waku);
!!waku && waku.stop().catch((e) => console.log("Waku failed to stop", e));
}); });
beforeEach(async function () { beforeEach(async function () {
@ -165,8 +165,7 @@ describe("Waku Message Ephemeral field", () => {
expect(messages?.length).eq(0); expect(messages?.length).eq(0);
!!waku1 && waku1.stop().catch((e) => console.log("Waku failed to stop", e)); await tearDownNodes([], [waku1, waku2]);
!!waku2 && waku2.stop().catch((e) => console.log("Waku failed to stop", e));
}); });
it("Ephemeral field is preserved - encoder v0", async function () { it("Ephemeral field is preserved - encoder v0", async function () {

View File

@ -265,7 +265,7 @@ describe("Waku Filter V2: FilterPush", function () {
expect(await messageCollector.waitForMessages(1)).to.eq(true); expect(await messageCollector.waitForMessages(1)).to.eq(true);
// Restart nwaku node // Restart nwaku node
await nwaku.stop(); await tearDownNodes(nwaku, []);
await nwaku.start(); await nwaku.start();
await waitForRemotePeer(waku, [Protocols.Filter, Protocols.LightPush]); await waitForRemotePeer(waku, [Protocols.Filter, Protocols.LightPush]);

View File

@ -321,7 +321,11 @@ describe("Waku Filter V2: Subscribe", function () {
// Set up and start a new nwaku node // Set up and start a new nwaku node
nwaku2 = new NimGoNode(makeLogFileName(this) + "2"); nwaku2 = new NimGoNode(makeLogFileName(this) + "2");
await nwaku2.start({ filter: true, lightpush: true, relay: true }); await nwaku2.start({
filter: true,
lightpush: true,
relay: true
});
await waku.dial(await nwaku2.getMultiaddrWithId()); await waku.dial(await nwaku2.getMultiaddrWithId());
await waitForRemotePeer(waku, [Protocols.Filter, Protocols.LightPush]); await waitForRemotePeer(waku, [Protocols.Filter, Protocols.LightPush]);
const subscription2 = await waku.filter.createSubscription( const subscription2 = await waku.filter.createSubscription(

View File

@ -69,7 +69,7 @@ export async function runNodes(
): Promise<[NimGoNode, LightNode]> { ): Promise<[NimGoNode, LightNode]> {
const nwaku = new NimGoNode(makeLogFileName(context)); const nwaku = new NimGoNode(makeLogFileName(context));
await nwaku.startWithRetries( await nwaku.start(
{ {
filter: true, filter: true,
lightpush: true, lightpush: true,

View File

@ -17,7 +17,7 @@ export async function runNodes(
pubSubTopics: string[] pubSubTopics: string[]
): Promise<[NimGoNode, LightNode]> { ): Promise<[NimGoNode, LightNode]> {
const nwaku = new NimGoNode(makeLogFileName(context)); const nwaku = new NimGoNode(makeLogFileName(context));
await nwaku.startWithRetries( await nwaku.start(
{ lightpush: true, relay: true, topic: pubSubTopics }, { lightpush: true, relay: true, topic: pubSubTopics },
{ retries: 3 } { retries: 3 }
); );

View File

@ -3,16 +3,15 @@ import type { Waku } from "@waku/interfaces";
import { createLightNode } from "@waku/sdk"; import { createLightNode } from "@waku/sdk";
import { expect } from "chai"; import { expect } from "chai";
import { NimGoNode } from "../src/index.js"; import { NimGoNode, tearDownNodes } from "../src/index.js";
describe("dials multiaddr", function () { describe("dials multiaddr", function () {
let waku: Waku; let waku: Waku;
let nwaku: NimGoNode; let nwaku: NimGoNode;
afterEach(async function () { afterEach(async function () {
!!nwaku && this.timeout(15000);
nwaku.stop().catch((e) => console.log("Nwaku failed to stop", e)); await tearDownNodes(nwaku, waku);
!!waku && waku.stop().catch((e) => console.log("Waku failed to stop", e));
}); });
it("TLS", async function () { it("TLS", async function () {

View File

@ -9,6 +9,7 @@ import { createLightNode, Libp2pComponents } from "@waku/sdk";
import { expect } from "chai"; import { expect } from "chai";
import { delay } from "../src/delay.js"; import { delay } from "../src/delay.js";
import { tearDownNodes } from "../src/index.js";
import { makeLogFileName } from "../src/log_file.js"; import { makeLogFileName } from "../src/log_file.js";
import { NimGoNode } from "../src/node/node.js"; import { NimGoNode } from "../src/node/node.js";
@ -24,10 +25,8 @@ describe("Peer Exchange", () => {
}); });
afterEach(async function () { afterEach(async function () {
this.timeout(10_000); this.timeout(15000);
await nwaku1?.stop(); await tearDownNodes([nwaku1, nwaku2], waku);
await nwaku2?.stop();
await waku?.stop();
}); });
it("nwaku interop", async function () { it("nwaku interop", async function () {
@ -126,9 +125,8 @@ describe("Peer Exchange", () => {
return new PeerExchangeDiscovery(waku.libp2p.components); return new PeerExchangeDiscovery(waku.libp2p.components);
}, },
teardown: async () => { teardown: async () => {
await nwaku1?.stop(); this.timeout(15000);
await nwaku2?.stop(); await tearDownNodes([nwaku1, nwaku2], waku);
await waku?.stop();
} }
}); });
}); });

View File

@ -8,12 +8,15 @@ import { wakuPeerExchangeDiscovery } from "@waku/peer-exchange";
import { createLightNode } from "@waku/sdk"; import { createLightNode } from "@waku/sdk";
import { expect } from "chai"; import { expect } from "chai";
import { tearDownNodes } from "../src";
describe("Peer Exchange", () => { describe("Peer Exchange", () => {
describe("Auto Discovery", function () { describe("Auto Discovery", function () {
let waku: LightNode; let waku: LightNode;
afterEach(async function () { afterEach(async function () {
await waku?.stop(); this.timeout(15000);
await tearDownNodes([], waku);
}); });
const testCases: [Fleet, number][] = [ const testCases: [Fleet, number][] = [

View File

@ -30,7 +30,8 @@ import {
MessageCollector, MessageCollector,
NOISE_KEY_1, NOISE_KEY_1,
NOISE_KEY_2, NOISE_KEY_2,
NOISE_KEY_3 NOISE_KEY_3,
tearDownNodes
} from "../src/index.js"; } from "../src/index.js";
import { MessageRpcResponse } from "../src/node/interfaces.js"; import { MessageRpcResponse } from "../src/node/interfaces.js";
import { base64ToUtf8, NimGoNode } from "../src/node/node.js"; import { base64ToUtf8, NimGoNode } from "../src/node/node.js";
@ -369,12 +370,24 @@ describe("Waku Relay [node only]", () => {
true true
); );
expect(msgCollector1.hasMessage(testItem.pubsub, "M2")).to.be.true; expect(
expect(msgCollector1.hasMessage(testItem.pubsub, "M3")).to.be.true; msgCollector1.hasMessage(testItem.encoder.contentTopic, "M2")
expect(msgCollector2.hasMessage(testItem.pubsub, "M1")).to.be.true; ).to.eq(true);
expect(msgCollector2.hasMessage(testItem.pubsub, "M3")).to.be.true; expect(
expect(msgCollector3.hasMessage(testItem.pubsub, "M1")).to.be.true; msgCollector1.hasMessage(testItem.encoder.contentTopic, "M3")
expect(msgCollector3.hasMessage(testItem.pubsub, "M2")).to.be.true; ).to.eq(true);
expect(
msgCollector2.hasMessage(testItem.encoder.contentTopic, "M1")
).to.eq(true);
expect(
msgCollector2.hasMessage(testItem.encoder.contentTopic, "M3")
).to.eq(true);
expect(
msgCollector3.hasMessage(testItem.encoder.contentTopic, "M1")
).to.eq(true);
expect(
msgCollector3.hasMessage(testItem.encoder.contentTopic, "M2")
).to.eq(true);
}); });
}); });
@ -447,16 +460,14 @@ describe("Waku Relay [node only]", () => {
expect(await msgCollector3.waitForMessages(2, { exact: true })).to.eq( expect(await msgCollector3.waitForMessages(2, { exact: true })).to.eq(
true true
); );
expect(msgCollector1.hasMessage(TestContentTopic, "M3")).to.eq(true);
expect(msgCollector1.hasMessage(DefaultPubSubTopic, "M3")).to.be.true; expect(msgCollector1.hasMessage(CustomContentTopic, "M4")).to.eq(true);
expect(msgCollector1.hasMessage(CustomPubSubTopic, "M4")).to.be.true; expect(msgCollector1.hasMessage(TestContentTopic, "M5")).to.eq(true);
expect(msgCollector1.hasMessage(DefaultPubSubTopic, "M5")).to.be.true; expect(msgCollector2.hasMessage(TestContentTopic, "M1")).to.eq(true);
expect(msgCollector1.hasMessage(DefaultPubSubTopic, "M1")).to.be.true; expect(msgCollector2.hasMessage(CustomContentTopic, "M2")).to.eq(true);
expect(msgCollector1.hasMessage(CustomPubSubTopic, "M2")).to.be.true; expect(msgCollector2.hasMessage(TestContentTopic, "M5")).to.eq(true);
expect(msgCollector1.hasMessage(DefaultPubSubTopic, "M5")).to.be.true; expect(msgCollector3.hasMessage(TestContentTopic, "M1")).to.eq(true);
expect(msgCollector2.hasMessage(CustomPubSubTopic, "M1")).to.be.true; expect(msgCollector3.hasMessage(TestContentTopic, "M3")).to.eq(true);
expect(msgCollector2.hasMessage(DefaultPubSubTopic, "M3")).to.be.true;
expect(msgCollector3.hasMessage(DefaultPubSubTopic, "M1")).to.be.true;
}); });
it("n1 and n2 uses a custom pubsub, n3 uses the default pubsub", async function () { it("n1 and n2 uses a custom pubsub, n3 uses the default pubsub", async function () {
@ -602,9 +613,8 @@ describe("Waku Relay [node only]", () => {
}); });
afterEach(async function () { afterEach(async function () {
!!nwaku && this.timeout(15000);
nwaku.stop().catch((e) => console.log("Nwaku failed to stop", e)); await tearDownNodes(nwaku, waku);
!!waku && waku.stop().catch((e) => console.log("Waku failed to stop", e));
}); });
it("nwaku subscribes", async function () { it("nwaku subscribes", async function () {
@ -674,12 +684,7 @@ describe("Waku Relay [node only]", () => {
let nwaku: NimGoNode; let nwaku: NimGoNode;
afterEach(async function () { afterEach(async function () {
!!nwaku && await tearDownNodes(nwaku, [waku1, waku2]);
nwaku.stop().catch((e) => console.log("Nwaku failed to stop", e));
!!waku1 &&
waku1.stop().catch((e) => console.log("Waku failed to stop", e));
!!waku2 &&
waku2.stop().catch((e) => console.log("Waku failed to stop", e));
}); });
it("Js publishes, other Js receives", async function () { it("Js publishes, other Js receives", async function () {

View File

@ -9,6 +9,7 @@ import Sinon, { SinonSpy } from "sinon";
import { delay } from "../../src/delay.js"; import { delay } from "../../src/delay.js";
import { makeLogFileName } from "../../src/log_file.js"; import { makeLogFileName } from "../../src/log_file.js";
import { NimGoNode } from "../../src/node/node.js"; import { NimGoNode } from "../../src/node/node.js";
import { tearDownNodes } from "../../src/teardown.js";
chai.use(chaiAsPromised); chai.use(chaiAsPromised);
@ -22,18 +23,15 @@ describe("Static Sharding: Peer Management", function () {
let attemptDialSpy: SinonSpy; let attemptDialSpy: SinonSpy;
beforeEach(async function () { beforeEach(async function () {
this.timeout(15000);
nwaku1 = new NimGoNode(makeLogFileName(this) + "1"); nwaku1 = new NimGoNode(makeLogFileName(this) + "1");
nwaku2 = new NimGoNode(makeLogFileName(this) + "2"); nwaku2 = new NimGoNode(makeLogFileName(this) + "2");
nwaku3 = new NimGoNode(makeLogFileName(this) + "3"); nwaku3 = new NimGoNode(makeLogFileName(this) + "3");
}); });
afterEach(async function () { afterEach(async function () {
this.timeout(5_000); this.timeout(15000);
await nwaku1?.stop(); await tearDownNodes([nwaku1, nwaku2, nwaku3], waku);
await nwaku2?.stop();
await nwaku3?.stop();
!!waku && waku.stop().catch((e) => console.log("Waku failed to stop", e));
attemptDialSpy && attemptDialSpy.restore(); attemptDialSpy && attemptDialSpy.restore();
}); });

View File

@ -2,6 +2,7 @@ import { LightNode } from "@waku/interfaces";
import { createEncoder, createLightNode, utf8ToBytes } from "@waku/sdk"; import { createEncoder, createLightNode, utf8ToBytes } from "@waku/sdk";
import { expect } from "chai"; import { expect } from "chai";
import { tearDownNodes } from "../../src/index.js";
import { makeLogFileName } from "../../src/log_file.js"; import { makeLogFileName } from "../../src/log_file.js";
import { NimGoNode } from "../../src/node/node.js"; import { NimGoNode } from "../../src/node/node.js";
@ -21,9 +22,8 @@ describe("Static Sharding: Running Nodes", () => {
}); });
afterEach(async function () { afterEach(async function () {
!!nwaku && this.timeout(15000);
nwaku.stop().catch((e) => console.log("Nwaku failed to stop", e)); await tearDownNodes(nwaku, waku);
!!waku && waku.stop().catch((e) => console.log("Waku failed to stop", e));
}); });
it("configure the node with multiple pubsub topics", async function () { it("configure the node with multiple pubsub topics", async function () {
@ -42,16 +42,16 @@ describe("Static Sharding: Running Nodes", () => {
pubSubTopic: PubSubTopic2 pubSubTopic: PubSubTopic2
}); });
const request1 = waku.lightPush.send(encoder1, { const request1 = await waku.lightPush.send(encoder1, {
payload: utf8ToBytes("Hello World") payload: utf8ToBytes("Hello World")
}); });
const request2 = waku.lightPush.send(encoder2, { const request2 = await waku.lightPush.send(encoder2, {
payload: utf8ToBytes("Hello World") payload: utf8ToBytes("Hello World")
}); });
await expect(request1).to.be.fulfilled; expect(request1.recipients.length).to.eq(0);
await expect(request2).to.be.fulfilled; expect(request2.recipients.length).to.eq(0);
}); });
it("using a protocol with unconfigured pubsub topic should fail", async function () { it("using a protocol with unconfigured pubsub topic should fail", async function () {
@ -66,11 +66,20 @@ describe("Static Sharding: Running Nodes", () => {
pubSubTopic: PubSubTopic2 pubSubTopic: PubSubTopic2
}); });
// the following request should throw an error try {
const request = waku.lightPush.send(encoder, { await waku.lightPush.send(encoder, {
payload: utf8ToBytes("Hello World") payload: utf8ToBytes("Hello World")
}); });
throw new Error("The request should've thrown an error");
await expect(request).to.be.rejectedWith(Error); } catch (err) {
if (
!(err instanceof Error) ||
!err.message.includes(
`PubSub topic ${PubSubTopic2} has not been configured on this instance. Configured topics are: ${PubSubTopic1}`
)
) {
throw err;
}
}
}); });
}); });

View File

@ -23,7 +23,7 @@ describe("Waku Store, cursor", function () {
beforeEach(async function () { beforeEach(async function () {
this.timeout(15000); this.timeout(15000);
nwaku = new NimGoNode(makeLogFileName(this)); nwaku = new NimGoNode(makeLogFileName(this));
await nwaku.startWithRetries({ store: true, lightpush: true, relay: true }); await nwaku.start({ store: true, lightpush: true, relay: true });
await nwaku.ensureSubscriptions(); await nwaku.ensureSubscriptions();
}); });

View File

@ -20,7 +20,7 @@ describe("Waku Store, error handling", function () {
beforeEach(async function () { beforeEach(async function () {
this.timeout(15000); this.timeout(15000);
nwaku = new NimGoNode(makeLogFileName(this)); nwaku = new NimGoNode(makeLogFileName(this));
await nwaku.startWithRetries({ store: true, lightpush: true, relay: true }); await nwaku.start({ store: true, lightpush: true, relay: true });
await nwaku.ensureSubscriptions(); await nwaku.ensureSubscriptions();
waku = await startAndConnectLightNode(nwaku); waku = await startAndConnectLightNode(nwaku);
}); });

View File

@ -54,7 +54,7 @@ describe("Waku Store, general", function () {
beforeEach(async function () { beforeEach(async function () {
this.timeout(15000); this.timeout(15000);
nwaku = new NimGoNode(makeLogFileName(this)); nwaku = new NimGoNode(makeLogFileName(this));
await nwaku.startWithRetries({ store: true, lightpush: true, relay: true }); await nwaku.start({ store: true, lightpush: true, relay: true });
await nwaku.ensureSubscriptions(); await nwaku.ensureSubscriptions();
}); });
@ -91,7 +91,7 @@ describe("Waku Store, general", function () {
}), }),
DefaultPubSubTopic DefaultPubSubTopic
) )
).to.be.true; ).to.eq(true);
await delay(1); // to ensure each timestamp is unique. await delay(1); // to ensure each timestamp is unique.
} }
@ -148,7 +148,7 @@ describe("Waku Store, general", function () {
}), }),
DefaultPubSubTopic DefaultPubSubTopic
) )
).to.be.true; ).to.eq(true);
await delay(1); // to ensure each timestamp is unique. await delay(1); // to ensure each timestamp is unique.
} }

View File

@ -21,7 +21,7 @@ describe("Waku Store, order", function () {
beforeEach(async function () { beforeEach(async function () {
this.timeout(15000); this.timeout(15000);
nwaku = new NimGoNode(makeLogFileName(this)); nwaku = new NimGoNode(makeLogFileName(this));
await nwaku.startWithRetries({ store: true, lightpush: true, relay: true }); await nwaku.start({ store: true, lightpush: true, relay: true });
await nwaku.ensureSubscriptions(); await nwaku.ensureSubscriptions();
}); });

View File

@ -19,7 +19,7 @@ describe("Waku Store, page size", function () {
beforeEach(async function () { beforeEach(async function () {
this.timeout(15000); this.timeout(15000);
nwaku = new NimGoNode(makeLogFileName(this)); nwaku = new NimGoNode(makeLogFileName(this));
await nwaku.startWithRetries({ store: true, lightpush: true, relay: true }); await nwaku.start({ store: true, lightpush: true, relay: true });
await nwaku.ensureSubscriptions(); await nwaku.ensureSubscriptions();
}); });

View File

@ -19,7 +19,7 @@ describe("Waku Store, sorting", function () {
beforeEach(async function () { beforeEach(async function () {
this.timeout(15000); this.timeout(15000);
nwaku = new NimGoNode(makeLogFileName(this)); nwaku = new NimGoNode(makeLogFileName(this));
await nwaku.startWithRetries({ store: true, lightpush: true, relay: true }); await nwaku.start({ store: true, lightpush: true, relay: true });
await nwaku.ensureSubscriptions(); await nwaku.ensureSubscriptions();
}); });

View File

@ -18,7 +18,7 @@ describe("Waku Store, time filter", function () {
beforeEach(async function () { beforeEach(async function () {
this.timeout(15000); this.timeout(15000);
nwaku = new NimGoNode(makeLogFileName(this)); nwaku = new NimGoNode(makeLogFileName(this));
await nwaku.startWithRetries({ store: true, lightpush: true, relay: true }); await nwaku.start({ store: true, lightpush: true, relay: true });
await nwaku.ensureSubscriptions(); await nwaku.ensureSubscriptions();
}); });
@ -48,7 +48,7 @@ describe("Waku Store, time filter", function () {
timestamp: msgTimestamp timestamp: msgTimestamp
}) })
) )
).to.be.true; ).to.eq(true);
waku = await startAndConnectLightNode(nwaku); waku = await startAndConnectLightNode(nwaku);
@ -93,7 +93,7 @@ describe("Waku Store, time filter", function () {
timestamp: msgTimestamp timestamp: msgTimestamp
}) })
) )
).to.be.true; ).to.eq(true);
waku = await startAndConnectLightNode(nwaku); waku = await startAndConnectLightNode(nwaku);

View File

@ -42,7 +42,7 @@ export async function sendMessages(
}), }),
pubSubTopic pubSubTopic
) )
).to.be.true; ).to.eq(true);
await delay(1); // to ensure each timestamp is unique. await delay(1); // to ensure each timestamp is unique.
} }
} }

View File

@ -38,7 +38,11 @@ describe("Util: toAsyncIterator: Filter", () => {
beforeEach(async function () { beforeEach(async function () {
this.timeout(15000); this.timeout(15000);
nwaku = new NimGoNode(makeLogFileName(this)); nwaku = new NimGoNode(makeLogFileName(this));
await nwaku.start({ filter: true, lightpush: true, relay: true }); await nwaku.start({
filter: true,
lightpush: true,
relay: true
});
waku = await createLightNode({ waku = await createLightNode({
staticNoiseKey: NOISE_KEY_1, staticNoiseKey: NOISE_KEY_1,
libp2p: { addresses: { listen: ["/ip4/0.0.0.0/tcp/0/ws"] } } libp2p: { addresses: { listen: ["/ip4/0.0.0.0/tcp/0/ws"] } }

View File

@ -4,21 +4,22 @@ import { Protocols } from "@waku/interfaces";
import { createLightNode, createRelayNode } from "@waku/sdk"; import { createLightNode, createRelayNode } from "@waku/sdk";
import { expect } from "chai"; import { expect } from "chai";
import { delay, makeLogFileName, NOISE_KEY_1 } from "../src/index.js"; import {
delay,
makeLogFileName,
NOISE_KEY_1,
tearDownNodes
} from "../src/index.js";
import { NimGoNode } from "../src/node/node.js"; import { NimGoNode } from "../src/node/node.js";
describe("Wait for remote peer", function () { describe("Wait for remote peer", function () {
let waku1: RelayNode; let waku1: RelayNode;
let waku2: LightNode; let waku2: LightNode;
let nwaku: NimGoNode | undefined; let nwaku: NimGoNode;
afterEach(async function () { afterEach(async function () {
if (nwaku) { this.timeout(15000);
nwaku.stop().catch((e) => console.log("Nwaku failed to stop", e)); await tearDownNodes(nwaku, [waku1, waku2]);
nwaku = undefined;
}
waku1?.stop().catch((e) => console.log("Waku failed to stop", e));
waku2?.stop().catch((e) => console.log("Waku failed to stop", e));
}); });
it("Relay - dialed first", async function () { it("Relay - dialed first", async function () {

View File

@ -4,15 +4,15 @@ import { LightNode } from "@waku/interfaces";
import { createLightNode } from "@waku/sdk"; import { createLightNode } from "@waku/sdk";
import { expect } from "chai"; import { expect } from "chai";
import { makeLogFileName, NimGoNode } from "../src/index.js"; import { makeLogFileName, NimGoNode, tearDownNodes } from "../src/index.js";
describe("Use static and several ENR trees for bootstrap", function () { describe("Use static and several ENR trees for bootstrap", function () {
let waku: LightNode; let waku: LightNode;
let nwaku: NimGoNode; let nwaku: NimGoNode;
afterEach(async function () { afterEach(async function () {
!!nwaku && (await nwaku.stop()); this.timeout(15000);
!!waku && waku.stop().catch((e) => console.log("Waku failed to stop", e)); await tearDownNodes(nwaku, waku);
}); });
it("", async function () { it("", async function () {

View File

@ -90,7 +90,8 @@ describe("Waku Dial [node only]", function () {
}); });
await waku.start(); await waku.start();
await waku.dial(multiAddrWithId); await waku.dial(multiAddrWithId);
await nwaku.stop();
await tearDownNodes(nwaku, []);
await waku.lightPush?.send(TestEncoder, { await waku.lightPush?.send(TestEncoder, {
payload: utf8ToBytes("hello world") payload: utf8ToBytes("hello world")
}); });
@ -190,8 +191,8 @@ describe("Decryption Keys", () => {
}); });
afterEach(async function () { afterEach(async function () {
!!waku1 && waku1.stop().catch((e) => console.log("Waku failed to stop", e)); this.timeout(15000);
!!waku2 && waku2.stop().catch((e) => console.log("Waku failed to stop", e)); await tearDownNodes([], [waku1, waku2]);
}); });
it("Used by Waku Relay", async function () { it("Used by Waku Relay", async function () {
@ -232,8 +233,8 @@ describe("User Agent", () => {
let waku2: Waku; let waku2: Waku;
afterEach(async function () { afterEach(async function () {
!!waku1 && waku1.stop().catch((e) => console.log("Waku failed to stop", e)); this.timeout(15000);
!!waku2 && waku2.stop().catch((e) => console.log("Waku failed to stop", e)); await tearDownNodes([], [waku1, waku2]);
}); });
it("Sets default value correctly", async function () { it("Sets default value correctly", async function () {