From db18f020aec53df8603bf11fd04b2269113970fe Mon Sep 17 00:00:00 2001 From: Tarik Gul <47201679+TarikGul@users.noreply.github.com> Date: Fri, 1 Oct 2021 13:18:07 -0400 Subject: [PATCH] fix: refactor e2e chain tests (#687) * fix: refactor e2e chain tests * lint --- scripts/runChainTests.ts | 108 ++++-------------------------------- scripts/runYarnPack.ts | 38 ++++++++----- scripts/sidecarScriptApi.ts | 8 +-- 3 files changed, 41 insertions(+), 113 deletions(-) diff --git a/scripts/runChainTests.ts b/scripts/runChainTests.ts index eab53001d..78d94f629 100644 --- a/scripts/runChainTests.ts +++ b/scripts/runChainTests.ts @@ -1,68 +1,11 @@ import { ArgumentParser, Namespace } from 'argparse'; -import { ChildProcessWithoutNullStreams, spawn } from 'child_process'; import { config, defaultSasBuildOpts } from './config'; -import { IProcOpts, StatusCode } from './types'; +import { killAll, launchProcess, setWsUrl } from './sidecarScriptApi'; +import { ProcsType, StatusCode } from './types'; // Stores all the processes -const procs: { [key: string]: ChildProcessWithoutNullStreams } = {}; - -// Set the env variable for SAS_SUBSTRATE_WS_URL -const setWsUrl = (url: string): void => { - process.env.SAS_SUBSTRATE_WS_URL = url; -}; - -/** - * Launch any given process. It accepts an options object. - * - * { - * proc => the name of the process to be saved in our cache - * resolver => If the stdout contains the resolver it will resolve the process - * resolverStartupErr => If the stderr contains the resolver it will resolve the process - * args => an array of args to be attached to the `yarn` command. - * } - * - * @param IProcOpts - */ -const launchProcess = async ({ - proc, - resolver, - resolverStartupErr, - args, -}: IProcOpts): Promise => { - return new Promise((resolve, reject) => { - const { Success, Failed } = StatusCode; - - const command = 'yarn'; - - procs[proc] = spawn(command, args, { detached: true }); - - procs[proc].stdout.on('data', (data: Buffer) => { - console.log(data.toString()); - - if (data.toString().includes(resolver)) { - resolve(Success); - } - }); - - procs[proc].stderr.on('data', (data: Buffer) => { - console.error(data.toString()); - - if (resolverStartupErr && data.toString().includes(resolverStartupErr)) { - resolve(Failed); - } - }); - - procs[proc].on('close', () => { - resolve(Success); - }); - - procs[proc].on('error', (err) => { - console.log(err); - reject(Failed); - }); - }); -}; +const procs: ProcsType = {}; /** * Launches Sidecar, and if successful it will launch the jest runner. This operation @@ -78,54 +21,27 @@ const launchChainTest = async (chain: string): Promise => { setWsUrl(wsUrl); console.log('Launching Sidecar...'); - const sidecarStart = await launchProcess(SasStartOpts); + const sidecarStart = await launchProcess('yarn', procs, SasStartOpts); if (sidecarStart === Success) { // Sidecar successfully launched, and jest will now get called console.log('Launching jest...'); - const jest = await launchProcess(JestProcOpts); + const jest = await launchProcess('yarn', procs, JestProcOpts); if (jest === Success) { - killAll(); + killAll(procs); return true; } else { - killAll(); + killAll(procs); return false; } } else { console.error('Error launching sidecar... exiting...'); - killAll(); + killAll(procs); process.exit(1); } }; -// Kill all processes spawned and tracked by this file. -const killAll = () => { - console.log('Killing all processes...'); - for (const key of Object.keys(procs)) { - if (!procs[key].killed) { - try { - console.log(`Killing ${key}`); - // Kill child and all its descendants. - process.kill(-procs[key].pid, 'SIGTERM'); - process.kill(-procs[key].pid, 'SIGKILL'); - } catch (e) { - /** - * The error we are catching here silently, is when `-procs[key].pid` takes - * the range of all pid's inside of the subprocess group created with - * `spawn`, and one of the process's is either already closed or doesn't exist anymore. - * - * ex: `Error: kill ESRCH` - * - * This is a very specific use case of an empty catch block and is used - * outside of the scope of the API therefore justifiable, and should be used cautiously - * elsewhere. - */ - } - } - } -}; - const checkTests = (...args: boolean[]) => { const testStatus = args.every((test) => test); @@ -143,13 +59,13 @@ const main = async (args: Namespace): Promise => { // Build sidecar console.log('Building Sidecar...'); - const sidecarBuild = await launchProcess(defaultSasBuildOpts); + const sidecarBuild = await launchProcess('yarn', procs, defaultSasBuildOpts); // When sidecar fails to build, we kill all process's and exit if (sidecarBuild === Failed) { console.error('Sidecar failed to build, exiting...'); // Kill all processes - killAll(); + killAll(procs); // Exit program process.exit(); } @@ -188,7 +104,7 @@ const args = parser.parse_args() as Namespace; */ process.on('SIGINT', function () { console.log('Caught interrupt signal'); - killAll(); + killAll(procs); process.exit(); }); @@ -197,7 +113,7 @@ process.on('SIGINT', function () { */ process.on('SIGHUP', function () { console.log('Caught terminal termination'); - killAll(); + killAll(procs); process.exit(); }); diff --git a/scripts/runYarnPack.ts b/scripts/runYarnPack.ts index 5b239886e..50ddb1140 100644 --- a/scripts/runYarnPack.ts +++ b/scripts/runYarnPack.ts @@ -19,11 +19,17 @@ const cleanup = async () => { resolver: 'YN0000: Done', args: ['remove', '@substrate/api-sidecar'], }; - const sidecarUnInstallPack = await launchProcess('yarn', procs, sasUnInstallPackOpts); + const sidecarUnInstallPack = await launchProcess( + 'yarn', + procs, + sasUnInstallPackOpts + ); if (sidecarUnInstallPack === Failed) { console.error('UnInstalling sidecar package failed..'); - console.error('Please uninstall the package using `yarn remove @substrate/api-sidecar`.'); + console.error( + 'Please uninstall the package using `yarn remove @substrate/api-sidecar`.' + ); killAll(procs); } @@ -36,11 +42,13 @@ const cleanup = async () => { resolver: '', args: ['-rf', `${__dirname}/../../package.tgz`], }; - const deleteTarball = await launchProcess('rm', procs, sasDeleteTarballOpts); + const deleteTarball = await launchProcess('rm', procs, sasDeleteTarballOpts); if (deleteTarball === Failed) { console.error('Error deleting tarball.'); - console.error('In order to delete tarball run: `rm -rf ./package.tgz` from the root directory of the repository.'); + console.error( + 'In order to delete tarball run: `rm -rf ./package.tgz` from the root directory of the repository.' + ); killAll(procs); } }; @@ -85,7 +93,11 @@ const main = async () => { resolver: 'YN0000: Done', args: ['add', `${__dirname}/../../package.tgz`], }; - const sidecarInstallPack = await launchProcess('yarn', procs, sasInstallPackOpts); + const sidecarInstallPack = await launchProcess( + 'yarn', + procs, + sasInstallPackOpts + ); if (sidecarInstallPack === Failed) { console.error('Installing the binary failed..'); @@ -96,7 +108,7 @@ const main = async () => { /** * Start sidecar and see if it works */ - setWsUrl('wss://kusama-rpc.polkadot.io'); + setWsUrl('wss://kusama-rpc.polkadot.io'); console.log('Initializing Sidecar'); const sasStartPackOpts = { proc: 'sidecar', @@ -107,7 +119,7 @@ const main = async () => { const sidecarStart = await launchProcess( `${__dirname}/../../node_modules/.bin/substrate-api-sidecar`, procs, - sasStartPackOpts + sasStartPackOpts ); if (sidecarStart === Success) { @@ -127,18 +139,18 @@ const main = async () => { * Signal interrupt */ process.on('SIGINT', function () { - console.log('Caught interrupt signal'); - killAll(procs); - process.exit(); + console.log('Caught interrupt signal'); + killAll(procs); + process.exit(); }); /** * Signal hangup terminal */ process.on('SIGHUP', function () { - console.log('Caught terminal termination'); - killAll(procs); - process.exit(); + console.log('Caught terminal termination'); + killAll(procs); + process.exit(); }); main().finally(() => process.exit()); diff --git a/scripts/sidecarScriptApi.ts b/scripts/sidecarScriptApi.ts index a971789ff..a6483b04e 100644 --- a/scripts/sidecarScriptApi.ts +++ b/scripts/sidecarScriptApi.ts @@ -4,11 +4,11 @@ import { IProcOpts, ProcsType, StatusCode } from './types'; /** * Sets the url that sidecar will use in the env - * + * * @param url ws url used in sidecar */ export const setWsUrl = (url: string): void => { - process.env.SAS_SUBSTRATE_WS_URL = url; + process.env.SAS_SUBSTRATE_WS_URL = url; }; /** @@ -46,7 +46,7 @@ export const killAll = (procs: ProcsType): void => { * Launch any given process. It accepts an options object. * * @param cmd Optional Command will default to 'yarn' - * @param procs Object of saved processes + * @param procs Object of saved processes * @param IProcOpts * { * proc => the name of the process to be saved in our cache @@ -58,7 +58,7 @@ export const killAll = (procs: ProcsType): void => { export const launchProcess = ( cmd: string, procs: ProcsType, - { proc, resolver, resolverStartupErr, args }: IProcOpts, + { proc, resolver, resolverStartupErr, args }: IProcOpts ): Promise => { return new Promise((resolve, reject) => { const { Success, Failed } = StatusCode;