diff --git a/.circleci/config.yml b/.circleci/config.yml index c2b9f6ae9b..9c9176b3e8 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -22,6 +22,19 @@ commands: sudo apt-get update \ && sudo apt-get install -y git clang curl libssl-dev \ && git config --global url."https://github.com/paritytech/".insteadOf https://github.com/paritytech// + prepare_launch_env: + steps: + - attach_workspace: + at: /tmp/workspace + - run: + name: Load Archived Docker Image + command: docker load -i /tmp/workspace/image.tar + - checkout + - run: + name: Build PINT launch Image + command: | + git submodule update --init + docker build -f docker/launch.Dockerfile -t launch . cargo_audit_setup: description: Install cargo-audit steps: @@ -147,29 +160,30 @@ jobs: executor: test-executor description: Build and run e2e tests steps: - - attach_workspace: - at: /tmp/workspace - - run: - name: Load Archived Docker Image - command: docker load -i /tmp/workspace/image.tar - - checkout - - run: - name: Build PINT launch Image - command: | - git submodule update --init - docker build -f docker/launch.Dockerfile -t launch . + - prepare_launch_env - run: name: Run e2e tests + command: | + sudo curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.38.0/install.sh | \ + sudo bash \ + && nvm install v15.9.0 \ + && nvm use v15.9.0 \ + && npm install yarn -g \ + && cd js/e2e && yarn && yarn start + docker-run-finalize: + executor: test-executor + description: Build and run finalization tests + steps: + - prepare_launch_env + - run: + name: Run finalization tests command: | - sudo curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.38.0/install.sh | sudo bash \ - && source ~/.bashrc \ + sudo curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.38.0/install.sh | \ + sudo bash \ && nvm install v15.9.0 \ && nvm use v15.9.0 \ && npm install yarn -g \ - && cd js/e2e \ - && yarn \ - && yarn start - + && cd js/finalize && yarn && yarn start docker-publish-latest: executor: test-executor description: Publish latest Docker Image @@ -216,6 +230,9 @@ workflows: - docker-run-e2e: requires: - docker-build-release + - docker-run-finalize: + requires: + - docker-build-release - docker-publish-latest: requires: - docker-build-release diff --git a/js/e2e/src/launch.ts b/js/e2e/src/launch.ts index 33403351bd..ec822aa6f6 100644 --- a/js/e2e/src/launch.ts +++ b/js/e2e/src/launch.ts @@ -32,6 +32,8 @@ export async function docker(stdio?: StdioOptions): Promise { [ "docker", "run", + "--name", + "launch", "-p", "9988:9988", "-p", diff --git a/js/e2e/src/runner.ts b/js/e2e/src/runner.ts index 07b96614ed..070dff6547 100644 --- a/js/e2e/src/runner.ts +++ b/js/e2e/src/runner.ts @@ -25,7 +25,7 @@ interface TxResult { } // Message of launching complete -const LAUNCH_COMPLETE: string = "POLKADOT LAUNCH COMPLETE"; +export const LAUNCH_COMPLETE: string = "POLKADOT LAUNCH COMPLETE"; // Kill subprocesses function killAll(ps: ChildProcess, exitCode: number) { @@ -108,7 +108,9 @@ export default class Runner implements Config { }); // Log errors - ps.stderr.on("data", (chunk: Buffer) => console.log(chunk.toString())); + ps.stderr.on("data", (chunk: Buffer) => + process.stderr.write(chunk.toString()) + ); // Kill all processes when exiting. process.on("exit", () => { diff --git a/js/finalize/index.ts b/js/finalize/index.ts new file mode 100644 index 0000000000..6407ad4ade --- /dev/null +++ b/js/finalize/index.ts @@ -0,0 +1,96 @@ +/** + * Test the finalization of parachain intergration + */ +import fs from "fs"; +import path from "path"; +import { Launch } from "@pint/e2e/src"; +import findUp from "find-up"; +import { ChildProcess, spawn } from "child_process"; + +// Message of launching complete +const LAUNCH_COMPLETE: string = "POLKADOT LAUNCH COMPLETE"; + +// PINT finalization regex +const PINT_FINALIZE: RegExp = /\[Parachain\].*finalized #(\d)/; + +// Kill subprocesses +function killAll(ps: ChildProcess, exitCode: number) { + try { + ps.send && !ps.killed && ps.send("exit"); + ps.kill("SIGINT"); + } catch (e) { + if (e.code !== "EPERM") { + process.stdout.write(e); + process.exit(2); + } + } + + process.exit(exitCode); +} + +/** + * Tail file and done when got expected message + */ +async function tail( + file: string, + match: (s: string) => boolean +): Promise { + const root = await findUp("Cargo.toml"); + + return new Promise(async (resolve) => { + const ps = fs.existsSync(path.resolve(String(root), "../bin/pint")) + ? spawn("tail", ["-f", file], { + cwd: path.resolve(String(root), ".."), + stdio: "pipe", + }) + : spawn("docker", ["exec", "launch", "tail", "-f", `${file}`], { + stdio: "pipe", + }); + + ps.stdout.on("data", (chunk: Buffer) => { + chunk && match(chunk.toString()) && resolve(null); + }); + + ps.stderr.on("data", (chunk: Buffer) => { + process.stderr.write(chunk); + process.exit(1); + }); + }); +} + +/** + * Entrypoint + */ +async function main() { + const ps = await Launch.launch("pipe"); + ps.stdout.on("data", async (chunk: Buffer) => { + process.stdout.write(chunk.toString()); + if (chunk.includes(LAUNCH_COMPLETE)) { + await tail("9988.log", (chunk: string): boolean => { + process.stdout.write(chunk); + const match = chunk.match(PINT_FINALIZE); + return ( + match && match.length == 2 && Number.parseInt(match[1]) > 0 + ); + }); + + console.log("FINALIZE SUCCEED!"); + process.exit(0); + } + }); + + // Kill all processes when exiting. + process.on("exit", () => { + console.log("-> exit polkadot-launch..."); + killAll(ps, process.exitCode); + }); + + // Log errors + ps.stderr.on("data", (chunk: Buffer) => + process.stderr.write(chunk.toString()) + ); +} + +(() => { + main(); +})(); diff --git a/js/finalize/package.json b/js/finalize/package.json new file mode 100644 index 0000000000..80e939cf59 --- /dev/null +++ b/js/finalize/package.json @@ -0,0 +1,23 @@ +{ + "name": "@pint/finalization", + "version": "1.0.0", + "description": "Test the finalization in parachain intergration", + "main": "index.js", + "license": "MIT", + "private": true, + "devDependencies": { + "@types/node": "^15.3.1", + "ts-node": "^10.0.0", + "tslint": "^6.1.3", + "typescript": "^4.2.4" + }, + "dependencies": { + "@pint/e2e": "^1.0.0", + "find-up": "^5.0.0" + }, + "scripts": { + "start": "ts-node index.ts", + "build": "tsc --strict", + "lint": "tsc --noEmit --strict && tslint --project ./tsconfig.json" + } +} diff --git a/js/finalize/tsconfig.json b/js/finalize/tsconfig.json new file mode 100644 index 0000000000..8db1eddfc2 --- /dev/null +++ b/js/finalize/tsconfig.json @@ -0,0 +1,19 @@ +{ + "indent": [true, "spaces", 2], + "compilerOptions": { + "allowSyntheticDefaultImports": true, + "baseUrl": ".", + "declaration": true, + "esModuleInterop": true, + "outDir": "lib", + "module": "commonjs", + "moduleResolution": "node", + "noImplicitAny": true, + "resolveJsonModule": true, + "sourceMap": true, + "skipLibCheck": true, + "target": "es6" + }, + "include": ["index.ts", "src/**/*"], + "exclude": ["node_modules"] +} diff --git a/js/package.json b/js/package.json index c82b4ad16e..dfffe3953f 100644 --- a/js/package.json +++ b/js/package.json @@ -1,4 +1,4 @@ { "private": true, - "workspaces": ["e2e", "pint-types-bundle"] + "workspaces": ["e2e", "pint-types-bundle", "finalize"] } diff --git a/js/yarn.lock b/js/yarn.lock index 78065d1876..206acc6020 100644 --- a/js/yarn.lock +++ b/js/yarn.lock @@ -136,7 +136,7 @@ "@polkadot/types" "4.15.1" "@polkadot/util" "^6.9.1" -"@polkadot/types@4.15.1", "@polkadot/types@^4.15.1", "@polkadot/types@^4.15.1": +"@polkadot/types@4.15.1", "@polkadot/types@^4.15.1": version "4.15.1" resolved "https://registry.nlark.com/@polkadot/types/download/@polkadot/types-4.15.1.tgz#03f32fd4ce81d69c43368d3e476c0421cedb8607" integrity sha1-A/Mv1M6B1pxDNo0+R2wEIc7bhgc= @@ -554,7 +554,7 @@ ext@^1.1.2: find-up@^5.0.0: version "5.0.0" - resolved "https://registry.npm.taobao.org/find-up/download/find-up-5.0.0.tgz#4c92819ecb7083561e4f4a240a86be5198f536fc" + resolved "https://registry.nlark.com/find-up/download/find-up-5.0.0.tgz#4c92819ecb7083561e4f4a240a86be5198f536fc" integrity sha1-TJKBnstwg1YeT0okCoa+UZj1Nvw= dependencies: locate-path "^6.0.0"