UNPKG

@moonsong-labs/moonwall-cli

Version:

Testing framework for the Moon family of projects

224 lines (221 loc) 7.05 kB
import { parseChopsticksRunCmd, parseRunCmd } from "./chunk-XIBPDQIU.js"; import { launchNode } from "./chunk-CY4QSJCG.js"; import { populateProviderInterface, prepareProviders } from "./chunk-75ODDMN6.js"; import { importJsonConfig } from "./chunk-3P647NU6.js"; import { __publicField } from "./chunk-7B2TVWXJ.js"; // src/lib/globalContext.ts import "@moonbeam-network/api-augment"; import Debug from "debug"; var debugSetup = Debug("global:context"); var _MoonwallContext = class { environment; providers; nodes; foundation; _finalizedHead; rtUpgradePath; constructor(config) { this.environment; this.providers = []; this.nodes = []; const env = config.environments.find(({ name }) => name == process.env.MOON_TEST_ENV); const blob = { name: env.name, context: {}, providers: [], nodes: [], foundationType: env.foundation.type }; switch (env.foundation.type) { case "read_only": if (!env.connections) { throw new Error( `${env.name} env config is missing connections specification, required by foundation READ_ONLY` ); } else { blob.providers = prepareProviders(env.connections); } debugSetup(`\u{1F7E2} Foundation "${env.foundation.type}" parsed for environment: ${env.name}`); break; case "chopsticks": blob.nodes.push(parseChopsticksRunCmd(env.foundation.launchSpec)); blob.providers.push(...prepareProviders(env.connections)); this.rtUpgradePath = env.foundation.rtUpgradePath; debugSetup(`\u{1F7E2} Foundation "${env.foundation.type}" parsed for environment: ${env.name}`); break; case "dev": const { cmd, args, launch } = parseRunCmd(env.foundation.launchSpec[0]); blob.nodes.push({ name: env.foundation.launchSpec[0].name, cmd, args, launch }); blob.providers = env.connections ? prepareProviders(env.connections) : prepareProviders([ { name: "w3", type: "web3", endpoints: [ `ws://127.0.0.1:${1e4 + Number(process.env.VITEST_POOL_ID || 1) * 100}` ] }, { name: "eth", type: "ethers", endpoints: [ `ws://127.0.0.1:${1e4 + Number(process.env.VITEST_POOL_ID || 1) * 100}` ] }, { name: "mb", type: "moon", endpoints: [ `ws://127.0.0.1:${1e4 + Number(process.env.VITEST_POOL_ID || 1) * 100}` ] } ]); debugSetup(`\u{1F7E2} Foundation "${env.foundation.type}" parsed for environment: ${env.name}`); break; default: debugSetup(`\u{1F6A7} Foundation "${env.foundation.type}" unsupported, skipping`); return; } this.environment = blob; } get genesis() { if (this._finalizedHead) { return this._finalizedHead; } else { return ""; } } set genesis(hash) { if (hash.length !== 66) { throw new Error("Cannot set genesis to invalid hash"); } this._finalizedHead = hash; } async startNetwork() { const activeNodes = this.nodes.filter((node) => !node.killed); if (activeNodes.length > 0) { console.log("Nodes already started! Skipping command"); return _MoonwallContext.getContext(); } const nodes = _MoonwallContext.getContext().environment.nodes; const promises = nodes.map(async ({ cmd, args, name, launch }) => { return launch && this.nodes.push(await launchNode(cmd, args, name)); }); await Promise.all(promises); } async stopNetwork() { if (this.nodes.length === 0) { console.log("Nodes already stopped! Skipping command"); return _MoonwallContext.getContext(); } this.nodes.forEach((node) => node.kill()); await this.wipeNodes(); } async connectEnvironment(environmentName) { if (this.providers.length > 0) { console.log("Providers already connected! Skipping command"); return _MoonwallContext.getContext(); } const globalConfig = await importJsonConfig(); const promises = this.environment.providers.map( async ({ name, type, connect }) => new Promise(async (resolve) => { this.providers.push(await populateProviderInterface(name, type, connect)); resolve(""); }) ); await Promise.all(promises); this.foundation = globalConfig.environments.find( ({ name }) => name == environmentName ).foundation.type; if (this.foundation == "dev") { this.genesis = (await this.providers.find(({ type }) => type == "polkadotJs" || type == "moon").api.rpc.chain.getBlockHash(0)).toString(); } if (this.foundation == "chopsticks") { this.genesis = (await this.providers.find(({ type }) => type == "polkadotJs" || type == "moon").api.rpc.chain.getFinalizedHead()).toString(); } } async wipeNodes() { this.nodes = []; } async disconnect(providerName) { if (providerName) { this.providers.find(({ name }) => name === providerName).disconnect(); this.providers.filter(({ name }) => name !== providerName); } else { await Promise.all(this.providers.map((prov) => prov.disconnect())); this.providers = []; } } static printStats() { if (_MoonwallContext) { console.dir(_MoonwallContext.getContext(), { depth: 1 }); } else { console.log("Global context not created!"); } } static getContext(config, force = false) { if (!_MoonwallContext.instance || force) { if (global.moonInstance && !force) { _MoonwallContext.instance = global.moonInstance; return _MoonwallContext.instance; } if (!config) { console.error("\u274C Config must be provided on Global Context instantiation"); return void 0; } _MoonwallContext.instance = new _MoonwallContext(config); debugSetup(`\u{1F7E2} Moonwall context "${config.label}" created`); } return _MoonwallContext.instance; } static async destroy() { const ctx = _MoonwallContext.getContext(); try { ctx.disconnect(); } catch { console.log("\u{1F6D1} All connections disconnected"); } const promises = ctx.nodes.map((process2) => { return new Promise((resolve) => { process2.kill(); if (process2.killed) { resolve(`process ${process2.pid} killed`); } }); }); await Promise.all(promises); } }; var MoonwallContext = _MoonwallContext; __publicField(MoonwallContext, "instance"); var contextCreator = async (config, env) => { const ctx = MoonwallContext.getContext(config); await runNetworkOnly(config); await ctx.connectEnvironment(env); return ctx; }; var runNetworkOnly = async (config) => { const ctx = MoonwallContext.getContext(config); await ctx.startNetwork(); }; export { MoonwallContext, contextCreator, runNetworkOnly };