Skip to content

Commit

Permalink
Merge pull request #1856 from waku-org/feat/rpc-to-rest
Browse files Browse the repository at this point in the history
feat: migrates e2e tests to use rest instead of rpc
  • Loading branch information
adklempner authored Feb 19, 2024
2 parents 199f6ab + 6009af7 commit 26eb7dd
Show file tree
Hide file tree
Showing 8 changed files with 97 additions and 255 deletions.
3 changes: 1 addition & 2 deletions packages/tests/src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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;
27 changes: 10 additions & 17 deletions packages/tests/src/lib/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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";
Expand All @@ -27,7 +28,7 @@ export class ServiceNodesFleet {
pubsubTopics: PubsubTopic[],
nodesToCreate: number = 3,
strictChecking: boolean = false,
shardInfo?: ShardingParams,
shardInfo?: ShardInfo,
_args?: Args,
withoutFilter = false
): Promise<ServiceNodesFleet> {
Expand All @@ -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
Expand Down Expand Up @@ -100,22 +104,11 @@ export class ServiceNodesFleet {

async sendRelayMessage(
message: MessageRpcQuery,
pubsubTopic?: string,
raw = false
pubsubTopic: string = DefaultPubsubTopic
): Promise<boolean> {
let relayMessagePromises: Promise<boolean>[];
if (raw) {
relayMessagePromises = this.nodes.map((node) =>
node.rpcCall<boolean>("post_waku_v2_relay_v1_message", [
pubsubTopic && pubsubTopic,
message
])
);
} else {
relayMessagePromises = this.nodes.map((node) =>
node.sendMessage(message, pubsubTopic)
);
}
const relayMessagePromises: Promise<boolean>[] = this.nodes.map((node) =>
node.sendMessage(message, pubsubTopic)
);
const relayMessages = await Promise.all(relayMessagePromises);
return relayMessages.every((message) => message);
}
Expand Down
169 changes: 30 additions & 139 deletions packages/tests/src/lib/service_node.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -210,13 +208,26 @@ export class ServiceNode {
async peers(): Promise<string[]> {
this.checkProcess();

return this.rpcCall<string[]>("get_waku_v2_admin_v1_peers", []);
return this.restCall<string[]>(
"/admin/v1/peers",
"GET",
undefined,
async (response) => {
const data = await response.json();
return data?.length ? data : [];
}
);
}

async info(): Promise<RpcInfoResponse> {
this.checkProcess();

return this.rpcCall<RpcInfoResponse>("get_waku_v2_debug_v1_info", []);
return this.restCall<RpcInfoResponse>(
"/debug/v1/info",
"GET",
undefined,
async (response) => await response.json()
);
}

async ensureSubscriptions(
Expand All @@ -233,9 +244,8 @@ export class ServiceNode {
async messages(
pubsubTopic: string = DefaultPubsubTopic
): Promise<MessageRpcResponse[]> {
pubsubTopic = encodeURIComponent(pubsubTopic);
return this.restCall<MessageRpcResponse[]>(
`/relay/v1/messages/${pubsubTopic}`,
`/relay/v1/messages/${encodeURIComponent(pubsubTopic)}`,
"GET",
null,
async (response) => {
Expand Down Expand Up @@ -268,10 +278,12 @@ export class ServiceNode {
message.timestamp = BigInt(new Date().valueOf()) * OneMillion;
}

return this.rpcCall<boolean>("post_waku_v2_relay_v1_message", [
pubsubTopic,
message
]);
return this.restCall<boolean>(
`/relay/v1/messages/${encodeURIComponent(pubsubTopic)}`,
"POST",
message,
async (response) => response.status === 200
);
}

async sendMessageAutosharding(message: MessageRpcQuery): Promise<boolean> {
Expand All @@ -281,19 +293,21 @@ export class ServiceNode {
message.timestamp = BigInt(new Date().valueOf()) * OneMillion;
}

return this.rpcCall<boolean>("post_waku_v2_relay_v1_auto_message", [
message
]);
return this.restCall<boolean>(
`/relay/v1/auto/message`,
"POST",
message,
async (response) => response.status === 200
);
}

async messagesAutosharding(
contentTopic: string
): Promise<MessageRpcResponse[]> {
this.checkProcess();

contentTopic = encodeURIComponent(contentTopic);
return this.restCall<MessageRpcResponse[]>(
`/relay/v1/auto/messages/${contentTopic}`,
`/relay/v1/auto/messages/${encodeURIComponent(contentTopic)}`,
"GET",
null,
async (response) => {
Expand All @@ -303,99 +317,6 @@ export class ServiceNode {
);
}

async getAsymmetricKeyPair(): Promise<KeyPair> {
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<boolean> {
this.checkProcess();

if (!message.payload) {
throw "Attempting to send empty message";
}

return this.rpcCall<boolean>("post_waku_v2_private_v1_asymmetric_message", [
pubsubTopic ? pubsubTopic : DefaultPubsubTopic,
message,
"0x" + bytesToHex(publicKey)
]);
}

async getAsymmetricMessages(
privateKey: Uint8Array,
pubsubTopic?: string
): Promise<MessageRpcResponse[]> {
this.checkProcess();

return await this.rpcCall<MessageRpcResponse[]>(
"get_waku_v2_private_v1_asymmetric_messages",
[
pubsubTopic ? pubsubTopic : DefaultPubsubTopic,
"0x" + bytesToHex(privateKey)
]
);
}

async getSymmetricKey(): Promise<Uint8Array> {
this.checkProcess();

return this.rpcCall<string>(
"get_waku_v2_private_v1_symmetric_key",
[]
).then(hexToBytes);
}

async postSymmetricMessage(
message: MessageRpcQuery,
symKey: Uint8Array,
pubsubTopic?: string
): Promise<boolean> {
this.checkProcess();

if (!message.payload) {
throw "Attempting to send empty message";
}

return this.rpcCall<boolean>("post_waku_v2_private_v1_symmetric_message", [
pubsubTopic ? pubsubTopic : DefaultPubsubTopic,
message,
"0x" + bytesToHex(symKey)
]);
}

async getSymmetricMessages(
symKey: Uint8Array,
pubsubTopic?: string
): Promise<MessageRpcResponse[]> {
this.checkProcess();

return await this.rpcCall<MessageRpcResponse[]>(
"get_waku_v2_private_v1_symmetric_messages",
[
pubsubTopic ? pubsubTopic : DefaultPubsubTopic,
"0x" + bytesToHex(symKey)
]
);
}

async getPeerId(): Promise<PeerId> {
if (this.peerId) return this.peerId;
this.peerId = await this._getPeerId();
Expand Down Expand Up @@ -437,37 +358,6 @@ export class ServiceNode {
return `http://127.0.0.1:${this.restPort}`;
}

async rpcCall<T>(
method: string,
params: Array<string | number | unknown>
): Promise<T> {
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<T>(
endpoint: string,
method: "GET" | "POST",
Expand Down Expand Up @@ -507,6 +397,7 @@ export function defaultArgs(): Args {
relay: false,
rest: true,
rpcAdmin: true,
restAdmin: true,
websocketSupport: true,
logLevel: LogLevel.Trace
};
Expand Down
1 change: 1 addition & 0 deletions packages/tests/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ export interface Args {
relay?: boolean;
rest?: boolean;
rpc?: boolean;
restAdmin?: boolean;
rpcAdmin?: boolean;
nodekey?: string;
portsShift?: number;
Expand Down
31 changes: 3 additions & 28 deletions packages/tests/tests/filter/push.node.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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],
Expand Down Expand Up @@ -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)
Expand Down
Loading

0 comments on commit 26eb7dd

Please sign in to comment.