From 03ab2df59d6a57c7ae75fd9dc3abaa7c738c2187 Mon Sep 17 00:00:00 2001 From: Phillip Jensen <33448819+cryptobench@users.noreply.github.com> Date: Wed, 2 Aug 2023 10:54:45 +0200 Subject: [PATCH 1/9] Update summary-generator.cjs --- .docs/summary-generator.cjs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.docs/summary-generator.cjs b/.docs/summary-generator.cjs index 001eda412..d88c57ecd 100644 --- a/.docs/summary-generator.cjs +++ b/.docs/summary-generator.cjs @@ -8,7 +8,7 @@ async function prepareDocAnchor(type, file) { const fileContent = await fs.readFileSync(filePath, "utf-8"); const firstLine = (fileContent.match(/(^.*)/) || [])[1] || ""; return { - link: `${docsDir}/${type}/${file}`, + link: `${type}/${file.replace(".md", "")}`, title: firstLine.substring(firstLine.indexOf(":") + 2), }; } @@ -18,7 +18,7 @@ function capitalizeFirstLetter(string) { } (async () => { - const logStream = fs.createWriteStream(path.join(directoryPath, ".SUMMARY.md"), { flags: "w" }); + const logStream = fs.createWriteStream(path.join(directoryPath, "overview.md"), { flags: "w" }); const types = fs .readdirSync(directoryPath, { withFileTypes: true }) From 39e071c17558c577deca1a9edac41eec27d4e100 Mon Sep 17 00:00:00 2001 From: Phillip Jensen <33448819+cryptobench@users.noreply.github.com> Date: Wed, 2 Aug 2023 11:21:49 +0200 Subject: [PATCH 2/9] Update summary-generator.cjs --- .docs/summary-generator.cjs | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/.docs/summary-generator.cjs b/.docs/summary-generator.cjs index d88c57ecd..aa97df189 100644 --- a/.docs/summary-generator.cjs +++ b/.docs/summary-generator.cjs @@ -1,9 +1,8 @@ const path = require("path"); const fs = require("fs"); -const docsDir = "docs"; -const directoryPath = path.join(__dirname, "..", docsDir); -async function prepareDocAnchor(type, file) { +async function prepareDocAnchor(docsDir, type, file) { + const directoryPath = path.join(docsDir); const filePath = path.join(directoryPath, type, file); const fileContent = await fs.readFileSync(filePath, "utf-8"); const firstLine = (fileContent.match(/(^.*)/) || [])[1] || ""; @@ -18,7 +17,9 @@ function capitalizeFirstLetter(string) { } (async () => { - const logStream = fs.createWriteStream(path.join(directoryPath, "overview.md"), { flags: "w" }); + const docsDir = "docs"; + const directoryPath = path.join(__dirname, "..", docsDir); + const logStream = fs.createWriteStream(path.join(process.argv[2], "overview.md"), { flags: "w" }); const types = fs .readdirSync(directoryPath, { withFileTypes: true }) @@ -31,7 +32,7 @@ function capitalizeFirstLetter(string) { const files = fs.readdirSync(path.join(directoryPath, type), { withFileTypes: true }).map((f) => f.name); for (let file of files) { - const doc = await prepareDocAnchor(type, file); + const doc = await prepareDocAnchor(docsDir, type, file); logStream.write(`\n\t* [${doc.title}](${doc.link})`); } } From 2663a1587ad41a930d214c4686887a85939209f4 Mon Sep 17 00:00:00 2001 From: Phillip Jensen <33448819+cryptobench@users.noreply.github.com> Date: Wed, 2 Aug 2023 11:27:04 +0200 Subject: [PATCH 3/9] Update summary-generator.cjs --- .docs/summary-generator.cjs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.docs/summary-generator.cjs b/.docs/summary-generator.cjs index aa97df189..3c33c4de5 100644 --- a/.docs/summary-generator.cjs +++ b/.docs/summary-generator.cjs @@ -17,9 +17,9 @@ function capitalizeFirstLetter(string) { } (async () => { - const docsDir = "docs"; + const docsDir = process.argv[2] || "docs"; const directoryPath = path.join(__dirname, "..", docsDir); - const logStream = fs.createWriteStream(path.join(process.argv[2], "overview.md"), { flags: "w" }); + const logStream = fs.createWriteStream(path.join(process.argv[3], "overview.md"), { flags: "w" }); const types = fs .readdirSync(directoryPath, { withFileTypes: true }) From eb99dfae003de3287764eea7e0fec8e03374f8d8 Mon Sep 17 00:00:00 2001 From: Phillip Jensen <33448819+cryptobench@users.noreply.github.com> Date: Thu, 17 Aug 2023 13:23:09 +0200 Subject: [PATCH 4/9] refactor(docs): refine and remove redundant summary generation code type: refactor scope: docs subject: refine and remove redundant summary generation code based on code review comments --- .docs/summary-generator.cjs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/.docs/summary-generator.cjs b/.docs/summary-generator.cjs index 3c33c4de5..674ed2040 100644 --- a/.docs/summary-generator.cjs +++ b/.docs/summary-generator.cjs @@ -2,9 +2,8 @@ const path = require("path"); const fs = require("fs"); async function prepareDocAnchor(docsDir, type, file) { - const directoryPath = path.join(docsDir); - const filePath = path.join(directoryPath, type, file); - const fileContent = await fs.readFileSync(filePath, "utf-8"); + const filePath = path.join(docsDir, type, file); + const fileContent = fs.readFileSync(filePath, "utf-8"); const firstLine = (fileContent.match(/(^.*)/) || [])[1] || ""; return { link: `${type}/${file.replace(".md", "")}`, @@ -19,7 +18,7 @@ function capitalizeFirstLetter(string) { (async () => { const docsDir = process.argv[2] || "docs"; const directoryPath = path.join(__dirname, "..", docsDir); - const logStream = fs.createWriteStream(path.join(process.argv[3], "overview.md"), { flags: "w" }); + const logStream = fs.createWriteStream(path.join(process.argv[3] || docsDir, "overview.md"), { flags: "w" }); const types = fs .readdirSync(directoryPath, { withFileTypes: true }) From 123c922a2b891dadfb23410f0fbdc7519eca47be Mon Sep 17 00:00:00 2001 From: Grzegorz Godlewski Date: Fri, 21 Jul 2023 15:47:30 +0200 Subject: [PATCH 5/9] fix: batch no longer rejects on single step error JST-64 - When a command executed in a batch fails on the provider, instead of throwing, it returns a 'Error' Result which improves debugging. In addition, the batch is not retried on a different provider where the broken command could still incurr additional cost --- src/task/batch.ts | 13 +++++++------ src/task/work.ts | 2 +- tests/unit/work.test.ts | 42 +++++++++++++++++------------------------ 3 files changed, 25 insertions(+), 32 deletions(-) diff --git a/src/task/batch.ts b/src/task/batch.ts index ddf1f9a78..63917af22 100644 --- a/src/task/batch.ts +++ b/src/task/batch.ts @@ -48,18 +48,19 @@ export class Batch { return this; } + /** + * Executes the batch of commands added via {@link run} returning result for each of the steps. + * + * In case any of the commands will fail, the execution of the batch will be interrupted by the Provider. + */ async end(): Promise { await this.script.before(); await sleep(100, true); const results = await this.activity.execute(this.script.getExeScriptRequest()); const allResults: Result[] = []; return new Promise((resolve, reject) => { - results.on("data", (result) => { - allResults.push(result); - if (result.result === "Error") { - this.script.after(allResults).catch(); - return reject(`Error: ${result.message}`); - } + results.on("data", (res) => { + allResults.push(res); }); results.on("end", () => { diff --git a/src/task/work.ts b/src/task/work.ts index 32efc0e09..162506537 100644 --- a/src/task/work.ts +++ b/src/task/work.ts @@ -20,7 +20,7 @@ import { NetworkNode } from "../network"; export type Worker = ( ctx: WorkContext, data?: InputType, -) => Promise; +) => Promise; const DEFAULTS = { activityPreparingTimeout: 300_000, diff --git a/tests/unit/work.test.ts b/tests/unit/work.test.ts index 35aad35dd..e7687c44a 100644 --- a/tests/unit/work.test.ts +++ b/tests/unit/work.test.ts @@ -16,7 +16,7 @@ describe("Work Context", () => { describe("Executing", () => { it("should execute run command", async () => { const activity = await Activity.create("test_agreement_id"); - const worker: Worker = async (ctx) => ctx.run("some_shell_command"); + const worker: Worker = async (ctx) => ctx.run("some_shell_command"); const ctx = new WorkContext(activity, { logger, activityStateCheckingInterval: 10, isRunning }); await ctx.before(); const results = await worker(ctx); @@ -25,7 +25,7 @@ describe("Work Context", () => { it("should execute upload file command", async () => { const activity = await Activity.create("test_agreement_id"); - const worker: Worker = async (ctx) => ctx.uploadFile("./file.txt", "/golem/file.txt"); + const worker: Worker = async (ctx) => ctx.uploadFile("./file.txt", "/golem/file.txt"); const ctx = new WorkContext(activity, { logger, activityStateCheckingInterval: 10, @@ -40,7 +40,7 @@ describe("Work Context", () => { it("should execute upload json command", async () => { const activity = await Activity.create("test_agreement_id"); - const worker: Worker = async (ctx) => ctx.uploadJson({ test: true }, "/golem/file.txt"); + const worker: Worker = async (ctx) => ctx.uploadJson({ test: true }, "/golem/file.txt"); const ctx = new WorkContext(activity, { logger, activityStateCheckingInterval: 10, @@ -55,7 +55,7 @@ describe("Work Context", () => { it("should execute download file command", async () => { const activity = await Activity.create("test_agreement_id"); - const worker: Worker = async (ctx) => ctx.downloadFile("/golem/file.txt", "./file.txt"); + const worker: Worker = async (ctx) => ctx.downloadFile("/golem/file.txt", "./file.txt"); const ctx = new WorkContext(activity, { logger, activityStateCheckingInterval: 10, @@ -71,7 +71,7 @@ describe("Work Context", () => { describe("Batch", () => { it("should execute batch as promise", async () => { const activity = await Activity.create("test_agreement_id"); - const worker: Worker = async (ctx) => { + const worker: Worker = async (ctx) => { return ctx .beginBatch() .run("some_shell_command") @@ -102,7 +102,7 @@ describe("Work Context", () => { it("should execute batch as stream", async () => { const activity = await Activity.create("test_agreement_id"); - const worker: Worker = async (ctx) => { + const worker: Worker = async (ctx) => { return ctx .beginBatch() .run("some_shell_command") @@ -141,9 +141,9 @@ describe("Work Context", () => { }); }); describe("Error handling", () => { - it("should catch error while executing batch as promise with invalid command", async () => { + it("should return a result with error in case the command to execute is invalid", async () => { const activity = await Activity.create("test_agreement_id"); - const worker: Worker = async (ctx) => ctx.beginBatch().run("invalid_shell_command").end(); + const worker: Worker = async (ctx) => ctx.beginBatch().run("invalid_shell_command").end(); const ctx = new WorkContext(activity, { logger, activityStateCheckingInterval: 10, @@ -152,18 +152,16 @@ describe("Work Context", () => { }); const expectedStdout = [{ result: "Error", stderr: "error", message: "Some error occurred" }]; activityMock.setExpectedExeResults(expectedStdout); - let expectedError; - try { - await worker(ctx); - } catch (err) { - expectedError = err; - } - expect(expectedError).toEqual(`Error: ${expectedStdout[0].message}`); + + const [result] = await worker(ctx); + + expect(result.result).toEqual("Error"); + expect(result.message).toEqual("Some error occurred"); }); it("should catch error while executing batch as stream with invalid command", async () => { const activity = await Activity.create("test_agreement_id"); - const worker: Worker = async (ctx) => ctx.beginBatch().run("invalid_shell_command").endStream(); + const worker: Worker = async (ctx) => ctx.beginBatch().run("invalid_shell_command").endStream(); const ctx = new WorkContext(activity, { logger, activityStateCheckingInterval: 10, @@ -173,15 +171,9 @@ describe("Work Context", () => { const expectedStdout = [{ result: "Error", stderr: "error", message: "Some error occurred" }]; activityMock.setExpectedExeResults(expectedStdout); const results = await worker(ctx); - await new Promise((res, rej) => { - results?.on("error", (error) => { - try { - expect(error.message).toEqual("Some error occurred. Stdout: test_result. Stderr: error"); - } catch (e) { - rej(e); - } - res(true); - }); + + results.once("error", (error) => { + expect(error.message).toEqual("Some error occurred. Stdout: test_result. Stderr: error"); }); }); }); From 5c17ceae6a77c0c53ffd49d1f0f16baa58db8408 Mon Sep 17 00:00:00 2001 From: Grzegorz Godlewski Date: Fri, 11 Aug 2023 21:26:29 +0200 Subject: [PATCH 6/9] build: adjusted the linting rules to also lint TS early so that issues in E2E tets will be discovered on the fast pipeline --- .husky/pre-commit | 2 +- package.json | 5 ++++- tests/e2e/strategies.spec.ts | 8 ++++---- tests/e2e/tasks.spec.ts | 2 +- tests/tsconfig.json | 4 +++- 5 files changed, 13 insertions(+), 8 deletions(-) diff --git a/.husky/pre-commit b/.husky/pre-commit index fef652dd1..f1ef303b0 100755 --- a/.husky/pre-commit +++ b/.husky/pre-commit @@ -1,4 +1,4 @@ #!/usr/bin/env sh . "$(dirname -- "$0")/_/husky.sh" -npm run format:check +npm run format:check && npm run lint diff --git a/package.json b/package.json index 6fb633a34..08a007a92 100644 --- a/package.json +++ b/package.json @@ -29,7 +29,10 @@ "test:e2e": "jest --config tests/e2e/jest.config.json tests/e2e/**.spec.ts --runInBand --forceExit", "test:e2e:no-goth": "jest tests/e2e/**.spec.ts --testTimeout=180000 --runInBand --forceExit", "test:cypress": "cypress run", - "lint": "eslint .", + "lint": "npm run lint:ts && npm run lint:ts:tests && npm run lint:eslint", + "lint:ts": "tsc --project tsconfig.json --noEmit", + "lint:ts:tests": "tsc --project tests/tsconfig.json --noEmit", + "lint:eslint": "eslint .", "format": "prettier -w .", "format:check": "prettier -c .", "prepare": "husky install" diff --git a/tests/e2e/strategies.spec.ts b/tests/e2e/strategies.spec.ts index c06c12b79..dead03f99 100644 --- a/tests/e2e/strategies.spec.ts +++ b/tests/e2e/strategies.spec.ts @@ -15,7 +15,7 @@ describe("Strategies", function () { logger, }); const data = ["one", "two", "three"]; - const results = executor.map(data, async (ctx, x) => { + const results = executor.map(data, async (ctx, x) => { const res = await ctx.run(`echo "${x}"`); return res.stdout?.trim(); }); @@ -36,7 +36,7 @@ describe("Strategies", function () { logger, }); const data = ["one", "two", "three"]; - const results = executor.map(data, async (ctx, x) => { + const results = executor.map(data, async (ctx, x) => { const res = await ctx.run(`echo "${x}"`); return res.stdout?.trim(); }); @@ -58,7 +58,7 @@ describe("Strategies", function () { logger, }); const data = ["one", "two"]; - const results = executor.map(data, async (ctx, x) => { + const results = executor.map(data, async (ctx, x) => { const res = await ctx.run(`echo "${x}"`); return res.stdout?.trim(); }); @@ -76,7 +76,7 @@ describe("Strategies", function () { logger, }); const data = ["one", "two"]; - const results = executor.map(data, async (ctx, x) => { + const results = executor.map(data, async (ctx, x) => { const res = await ctx.run(`echo "${x}"`); return res.stdout?.trim(); }); diff --git a/tests/e2e/tasks.spec.ts b/tests/e2e/tasks.spec.ts index 6c272c67f..9330a747b 100644 --- a/tests/e2e/tasks.spec.ts +++ b/tests/e2e/tasks.spec.ts @@ -66,7 +66,7 @@ describe("Task Executor", function () { logger, }); const data = ["one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten"]; - const results = executor.map(data, async (ctx, x) => { + const results = executor.map(data, async (ctx, x) => { const res = await ctx.run(`echo "${x}"`); return res.stdout?.trim(); }); diff --git a/tests/tsconfig.json b/tests/tsconfig.json index 0c80252b2..f71bd877a 100644 --- a/tests/tsconfig.json +++ b/tests/tsconfig.json @@ -2,5 +2,7 @@ "extends": "../tsconfig.json", "include": ["."], "exclude": ["./cypress"], - "types": ["jest"] + "compilerOptions": { + "types": ["jest"] + } } From cb84b76b4ca279da7f73d766ffd9204614f0ca12 Mon Sep 17 00:00:00 2001 From: Grzegorz Godlewski Date: Fri, 18 Aug 2023 12:38:18 +0200 Subject: [PATCH 7/9] test: removed redundant e2e test which case is covered in unit tests --- tests/e2e/tasks.spec.ts | 25 ------------------------- 1 file changed, 25 deletions(-) diff --git a/tests/e2e/tasks.spec.ts b/tests/e2e/tasks.spec.ts index 9330a747b..1926807e4 100644 --- a/tests/e2e/tasks.spec.ts +++ b/tests/e2e/tasks.spec.ts @@ -116,31 +116,6 @@ describe("Task Executor", function () { expect(onEnd).toEqual("END"); }); - it("should run simple batch script and catch error on stream", async () => { - executor = await TaskExecutor.create({ - package: "9a3b5d67b0b27746283cb5f287c13eab1beaa12d92a9f536b747c7ae", - logger, - }); - const outputs: string[] = []; - let expectedError = ""; - await executor - .run(async (ctx) => { - const results = await ctx.beginBatch().run('echo "Hello Golem"').run("invalid_command").endStream(); - results.on("data", ({ stdout }) => outputs.push(stdout?.trim())); - results.on("error", (error) => { - expectedError = error.toString(); - }); - }) - .catch((e) => { - expect(e).toBeUndefined(); - }); - await logger.expectToInclude("Task 1 computed by provider", 5000); - expect(outputs[0]).toEqual("Hello Golem"); - expect(expectedError).toEqual( - "Error: ExeScript command exited with code 127. Stdout: undefined. Stderr: sh: 1: invalid_command: not found", - ); - }); - it("should run simple batch script and get results as promise", async () => { executor = await TaskExecutor.create({ package: "9a3b5d67b0b27746283cb5f287c13eab1beaa12d92a9f536b747c7ae", From 091ccfb9c4029c8065179c1c0773b743ffb7ded6 Mon Sep 17 00:00:00 2001 From: Grzegorz Godlewski Date: Fri, 18 Aug 2023 13:13:40 +0200 Subject: [PATCH 8/9] test: removed redundant e2e test which case is covered in unit tests --- tests/e2e/tasks.spec.ts | 22 ---------------------- 1 file changed, 22 deletions(-) diff --git a/tests/e2e/tasks.spec.ts b/tests/e2e/tasks.spec.ts index 1926807e4..7d7106a5e 100644 --- a/tests/e2e/tasks.spec.ts +++ b/tests/e2e/tasks.spec.ts @@ -140,28 +140,6 @@ describe("Task Executor", function () { expect(outputs[2]).toEqual("OK"); }); - it("should run simple batch script and catch error on promise", async () => { - executor = await TaskExecutor.create({ - package: "9a3b5d67b0b27746283cb5f287c13eab1beaa12d92a9f536b747c7ae", - logger, - }); - let results; - let error; - await executor - .run(async (ctx) => { - results = await ctx - .beginBatch() - .run('echo "Hello Golem"') - .run("invalid_command") - .end() - .catch((err) => (error = err)); - }) - .catch((e) => { - expect(e).toBeUndefined(); - }); - expect(error).toEqual("Error: ExeScript command exited with code 127"); - }); - it("should run transfer file", async () => { executor = await TaskExecutor.create({ package: "9a3b5d67b0b27746283cb5f287c13eab1beaa12d92a9f536b747c7ae", From 71d52a2330de1ba7bd4d3e248c937b14974d2405 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 21 Aug 2023 09:04:15 +0000 Subject: [PATCH 9/9] Bump cypress from 12.17.3 to 12.17.4 Bumps [cypress](https://github.com/cypress-io/cypress) from 12.17.3 to 12.17.4. - [Release notes](https://github.com/cypress-io/cypress/releases) - [Changelog](https://github.com/cypress-io/cypress/blob/develop/CHANGELOG.md) - [Commits](https://github.com/cypress-io/cypress/compare/v12.17.3...v12.17.4) --- updated-dependencies: - dependency-name: cypress dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 6fb633a34..7787fb882 100644 --- a/package.json +++ b/package.json @@ -73,7 +73,7 @@ "@typescript-eslint/eslint-plugin": "^6.0.0", "@typescript-eslint/parser": "^6.0.0", "buffer": "^6.0.3", - "cypress": "12.17.3", + "cypress": "12.17.4", "eslint": "~8.47.0", "eslint-config-prettier": "^9.0.0", "husky": "^8.0.3",