From 6009af74537e15f96812b601e9ecbdd64a1a8f8b Mon Sep 17 00:00:00 2001 From: Arseniy Klempner Date: Thu, 15 Feb 2024 17:53:51 -0800 Subject: [PATCH] feat: migrates e2e tests to use rest instead of rpc --- packages/tests/src/constants.ts | 3 +- packages/tests/src/lib/index.ts | 27 ++- packages/tests/src/lib/service_node.ts | 169 ++++-------------- packages/tests/src/types.ts | 1 + packages/tests/tests/filter/push.node.spec.ts | 31 +--- .../filter/single_node/push.node.spec.ts | 110 +++++------- packages/tests/tests/filter/utils.ts | 10 +- packages/tests/tests/nwaku.node.spec.ts | 1 + 8 files changed, 97 insertions(+), 255 deletions(-) diff --git a/packages/tests/src/constants.ts b/packages/tests/src/constants.ts index ab2c4b8eea..bba66ecc84 100644 --- a/packages/tests/src/constants.ts +++ b/packages/tests/src/constants.ts @@ -58,8 +58,7 @@ export const TEST_TIMESTAMPS = [ BigInt(Date.now()) * BigInt(1000000), Date.now(), 1649153314, - 1949153314000, - undefined + 1949153314000 ]; export const MOCHA_HOOK_MAX_TIMEOUT = 50_000; diff --git a/packages/tests/src/lib/index.ts b/packages/tests/src/lib/index.ts index 631a56750a..5bcc9c947c 100644 --- a/packages/tests/src/lib/index.ts +++ b/packages/tests/src/lib/index.ts @@ -2,9 +2,10 @@ import { DecodedMessage } from "@waku/core"; import { DefaultPubsubTopic, PubsubTopic, + ShardInfo, ShardingParams } from "@waku/interfaces"; -import { Logger } from "@waku/utils"; +import { ensureShardingConfigured, Logger } from "@waku/utils"; import { expect } from "chai"; import { Args, MessageRpcQuery, MessageRpcResponse } from "../types"; @@ -27,7 +28,7 @@ export class ServiceNodesFleet { pubsubTopics: PubsubTopic[], nodesToCreate: number = 3, strictChecking: boolean = false, - shardInfo?: ShardingParams, + shardInfo?: ShardInfo, _args?: Args, withoutFilter = false ): Promise { @@ -39,6 +40,9 @@ export class ServiceNodesFleet { Math.random().toString(36).substring(7) ); + shardInfo = shardInfo + ? ensureShardingConfigured(shardInfo).shardInfo + : undefined; const args = getArgs(pubsubTopics, shardInfo, _args); await node.start(args, { retries: 3 @@ -100,22 +104,11 @@ export class ServiceNodesFleet { async sendRelayMessage( message: MessageRpcQuery, - pubsubTopic?: string, - raw = false + pubsubTopic: string = DefaultPubsubTopic ): Promise { - let relayMessagePromises: Promise[]; - if (raw) { - relayMessagePromises = this.nodes.map((node) => - node.rpcCall("post_waku_v2_relay_v1_message", [ - pubsubTopic && pubsubTopic, - message - ]) - ); - } else { - relayMessagePromises = this.nodes.map((node) => - node.sendMessage(message, pubsubTopic) - ); - } + const relayMessagePromises: Promise[] = this.nodes.map((node) => + node.sendMessage(message, pubsubTopic) + ); const relayMessages = await Promise.all(relayMessagePromises); return relayMessages.every((message) => message); } diff --git a/packages/tests/src/lib/service_node.ts b/packages/tests/src/lib/service_node.ts index 7006a8ad5a..2ce4eefe89 100644 --- a/packages/tests/src/lib/service_node.ts +++ b/packages/tests/src/lib/service_node.ts @@ -4,13 +4,11 @@ import { Multiaddr, multiaddr } from "@multiformats/multiaddr"; import { DefaultPubsubTopic } from "@waku/interfaces"; import { isDefined } from "@waku/utils"; import { Logger } from "@waku/utils"; -import { bytesToHex, hexToBytes } from "@waku/utils/bytes"; import pRetry from "p-retry"; import portfinder from "portfinder"; import { Args, - KeyPair, LogLevel, MessageRpcQuery, MessageRpcResponse, @@ -210,13 +208,26 @@ export class ServiceNode { async peers(): Promise { this.checkProcess(); - return this.rpcCall("get_waku_v2_admin_v1_peers", []); + return this.restCall( + "/admin/v1/peers", + "GET", + undefined, + async (response) => { + const data = await response.json(); + return data?.length ? data : []; + } + ); } async info(): Promise { this.checkProcess(); - return this.rpcCall("get_waku_v2_debug_v1_info", []); + return this.restCall( + "/debug/v1/info", + "GET", + undefined, + async (response) => await response.json() + ); } async ensureSubscriptions( @@ -233,9 +244,8 @@ export class ServiceNode { async messages( pubsubTopic: string = DefaultPubsubTopic ): Promise { - pubsubTopic = encodeURIComponent(pubsubTopic); return this.restCall( - `/relay/v1/messages/${pubsubTopic}`, + `/relay/v1/messages/${encodeURIComponent(pubsubTopic)}`, "GET", null, async (response) => { @@ -268,10 +278,12 @@ export class ServiceNode { message.timestamp = BigInt(new Date().valueOf()) * OneMillion; } - return this.rpcCall("post_waku_v2_relay_v1_message", [ - pubsubTopic, - message - ]); + return this.restCall( + `/relay/v1/messages/${encodeURIComponent(pubsubTopic)}`, + "POST", + message, + async (response) => response.status === 200 + ); } async sendMessageAutosharding(message: MessageRpcQuery): Promise { @@ -281,9 +293,12 @@ export class ServiceNode { message.timestamp = BigInt(new Date().valueOf()) * OneMillion; } - return this.rpcCall("post_waku_v2_relay_v1_auto_message", [ - message - ]); + return this.restCall( + `/relay/v1/auto/message`, + "POST", + message, + async (response) => response.status === 200 + ); } async messagesAutosharding( @@ -291,9 +306,8 @@ export class ServiceNode { ): Promise { this.checkProcess(); - contentTopic = encodeURIComponent(contentTopic); return this.restCall( - `/relay/v1/auto/messages/${contentTopic}`, + `/relay/v1/auto/messages/${encodeURIComponent(contentTopic)}`, "GET", null, async (response) => { @@ -303,99 +317,6 @@ export class ServiceNode { ); } - async getAsymmetricKeyPair(): Promise { - this.checkProcess(); - - const { privateKey, publicKey, seckey, pubkey } = await this.rpcCall<{ - seckey: string; - pubkey: string; - privateKey: string; - publicKey: string; - }>("get_waku_v2_private_v1_asymmetric_keypair", []); - - // To be removed once https://github.com/vacp2p/rfc/issues/507 is fixed - if (seckey) { - return { privateKey: seckey, publicKey: pubkey }; - } else { - return { privateKey, publicKey }; - } - } - - async postAsymmetricMessage( - message: MessageRpcQuery, - publicKey: Uint8Array, - pubsubTopic?: string - ): Promise { - this.checkProcess(); - - if (!message.payload) { - throw "Attempting to send empty message"; - } - - return this.rpcCall("post_waku_v2_private_v1_asymmetric_message", [ - pubsubTopic ? pubsubTopic : DefaultPubsubTopic, - message, - "0x" + bytesToHex(publicKey) - ]); - } - - async getAsymmetricMessages( - privateKey: Uint8Array, - pubsubTopic?: string - ): Promise { - this.checkProcess(); - - return await this.rpcCall( - "get_waku_v2_private_v1_asymmetric_messages", - [ - pubsubTopic ? pubsubTopic : DefaultPubsubTopic, - "0x" + bytesToHex(privateKey) - ] - ); - } - - async getSymmetricKey(): Promise { - this.checkProcess(); - - return this.rpcCall( - "get_waku_v2_private_v1_symmetric_key", - [] - ).then(hexToBytes); - } - - async postSymmetricMessage( - message: MessageRpcQuery, - symKey: Uint8Array, - pubsubTopic?: string - ): Promise { - this.checkProcess(); - - if (!message.payload) { - throw "Attempting to send empty message"; - } - - return this.rpcCall("post_waku_v2_private_v1_symmetric_message", [ - pubsubTopic ? pubsubTopic : DefaultPubsubTopic, - message, - "0x" + bytesToHex(symKey) - ]); - } - - async getSymmetricMessages( - symKey: Uint8Array, - pubsubTopic?: string - ): Promise { - this.checkProcess(); - - return await this.rpcCall( - "get_waku_v2_private_v1_symmetric_messages", - [ - pubsubTopic ? pubsubTopic : DefaultPubsubTopic, - "0x" + bytesToHex(symKey) - ] - ); - } - async getPeerId(): Promise { if (this.peerId) return this.peerId; this.peerId = await this._getPeerId(); @@ -437,37 +358,6 @@ export class ServiceNode { return `http://127.0.0.1:${this.restPort}`; } - async rpcCall( - method: string, - params: Array - ): Promise { - return await pRetry( - async () => { - try { - log.info("Making an RPC Query: ", method, params); - const res = await fetch(this.rpcUrl, { - method: "POST", - body: JSON.stringify({ - jsonrpc: "2.0", - id: 1, - method, - params - }), - headers: new Headers({ "Content-Type": "application/json" }) - }); - const json = await res.json(); - log.info(`Received RPC Response: `, JSON.stringify(json)); - return json.result; - } catch (error) { - log.error(`${this.rpcUrl} failed with error:`, error); - await delay(10); - throw error; - } - }, - { retries: 5 } - ); - } - async restCall( endpoint: string, method: "GET" | "POST", @@ -507,6 +397,7 @@ export function defaultArgs(): Args { relay: false, rest: true, rpcAdmin: true, + restAdmin: true, websocketSupport: true, logLevel: LogLevel.Trace }; diff --git a/packages/tests/src/types.ts b/packages/tests/src/types.ts index cdc07fa7e5..60e6b1401e 100644 --- a/packages/tests/src/types.ts +++ b/packages/tests/src/types.ts @@ -5,6 +5,7 @@ export interface Args { relay?: boolean; rest?: boolean; rpc?: boolean; + restAdmin?: boolean; rpcAdmin?: boolean; nodekey?: string; portsShift?: number; diff --git a/packages/tests/tests/filter/push.node.spec.ts b/packages/tests/tests/filter/push.node.spec.ts index bc1d049ffb..67a862071e 100644 --- a/packages/tests/tests/filter/push.node.spec.ts +++ b/packages/tests/tests/filter/push.node.spec.ts @@ -79,8 +79,7 @@ const runTests = (strictCheckNodes: boolean): void => { payload: Buffer.from(utf8ToBytes(messageText)).toString("base64"), timestamp: testItem as any }, - DefaultPubsubTopic, - true + DefaultPubsubTopic ); expect(await serviceNodes.messageCollector.waitForMessages(1)).to.eq( @@ -118,8 +117,7 @@ const runTests = (strictCheckNodes: boolean): void => { payload: Buffer.from(utf8ToBytes(messageText)).toString("base64"), timestamp: "2023-09-06T12:05:38.609Z" as any }, - DefaultPubsubTopic, - true + DefaultPubsubTopic ); // Verify that no message was received @@ -149,28 +147,6 @@ const runTests = (strictCheckNodes: boolean): void => { ); }); - it("Check message with no pubsub topic is not received", async function () { - await subscription.subscribe( - [TestDecoder], - serviceNodes.messageCollector.callback - ); - await delay(400); - - await serviceNodes.sendRelayMessage( - { - contentTopic: TestContentTopic, - payload: Buffer.from(utf8ToBytes(messageText)).toString("base64"), - timestamp: BigInt(Date.now()) * BigInt(1000000) - }, - undefined, - true - ); - - expect(await serviceNodes.messageCollector.waitForMessages(1)).to.eq( - false - ); - }); - it("Check message with no content topic is not received", async function () { await subscription.subscribe( [TestDecoder], @@ -204,8 +180,7 @@ const runTests = (strictCheckNodes: boolean): void => { timestamp: BigInt(Date.now()) * BigInt(1000000), payload: undefined as any }, - DefaultPubsubTopic, - true + DefaultPubsubTopic ); // For go-waku the message is received (it is possible to send a message with no payload) diff --git a/packages/tests/tests/filter/single_node/push.node.spec.ts b/packages/tests/tests/filter/single_node/push.node.spec.ts index 4b900c66f5..e905a0fdd0 100644 --- a/packages/tests/tests/filter/single_node/push.node.spec.ts +++ b/packages/tests/tests/filter/single_node/push.node.spec.ts @@ -64,14 +64,17 @@ describe("Waku Filter V2: FilterPush", function () { await subscription.subscribe([TestDecoder], messageCollector.callback); await delay(400); - await nwaku.rpcCall("post_waku_v2_relay_v1_message", [ - DefaultPubsubTopic, + await nwaku.restCall( + `/relay/v1/messages/${encodeURIComponent(DefaultPubsubTopic)}`, + "POST", { contentTopic: TestContentTopic, payload: Buffer.from(utf8ToBytes(messageText)).toString("base64"), - timestamp: testItem - } - ]); + timestamp: testItem, + version: 0 + }, + async (res) => res.status === 200 + ); expect(await messageCollector.waitForMessages(1)).to.eq(true); messageCollector.verifyReceivedMessage(0, { @@ -95,14 +98,16 @@ describe("Waku Filter V2: FilterPush", function () { await subscription.subscribe([TestDecoder], messageCollector.callback); await delay(400); - await nwaku.rpcCall("post_waku_v2_relay_v1_message", [ - DefaultPubsubTopic, + await nwaku.restCall( + `/relay/v1/messages/${encodeURIComponent(DefaultPubsubTopic)}`, + "POST", { contentTopic: TestContentTopic, payload: Buffer.from(utf8ToBytes(messageText)).toString("base64"), timestamp: "2023-09-06T12:05:38.609Z" - } - ]); + }, + async (res) => res.status === 200 + ); // Verify that no message was received expect(await messageCollector.waitForMessages(1)).to.eq(false); @@ -112,14 +117,16 @@ describe("Waku Filter V2: FilterPush", function () { await subscription.subscribe([TestDecoder], messageCollector.callback); await delay(400); - await nwaku.rpcCall("post_waku_v2_relay_v1_message", [ - "DefaultPubsubTopic", + await nwaku.restCall( + `/relay/v1/messages/${encodeURIComponent("/othertopic")}`, + "POST", { contentTopic: TestContentTopic, payload: Buffer.from(utf8ToBytes(messageText)).toString("base64"), timestamp: BigInt(Date.now()) * BigInt(1000000) - } - ]); + }, + async (res) => res.status === 200 + ); expect(await messageCollector.waitForMessages(1)).to.eq(false); }); @@ -128,13 +135,16 @@ describe("Waku Filter V2: FilterPush", function () { await subscription.subscribe([TestDecoder], messageCollector.callback); await delay(400); - await nwaku.rpcCall("post_waku_v2_relay_v1_message", [ + await nwaku.restCall( + `/relay/v1/messages/`, + "POST", { contentTopic: TestContentTopic, payload: Buffer.from(utf8ToBytes(messageText)).toString("base64"), timestamp: BigInt(Date.now()) * BigInt(1000000) - } - ]); + }, + async (res) => res.status === 200 + ); expect(await messageCollector.waitForMessages(1)).to.eq(false); }); @@ -143,13 +153,15 @@ describe("Waku Filter V2: FilterPush", function () { await subscription.subscribe([TestDecoder], messageCollector.callback); await delay(400); - await nwaku.rpcCall("post_waku_v2_relay_v1_message", [ - DefaultPubsubTopic, + await nwaku.restCall( + `/relay/v1/messages/${encodeURIComponent(DefaultPubsubTopic)}`, + "POST", { payload: Buffer.from(utf8ToBytes(messageText)).toString("base64"), timestamp: BigInt(Date.now()) * BigInt(1000000) - } - ]); + }, + async (res) => res.status === 200 + ); expect(await messageCollector.waitForMessages(1)).to.eq(false); }); @@ -158,13 +170,15 @@ describe("Waku Filter V2: FilterPush", function () { await subscription.subscribe([TestDecoder], messageCollector.callback); await delay(400); - await nwaku.rpcCall("post_waku_v2_relay_v1_message", [ - DefaultPubsubTopic, + await nwaku.restCall( + `/relay/v1/messages/${encodeURIComponent(DefaultPubsubTopic)}`, + "POST", { contentTopic: TestContentTopic, timestamp: BigInt(Date.now()) * BigInt(1000000) - } - ]); + }, + async (res) => res.status === 200 + ); // For go-waku the message is received (it is possible to send a message with no payload) if (nwaku.type == "go-waku") { @@ -178,56 +192,20 @@ describe("Waku Filter V2: FilterPush", function () { await subscription.subscribe([TestDecoder], messageCollector.callback); await delay(400); - await nwaku.rpcCall("post_waku_v2_relay_v1_message", [ - DefaultPubsubTopic, + await nwaku.restCall( + `/relay/v1/messages/${encodeURIComponent(DefaultPubsubTopic)}`, + "POST", { contentTopic: TestContentTopic, payload: 12345, timestamp: BigInt(Date.now()) * BigInt(1000000) - } - ]); + }, + async (res) => res.status === 200 + ); expect(await messageCollector.waitForMessages(1)).to.eq(false); }); - it("Check message with extra parameter is not received", async function () { - await subscription.subscribe([TestDecoder], messageCollector.callback); - await delay(400); - - await nwaku.rpcCall("post_waku_v2_relay_v1_message", [ - DefaultPubsubTopic, - "extraField", - { - contentTopic: TestContentTopic, - payload: Buffer.from(utf8ToBytes(messageText)).toString("base64"), - timestamp: BigInt(Date.now()) * BigInt(1000000) - } - ]); - - expect(await messageCollector.waitForMessages(1)).to.eq(false); - }); - - it("Check received message with extra option is received", async function () { - await subscription.subscribe([TestDecoder], messageCollector.callback); - await delay(400); - - await nwaku.rpcCall("post_waku_v2_relay_v1_message", [ - DefaultPubsubTopic, - { - contentTopic: TestContentTopic, - payload: Buffer.from(utf8ToBytes(messageText)).toString("base64"), - timestamp: BigInt(Date.now()) * BigInt(1000000), - extraOption: "extraOption" - } - ]); - - expect(await messageCollector.waitForMessages(1)).to.eq(true); - messageCollector.verifyReceivedMessage(0, { - expectedMessageText: messageText, - expectedContentTopic: TestContentTopic - }); - }); - // Will be skipped until https://github.com/waku-org/js-waku/issues/1464 si done it.skip("Check message received after jswaku node is restarted", async function () { // Subscribe and send message diff --git a/packages/tests/tests/filter/utils.ts b/packages/tests/tests/filter/utils.ts index a49830656a..d7aec2fab9 100644 --- a/packages/tests/tests/filter/utils.ts +++ b/packages/tests/tests/filter/utils.ts @@ -9,7 +9,11 @@ import { Waku } from "@waku/interfaces"; import { createLightNode } from "@waku/sdk"; -import { Logger } from "@waku/utils"; +import { + ensureShardingConfigured, + Logger, + shardInfoToPubsubTopics +} from "@waku/utils"; import { utf8ToBytes } from "@waku/utils/bytes"; import { Context } from "mocha"; import pRetry from "p-retry"; @@ -64,7 +68,7 @@ export async function runMultipleNodes( pubsubTopics, numServiceNodes, strictChecking, - shardInfo, + shardInfo ? ensureShardingConfigured(shardInfo).shardInfo : shardInfo, undefined, withoutFilter ); @@ -74,7 +78,7 @@ export async function runMultipleNodes( libp2p: { addresses: { listen: ["/ip4/0.0.0.0/tcp/0/ws"] } }, - pubsubTopics: shardInfo ? undefined : pubsubTopics, + pubsubTopics: shardInfo ? shardInfoToPubsubTopics(shardInfo) : pubsubTopics, ...((pubsubTopics.length !== 1 || pubsubTopics[0] !== DefaultPubsubTopic) && { shardInfo: shardInfo diff --git a/packages/tests/tests/nwaku.node.spec.ts b/packages/tests/tests/nwaku.node.spec.ts index 9dac38f899..6210bd494b 100644 --- a/packages/tests/tests/nwaku.node.spec.ts +++ b/packages/tests/tests/nwaku.node.spec.ts @@ -16,6 +16,7 @@ describe("nwaku", () => { "--relay=false", "--rest=true", "--rpc-admin=true", + "--rest-admin=true", "--websocket-support=true", "--log-level=TRACE", "--ports-shift=42"