fix(tests): Repair integration tests [fixes DXJ-506] (#364)

* Add test server

* remove headless

* Support for web-cra

* Review fixes and bug fixes

* Add error message
This commit is contained in:
Akim
2023-10-18 08:38:49 +07:00
committed by GitHub
parent 29ec812fc1
commit 36c7619b4a
18 changed files with 216 additions and 138 deletions

View File

@ -14,13 +14,6 @@
* limitations under the License.
*/
import {
ClientConfig,
ConnectionState,
IFluenceClient,
RelayOptions,
} from "@fluencelabs/interfaces";
import {
RelayConnection,
RelayConnectionConfig,
@ -32,6 +25,13 @@ import { IMarineHost } from "../marine/interfaces.js";
import { relayOptionToMultiaddr } from "../util/libp2pUtils.js";
import { logger } from "../util/logger.js";
import {
ClientConfig,
IFluenceClient,
ConnectionState,
RelayOptions,
} from "./types.js";
const log = logger("client");
const DEFAULT_TTL_MS = 7000;

View File

@ -0,0 +1,171 @@
/**
* Copyright 2023 Fluence Labs Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* Peer ID's id as a base58 string (multihash/CIDv0).
*/
export type PeerIdB58 = string;
/**
* Node of the Fluence network specified as a pair of node's multiaddr and it's peer id
*/
export type Node = {
peerId: PeerIdB58;
multiaddr: string;
};
/**
* A node in Fluence network a client can connect to.
* Can be in the form of:
* - string: multiaddr in string format
* - Node: node structure, @see Node
*/
export type RelayOptions = string | Node;
/**
* Fluence Peer's key pair types
*/
export type KeyTypes = "RSA" | "Ed25519" | "secp256k1";
/**
* Options to specify key pair used in Fluence Peer
*/
export type KeyPairOptions = {
type: "Ed25519";
source: "random" | Uint8Array;
};
/**
* Fluence JS Client connection states as string literals
*/
export const ConnectionStates = [
"disconnected",
"connecting",
"connected",
"disconnecting",
] as const;
/**
* Fluence JS Client connection states
*/
export type ConnectionState = (typeof ConnectionStates)[number];
export interface IFluenceInternalApi {
/**
* Internal API
*/
internals: unknown;
}
/**
* Public API of Fluence JS Client
*/
export interface IFluenceClient extends IFluenceInternalApi {
/**
* Connect to the Fluence network
*/
connect: () => Promise<void>;
/**
* Disconnect from the Fluence network
*/
disconnect(): Promise<void>;
/**
* Handle connection state changes. Immediately returns current connection state
*/
onConnectionStateChange(
handler: (state: ConnectionState) => void,
): ConnectionState;
/**
* Return peer's secret key as byte array.
*/
getPeerSecretKey(): Uint8Array;
/**
* Return peer's public key as a base58 string (multihash/CIDv0).
*/
getPeerId(): string;
/**
* Return relay's public key as a base58 string (multihash/CIDv0).
*/
getRelayPeerId(): string;
}
/**
* Configuration used when initiating Fluence Client
*/
export interface ClientConfig {
/**
* Specify the KeyPair to be used to identify the Fluence Peer.
* Will be generated randomly if not specified
*/
keyPair?: KeyPairOptions;
/**
* Options to configure the connection to the Fluence network
*/
connectionOptions?: {
/**
* When the peer established the connection to the network it sends a ping-like message to check if it works correctly.
* The options allows to specify the timeout for that message in milliseconds.
* If not specified the default timeout will be used
*/
skipCheckConnection?: boolean;
/**
* The dialing timeout in milliseconds
*/
dialTimeoutMs?: number;
/**
* The maximum number of inbound streams for the libp2p node.
* Default: 1024
*/
maxInboundStreams?: number;
/**
* The maximum number of outbound streams for the libp2p node.
* Default: 1024
*/
maxOutboundStreams?: number;
};
/**
* Sets the default TTL for all particles originating from the peer with no TTL specified.
* If the originating particle's TTL is defined then that value will be used
* If the option is not set default TTL will be 7000
*/
defaultTtlMs?: number;
/**
* Property for passing custom CDN Url to load dependencies from browser. https://unpkg.com used by default
*/
CDNUrl?: string;
/**
* Enables\disabled various debugging features
*/
debug?: {
/**
* If set to true, newly initiated particle ids will be printed to console.
* Useful to see what particle id is responsible for aqua function
*/
printParticleId?: boolean;
};
}

View File

@ -23,9 +23,16 @@ interface PackageJsonContent {
const packageJsonContentString = `__PACKAGE_JSON_CONTENT__`;
let parsedPackageJsonContent: PackageJsonContent | undefined;
const PRIMARY_CDN = "https://unpkg.com/";
export async function fetchResource(pkg: string, assetPath: string) {
/**
* @param pkg name of package
* @param assetPath path of required asset in given package
* @param root CDN domain in browser or file system root in node
*/
export async function fetchResource(
pkg: string,
assetPath: string,
root: string,
) {
const packageJsonContent =
parsedPackageJsonContent ??
// TODO: Should be validated
@ -55,7 +62,8 @@ export async function fetchResource(pkg: string, assetPath: string) {
? assetPath.slice(1)
: assetPath;
return fetch(
new globalThis.URL(`${pkg}@${version}/` + refinedAssetPath, PRIMARY_CDN),
);
const url = new globalThis.URL(`${pkg}@${version}/` + refinedAssetPath, root);
return fetch(url).catch(() => {
throw new Error(`Cannot fetch from ${url.toString()}`);
});
}

View File

@ -18,7 +18,18 @@ import fs from "fs";
import module from "module";
import path from "path";
export async function fetchResource(pkg: string, assetPath: string) {
/**
* @param pkg name of package
* @param assetPath path of required asset in given package
* @param root CDN domain in browser or file system root in node
*/
export async function fetchResource(
pkg: string,
assetPath: string,
root: string,
) {
// TODO: `root` will be handled somehow in the future. For now, we use filesystem root where js-client is running;
root = "/";
const require = module.createRequire(import.meta.url);
const packagePathIndex = require.resolve(pkg);
@ -33,7 +44,7 @@ export async function fetchResource(pkg: string, assetPath: string) {
throw new Error(`Cannot find dependency ${pkg} in path ${posixPath}`);
}
const pathToResource = path.join(packagePath, assetPath);
const pathToResource = path.join(root, packagePath, assetPath);
const file = await new Promise<ArrayBuffer>((resolve, reject) => {
// Cannot use 'fs/promises' with current vite config. This module is not polyfilled by default.

View File

@ -19,14 +19,14 @@ import path from "path";
import process from "process";
import url from "url";
import type {
ClientConfig,
ConnectionState,
RelayOptions,
} from "@fluencelabs/interfaces";
import { BlobWorker, Worker } from "threads/master";
import { ClientPeer, makeClientPeerConfig } from "./clientPeer/ClientPeer.js";
import {
ClientConfig,
ConnectionState,
RelayOptions,
} from "./clientPeer/types.js";
import { callAquaFunction } from "./compilerSupport/callFunction.js";
import { registerService } from "./compilerSupport/registerService.js";
import { MarineBackgroundRunner } from "./marine/worker/index.js";
@ -34,38 +34,49 @@ import { doRegisterNodeUtils } from "./services/NodeUtils.js";
import { fetchResource } from "#fetcher";
const DEFAULT_CDN_URL = "https://unpkg.com";
const isNode =
// process.release is undefined in browser env
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
typeof process !== "undefined" && process.release?.name === "node";
const fetchWorkerCode = async () => {
const resource = await fetchResource(
"@fluencelabs/marine-worker",
"/dist/browser/marine-worker.umd.cjs",
);
return resource.text();
};
const fetchMarineJsWasm = async () => {
const resource = await fetchResource(
"@fluencelabs/marine-js",
"/dist/marine-js.wasm",
);
return resource.arrayBuffer();
};
const fetchAvmWasm = async () => {
const resource = await fetchResource("@fluencelabs/avm", "/dist/avm.wasm");
return resource.arrayBuffer();
};
const createClient = async (
relay: RelayOptions,
config: ClientConfig,
): Promise<ClientPeer> => {
const CDNUrl = config.CDNUrl ?? DEFAULT_CDN_URL;
const fetchWorkerCode = async () => {
const resource = await fetchResource(
"@fluencelabs/marine-worker",
"/dist/browser/marine-worker.umd.cjs",
CDNUrl,
);
return resource.text();
};
const fetchMarineJsWasm = async () => {
const resource = await fetchResource(
"@fluencelabs/marine-js",
"/dist/marine-js.wasm",
CDNUrl,
);
return resource.arrayBuffer();
};
const fetchAvmWasm = async () => {
const resource = await fetchResource(
"@fluencelabs/avm",
"/dist/avm.wasm",
CDNUrl,
);
return resource.arrayBuffer();
};
const marineJsWasm = await fetchMarineJsWasm();
const avmWasm = await fetchAvmWasm();
@ -194,11 +205,9 @@ export const Fluence: FluencePublicApi = {
},
};
export type {
IFluenceClient,
ClientConfig,
CallParams,
} from "@fluencelabs/interfaces";
export type { CallParams } from "@fluencelabs/interfaces";
export type { ClientConfig, IFluenceClient } from "./clientPeer/types.js";
export type {
ArrayType,

View File

@ -14,7 +14,6 @@
* limitations under the License.
*/
import { KeyPairOptions } from "@fluencelabs/interfaces";
import {
generateKeyPairFromSeed,
generateKeyPair,
@ -26,6 +25,8 @@ import { createFromPrivKey } from "@libp2p/peer-id-factory";
import bs58 from "bs58";
import { toUint8Array } from "js-base64";
import { KeyPairOptions } from "../clientPeer/types.js";
export class KeyPair {
private publicKey: PublicKey;

View File

@ -14,9 +14,10 @@
* limitations under the License.
*/
import { RelayOptions } from "@fluencelabs/interfaces";
import { multiaddr, Multiaddr } from "@multiformats/multiaddr";
import { RelayOptions } from "../clientPeer/types.js";
import { isString } from "./utils.js";
export function relayOptionToMultiaddr(relay: RelayOptions): Multiaddr {

View File

@ -18,16 +18,15 @@ import { promises as fs } from "fs";
import * as api from "@fluencelabs/aqua-api/aqua-api.js";
import {
ClientConfig,
FunctionCallDef,
JSONArray,
PassedArgs,
RelayOptions,
ServiceDef,
} from "@fluencelabs/interfaces";
import { Subject, Subscribable } from "rxjs";
import { ClientPeer, makeClientPeerConfig } from "../clientPeer/ClientPeer.js";
import { ClientConfig, RelayOptions } from "../clientPeer/types.js";
import { callAquaFunction } from "../compilerSupport/callFunction.js";
import { IConnection } from "../connection/interfaces.js";
import { DEFAULT_CONFIG, FluencePeer } from "../jsPeer/FluencePeer.js";