From 8a98fad3f1292d8c19d69b5d3cac0aafe1db1fcc Mon Sep 17 00:00:00 2001 From: Danny Kopping Date: Thu, 27 Feb 2025 14:53:09 +0200 Subject: [PATCH] Add e2e test for provisioning and claiming a prebuild Signed-off-by: Danny Kopping --- .../basic-presets-with-prebuild/main.tf | 13 ++- site/e2e/tests/presets/prebuilds.spec.ts | 80 +++++++++++++++++-- site/e2e/tests/presets/presets.spec.ts | 2 + 3 files changed, 83 insertions(+), 12 deletions(-) diff --git a/site/e2e/tests/presets/basic-presets-with-prebuild/main.tf b/site/e2e/tests/presets/basic-presets-with-prebuild/main.tf index 804545274b..1f5e4e5991 100644 --- a/site/e2e/tests/presets/basic-presets-with-prebuild/main.tf +++ b/site/e2e/tests/presets/basic-presets-with-prebuild/main.tf @@ -32,7 +32,7 @@ data "coder_workspace_preset" "goland" { "jetbrains_ide" = "GO" } prebuilds { - instances = 1 + instances = 2 } } @@ -41,9 +41,6 @@ data "coder_workspace_preset" "python" { parameters = { "jetbrains_ide" = "PY" } - prebuilds { - instances = 2 - } } resource "coder_agent" "main" { @@ -58,7 +55,9 @@ resource "coder_agent" "main" { touch ~/.init_done fi - # Add any commands that should be executed at workspace startup (e.g install requirements, start a program, etc) here + if [[ "${data.coder_workspace.me.prebuild_count}" -eq 1 ]]; then + touch ~/.prebuild_note + fi EOT # These environment variables allow you to make Git commits right away after creating a @@ -78,9 +77,9 @@ resource "coder_agent" "main" { # For basic resources, you can use the `coder stat` command. # If you need more control, you can write your own script. metadata { - display_name = "Is Prebuild" + display_name = "Was Prebuild" key = "prebuild" - script = "echo ${data.coder_workspace.me.prebuild_count}" + script = "[[ -e ~/.prebuild_note ]] && echo 'Yes' || echo 'No'" interval = 10 timeout = 1 } diff --git a/site/e2e/tests/presets/prebuilds.spec.ts b/site/e2e/tests/presets/prebuilds.spec.ts index ea41b1ecad..38a296be96 100644 --- a/site/e2e/tests/presets/prebuilds.spec.ts +++ b/site/e2e/tests/presets/prebuilds.spec.ts @@ -1,6 +1,7 @@ import path from "node:path"; import { expect, test } from "@playwright/test"; import { + currentUser, importTemplate, login, randomName, @@ -17,7 +18,7 @@ test.beforeEach(async ({ page }) => { test("create template with desired prebuilds", async ({ page, baseURL }) => { requiresLicense(); - const expectedPrebuilds = 3; + const expectedPrebuilds = 2; // Create new template. const templateName = randomName(); @@ -28,6 +29,7 @@ test("create template with desired prebuilds", async ({ page, baseURL }) => { await page.goto( `/workspaces?filter=owner:prebuilds%20template:${templateName}&page=1`, + { waitUntil: "domcontentloaded" }, ); // Wait for prebuilds to show up. @@ -35,8 +37,76 @@ test("create template with desired prebuilds", async ({ page, baseURL }) => { await prebuilds.first().waitFor({ state: "visible", timeout: 120_000 }); expect((await prebuilds.all()).length).toEqual(expectedPrebuilds); - // Wait for prebuilds to become ready. - const readyPrebuilds = page.getByTestId("build-status"); - await readyPrebuilds.first().waitFor({ state: "visible", timeout: 120_000 }); - expect((await readyPrebuilds.all()).length).toEqual(expectedPrebuilds); + // Wait for prebuilds to start. + const runningPrebuilds = page.getByTestId("build-status").getByText("Running"); + await runningPrebuilds.first().waitFor({ state: "visible", timeout: 120_000 }); + expect((await runningPrebuilds.all()).length).toEqual(expectedPrebuilds); +}); + +// NOTE: requires the `workspace-prebuilds` experiment enabled! +test("claim prebuild matching selected preset", async ({ page, baseURL }) => { + test.setTimeout(300_000); + + requiresLicense(); + + // Create new template. + const templateName = randomName(); + await importTemplate(page, templateName, [ + path.join(__dirname, "basic-presets-with-prebuild/main.tf"), + path.join(__dirname, "basic-presets-with-prebuild/.terraform.lock.hcl"), + ]); + + await page.goto( + `/workspaces?filter=owner:prebuilds%20template:${templateName}&page=1`, + { waitUntil: "domcontentloaded" }, + ); + + // Wait for prebuilds to show up. + const prebuilds = page.getByTestId(/^workspace-.+$/); + await prebuilds.first().waitFor({ state: "visible", timeout: 120_000 }); + + // Wait for prebuilds to start. + const runningPrebuilds = page.getByTestId("build-status").getByText("Running"); + await runningPrebuilds.first().waitFor({ state: "visible", timeout: 120_000 }); + + // Open the first prebuild. + await runningPrebuilds.first().click(); + await page.waitForURL(/\/@prebuilds\/prebuild-.+/); + + // Wait for the prebuild to become ready so it's eligible to be claimed. + await page.getByTestId("agent-status-ready").waitFor({ timeout: 60_000 }); + + // Create a new workspace using the same preset as one of the prebuilds. + await page.goto(`/templates/coder/${templateName}/workspace`, { + waitUntil: "domcontentloaded", + }); + + // Visit workspace creation page for new template. + await page.goto(`/templates/default/${templateName}/workspace`, { + waitUntil: "domcontentloaded", + }); + + // Choose a preset. + await page.locator('button[aria-label="Preset"]').click(); + // Choose the GoLand preset. + const preset = page.getByText("I Like GoLand"); + await expect(preset).toBeVisible(); + await preset.click(); + + // Create a workspace. + const workspaceName = randomName(); + await page.locator("input[name=name]").fill(workspaceName); + await page.getByRole("button", { name: "Create workspace" }).click(); + + // Wait for the workspace build display to be navigated to. + const user = currentUser(page); + await page.waitForURL(`/@${user.username}/${workspaceName}`, { + timeout: 120_000, // Account for workspace build time. + }); + + // Validate the workspace metadata that it was indeed a claimed prebuild. + const indicator = page.getByText("Was Prebuild"); + await indicator.waitFor({ timeout: 60_000 }); + const text = indicator.locator("xpath=..").getByText("Yes"); + await text.waitFor({ timeout: 30_000 }); }); diff --git a/site/e2e/tests/presets/presets.spec.ts b/site/e2e/tests/presets/presets.spec.ts index 4b0a10b3f2..85266d281d 100644 --- a/site/e2e/tests/presets/presets.spec.ts +++ b/site/e2e/tests/presets/presets.spec.ts @@ -12,6 +12,8 @@ test("create template with preset and use in workspace", async ({ page, baseURL, }) => { + test.setTimeout(300_000); + // Create new template. const templateName = randomName(); await importTemplate(page, templateName, [