From 19ceca9879b8df110c7e146a4be85a317da4960e Mon Sep 17 00:00:00 2001 From: Javier Viola Date: Mon, 3 Apr 2023 09:05:06 -0300 Subject: [PATCH 01/18] refactor(cli): split cli in actions files --- .../packages/cli/src/actions/convert.ts | 130 ++++ javascript/packages/cli/src/actions/setup.ts | 235 +++++++ javascript/packages/cli/src/actions/spawn.ts | 100 +++ javascript/packages/cli/src/actions/test.ts | 83 +++ javascript/packages/cli/src/cli.ts | 575 +----------------- 5 files changed, 580 insertions(+), 543 deletions(-) create mode 100644 javascript/packages/cli/src/actions/convert.ts create mode 100644 javascript/packages/cli/src/actions/setup.ts create mode 100644 javascript/packages/cli/src/actions/spawn.ts create mode 100644 javascript/packages/cli/src/actions/test.ts diff --git a/javascript/packages/cli/src/actions/convert.ts b/javascript/packages/cli/src/actions/convert.ts new file mode 100644 index 000000000..9bf18d41e --- /dev/null +++ b/javascript/packages/cli/src/actions/convert.ts @@ -0,0 +1,130 @@ +import type { + NodeConfig, + PL_ConfigType, + ParachainConfig, + PolkadotLaunchConfig, +} from "@zombienet/orchestrator"; +import { decorators, getFilePathNameExt } from "@zombienet/utils"; +import fs from "fs"; +import path from "path"; +import { DEFAULT_BALANCE } from "src/constants"; + +export async function convert(param: string) { + try { + const filePath = param; + + if (!filePath) { + throw Error("Path of configuration file was not provided"); + } + + // Read through the JSON and write to stream sample + await convertInput(filePath); + } catch (err) { + console.log( + `\n ${decorators.red("Error: ")} \t ${decorators.bright(err)}\n`, + ); + } +} + +// Convert functions +// Read the input file +async function readInputFile( + ext: string, + fPath: string, +): Promise { + let json: object; + if (ext === "json" || ext === "js") { + json = + ext === "json" + ? JSON.parse(fs.readFileSync(`${fPath}`, "utf8")) + : await import(path.resolve(fPath)); + } else { + throw Error("No valid extension was found."); + } + return json; +} + +async function convertInput(filePath: string) { + const { fullPath, fileName, extension } = getFilePathNameExt(filePath); + + const convertedJson = await readInputFile(extension, filePath); + + const { relaychain, parachains, simpleParachains, hrmpChannels, types } = + convertedJson; + + let jsonOutput: PolkadotLaunchConfig; + const nodes: NodeConfig[] = []; + const paras: ParachainConfig[] = []; + let collators: NodeConfig[] = []; + + const DEFAULT_NODE_VALUES = { + validator: true, + invulnerable: true, + balance: DEFAULT_BALANCE, + }; + + parachains && + parachains.forEach((parachain: any) => { + collators = []; + parachain.nodes.forEach((n: any) => { + collators.push({ + name: n.name, + command: "adder-collator", + ...DEFAULT_NODE_VALUES, + }); + }); + paras.push({ + id: parachain.id, + collators, + }); + }); + + collators = []; + + simpleParachains && + simpleParachains.forEach((sp: any) => { + collators.push({ + name: sp.name, + command: "adder-collator", + ...DEFAULT_NODE_VALUES, + }); + paras.push({ + id: sp.id, + collators, + }); + }); + + if (relaychain?.nodes) { + relaychain.nodes.forEach((n: any) => { + nodes.push({ + name: `"${n.name}"`, + ...DEFAULT_NODE_VALUES, + }); + }); + } + + jsonOutput = { + relaychain: { + default_image: "docker.io/paritypr/polkadot-debug:master", + default_command: "polkadot", + default_args: ["-lparachain=debug"], + chain: relaychain?.chain || "", + nodes, + genesis: relaychain?.genesis, + }, + types, + hrmp_channels: hrmpChannels || [], + parachains: paras, + }; + + fs.writeFile( + `${fullPath}/${fileName}-zombienet.json`, + JSON.stringify(jsonOutput), + (error: any) => { + if (error) throw error; + }, + ); + console.log( + `Converted JSON config exists now under: ${fullPath}/${fileName}-zombienet.json`, + ); +} diff --git a/javascript/packages/cli/src/actions/setup.ts b/javascript/packages/cli/src/actions/setup.ts new file mode 100644 index 000000000..fd268d2cc --- /dev/null +++ b/javascript/packages/cli/src/actions/setup.ts @@ -0,0 +1,235 @@ +import { askQuestion, convertBytes, decorators } from "@zombienet/utils"; +import cliProgress from "cli-progress"; +import fs from "fs"; +import path from "path"; + +interface OptIf { + [key: string]: { name: string; url?: string; size?: string }; +} + +const options: OptIf = {}; +/** + * Setup - easily download latest artifacts and make them executablein order to use them with zombienet + * Read more here: https://paritytech.github.io/zombienet/cli/setup.html + * @param params binaries that willbe downloaded and set up. Possible values: `polkadot` `polkadot-parachain` + * @returns + */ +export async function setup(params: any) { + const POSSIBLE_BINARIES = ["polkadot", "polkadot-parachain"]; + + console.log(decorators.green("\n\nšŸ§ŸšŸ§ŸšŸ§Ÿ ZombieNet Setup šŸ§ŸšŸ§ŸšŸ§Ÿ\n\n")); + if ( + ["aix", "freebsd", "openbsd", "sunos", "win32"].includes(process.platform) + ) { + console.log( + "Zombienet currently supports linux and MacOS. \n Alternative, you can use k8s or podman. For more read here: https://github.com/paritytech/zombienet#requirements-by-provider", + ); + return; + } + + console.log(decorators.green("Gathering latest releases' versions...\n")); + await new Promise((resolve) => { + latestPolkadotReleaseURL("polkadot", "polkadot").then( + (res: [string, string]) => { + options.polkadot = { + name: "polkadot", + url: res[0], + size: res[1], + }; + resolve(); + }, + ); + }); + + await new Promise((resolve) => { + latestPolkadotReleaseURL("cumulus", "polkadot-parachain").then( + (res: [string, string]) => { + options["polkadot-parachain"] = { + name: "polkadot-parachain", + url: res[0], + size: res[1], + }; + resolve(); + }, + ); + }); + + // If the platform is MacOS then the polkadot repo needs to be cloned and run locally by the user + // as polkadot do not release a binary for MacOS + if (process.platform === "darwin" && params.includes("polkadot")) { + console.log( + `${decorators.yellow( + "Note: ", + )} You are using MacOS. Please, clone the polkadot repo ` + + decorators.cyan("(https://github.com/paritytech/polkadot)") + + ` and run it locally.\n At the moment there is no polkadot binary for MacOs.\n\n`, + ); + const index = params.indexOf("polkadot"); + if (index !== -1) { + params.splice(index, 1); + } + } + + if (params.length === 0) { + console.log(decorators.green("No binaries to download. Exiting...")); + return; + } + let count = 0; + console.log("Setup will start to download binaries:"); + params.forEach((a: any) => { + if (!POSSIBLE_BINARIES.includes(a)) { + const index = params.indexOf(a); + index > -1 && params.splice(index, 1); + console.log( + decorators.red( + `"${a}" is not one of the possible options for this setup and will be skipped;`, + ), + decorators.green(` Valid options: polkadot polkadot-parachain`), + ); + return; + } + const size = parseInt(opts[a]?.size || "0", 10); + count += size; + console.log("-", a, "\t Approx. size ", size, " MB"); + }); + console.log("Total approx. size: ", count, "MB"); + const response = await askQuestion( + decorators.yellow("\nDo you want to continue? (y/n)"), + ); + if (response.toLowerCase() !== "n" && response.toLowerCase() !== "y") { + console.log("Invalid input. Exiting..."); + return; + } + if (response.toLowerCase() === "n") { + return; + } + downloadBinaries(params); + return; +} + +// helper fns +// Download the binaries +const downloadBinaries = async (binaries: string[]): Promise => { + try { + console.log(decorators.yellow("\nStart download...\n")); + const promises = []; + + const multibar = new cliProgress.MultiBar( + { + clearOnComplete: false, + hideCursor: true, + format: + decorators.yellow("{bar} - {percentage}%") + + " | " + + decorators.cyan("Binary name:") + + " {filename}", + }, + cliProgress.Presets.shades_grey, + ); + + for (let binary of binaries) { + promises.push( + new Promise(async (resolve, reject) => { + let result = options[binary]; + if (!result) { + console.log("options", options, "binary", binary); + throw new Error("Binary is not defined"); + } + const { url, name } = result; + + if (!url) throw new Error("No url for downloading, was provided"); + + const response = await fetch(url); + + if (!response.ok) + throw Error(response.status + " " + response.statusText); + + const contentLength = response.headers.get( + "content-length", + ) as string; + let loaded = 0; + + const progressBar = multibar.create(parseInt(contentLength, 10), 0); + const reader = response.body?.getReader(); + const writer = fs.createWriteStream(path.resolve(name)); + + while (true) { + const read = await reader?.read()!; + if (read?.done) { + writer.close(); + resolve(); + break; + } + + loaded += read.value.length; + progressBar.increment(); + progressBar.update(loaded, { + filename: name, + }); + writer.write(read.value); + } + }), + ); + } + + await Promise.all(promises); + multibar.stop(); + console.log( + decorators.cyan( + `\n\nPlease add the current dir to your $PATH by running the command:\n`, + ), + decorators.blue(`export PATH=${process.cwd()}:$PATH\n\n`), + ); + } catch (err) { + console.log( + `\n ${decorators.red("Unexpected error: ")} \t ${decorators.bright( + err, + )}\n`, + ); + } +}; + +// Retrieve the latest release for polkadot +const latestPolkadotReleaseURL = async ( + repo: string, + name: string, +): Promise<[string, string]> => { + try { + const releases = await fetch( + `https://api.github.com/repos/paritytech/${repo}/releases`, + ); + + let obj: any; + let tag_name; + + const allReleases = await releases.json(); + const release = allReleases.find((r: any) => { + obj = r?.assets?.find((a: any) => a.name === name); + return Boolean(obj); + }); + + tag_name = release.tag_name; + + if (!tag_name) { + throw new Error( + "Should never come to this point. Tag_name should never be undefined!", + ); + } + + return [ + `https://github.com/paritytech/${repo}/releases/download/${tag_name}/${name}`, + convertBytes(obj.size), + ]; + } catch (err: any) { + if (err.code === "ENOTFOUND") { + throw new Error("Network error."); + } else if (err.response && err.response.status === 404) { + throw new Error( + "Could not find a release. Error 404 (not found) detected", + ); + } + throw new Error( + `Error status: ${err?.response?.status}. Error message: ${err?.response}`, + ); + } +}; diff --git a/javascript/packages/cli/src/actions/spawn.ts b/javascript/packages/cli/src/actions/spawn.ts new file mode 100644 index 000000000..29f0bdc42 --- /dev/null +++ b/javascript/packages/cli/src/actions/spawn.ts @@ -0,0 +1,100 @@ +import { Network, start } from "@zombienet/orchestrator"; +import { LaunchConfig } from "@zombienet/orchestrator/dist/types"; +import { + decorators, + getCredsFilePath, + readNetworkConfig, +} from "@zombienet/utils"; +import fs from "fs"; +import { resolve } from "path"; +import { + AVAILABLE_PROVIDERS, + DEFAULT_GLOBAL_TIMEOUT, + DEFAULT_PROVIDER, +} from "../constants"; + +/** + * Spawn - spawns ephemeral networks, providing a simple but poweful cli that allow you to declare + * the desired network in toml or json format. + * Read more here: https://paritytech.github.io/zombienet/cli/spawn.html + * @param configFile: config file, supported both json and toml formats + * @param credsFile: Credentials file name or path> to use (Only> with kubernetes provider), we look + * in the current directory or in $HOME/.kube/ if a filename is passed. + * @param _opts + * + * @returns Network + */ + +export async function spawn( + configFile: string, + credsFile: string | undefined, + cmdOpts: any, + program: any, +): Promise { + const opts = { ...program.parent.opts(), ...cmdOpts }; + const dir = opts.dir || ""; + const force = opts.force || false; + const monitor = opts.monitor || false; + // By default spawn pods/process in batches of 4, + // since this shouldn't be a bottleneck in most of the cases, + // but also can be set with the `-c` flag. + const spawnConcurrency = opts.spawnConcurrency || 4; + const configPath = resolve(process.cwd(), configFile); + if (!fs.existsSync(configPath)) { + console.error( + `${decorators.reverse( + decorators.red(` āš  Config file does not exist: ${configPath}`), + )}`, + ); + process.exit(); + } + + const filePath = resolve(configFile); + const config: LaunchConfig = readNetworkConfig(filePath); + + // set default provider and timeout if not provided + if (!config.settings) { + config.settings = { + provider: DEFAULT_PROVIDER, + timeout: DEFAULT_GLOBAL_TIMEOUT, + }; + } else { + if (!config.settings.provider) config.settings.provider = DEFAULT_PROVIDER; + if (!config.settings.timeout) + config.settings.timeout = DEFAULT_GLOBAL_TIMEOUT; + } + + // if a provider is passed, let just use it. + if (opts.provider && AVAILABLE_PROVIDERS.includes(opts.provider)) { + config.settings.provider = opts.provider; + } + + let creds = ""; + if (config.settings?.provider === "kubernetes") { + creds = getCredsFilePath(credsFile || "config") || ""; + if (!creds) { + console.log( + `Running ${config.settings?.provider || DEFAULT_PROVIDER} provider:`, + ); + console.error( + `${decorators.reverse( + decorators.red(` āš  I can't find the Creds file: ${credsFile}`), + )}`, + ); + process.exit(); + } + } + + const inCI = process.env.RUN_IN_CONTAINER === "1"; + const options = { + monitor, + spawnConcurrency, + dir, + force, + inCI, + silent: false, + }; + const network = await start(creds, config, options); + network.showNetworkInfo(config.settings?.provider); + return network; +} diff --git a/javascript/packages/cli/src/actions/test.ts b/javascript/packages/cli/src/actions/test.ts new file mode 100644 index 000000000..de77b6c95 --- /dev/null +++ b/javascript/packages/cli/src/actions/test.ts @@ -0,0 +1,83 @@ +import parser from "@zombienet/dsl-parser-wrapper"; +import type { TestDefinition } from "@zombienet/orchestrator"; +import { run } from "@zombienet/orchestrator"; +import { decorators, RelativeLoader } from "@zombienet/utils"; +import fs from "fs"; +import { Environment } from "nunjucks"; +import path from "path"; +import { AVAILABLE_PROVIDERS } from "../constants"; + +/** + * Test - performs test/assertions agins the spawned network, using a set of natural + * language expressions that allow to make assertions based on metrics, logs and some + * built-in function that query the network using polkadot.js + * Read more here: https://paritytech.github.io/zombienet/cli/testing.html + * @param testFile + * @param runningNetworkSpec + * @param opts (commander) + * @param program (commander) + */ +export async function test( + testFile: string, + runningNetworkSpec: string | undefined, + cmdOpts: any, + program: any, +) { + const opts = { ...program.parent.opts(), ...cmdOpts }; + const dir = opts.dir || ""; + + let extension = testFile.slice(testFile.lastIndexOf(".") + 1); + + if (extension !== "zndsl") { + console.log( + `\n ${decorators.red( + "Error:", + )} File extension is not correct. Extension for tests should be '.zndsl'.\n`, + ); + } + + process.env.DEBUG = "zombie"; + const inCI = process.env.RUN_IN_CONTAINER === "1"; + // use `k8s` as default + const providerToUse = + opts.provider && AVAILABLE_PROVIDERS.includes(opts.provider) + ? opts.provider + : "kubernetes"; + + const configBasePath = path.dirname(testFile); + const env = new Environment(new RelativeLoader([configBasePath])); + const templateContent = fs.readFileSync(testFile).toString(); + const content = env.renderString(templateContent, process.env); + + const testName = getTestNameFromFileName(testFile); + + let testDef: TestDefinition; + try { + testDef = JSON.parse(parser.parse_to_json(content)); + } catch (e) { + console.log(`\n ${decorators.red("Error:")} \t ${decorators.bright(e)}\n`); + process.exit(1); + } + + await run( + configBasePath, + testName, + testDef, + providerToUse, + inCI, + opts.spawnConcurrency, + false, + runningNetworkSpec, + dir, + ); +} + +function getTestNameFromFileName(testFile: string): string { + const fileWithOutExt = testFile.split(".")[0]; + const fileName: string = fileWithOutExt.split("/").pop() || ""; + const parts = fileName.split("-"); + const name = parts[0].match(/\d/) + ? parts.slice(1).join(" ") + : parts.join(" "); + return name; +} diff --git a/javascript/packages/cli/src/cli.ts b/javascript/packages/cli/src/cli.ts index 819163e93..b8bb914ae 100644 --- a/javascript/packages/cli/src/cli.ts +++ b/javascript/packages/cli/src/cli.ts @@ -1,41 +1,11 @@ #!/usr/bin/env node -import parser from "@zombienet/dsl-parser-wrapper"; -import { Network, run, start } from "@zombienet/orchestrator"; - -import type { - LaunchConfig, - NodeConfig, - ParachainConfig, - PL_ConfigType, - PolkadotLaunchConfig, - TestDefinition, -} from "@zombienet/orchestrator"; -import { - askQuestion, - convertBytes, - decorators, - getCredsFilePath, - getFilePathNameExt, - readNetworkConfig, - RelativeLoader, -} from "@zombienet/utils"; -import cliProgress from "cli-progress"; +import { Network } from "@zombienet/orchestrator"; +import { decorators } from "@zombienet/utils"; import { Command, Option } from "commander"; -import fs from "fs"; -import { Environment } from "nunjucks"; -import path, { resolve } from "path"; -import { - AVAILABLE_PROVIDERS, - DEFAULT_BALANCE, - DEFAULT_GLOBAL_TIMEOUT, - DEFAULT_PROVIDER, -} from "./constants"; - -interface OptIf { - [key: string]: { name: string; url?: string; size?: string }; -} - -const options: OptIf = {}; +import { convert } from "./actions/convert"; +import { setup } from "./actions/setup"; +import { spawn } from "./actions/spawn"; +import { test } from "./actions/test"; const debug = require("debug")("zombie-cli"); @@ -43,245 +13,6 @@ const program = new Command("zombienet"); let network: Network | undefined; -// Download the binaries -const downloadBinaries = async (binaries: string[]): Promise => { - try { - console.log(decorators.yellow("\nStart download...\n")); - const promises = []; - - const multibar = new cliProgress.MultiBar( - { - clearOnComplete: false, - hideCursor: true, - format: - decorators.yellow("{bar} - {percentage}%") + - " | " + - decorators.cyan("Binary name:") + - " {filename}", - }, - cliProgress.Presets.shades_grey, - ); - - for (let binary of binaries) { - promises.push( - new Promise(async (resolve, reject) => { - let result = options[binary]; - if (!result) { - console.log("options", options, "binary", binary); - throw new Error("Binary is not defined"); - } - const { url, name } = result; - - if (!url) throw new Error("No url for downloading, was provided"); - - const response = await fetch(url); - - if (!response.ok) - throw Error(response.status + " " + response.statusText); - - const contentLength = response.headers.get( - "content-length", - ) as string; - let loaded = 0; - - const progressBar = multibar.create(parseInt(contentLength, 10), 0); - const reader = response.body?.getReader(); - const writer = fs.createWriteStream(path.resolve(name)); - - while (true) { - const read = await reader?.read()!; - if (read?.done) { - writer.close(); - resolve(); - break; - } - - loaded += read.value.length; - progressBar.increment(); - progressBar.update(loaded, { - filename: name, - }); - writer.write(read.value); - } - }), - ); - } - - await Promise.all(promises); - multibar.stop(); - console.log( - decorators.cyan( - `\n\nPlease add the current dir to your $PATH by running the command:\n`, - ), - decorators.blue(`export PATH=${process.cwd()}:$PATH\n\n`), - ); - } catch (err) { - console.log( - `\n ${decorators.red("Unexpected error: ")} \t ${decorators.bright( - err, - )}\n`, - ); - } -}; - -// Retrieve the latest release for polkadot -const latestPolkadotReleaseURL = async ( - repo: string, - name: string, -): Promise<[string, string]> => { - try { - const releases = await fetch( - `https://api.github.com/repos/paritytech/${repo}/releases`, - ); - - let obj: any; - let tag_name; - - const allReleases = await releases.json(); - const release = allReleases.find((r: any) => { - obj = r?.assets?.find((a: any) => a.name === name); - return Boolean(obj); - }); - - tag_name = release.tag_name; - - if (!tag_name) { - throw new Error( - "Should never come to this point. Tag_name should never be undefined!", - ); - } - - return [ - `https://github.com/paritytech/${repo}/releases/download/${tag_name}/${name}`, - convertBytes(obj.size), - ]; - } catch (err: any) { - if (err.code === "ENOTFOUND") { - throw new Error("Network error."); - } else if (err.response && err.response.status === 404) { - throw new Error( - "Could not find a release. Error 404 (not found) detected", - ); - } - throw new Error( - `Error status: ${err?.response?.status}. Error message: ${err?.response}`, - ); - } -}; - -function getTestNameFromFileName(testFile: string): string { - const fileWithOutExt = testFile.split(".")[0]; - const fileName: string = fileWithOutExt.split("/").pop() || ""; - const parts = fileName.split("-"); - const name = parts[0].match(/\d/) - ? parts.slice(1).join(" ") - : parts.join(" "); - return name; -} - -// Convert functions -// Read the input file -async function readInputFile( - ext: string, - fPath: string, -): Promise { - let json: object; - if (ext === "json" || ext === "js") { - json = - ext === "json" - ? JSON.parse(fs.readFileSync(`${fPath}`, "utf8")) - : await import(path.resolve(fPath)); - } else { - throw Error("No valid extension was found."); - } - return json; -} - -async function convertInput(filePath: string) { - const { fullPath, fileName, extension } = getFilePathNameExt(filePath); - - const convertedJson = await readInputFile(extension, filePath); - - const { relaychain, parachains, simpleParachains, hrmpChannels, types } = - convertedJson; - - let jsonOutput: PolkadotLaunchConfig; - const nodes: NodeConfig[] = []; - const paras: ParachainConfig[] = []; - let collators: NodeConfig[] = []; - - const DEFAULT_NODE_VALUES = { - validator: true, - invulnerable: true, - balance: DEFAULT_BALANCE, - }; - - parachains && - parachains.forEach((parachain: any) => { - collators = []; - parachain.nodes.forEach((n: any) => { - collators.push({ - name: n.name, - command: "adder-collator", - ...DEFAULT_NODE_VALUES, - }); - }); - paras.push({ - id: parachain.id, - collators, - }); - }); - - collators = []; - - simpleParachains && - simpleParachains.forEach((sp: any) => { - collators.push({ - name: sp.name, - command: "adder-collator", - ...DEFAULT_NODE_VALUES, - }); - paras.push({ - id: sp.id, - collators, - }); - }); - - if (relaychain?.nodes) { - relaychain.nodes.forEach((n: any) => { - nodes.push({ - name: `"${n.name}"`, - ...DEFAULT_NODE_VALUES, - }); - }); - } - - jsonOutput = { - relaychain: { - default_image: "docker.io/paritypr/polkadot-debug:master", - default_command: "polkadot", - default_args: ["-lparachain=debug"], - chain: relaychain?.chain || "", - nodes, - genesis: relaychain?.genesis, - }, - types, - hrmp_channels: hrmpChannels || [], - parachains: paras, - }; - - fs.writeFile( - `${fullPath}/${fileName}-zombienet.json`, - JSON.stringify(jsonOutput), - (error: any) => { - if (error) throw error; - }, - ); - console.log( - `Converted JSON config exists now under: ${fullPath}/${fileName}-zombienet.json`, - ); -} - // Ensure to log the uncaught exceptions // to debug the problem, also exit because we don't know // what happens there. @@ -352,12 +83,7 @@ program ["podman", "kubernetes", "native"], ), ) - .addOption( - new Option( - "-m, --monitor", - "Start as monitor, do not auto cleanup network", - ), - ) + .addOption( new Option( "-d, --dir ", @@ -371,7 +97,13 @@ program .description("Spawn the network defined in the config") .argument("", "Network config file path") .argument("[creds]", "kubeclt credentials file") - .action(spawn); + .addOption( + new Option( + "-m, --monitor", + "Start as monitor, do not auto cleanup network", + ), + ) + .action(asyncAction(spawn)); program .command("test") @@ -381,7 +113,7 @@ program "[runningNetworkSpec]", "Path to the network spec json, for using a running network for running the test", ) - .action(test); + .action(asyncAction(test)); program .command("setup") @@ -394,7 +126,7 @@ program "zombienet setup polkadot polkadot-parachain", )}`, ) - .action(setup); + .action(asyncAction(setup)); program .command("convert") @@ -405,7 +137,7 @@ program "", `Expecting 1 mandatory param which is the path of the polkadot-lauch configuration file (could be either a .js or .json file).`, ) - .action(convert); + .action(asyncAction(convert)); program .command("version") @@ -416,264 +148,21 @@ program process.exit(0); }); -/** - * Spawn - spawns ephemeral networks, providing a simple but poweful cli that allow you to declare - * the desired network in toml or json format. - * Read more here: https://paritytech.github.io/zombienet/cli/spawn.html - * @param configFile: config file, supported both json and toml formats - * @param credsFile: Credentials file name or path> to use (Only> with kubernetes provider), we look - * in the current directory or in $HOME/.kube/ if a filename is passed. - * @param _opts - */ -async function spawn( - configFile: string, - credsFile: string | undefined, - _opts: any, -) { - const opts = program.opts(); - const dir = opts.dir || ""; - const force = opts.force || false; - const monitor = opts.monitor || false; - // By default spawn pods/process in batches of 4, - // since this shouldn't be a bottleneck in most of the cases, - // but also can be set with the `-c` flag. - const spawnConcurrency = opts.spawnConcurrency || 4; - const configPath = resolve(process.cwd(), configFile); - if (!fs.existsSync(configPath)) { - console.error( - `${decorators.reverse( - decorators.red(` āš  Config file does not exist: ${configPath}`), - )}`, - ); - process.exit(); - } - - const filePath = resolve(configFile); - const config: LaunchConfig = readNetworkConfig(filePath); - - // set default provider and timeout if not provided - if (!config.settings) { - config.settings = { - provider: DEFAULT_PROVIDER, - timeout: DEFAULT_GLOBAL_TIMEOUT, - }; - } else { - if (!config.settings.provider) config.settings.provider = DEFAULT_PROVIDER; - if (!config.settings.timeout) - config.settings.timeout = DEFAULT_GLOBAL_TIMEOUT; - } - - // if a provider is passed, let just use it. - if (opts.provider && AVAILABLE_PROVIDERS.includes(opts.provider)) { - config.settings.provider = opts.provider; - } - - let creds = ""; - if (config.settings?.provider === "kubernetes") { - creds = getCredsFilePath(credsFile || "config") || ""; - if (!creds) { - console.log( - `Running ${config.settings?.provider || DEFAULT_PROVIDER} provider:`, - ); - console.error( - `${decorators.reverse( - decorators.red(` āš  I can't find the Creds file: ${credsFile}`), - )}`, - ); - process.exit(); - } - } +program.parse(process.argv); - const inCI = process.env.RUN_IN_CONTAINER === "1"; - const options = { - monitor, - spawnConcurrency, - dir, - force, - inCI, - silent: false, +function asyncAction(cmd: Function) { + return function () { + const args = [...arguments]; + (async () => { + try { + if (cmd.name == "spawn") network = await cmd.apply(null, args); + else await cmd.apply(null, args); + } catch (err) { + console.log( + `\n ${decorators.red("Error: ")} \t ${decorators.bright(err)}\n`, + ); + process.exit(1); + } + })(); }; - network = await start(creds, config, options); - network.showNetworkInfo(config.settings?.provider); } - -/** - * Test - performs test/assertions agins the spawned network, using a set of natural - * language expressions that allow to make assertions based on metrics, logs and some - * built-in function that query the network using polkadot.js - * Read more here: https://paritytech.github.io/zombienet/cli/testing.html - * @param testFile - * @param runningNetworkSpec - * @param _opts - */ -async function test( - testFile: string, - runningNetworkSpec: string | undefined, - _opts: any, -) { - const opts = program.opts(); - const dir = opts.dir || ""; - - let extension = testFile.slice(testFile.lastIndexOf(".") + 1); - - if (extension !== "zndsl") { - console.log( - `\n ${decorators.red( - "Error:", - )} File extension is not correct. Extension for tests should be '.zndsl'.\n`, - ); - } - - process.env.DEBUG = "zombie"; - const inCI = process.env.RUN_IN_CONTAINER === "1"; - // use `k8s` as default - const providerToUse = - opts.provider && AVAILABLE_PROVIDERS.includes(opts.provider) - ? opts.provider - : "kubernetes"; - - const configBasePath = path.dirname(testFile); - const env = new Environment(new RelativeLoader([configBasePath])); - const templateContent = fs.readFileSync(testFile).toString(); - const content = env.renderString(templateContent, process.env); - - const testName = getTestNameFromFileName(testFile); - - let testDef: TestDefinition; - try { - testDef = JSON.parse(parser.parse_to_json(content)); - } catch (e) { - console.log(`\n ${decorators.red("Error:")} \t ${decorators.bright(e)}\n`); - process.exit(1); - } - - await run( - configBasePath, - testName, - testDef, - providerToUse, - inCI, - opts.spawnConcurrency, - false, - runningNetworkSpec, - dir, - ); -} - -/** - * Setup - easily download latest artifacts and make them executablein order to use them with zombienet - * Read more here: https://paritytech.github.io/zombienet/cli/setup.html - * @param params binaries that willbe downloaded and set up. Possible values: `polkadot` `polkadot-parachain` - * @returns - */ -async function setup(params: any) { - const POSSIBLE_BINARIES = ["polkadot", "polkadot-parachain"]; - - console.log(decorators.green("\n\nšŸ§ŸšŸ§ŸšŸ§Ÿ ZombieNet Setup šŸ§ŸšŸ§ŸšŸ§Ÿ\n\n")); - if ( - ["aix", "freebsd", "openbsd", "sunos", "win32"].includes(process.platform) - ) { - console.log( - "Zombienet currently supports linux and MacOS. \n Alternative, you can use k8s or podman. For more read here: https://github.com/paritytech/zombienet#requirements-by-provider", - ); - return; - } - - console.log(decorators.green("Gathering latest releases' versions...\n")); - await new Promise((resolve) => { - latestPolkadotReleaseURL("polkadot", "polkadot").then( - (res: [string, string]) => { - options.polkadot = { - name: "polkadot", - url: res[0], - size: res[1], - }; - resolve(); - }, - ); - }); - - await new Promise((resolve) => { - latestPolkadotReleaseURL("cumulus", "polkadot-parachain").then( - (res: [string, string]) => { - options["polkadot-parachain"] = { - name: "polkadot-parachain", - url: res[0], - size: res[1], - }; - resolve(); - }, - ); - }); - - // If the platform is MacOS then the polkadot repo needs to be cloned and run locally by the user - // as polkadot do not release a binary for MacOS - if (process.platform === "darwin" && params.includes("polkadot")) { - console.log( - `${decorators.yellow( - "Note: ", - )} You are using MacOS. Please, clone the polkadot repo ` + - decorators.cyan("(https://github.com/paritytech/polkadot)") + - ` and run it locally.\n At the moment there is no polkadot binary for MacOs.\n\n`, - ); - const index = params.indexOf("polkadot"); - if (index !== -1) { - params.splice(index, 1); - } - } - - if (params.length === 0) { - console.log(decorators.green("No binaries to download. Exiting...")); - return; - } - let count = 0; - console.log("Setup will start to download binaries:"); - params.forEach((a: any) => { - if (!POSSIBLE_BINARIES.includes(a)) { - const index = params.indexOf(a); - index > -1 && params.splice(index, 1); - console.log( - decorators.red( - `"${a}" is not one of the possible options for this setup and will be skipped;`, - ), - decorators.green(` Valid options: polkadot polkadot-parachain`), - ); - return; - } - const size = parseInt(options[a]?.size || "0", 10); - count += size; - console.log("-", a, "\t Approx. size ", size, " MB"); - }); - console.log("Total approx. size: ", count, "MB"); - const response = await askQuestion( - decorators.yellow("\nDo you want to continue? (y/n)"), - ); - if (response.toLowerCase() !== "n" && response.toLowerCase() !== "y") { - console.log("Invalid input. Exiting..."); - return; - } - if (response.toLowerCase() === "n") { - return; - } - downloadBinaries(params); - return; -} - -async function convert(param: string) { - try { - const filePath = param; - - if (!filePath) { - throw Error("Path of configuration file was not provided"); - } - - // Read through the JSON and write to stream sample - await convertInput(filePath); - } catch (err) { - console.log( - `\n ${decorators.red("Error: ")} \t ${decorators.bright(err)}\n`, - ); - } -} - -program.parse(process.argv); From a0a89c33dbeff8853b30abee215b567aad31f019 Mon Sep 17 00:00:00 2001 From: Javier Viola Date: Mon, 3 Apr 2023 09:23:54 -0300 Subject: [PATCH 02/18] typo --- javascript/packages/cli/src/actions/setup.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/javascript/packages/cli/src/actions/setup.ts b/javascript/packages/cli/src/actions/setup.ts index fd268d2cc..1ccbc6f16 100644 --- a/javascript/packages/cli/src/actions/setup.ts +++ b/javascript/packages/cli/src/actions/setup.ts @@ -88,7 +88,7 @@ export async function setup(params: any) { ); return; } - const size = parseInt(opts[a]?.size || "0", 10); + const size = parseInt(options[a]?.size || "0", 10); count += size; console.log("-", a, "\t Approx. size ", size, " MB"); }); From 2fa87f60a79ae3bbf80f33a2b0b187ed8ce0b678 Mon Sep 17 00:00:00 2001 From: Javier Viola Date: Mon, 3 Apr 2023 10:30:07 -0300 Subject: [PATCH 03/18] Update javascript/packages/cli/src/cli.ts Co-authored-by: Loris Moulin <45130584+l0r1s@users.noreply.github.com> --- javascript/packages/cli/src/cli.ts | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/javascript/packages/cli/src/cli.ts b/javascript/packages/cli/src/cli.ts index b8bb914ae..87ab30210 100644 --- a/javascript/packages/cli/src/cli.ts +++ b/javascript/packages/cli/src/cli.ts @@ -155,8 +155,11 @@ function asyncAction(cmd: Function) { const args = [...arguments]; (async () => { try { - if (cmd.name == "spawn") network = await cmd.apply(null, args); - else await cmd.apply(null, args); + if (cmd.name == "spawn") { + network = await cmd.apply(null, args); + } else { + await cmd.apply(null, args); + } } catch (err) { console.log( `\n ${decorators.red("Error: ")} \t ${decorators.bright(err)}\n`, From ffa563d677083bfa0a0b1b1b1ef3dde9bdab7d7a Mon Sep 17 00:00:00 2001 From: Javier Viola Date: Mon, 3 Apr 2023 10:58:39 -0300 Subject: [PATCH 04/18] fmt --- javascript/packages/cli/src/cli.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/javascript/packages/cli/src/cli.ts b/javascript/packages/cli/src/cli.ts index 87ab30210..dfff4e332 100644 --- a/javascript/packages/cli/src/cli.ts +++ b/javascript/packages/cli/src/cli.ts @@ -156,9 +156,9 @@ function asyncAction(cmd: Function) { (async () => { try { if (cmd.name == "spawn") { - network = await cmd.apply(null, args); - } else { - await cmd.apply(null, args); + network = await cmd.apply(null, args); + } else { + await cmd.apply(null, args); } } catch (err) { console.log( From 1aa89837518868ce0ad94d2d6b66953f073aec9c Mon Sep 17 00:00:00 2001 From: Javier Viola Date: Mon, 3 Apr 2023 13:53:26 -0300 Subject: [PATCH 05/18] typo in path --- javascript/packages/cli/src/actions/convert.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/javascript/packages/cli/src/actions/convert.ts b/javascript/packages/cli/src/actions/convert.ts index 9bf18d41e..15b64ac10 100644 --- a/javascript/packages/cli/src/actions/convert.ts +++ b/javascript/packages/cli/src/actions/convert.ts @@ -7,7 +7,7 @@ import type { import { decorators, getFilePathNameExt } from "@zombienet/utils"; import fs from "fs"; import path from "path"; -import { DEFAULT_BALANCE } from "src/constants"; +import { DEFAULT_BALANCE } from "../constants"; export async function convert(param: string) { try { From a4a073b0e852c9fe8e85d5d740fa50ecb75e1c51 Mon Sep 17 00:00:00 2001 From: Javier Viola Date: Wed, 5 Apr 2023 09:37:40 -0300 Subject: [PATCH 06/18] Update javascript/packages/cli/src/actions/convert.ts Co-authored-by: Loris Moulin <45130584+l0r1s@users.noreply.github.com> --- javascript/packages/cli/src/actions/convert.ts | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/javascript/packages/cli/src/actions/convert.ts b/javascript/packages/cli/src/actions/convert.ts index 15b64ac10..88b7b6585 100644 --- a/javascript/packages/cli/src/actions/convert.ts +++ b/javascript/packages/cli/src/actions/convert.ts @@ -32,16 +32,13 @@ async function readInputFile( ext: string, fPath: string, ): Promise { - let json: object; if (ext === "json" || ext === "js") { - json = - ext === "json" + return ext === "json" ? JSON.parse(fs.readFileSync(`${fPath}`, "utf8")) : await import(path.resolve(fPath)); - } else { - throw Error("No valid extension was found."); } - return json; + + throw Error("No valid extension was found."); } async function convertInput(filePath: string) { From 55e6e275649a5e27bf7118c42ebe43ba1fa87793 Mon Sep 17 00:00:00 2001 From: Javier Viola Date: Wed, 5 Apr 2023 09:51:39 -0300 Subject: [PATCH 07/18] Update javascript/packages/cli/src/actions/convert.ts Co-authored-by: Loris Moulin <45130584+l0r1s@users.noreply.github.com> --- javascript/packages/cli/src/actions/convert.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/javascript/packages/cli/src/actions/convert.ts b/javascript/packages/cli/src/actions/convert.ts index 88b7b6585..a9e954449 100644 --- a/javascript/packages/cli/src/actions/convert.ts +++ b/javascript/packages/cli/src/actions/convert.ts @@ -46,7 +46,7 @@ async function convertInput(filePath: string) { const convertedJson = await readInputFile(extension, filePath); - const { relaychain, parachains, simpleParachains, hrmpChannels, types } = + const { relaychain, parachains = [], simpleParachains = [], hrmpChannels = [], types } = convertedJson; let jsonOutput: PolkadotLaunchConfig; From 4fae2d2495b5aecbc001f70ea18a8e47af03c777 Mon Sep 17 00:00:00 2001 From: Javier Viola Date: Wed, 5 Apr 2023 09:51:49 -0300 Subject: [PATCH 08/18] Update javascript/packages/cli/src/actions/convert.ts Co-authored-by: Loris Moulin <45130584+l0r1s@users.noreply.github.com> --- javascript/packages/cli/src/actions/convert.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/javascript/packages/cli/src/actions/convert.ts b/javascript/packages/cli/src/actions/convert.ts index a9e954449..85cdc927f 100644 --- a/javascript/packages/cli/src/actions/convert.ts +++ b/javascript/packages/cli/src/actions/convert.ts @@ -51,7 +51,7 @@ async function convertInput(filePath: string) { let jsonOutput: PolkadotLaunchConfig; const nodes: NodeConfig[] = []; - const paras: ParachainConfig[] = []; + let paras: ParachainConfig[] = []; let collators: NodeConfig[] = []; const DEFAULT_NODE_VALUES = { From 319aea7c6df103387ec699669abb1dcccea36996 Mon Sep 17 00:00:00 2001 From: Javier Viola Date: Wed, 5 Apr 2023 09:52:22 -0300 Subject: [PATCH 09/18] Update javascript/packages/cli/src/actions/convert.ts Co-authored-by: Loris Moulin <45130584+l0r1s@users.noreply.github.com> --- javascript/packages/cli/src/actions/convert.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/javascript/packages/cli/src/actions/convert.ts b/javascript/packages/cli/src/actions/convert.ts index 85cdc927f..5a949ae51 100644 --- a/javascript/packages/cli/src/actions/convert.ts +++ b/javascript/packages/cli/src/actions/convert.ts @@ -60,7 +60,6 @@ async function convertInput(filePath: string) { balance: DEFAULT_BALANCE, }; - parachains && parachains.forEach((parachain: any) => { collators = []; parachain.nodes.forEach((n: any) => { From d34c26c7e4165718efa66b3c340c41a1823a3115 Mon Sep 17 00:00:00 2001 From: Javier Viola Date: Wed, 5 Apr 2023 09:52:31 -0300 Subject: [PATCH 10/18] Update javascript/packages/cli/src/actions/convert.ts Co-authored-by: Loris Moulin <45130584+l0r1s@users.noreply.github.com> --- javascript/packages/cli/src/actions/convert.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/javascript/packages/cli/src/actions/convert.ts b/javascript/packages/cli/src/actions/convert.ts index 5a949ae51..866d5f709 100644 --- a/javascript/packages/cli/src/actions/convert.ts +++ b/javascript/packages/cli/src/actions/convert.ts @@ -77,7 +77,6 @@ async function convertInput(filePath: string) { collators = []; - simpleParachains && simpleParachains.forEach((sp: any) => { collators.push({ name: sp.name, From 79f3fa0fcdeb84716e38bc61e984331479d72cf7 Mon Sep 17 00:00:00 2001 From: Javier Viola Date: Wed, 5 Apr 2023 09:52:41 -0300 Subject: [PATCH 11/18] Update javascript/packages/cli/src/actions/convert.ts Co-authored-by: Loris Moulin <45130584+l0r1s@users.noreply.github.com> --- javascript/packages/cli/src/actions/convert.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/javascript/packages/cli/src/actions/convert.ts b/javascript/packages/cli/src/actions/convert.ts index 866d5f709..0792a9639 100644 --- a/javascript/packages/cli/src/actions/convert.ts +++ b/javascript/packages/cli/src/actions/convert.ts @@ -75,7 +75,6 @@ async function convertInput(filePath: string) { }); }); - collators = []; simpleParachains.forEach((sp: any) => { collators.push({ From 65c01c9e5b7856b6e5182b839f19ee7675edc623 Mon Sep 17 00:00:00 2001 From: Javier Viola Date: Wed, 5 Apr 2023 09:52:52 -0300 Subject: [PATCH 12/18] Update javascript/packages/cli/src/actions/convert.ts Co-authored-by: Loris Moulin <45130584+l0r1s@users.noreply.github.com> --- javascript/packages/cli/src/actions/convert.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/javascript/packages/cli/src/actions/convert.ts b/javascript/packages/cli/src/actions/convert.ts index 0792a9639..e94ef5198 100644 --- a/javascript/packages/cli/src/actions/convert.ts +++ b/javascript/packages/cli/src/actions/convert.ts @@ -107,7 +107,7 @@ async function convertInput(filePath: string) { genesis: relaychain?.genesis, }, types, - hrmp_channels: hrmpChannels || [], + hrmp_channels: hrmpChannels parachains: paras, }; From 1193aee79584d1baf9b36612de76d87968cb276a Mon Sep 17 00:00:00 2001 From: Javier Viola Date: Wed, 5 Apr 2023 09:54:03 -0300 Subject: [PATCH 13/18] Update javascript/packages/cli/src/actions/setup.ts Co-authored-by: Loris Moulin <45130584+l0r1s@users.noreply.github.com> --- javascript/packages/cli/src/actions/setup.ts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/javascript/packages/cli/src/actions/setup.ts b/javascript/packages/cli/src/actions/setup.ts index 1ccbc6f16..eb813cbea 100644 --- a/javascript/packages/cli/src/actions/setup.ts +++ b/javascript/packages/cli/src/actions/setup.ts @@ -18,9 +18,7 @@ export async function setup(params: any) { const POSSIBLE_BINARIES = ["polkadot", "polkadot-parachain"]; console.log(decorators.green("\n\nšŸ§ŸšŸ§ŸšŸ§Ÿ ZombieNet Setup šŸ§ŸšŸ§ŸšŸ§Ÿ\n\n")); - if ( - ["aix", "freebsd", "openbsd", "sunos", "win32"].includes(process.platform) - ) { + if (!["linux", "darwin"].includes(process.platform)) { console.log( "Zombienet currently supports linux and MacOS. \n Alternative, you can use k8s or podman. For more read here: https://github.com/paritytech/zombienet#requirements-by-provider", ); From 7c9b1cdf52343468dc87e13ca4cb6fd580f98d89 Mon Sep 17 00:00:00 2001 From: Javier Viola Date: Wed, 5 Apr 2023 09:54:37 -0300 Subject: [PATCH 14/18] Update javascript/packages/cli/src/actions/setup.ts Co-authored-by: Loris Moulin <45130584+l0r1s@users.noreply.github.com> --- javascript/packages/cli/src/actions/setup.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/javascript/packages/cli/src/actions/setup.ts b/javascript/packages/cli/src/actions/setup.ts index eb813cbea..48bac5838 100644 --- a/javascript/packages/cli/src/actions/setup.ts +++ b/javascript/packages/cli/src/actions/setup.ts @@ -215,7 +215,7 @@ const latestPolkadotReleaseURL = async ( } return [ - `https://github.com/paritytech/${repo}/releases/download/${tag_name}/${name}`, + obj.browser_download_url convertBytes(obj.size), ]; } catch (err: any) { From 4709b11f61f1952ccfbed992dfa70305c293b3f3 Mon Sep 17 00:00:00 2001 From: Javier Viola Date: Wed, 5 Apr 2023 09:54:49 -0300 Subject: [PATCH 15/18] Update javascript/packages/cli/src/actions/setup.ts Co-authored-by: Loris Moulin <45130584+l0r1s@users.noreply.github.com> --- javascript/packages/cli/src/actions/setup.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/javascript/packages/cli/src/actions/setup.ts b/javascript/packages/cli/src/actions/setup.ts index 48bac5838..0b505e529 100644 --- a/javascript/packages/cli/src/actions/setup.ts +++ b/javascript/packages/cli/src/actions/setup.ts @@ -76,8 +76,7 @@ export async function setup(params: any) { console.log("Setup will start to download binaries:"); params.forEach((a: any) => { if (!POSSIBLE_BINARIES.includes(a)) { - const index = params.indexOf(a); - index > -1 && params.splice(index, 1); + params = params.filter(param => param !== a); console.log( decorators.red( `"${a}" is not one of the possible options for this setup and will be skipped;`, From 27f34a2636ae892e1403b38890391920514e69fb Mon Sep 17 00:00:00 2001 From: Javier Viola Date: Wed, 5 Apr 2023 09:55:49 -0300 Subject: [PATCH 16/18] Update javascript/packages/cli/src/actions/setup.ts Co-authored-by: Loris Moulin <45130584+l0r1s@users.noreply.github.com> --- javascript/packages/cli/src/actions/setup.ts | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/javascript/packages/cli/src/actions/setup.ts b/javascript/packages/cli/src/actions/setup.ts index 0b505e529..cdc8bdd53 100644 --- a/javascript/packages/cli/src/actions/setup.ts +++ b/javascript/packages/cli/src/actions/setup.ts @@ -62,10 +62,7 @@ export async function setup(params: any) { decorators.cyan("(https://github.com/paritytech/polkadot)") + ` and run it locally.\n At the moment there is no polkadot binary for MacOs.\n\n`, ); - const index = params.indexOf("polkadot"); - if (index !== -1) { - params.splice(index, 1); - } +params = params.filter(param => param !== "polkadot") } if (params.length === 0) { From d6ea40398798ec837b1c5ece064ea8a94433d724 Mon Sep 17 00:00:00 2001 From: Javier Viola Date: Wed, 5 Apr 2023 10:45:20 -0300 Subject: [PATCH 17/18] fix conflicts --- .../packages/cli/src/actions/convert.ts | 62 +++++++++---------- javascript/packages/cli/src/actions/setup.ts | 9 +-- javascript/packages/orchestrator/src/index.ts | 3 +- javascript/packages/orchestrator/src/types.ts | 34 +--------- 4 files changed, 34 insertions(+), 74 deletions(-) diff --git a/javascript/packages/cli/src/actions/convert.ts b/javascript/packages/cli/src/actions/convert.ts index e94ef5198..53e64536f 100644 --- a/javascript/packages/cli/src/actions/convert.ts +++ b/javascript/packages/cli/src/actions/convert.ts @@ -1,12 +1,12 @@ import type { NodeConfig, - PL_ConfigType, ParachainConfig, PolkadotLaunchConfig, } from "@zombienet/orchestrator"; import { decorators, getFilePathNameExt } from "@zombienet/utils"; import fs from "fs"; import path from "path"; +import { PL_ConfigType, PL_NodesConfig } from "src/types"; import { DEFAULT_BALANCE } from "../constants"; export async function convert(param: string) { @@ -33,11 +33,11 @@ async function readInputFile( fPath: string, ): Promise { if (ext === "json" || ext === "js") { - return ext === "json" - ? JSON.parse(fs.readFileSync(`${fPath}`, "utf8")) - : await import(path.resolve(fPath)); + return ext === "json" + ? JSON.parse(fs.readFileSync(`${fPath}`, "utf8")) + : await import(path.resolve(fPath)); } - + throw Error("No valid extension was found."); } @@ -46,13 +46,17 @@ async function convertInput(filePath: string) { const convertedJson = await readInputFile(extension, filePath); - const { relaychain, parachains = [], simpleParachains = [], hrmpChannels = [], types } = - convertedJson; + const { + relaychain, + parachains = [], + simpleParachains = [], + hrmpChannels = [], + types, + } = convertedJson; let jsonOutput: PolkadotLaunchConfig; const nodes: NodeConfig[] = []; let paras: ParachainConfig[] = []; - let collators: NodeConfig[] = []; const DEFAULT_NODE_VALUES = { validator: true, @@ -60,33 +64,23 @@ async function convertInput(filePath: string) { balance: DEFAULT_BALANCE, }; - parachains.forEach((parachain: any) => { - collators = []; - parachain.nodes.forEach((n: any) => { - collators.push({ - name: n.name, - command: "adder-collator", - ...DEFAULT_NODE_VALUES, - }); - }); - paras.push({ - id: parachain.id, - collators, - }); - }); - - - simpleParachains.forEach((sp: any) => { - collators.push({ - name: sp.name, + paras = paras.concat( + parachains.map(({ id, nodes }) => ({ + id, + collators: ((nodes as PL_NodesConfig[]) || []).map(({ name }) => ({ + name, command: "adder-collator", ...DEFAULT_NODE_VALUES, - }); - paras.push({ - id: sp.id, - collators, - }); - }); + })), + })), + ); + + paras = paras.concat( + simpleParachains.map(({ id, name }) => ({ + id, + collators: [{ name, command: "adder-collator", ...DEFAULT_NODE_VALUES }], + })), + ); if (relaychain?.nodes) { relaychain.nodes.forEach((n: any) => { @@ -107,7 +101,7 @@ async function convertInput(filePath: string) { genesis: relaychain?.genesis, }, types, - hrmp_channels: hrmpChannels + hrmp_channels: hrmpChannels, parachains: paras, }; diff --git a/javascript/packages/cli/src/actions/setup.ts b/javascript/packages/cli/src/actions/setup.ts index cdc8bdd53..4f808f0cf 100644 --- a/javascript/packages/cli/src/actions/setup.ts +++ b/javascript/packages/cli/src/actions/setup.ts @@ -62,7 +62,7 @@ export async function setup(params: any) { decorators.cyan("(https://github.com/paritytech/polkadot)") + ` and run it locally.\n At the moment there is no polkadot binary for MacOs.\n\n`, ); -params = params.filter(param => param !== "polkadot") + params = params.filter((param: string) => param !== "polkadot"); } if (params.length === 0) { @@ -73,7 +73,7 @@ params = params.filter(param => param !== "polkadot") console.log("Setup will start to download binaries:"); params.forEach((a: any) => { if (!POSSIBLE_BINARIES.includes(a)) { - params = params.filter(param => param !== a); + params = params.filter((param: any) => param !== a); console.log( decorators.red( `"${a}" is not one of the possible options for this setup and will be skipped;`, @@ -210,10 +210,7 @@ const latestPolkadotReleaseURL = async ( ); } - return [ - obj.browser_download_url - convertBytes(obj.size), - ]; + return [obj.browser_download_url, convertBytes(obj.size)]; } catch (err: any) { if (err.code === "ENOTFOUND") { throw new Error("Network error."); diff --git a/javascript/packages/orchestrator/src/index.ts b/javascript/packages/orchestrator/src/index.ts index 275276a95..6b94c02b7 100644 --- a/javascript/packages/orchestrator/src/index.ts +++ b/javascript/packages/orchestrator/src/index.ts @@ -3,9 +3,10 @@ export { start, test } from "./orchestrator"; export { Providers } from "./providers"; export { run } from "./test-runner"; export { + HrmpChannelsConfig, LaunchConfig, NodeConfig, - PL_ConfigType, + ObjectJSON, ParachainConfig, PolkadotLaunchConfig, TestDefinition, diff --git a/javascript/packages/orchestrator/src/types.ts b/javascript/packages/orchestrator/src/types.ts index bcabedfb4..c18320fec 100644 --- a/javascript/packages/orchestrator/src/types.ts +++ b/javascript/packages/orchestrator/src/types.ts @@ -262,7 +262,7 @@ export interface Override { remote_name: string; } -interface ObjectJSON { +export interface ObjectJSON { [key: string]: ObjectJSON | number | string; } @@ -315,35 +315,3 @@ export interface FnArgs { after?: number; seconds?: number; } - -// Config interfaces -interface PL_NodesConfig { - name: string; - wsPort: number; - port: number; - flags?: [string]; -} - -interface PL_RelayChainConfig { - bin?: string; - chain: string; - nodes: [NodeConfig]; - genesis?: JSON | ObjectJSON; -} - -interface PL_ParaChainConfig { - bin?: string; - id: number; - port?: string; - balance?: string; - nodes: [PL_NodesConfig]; -} - -export interface PL_ConfigType { - relaychain?: PL_RelayChainConfig; - parachains?: [PL_ParaChainConfig]; - simpleParachains?: [PL_NodesConfig & { id: number }]; - hrmpChannels?: HrmpChannelsConfig[]; - types?: any; - finalization?: boolean; -} From 520a984829f6b20bf0b46ab399521ef2211f77ef Mon Sep 17 00:00:00 2001 From: Javier Viola Date: Wed, 5 Apr 2023 11:13:35 -0300 Subject: [PATCH 18/18] types for cli --- javascript/packages/cli/src/types.ts | 34 ++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 javascript/packages/cli/src/types.ts diff --git a/javascript/packages/cli/src/types.ts b/javascript/packages/cli/src/types.ts new file mode 100644 index 000000000..3002dc257 --- /dev/null +++ b/javascript/packages/cli/src/types.ts @@ -0,0 +1,34 @@ +import type { HrmpChannelsConfig, ObjectJSON } from "@zombienet/orchestrator"; + +// Config interfaces +export interface PL_NodesConfig { + name: string; + wsPort: number; + port: number; + flags?: [string]; +} + +export interface PL_RelayChainConfig { + bin?: string; + chain: string; + nodes: [PL_NodesConfig]; + genesis?: JSON | ObjectJSON; +} + +export interface PL_ParaChainConfig { + bin?: string; + name?: string; + id: number; + port?: string; + balance?: string; + nodes: [PL_NodesConfig]; +} + +export interface PL_ConfigType { + relaychain?: PL_RelayChainConfig; + parachains?: [PL_ParaChainConfig]; + simpleParachains?: [PL_NodesConfig & { id: number }]; + hrmpChannels?: HrmpChannelsConfig[]; + types?: any; + finalization?: boolean; +}