Add e2e test for provisioning and claiming a prebuild

Signed-off-by: Danny Kopping <danny@coder.com>
This commit is contained in:
Danny Kopping
2025-02-27 14:53:09 +02:00
parent 8f051e646d
commit 8a98fad3f1
3 changed files with 83 additions and 12 deletions

View File

@ -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
}

View File

@ -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 });
});

View File

@ -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, [