From 30a8d3cde0ddca91a2a3b0abd160c464dce51ee6 Mon Sep 17 00:00:00 2001 From: Stephen Kirby Date: Mon, 9 Oct 2023 19:51:18 +0000 Subject: [PATCH 01/16] added starter test for personalize --- jetbrains-gateway/main.test.ts | 2 +- personalize/main.test.ts | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 35 insertions(+), 1 deletion(-) create mode 100644 personalize/main.test.ts diff --git a/jetbrains-gateway/main.test.ts b/jetbrains-gateway/main.test.ts index ffd970f..d4ab4a0 100644 --- a/jetbrains-gateway/main.test.ts +++ b/jetbrains-gateway/main.test.ts @@ -1,7 +1,7 @@ import { describe } from "bun:test"; import { runTerraformInit, testRequiredVariables } from "../test"; -describe("jetbrains-gateway`", async () => { +describe("jetbrains-gateway", async () => { await runTerraformInit(import.meta.dir); await testRequiredVariables(import.meta.dir, { diff --git a/personalize/main.test.ts b/personalize/main.test.ts new file mode 100644 index 0000000..0ecf377 --- /dev/null +++ b/personalize/main.test.ts @@ -0,0 +1,34 @@ +import { describe, expect, it } from "bun:test"; +import { + executeScriptInContainer, + runTerraformApply, + runTerraformInit, + testRequiredVariables, + runContainer, + execContainer, + findResourceInstance +} from "../test"; + +describe("personalize", async () => { + await runTerraformInit(import.meta.dir); + + testRequiredVariables(import.meta.dir, { + agent_id: "foo", + }); + + it("warns without personalize script", async () => { + const state = await runTerraformApply(import.meta.dir, { + agent_id: "foo", + }); + const output = await executeScriptInContainer(state, "alpine"); + expect(output.exitCode).toBe(0); + expect(output.stdout).toEqual([ + "✨ \u001b[0;1mYou don't have a personalize script!", + "", + "Run \u001b[36;40;1mtouch ~/personalize && chmod +x ~/personalize\u001b[0m to create one.", + "It will run every time your workspace starts. Use it to install personal packages!" + ]); + }); + + +}); From db2441f831225c767d5ddb0145e8cad6d82a02bc Mon Sep 17 00:00:00 2001 From: Stephen Kirby Date: Mon, 9 Oct 2023 21:28:35 +0000 Subject: [PATCH 02/16] personalize wip, gcp region added --- gcp-region/main.test.ts | 26 ++++++++++++++++++++++++++ personalize/main.test.ts | 19 ++++++++++++++++++- 2 files changed, 44 insertions(+), 1 deletion(-) create mode 100644 gcp-region/main.test.ts diff --git a/gcp-region/main.test.ts b/gcp-region/main.test.ts new file mode 100644 index 0000000..8b419d1 --- /dev/null +++ b/gcp-region/main.test.ts @@ -0,0 +1,26 @@ +import { describe, expect, it } from "bun:test"; +import { + executeScriptInContainer, + runTerraformApply, + runTerraformInit, + testRequiredVariables, +} from "../test"; + +describe("gcp-region", async () => { + await runTerraformInit(import.meta.dir); + + testRequiredVariables(import.meta.dir, {}); + + it("default output", async () => { + const state = await runTerraformApply(import.meta.dir, {}); + expect(state.outputs.value.value).toBe(""); + }); + + it("customized default", async () => { + const state = await runTerraformApply(import.meta.dir, { + regions: '["asia"]', + default: "asia-east1-a", + }); + expect(state.outputs.value.value).toBe("asia-east1-a"); + }); +}); diff --git a/personalize/main.test.ts b/personalize/main.test.ts index 0ecf377..98c3314 100644 --- a/personalize/main.test.ts +++ b/personalize/main.test.ts @@ -1,3 +1,4 @@ +import { readableStreamToText, spawn } from "bun"; import { describe, expect, it } from "bun:test"; import { executeScriptInContainer, @@ -30,5 +31,21 @@ describe("personalize", async () => { ]); }); - +// it("runs with personalize script", async () => { +// const state = await runTerraformApply(import.meta.dir, { +// agent_id: "foo", +// }); +// const instance = findResourceInstance(state, "coder_script"); +// const id = await runContainer("alpine"); +// const resp = await execContainer(id, ["sh", "-c", "touch ~/personalize && echo \"echo test\" > ~/personalize && chmod +x ~/personalize &&" + instance.script]); +// const stdout = resp.stdout.trim().split("\n"); +// console.log("====== resp ==== stdout (", resp.exitCode, "):"); +// console.log(resp.stdout); +// console.log("====== resp ==== stderr:"); +// console.log(resp.stderr); +// console.log("======"); +// // const stderr = resp.stderr.trim().split("\n"); +// expect(resp.exitCode).toBe(0); +// expect(stdout).toEqual([""]); +// }); }); From 75d8d0dbcd736540493be759a6260d4519b3aa2e Mon Sep 17 00:00:00 2001 From: Stephen Kirby Date: Tue, 10 Oct 2023 15:08:55 +0000 Subject: [PATCH 03/16] testing personalize --- personalize/main.test.ts | 44 ++++++++++++++++++++++++---------------- 1 file changed, 27 insertions(+), 17 deletions(-) diff --git a/personalize/main.test.ts b/personalize/main.test.ts index 98c3314..45372e7 100644 --- a/personalize/main.test.ts +++ b/personalize/main.test.ts @@ -31,21 +31,31 @@ describe("personalize", async () => { ]); }); -// it("runs with personalize script", async () => { -// const state = await runTerraformApply(import.meta.dir, { -// agent_id: "foo", -// }); -// const instance = findResourceInstance(state, "coder_script"); -// const id = await runContainer("alpine"); -// const resp = await execContainer(id, ["sh", "-c", "touch ~/personalize && echo \"echo test\" > ~/personalize && chmod +x ~/personalize &&" + instance.script]); -// const stdout = resp.stdout.trim().split("\n"); -// console.log("====== resp ==== stdout (", resp.exitCode, "):"); -// console.log(resp.stdout); -// console.log("====== resp ==== stderr:"); -// console.log(resp.stderr); -// console.log("======"); -// // const stderr = resp.stderr.trim().split("\n"); -// expect(resp.exitCode).toBe(0); -// expect(stdout).toEqual([""]); -// }); + it("runs with personalize script", async () => { + const state = await runTerraformApply(import.meta.dir, { + agent_id: "foo", + }); + const instance = findResourceInstance(state, "coder_script"); + const id = await runContainer("alpine"); + const respInit = await execContainer(id, ["sh", "-c", "touch ~/personalize && echo \"echo test\" > ~/personalize && chmod +x ~/personalize && echo \"completed touch cmds\""]); + + console.log("\n id = ", id, "\n") + + console.log("\n====== init ==== stdout (", respInit.exitCode, "):"); + console.log(respInit.stdout); + console.log("====== init ==== stderr:"); + console.log(respInit.stderr); + console.log("======"); + const resp = await execContainer(id, ["sh", "-c", instance.script]); + console.log("====== resp ==== stdout (", resp.exitCode, "):"); + console.log(resp.stdout); + console.log("====== resp ==== stderr:"); + console.log(resp.stderr); + console.log("======"); + // await new Promise((resolve) => setTimeout(resolve, 100000000000)); + const stdout = resp.stdout.trim().split("\n"); + const stderr = resp.stderr.trim().split("\n"); + expect(resp.exitCode).toBe(0); + expect(stdout).toEqual([""]); + }); }); From 294047546aa36b2a358c76b8a3ccd87d56b1de92 Mon Sep 17 00:00:00 2001 From: Stephen Kirby Date: Tue, 10 Oct 2023 15:48:18 +0000 Subject: [PATCH 04/16] upped gcp-region testing --- gcp-region/main.test.ts | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/gcp-region/main.test.ts b/gcp-region/main.test.ts index 8b419d1..51a3601 100644 --- a/gcp-region/main.test.ts +++ b/gcp-region/main.test.ts @@ -23,4 +23,22 @@ describe("gcp-region", async () => { }); expect(state.outputs.value.value).toBe("asia-east1-a"); }); + + it("gpu only invalid default", async () => { + const state = await runTerraformApply(import.meta.dir, { + regions: '["us-west2"]', + default: "us-west2-a", + gpu_only: "true", + }); + expect(state.outputs.value.value).toBe(""); + }); + + it("gpu only valid default", async () => { + const state = await runTerraformApply(import.meta.dir, { + regions: '["us-west2"]', + default: "us-west2-b", + gpu_only: "true", + }); + expect(state.outputs.value.value).toBe("us-west2-b"); + }); }); From 3b40e2ee36e9e5b741994d33d53c2cca7e24b51f Mon Sep 17 00:00:00 2001 From: Stephen Kirby Date: Tue, 10 Oct 2023 15:49:35 +0000 Subject: [PATCH 05/16] fixed default with gpu_only true --- gcp-region/main.tf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gcp-region/main.tf b/gcp-region/main.tf index 4d675c8..e9f549d 100644 --- a/gcp-region/main.tf +++ b/gcp-region/main.tf @@ -714,7 +714,7 @@ data "coder_parameter" "region" { description = var.description icon = "/icon/gcp.png" mutable = var.mutable - default = var.default != null && var.default != "" ? var.default : null + default = var.default != null && var.default != "" && (!var.gpu_only || try(local.zones[var.default].gpu, false)) ? var.default : null dynamic "option" { for_each = { for k, v in local.zones : k => v From f17143405917d143b2f52e2ce4a9eb8e56dc9f01 Mon Sep 17 00:00:00 2001 From: Stephen Kirby Date: Tue, 10 Oct 2023 15:51:17 +0000 Subject: [PATCH 06/16] added note on gpu_only for gcp-region --- gcp-region/README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/gcp-region/README.md b/gcp-region/README.md index 0ca76e1..ab5daf3 100644 --- a/gcp-region/README.md +++ b/gcp-region/README.md @@ -28,6 +28,8 @@ resource "google_compute_instance" "example" { ### Add only GPU zones in the US West 1 region +Note: setting `gpu_only = true` and using a default region without GPU support, the default will be set to `null`. + ```hcl module "gcp_region" { source = "https://registry.coder.com/modules/gcp-region" From f7de34295f977896de0d119e00d39a304a989ee3 Mon Sep 17 00:00:00 2001 From: Stephen Kirby Date: Tue, 10 Oct 2023 15:53:54 +0000 Subject: [PATCH 07/16] test for fly-region region filter --- fly-region/main.test.ts | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/fly-region/main.test.ts b/fly-region/main.test.ts index 86f6bfc..642446e 100644 --- a/fly-region/main.test.ts +++ b/fly-region/main.test.ts @@ -22,4 +22,12 @@ describe("fly-region", async () => { }); expect(state.outputs.value.value).toBe("atl"); }); + + it("region filter", async () => { + const state = await runTerraformApply(import.meta.dir, { + default: "atl", + regions: '["arn", "ams", "bos"]' + }); + expect(state.outputs.value.value).toBe(""); + }); }); From 8eec58ed9bf481fc94e7856d4b78040944e71b2a Mon Sep 17 00:00:00 2001 From: Stephen Kirby Date: Tue, 10 Oct 2023 15:57:44 +0000 Subject: [PATCH 08/16] prep for merge --- dotfiles/main.test.ts | 15 ++++++++++ fly-region/main.test.ts | 1 - gcp-region/main.test.ts | 1 - personalize/main.test.ts | 62 +++++++++++++++++++++------------------- 4 files changed, 48 insertions(+), 31 deletions(-) create mode 100644 dotfiles/main.test.ts diff --git a/dotfiles/main.test.ts b/dotfiles/main.test.ts new file mode 100644 index 0000000..009aaff --- /dev/null +++ b/dotfiles/main.test.ts @@ -0,0 +1,15 @@ +import { describe, expect, it } from "bun:test"; +import { + runTerraformApply, + runTerraformInit, + testRequiredVariables, +} from "../test"; + +describe("dotfiles", async () => { + await runTerraformInit(import.meta.dir); + + testRequiredVariables(import.meta.dir, { + agent_id: "foo", + }); + +}); diff --git a/fly-region/main.test.ts b/fly-region/main.test.ts index 642446e..774490b 100644 --- a/fly-region/main.test.ts +++ b/fly-region/main.test.ts @@ -1,6 +1,5 @@ import { describe, expect, it } from "bun:test"; import { - executeScriptInContainer, runTerraformApply, runTerraformInit, testRequiredVariables, diff --git a/gcp-region/main.test.ts b/gcp-region/main.test.ts index 51a3601..2ec623b 100644 --- a/gcp-region/main.test.ts +++ b/gcp-region/main.test.ts @@ -1,6 +1,5 @@ import { describe, expect, it } from "bun:test"; import { - executeScriptInContainer, runTerraformApply, runTerraformInit, testRequiredVariables, diff --git a/personalize/main.test.ts b/personalize/main.test.ts index 45372e7..96b1e2e 100644 --- a/personalize/main.test.ts +++ b/personalize/main.test.ts @@ -7,7 +7,7 @@ import { testRequiredVariables, runContainer, execContainer, - findResourceInstance + findResourceInstance, } from "../test"; describe("personalize", async () => { @@ -27,35 +27,39 @@ describe("personalize", async () => { "✨ \u001b[0;1mYou don't have a personalize script!", "", "Run \u001b[36;40;1mtouch ~/personalize && chmod +x ~/personalize\u001b[0m to create one.", - "It will run every time your workspace starts. Use it to install personal packages!" + "It will run every time your workspace starts. Use it to install personal packages!", ]); }); - it("runs with personalize script", async () => { - const state = await runTerraformApply(import.meta.dir, { - agent_id: "foo", - }); - const instance = findResourceInstance(state, "coder_script"); - const id = await runContainer("alpine"); - const respInit = await execContainer(id, ["sh", "-c", "touch ~/personalize && echo \"echo test\" > ~/personalize && chmod +x ~/personalize && echo \"completed touch cmds\""]); - - console.log("\n id = ", id, "\n") - - console.log("\n====== init ==== stdout (", respInit.exitCode, "):"); - console.log(respInit.stdout); - console.log("====== init ==== stderr:"); - console.log(respInit.stderr); - console.log("======"); - const resp = await execContainer(id, ["sh", "-c", instance.script]); - console.log("====== resp ==== stdout (", resp.exitCode, "):"); - console.log(resp.stdout); - console.log("====== resp ==== stderr:"); - console.log(resp.stderr); - console.log("======"); - // await new Promise((resolve) => setTimeout(resolve, 100000000000)); - const stdout = resp.stdout.trim().split("\n"); - const stderr = resp.stderr.trim().split("\n"); - expect(resp.exitCode).toBe(0); - expect(stdout).toEqual([""]); - }); + // it("runs with personalize script", async () => { + // const state = await runTerraformApply(import.meta.dir, { + // agent_id: "foo", + // }); + // const instance = findResourceInstance(state, "coder_script"); + // const id = await runContainer("alpine"); + // const respInit = await execContainer(id, [ + // "sh", + // "-c", + // 'touch ~/personalize && echo "echo test" > ~/personalize && chmod +x ~/personalize && echo "completed touch cmds"', + // ]); + + // console.log("\n id = ", id, "\n"); + + // console.log("\n====== init ==== stdout (", respInit.exitCode, "):"); + // console.log(respInit.stdout); + // console.log("====== init ==== stderr:"); + // console.log(respInit.stderr); + // console.log("======"); + // const resp = await execContainer(id, ["sh", "-c", instance.script]); + // console.log("====== resp ==== stdout (", resp.exitCode, "):"); + // console.log(resp.stdout); + // console.log("====== resp ==== stderr:"); + // console.log(resp.stderr); + // console.log("======"); + // // await new Promise((resolve) => setTimeout(resolve, 100000000000)); + // const stdout = resp.stdout.trim().split("\n"); + // const stderr = resp.stderr.trim().split("\n"); + // expect(resp.exitCode).toBe(0); + // expect(stdout).toEqual([""]); + // }); }); From 1317bbdf519c25cd2715180a734bb0633db1ced0 Mon Sep 17 00:00:00 2001 From: Stephen Kirby Date: Tue, 10 Oct 2023 16:42:39 +0000 Subject: [PATCH 09/16] added tests for vscode-web --- dotfiles/main.test.ts | 6 ++++ test.ts | 2 +- vscode-web/main.test.ts | 67 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 74 insertions(+), 1 deletion(-) create mode 100644 vscode-web/main.test.ts diff --git a/dotfiles/main.test.ts b/dotfiles/main.test.ts index 009aaff..69eda32 100644 --- a/dotfiles/main.test.ts +++ b/dotfiles/main.test.ts @@ -12,4 +12,10 @@ describe("dotfiles", async () => { agent_id: "foo", }); + it("default output", async () => { + const state = await runTerraformApply(import.meta.dir, { + agent_id: "foo", + }); + expect(state.outputs.dotfiles_uri.value).toBe(""); + }); }); diff --git a/test.ts b/test.ts index 6546490..a32a995 100644 --- a/test.ts +++ b/test.ts @@ -129,7 +129,7 @@ export const findResourceInstance = ( return resource.instances[0].attributes as any; }; -// assertRequiredVariables creates a test-case +// testRequiredVariables creates a test-case // for each variable provided and ensures that // the apply fails without it. export const testRequiredVariables = ( diff --git a/vscode-web/main.test.ts b/vscode-web/main.test.ts new file mode 100644 index 0000000..73c64c2 --- /dev/null +++ b/vscode-web/main.test.ts @@ -0,0 +1,67 @@ +import { describe, expect, it } from "bun:test"; +import { + executeScriptInContainer, + runTerraformApply, + runTerraformInit, +} from "../test"; + +describe("vscode-web", async () => { + await runTerraformInit(import.meta.dir); + + + // replaces testRequiredVariables due to license var + it("missing agent_id", async () => { + try { + await runTerraformApply(import.meta.dir, { + accept_license: "true", + }); + } catch (ex) { + expect(ex.message).toContain( + 'input variable "agent_id" is not set' + ); + } + }); + + it("invalid license_agreement", async () => { + + try { + await runTerraformApply(import.meta.dir, { + agent_id: "foo", + }); + } catch (ex) { + expect(ex.message).toContain( + 'You must accept the VS Code license agreement by setting accept_license=true' + ); + } + }); + + it("fails without curl", async () => { + const state = await runTerraformApply(import.meta.dir, { + agent_id: "foo", + accept_license: "true", + }); + const output = await executeScriptInContainer(state, "alpine"); + expect(output.exitCode).toBe(1); + expect(output.stdout).toEqual([ + "\u001b[0;1mInstalling vscode-cli!", + "Failed to install vscode-cli:", // TODO: manually test error log + ]); + }); + + it("runs with curl", async () => { + const state = await runTerraformApply(import.meta.dir, { + agent_id: "foo", + accept_license: "true", + }); + const output = await executeScriptInContainer(state, "alpine/curl"); + expect(output.exitCode).toBe(0); + expect(output.stdout).toEqual([ + "\u001b[0;1mInstalling vscode-cli!", + "🥳 vscode-cli has been installed.", + "", + "👷 Running /tmp/vscode-cli/bin/code serve-web --port 13338 --without-connection-token --accept-server-license-terms in the background...", + "Check logs at /tmp/vscode-web.log!" + ]); + }); + +}); From f3200400933bb86fc83104be7b7775681ec691af Mon Sep 17 00:00:00 2001 From: Stephen Kirby Date: Tue, 10 Oct 2023 16:44:27 +0000 Subject: [PATCH 10/16] started vscode tests, fixed typo --- vscode-desktop/main.test.ts | 16 ++++++++++++++++ vscode-desktop/main.tf | 2 +- 2 files changed, 17 insertions(+), 1 deletion(-) create mode 100644 vscode-desktop/main.test.ts diff --git a/vscode-desktop/main.test.ts b/vscode-desktop/main.test.ts new file mode 100644 index 0000000..dfcd904 --- /dev/null +++ b/vscode-desktop/main.test.ts @@ -0,0 +1,16 @@ +import { describe, expect, it } from "bun:test"; +import { + executeScriptInContainer, + runTerraformApply, + runTerraformInit, + testRequiredVariables, +} from "../test"; + +describe("vscode-desktop", async () => { + await runTerraformInit(import.meta.dir); + + testRequiredVariables(import.meta.dir, { + agent_id: "foo", + }); + +}); diff --git a/vscode-desktop/main.tf b/vscode-desktop/main.tf index 9edae25..fa161fb 100644 --- a/vscode-desktop/main.tf +++ b/vscode-desktop/main.tf @@ -16,7 +16,7 @@ variable "agent_id" { variable "folder" { type = string - description = "The folder to opne in VS Code." + description = "The folder to open in VS Code." default = "" } From 698d8168f21bba3da80bda99a554aa9fba29dedc Mon Sep 17 00:00:00 2001 From: Stephen Kirby Date: Tue, 10 Oct 2023 16:49:36 +0000 Subject: [PATCH 11/16] output vscode-desktop url and finished tests --- vscode-desktop/main.test.ts | 11 +++++++++++ vscode-desktop/main.tf | 5 +++++ vscode-web/main.test.ts | 3 ++- 3 files changed, 18 insertions(+), 1 deletion(-) diff --git a/vscode-desktop/main.test.ts b/vscode-desktop/main.test.ts index dfcd904..ac4133f 100644 --- a/vscode-desktop/main.test.ts +++ b/vscode-desktop/main.test.ts @@ -13,4 +13,15 @@ describe("vscode-desktop", async () => { agent_id: "foo", }); + + it("default output", async () => { + const state = await runTerraformApply(import.meta.dir, { + agent_id: "foo", + }); + expect(state.outputs.vscode_url.value).toBe( + "vscode://coder.coder-remote/open?owner=default&workspace=default&token=$SESSION_TOKEN" + ); + }); + + }); diff --git a/vscode-desktop/main.tf b/vscode-desktop/main.tf index fa161fb..cc3340a 100644 --- a/vscode-desktop/main.tf +++ b/vscode-desktop/main.tf @@ -44,3 +44,8 @@ resource "coder_app" "vscode" { "&token=$SESSION_TOKEN", ]) } + +output "vscode_url" { + value = coder_app.vscode.url + description = "VS Code Desktop URL." +} diff --git a/vscode-web/main.test.ts b/vscode-web/main.test.ts index 73c64c2..dd31e86 100644 --- a/vscode-web/main.test.ts +++ b/vscode-web/main.test.ts @@ -9,7 +9,8 @@ describe("vscode-web", async () => { await runTerraformInit(import.meta.dir); - // replaces testRequiredVariables due to license var + // replaces testRequiredVariables due to license variable + // may add a testRequiredVariablesWithLicense function later it("missing agent_id", async () => { try { await runTerraformApply(import.meta.dir, { From a83cd5b140f21934c6dfdfebcc5588a823a28489 Mon Sep 17 00:00:00 2001 From: Stephen Kirby Date: Tue, 10 Oct 2023 17:22:48 +0000 Subject: [PATCH 12/16] added small test for jupyterlab --- fly-region/main.test.ts | 2 +- jupyterlab/main.test.ts | 57 +++++++++++++++++++++++++++++++++++++ vscode-desktop/main.test.ts | 5 +--- vscode-desktop/main.tf | 2 +- vscode-web/main.test.ts | 11 ++----- 5 files changed, 63 insertions(+), 14 deletions(-) create mode 100644 jupyterlab/main.test.ts diff --git a/fly-region/main.test.ts b/fly-region/main.test.ts index 774490b..7e72586 100644 --- a/fly-region/main.test.ts +++ b/fly-region/main.test.ts @@ -25,7 +25,7 @@ describe("fly-region", async () => { it("region filter", async () => { const state = await runTerraformApply(import.meta.dir, { default: "atl", - regions: '["arn", "ams", "bos"]' + regions: '["arn", "ams", "bos"]', }); expect(state.outputs.value.value).toBe(""); }); diff --git a/jupyterlab/main.test.ts b/jupyterlab/main.test.ts new file mode 100644 index 0000000..15fb487 --- /dev/null +++ b/jupyterlab/main.test.ts @@ -0,0 +1,57 @@ +import { describe, expect, it } from "bun:test"; +import { + executeScriptInContainer, + runTerraformApply, + runTerraformInit, + testRequiredVariables, + findResourceInstance, + runContainer, +} from "../test"; + +const executeScriptInContainer = async ( + state: TerraformState, + image: string, + shell: string = "sh", +): Promise<{ + exitCode: number; + stdout: string[]; + stderr: string[]; +}> => { + const instance = findResourceInstance(state, "coder_script"); + const id = await runContainer(image); + const resp = await execContainer(id, [shell, "-c", instance.script]); + const stdout = resp.stdout.trim().split("\n"); + const stderr = resp.stderr.trim().split("\n"); + return { + exitCode: resp.exitCode, + stdout, + stderr, + }; +}; + +describe("jupyterlab", async () => { + await runTerraformInit(import.meta.dir); + + testRequiredVariables(import.meta.dir, { + agent_id: "foo", + }); + + it("fails without pip3", async () => { + const state = await runTerraformApply(import.meta.dir, { + agent_id: "foo", + }); + + const instance = findResourceInstance(state, "coder_script"); + const id = await runContainer("alpine"); + const output = await executeScriptInContainer(state, "alpine"); + expect(output.exitCode).toBe(1); + expect(output.stdout).toEqual([ + "\u001B[0;1mInstalling jupyterlab!", + "pip3 is not installed", + "Please install pip3 in your Dockerfile/VM image before running this script", + ]); + }); + + // TODO: Add test that runs with pip + // May be best to use dockerfile +}); diff --git a/vscode-desktop/main.test.ts b/vscode-desktop/main.test.ts index ac4133f..304655d 100644 --- a/vscode-desktop/main.test.ts +++ b/vscode-desktop/main.test.ts @@ -13,15 +13,12 @@ describe("vscode-desktop", async () => { agent_id: "foo", }); - it("default output", async () => { const state = await runTerraformApply(import.meta.dir, { agent_id: "foo", }); expect(state.outputs.vscode_url.value).toBe( - "vscode://coder.coder-remote/open?owner=default&workspace=default&token=$SESSION_TOKEN" + "vscode://coder.coder-remote/open?owner=default&workspace=default&token=$SESSION_TOKEN", ); }); - - }); diff --git a/vscode-desktop/main.tf b/vscode-desktop/main.tf index cc3340a..715fb14 100644 --- a/vscode-desktop/main.tf +++ b/vscode-desktop/main.tf @@ -46,6 +46,6 @@ resource "coder_app" "vscode" { } output "vscode_url" { - value = coder_app.vscode.url + value = coder_app.vscode.url description = "VS Code Desktop URL." } diff --git a/vscode-web/main.test.ts b/vscode-web/main.test.ts index dd31e86..57277df 100644 --- a/vscode-web/main.test.ts +++ b/vscode-web/main.test.ts @@ -8,7 +8,6 @@ import { describe("vscode-web", async () => { await runTerraformInit(import.meta.dir); - // replaces testRequiredVariables due to license variable // may add a testRequiredVariablesWithLicense function later it("missing agent_id", async () => { @@ -17,21 +16,18 @@ describe("vscode-web", async () => { accept_license: "true", }); } catch (ex) { - expect(ex.message).toContain( - 'input variable "agent_id" is not set' - ); + expect(ex.message).toContain('input variable "agent_id" is not set'); } }); it("invalid license_agreement", async () => { - try { await runTerraformApply(import.meta.dir, { agent_id: "foo", }); } catch (ex) { expect(ex.message).toContain( - 'You must accept the VS Code license agreement by setting accept_license=true' + "You must accept the VS Code license agreement by setting accept_license=true", ); } }); @@ -61,8 +57,7 @@ describe("vscode-web", async () => { "🥳 vscode-cli has been installed.", "", "👷 Running /tmp/vscode-cli/bin/code serve-web --port 13338 --without-connection-token --accept-server-license-terms in the background...", - "Check logs at /tmp/vscode-web.log!" + "Check logs at /tmp/vscode-web.log!", ]); }); - }); From 2f248dd91f6edcdb31dc2b1cbf2aae0e9b9450b8 Mon Sep 17 00:00:00 2001 From: Stephen Kirby Date: Tue, 10 Oct 2023 17:40:43 +0000 Subject: [PATCH 13/16] placeholder test for jupyterlab with pip --- code-server/main.test.ts | 15 +++++++++++++++ jupyterlab/main.test.ts | 20 ++++++++++++++------ personalize/main.test.ts | 31 ------------------------------- 3 files changed, 29 insertions(+), 37 deletions(-) create mode 100644 code-server/main.test.ts diff --git a/code-server/main.test.ts b/code-server/main.test.ts new file mode 100644 index 0000000..6afbd5b --- /dev/null +++ b/code-server/main.test.ts @@ -0,0 +1,15 @@ +import { describe, expect, it } from "bun:test"; +import { + executeScriptInContainer, + runTerraformApply, + runTerraformInit, + testRequiredVariables, +} from "../test"; + +describe("code-server", async () => { + await runTerraformInit(import.meta.dir); + + testRequiredVariables(import.meta.dir, { + agent_id: "foo", + }); +}); diff --git a/jupyterlab/main.test.ts b/jupyterlab/main.test.ts index 15fb487..97e6329 100644 --- a/jupyterlab/main.test.ts +++ b/jupyterlab/main.test.ts @@ -6,9 +6,13 @@ import { testRequiredVariables, findResourceInstance, runContainer, + TerraformState, + execContainer, } from "../test"; -const executeScriptInContainer = async ( + +// executes the coder script after installing pip +const executeScriptInContainerWithPip = async ( state: TerraformState, image: string, shell: string = "sh", @@ -19,6 +23,7 @@ const executeScriptInContainer = async ( }> => { const instance = findResourceInstance(state, "coder_script"); const id = await runContainer(image); + const respPip = await execContainer(id, [shell, "-c", "apk add py3-pip"]); const resp = await execContainer(id, [shell, "-c", instance.script]); const stdout = resp.stdout.trim().split("\n"); const stderr = resp.stderr.trim().split("\n"); @@ -40,9 +45,6 @@ describe("jupyterlab", async () => { const state = await runTerraformApply(import.meta.dir, { agent_id: "foo", }); - - const instance = findResourceInstance(state, "coder_script"); - const id = await runContainer("alpine"); const output = await executeScriptInContainer(state, "alpine"); expect(output.exitCode).toBe(1); expect(output.stdout).toEqual([ @@ -52,6 +54,12 @@ describe("jupyterlab", async () => { ]); }); - // TODO: Add test that runs with pip - // May be best to use dockerfile + // TODO: Add faster test to run with pip3. + // currently times out. + // it("runs with pip3", async () => { + // ... + // const output = await executeScriptInContainerWithPip(state, "alpine"); + // ... + // }); + }); diff --git a/personalize/main.test.ts b/personalize/main.test.ts index 96b1e2e..cb31a9b 100644 --- a/personalize/main.test.ts +++ b/personalize/main.test.ts @@ -31,35 +31,4 @@ describe("personalize", async () => { ]); }); - // it("runs with personalize script", async () => { - // const state = await runTerraformApply(import.meta.dir, { - // agent_id: "foo", - // }); - // const instance = findResourceInstance(state, "coder_script"); - // const id = await runContainer("alpine"); - // const respInit = await execContainer(id, [ - // "sh", - // "-c", - // 'touch ~/personalize && echo "echo test" > ~/personalize && chmod +x ~/personalize && echo "completed touch cmds"', - // ]); - - // console.log("\n id = ", id, "\n"); - - // console.log("\n====== init ==== stdout (", respInit.exitCode, "):"); - // console.log(respInit.stdout); - // console.log("====== init ==== stderr:"); - // console.log(respInit.stderr); - // console.log("======"); - // const resp = await execContainer(id, ["sh", "-c", instance.script]); - // console.log("====== resp ==== stdout (", resp.exitCode, "):"); - // console.log(resp.stdout); - // console.log("====== resp ==== stderr:"); - // console.log(resp.stderr); - // console.log("======"); - // // await new Promise((resolve) => setTimeout(resolve, 100000000000)); - // const stdout = resp.stdout.trim().split("\n"); - // const stderr = resp.stderr.trim().split("\n"); - // expect(resp.exitCode).toBe(0); - // expect(stdout).toEqual([""]); - // }); }); From ac5c275d8dc7377aac931e68898e44447213c6ea Mon Sep 17 00:00:00 2001 From: Stephen Kirby Date: Tue, 10 Oct 2023 17:50:37 +0000 Subject: [PATCH 14/16] added tests that don't depend on shebang --- code-server/main.test.ts | 9 +++------ jupyterlab/main.test.ts | 6 ++---- personalize/main.test.ts | 1 - 3 files changed, 5 insertions(+), 11 deletions(-) diff --git a/code-server/main.test.ts b/code-server/main.test.ts index 6afbd5b..daf3ac1 100644 --- a/code-server/main.test.ts +++ b/code-server/main.test.ts @@ -1,10 +1,5 @@ import { describe, expect, it } from "bun:test"; -import { - executeScriptInContainer, - runTerraformApply, - runTerraformInit, - testRequiredVariables, -} from "../test"; +import { runTerraformInit, testRequiredVariables } from "../test"; describe("code-server", async () => { await runTerraformInit(import.meta.dir); @@ -12,4 +7,6 @@ describe("code-server", async () => { testRequiredVariables(import.meta.dir, { agent_id: "foo", }); + + // More tests depend on shebang refactors }); diff --git a/jupyterlab/main.test.ts b/jupyterlab/main.test.ts index 97e6329..2597dc2 100644 --- a/jupyterlab/main.test.ts +++ b/jupyterlab/main.test.ts @@ -10,7 +10,6 @@ import { execContainer, } from "../test"; - // executes the coder script after installing pip const executeScriptInContainerWithPip = async ( state: TerraformState, @@ -23,7 +22,7 @@ const executeScriptInContainerWithPip = async ( }> => { const instance = findResourceInstance(state, "coder_script"); const id = await runContainer(image); - const respPip = await execContainer(id, [shell, "-c", "apk add py3-pip"]); + const respPip = await execContainer(id, [shell, "-c", "apk add py3-pip"]); const resp = await execContainer(id, [shell, "-c", instance.script]); const stdout = resp.stdout.trim().split("\n"); const stderr = resp.stderr.trim().split("\n"); @@ -54,12 +53,11 @@ describe("jupyterlab", async () => { ]); }); - // TODO: Add faster test to run with pip3. + // TODO: Add faster test to run with pip3. // currently times out. // it("runs with pip3", async () => { // ... // const output = await executeScriptInContainerWithPip(state, "alpine"); // ... // }); - }); diff --git a/personalize/main.test.ts b/personalize/main.test.ts index cb31a9b..9c8134e 100644 --- a/personalize/main.test.ts +++ b/personalize/main.test.ts @@ -30,5 +30,4 @@ describe("personalize", async () => { "It will run every time your workspace starts. Use it to install personal packages!", ]); }); - }); From b03bb1ba04ea44e5043dde90963601f48fbb5828 Mon Sep 17 00:00:00 2001 From: Stephen Kirby Date: Tue, 10 Oct 2023 18:07:41 +0000 Subject: [PATCH 15/16] fixed coder icon url in coder-login --- coder-login/main.tf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/coder-login/main.tf b/coder-login/main.tf index 2d3ac8b..58d1bf0 100644 --- a/coder-login/main.tf +++ b/coder-login/main.tf @@ -23,7 +23,7 @@ resource "coder_script" "coder-login" { CODER_DEPLOYMENT_URL : data.coder_workspace.me.access_url }) display_name = "Coder Login" - icon = "http://svgur.com/i/y5G.svg" + icon = "/icon/coder.svg" run_on_start = true start_blocks_login = true } From c23edf47d8380f151976264432d4c0c74d4c952b Mon Sep 17 00:00:00 2001 From: Stephen Kirby Date: Tue, 10 Oct 2023 18:58:51 +0000 Subject: [PATCH 16/16] added jetbrains-gateway test --- jetbrains-gateway/main.test.ts | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/jetbrains-gateway/main.test.ts b/jetbrains-gateway/main.test.ts index d4ab4a0..9a0628f 100644 --- a/jetbrains-gateway/main.test.ts +++ b/jetbrains-gateway/main.test.ts @@ -1,5 +1,10 @@ -import { describe } from "bun:test"; -import { runTerraformInit, testRequiredVariables } from "../test"; +import { it, expect, describe } from "bun:test"; +import { + runTerraformInit, + testRequiredVariables, + executeScriptInContainer, + runTerraformApply, +} from "../test"; describe("jetbrains-gateway", async () => { await runTerraformInit(import.meta.dir); @@ -10,4 +15,16 @@ describe("jetbrains-gateway", async () => { folder: "/baz/", jetbrains_ides: '["IU", "IC", "PY"]', }); + + it("default to first ide", async () => { + const state = await runTerraformApply(import.meta.dir, { + agent_id: "foo", + agent_name: "bar", + folder: "/baz/", + jetbrains_ides: '["IU", "IC", "PY"]', + }); + expect(state.outputs.jetbrains_ides.value).toBe( + '["IU","232.9921.47","https://download.jetbrains.com/idea/ideaIU-2023.2.2.tar.gz"]', + ); + }); });