Skip to content

test: verify that enterprise tests are being run #12871

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Apr 5, 2024
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -483,6 +483,7 @@ jobs:
env:
DEBUG: pw:api
CODER_E2E_ENTERPRISE_LICENSE: ${{ secrets.CODER_E2E_ENTERPRISE_LICENSE }}
CODER_E2E_REQUIRE_ENTERPRISE_TESTS: "1"
working-directory: site

- name: Upload Playwright Failed Tests
Expand Down
6 changes: 3 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -382,9 +382,9 @@ install: build/coder_$(VERSION)_$(GOOS)_$(GOARCH)$(GOOS_BIN_EXT)
cp "$<" "$$output_file"
.PHONY: install

BOLD := $(shell tput bold)
GREEN := $(shell tput setaf 2)
RESET := $(shell tput sgr0)
BOLD := $(shell tput bold 2>/dev/null)
GREEN := $(shell tput setaf 2 2>/dev/null)
RESET := $(shell tput sgr0 2>/dev/null)

fmt: fmt/eslint fmt/prettier fmt/terraform fmt/shfmt fmt/go
.PHONY: fmt
Expand Down
3 changes: 3 additions & 0 deletions site/e2e/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,4 +33,7 @@ export const gitAuth = {
installationsPath: "/installations",
};

export const requireEnterpriseTests = Boolean(
process.env.CODER_E2E_REQUIRE_ENTERPRISE_TESTS,
);
export const enterpriseLicense = process.env.CODER_E2E_ENTERPRISE_LICENSE ?? "";
9 changes: 7 additions & 2 deletions site/e2e/global.setup.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { test, expect } from "@playwright/test";
import { expect, test } from "@playwright/test";
import { Language } from "pages/CreateUserPage/CreateUserForm";
import * as constants from "./constants";
import { storageState } from "./playwright.config";
Expand All @@ -18,7 +18,12 @@ test("setup deployment", async ({ page }) => {
await page.getByTestId("button-select-template").isVisible();

// Setup license
if (constants.enterpriseLicense) {
if (constants.requireEnterpriseTests || constants.enterpriseLicense) {
// Make sure that we have something that looks like a real license
expect(constants.enterpriseLicense).toBeTruthy();
expect(constants.enterpriseLicense.length).toBeGreaterThan(92); // the signature alone should be this long
expect(constants.enterpriseLicense.split(".").length).toBe(3); // otherwise it's invalid

await page.goto("/deployment/licenses", { waitUntil: "domcontentloaded" });

await page.getByText("Add a license").click();
Expand Down
5 changes: 5 additions & 0 deletions site/e2e/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import {
coderPort,
enterpriseLicense,
prometheusPort,
requireEnterpriseTests,
} from "./constants";
import {
Agent,
Expand All @@ -33,6 +34,10 @@ import {

// requiresEnterpriseLicense will skip the test if we're not running with an enterprise license
export function requiresEnterpriseLicense() {
if (requireEnterpriseTests) {
return;
}

test.skip(!enterpriseLicense);
}

Expand Down
71 changes: 44 additions & 27 deletions site/e2e/reporter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,13 @@ import type {
import axios from "axios";
import * as fs from "fs/promises";
import type { Writable } from "stream";
import { coderdPProfPort } from "./constants";
import { coderdPProfPort, enterpriseLicense } from "./constants";

class CoderReporter implements Reporter {
config: FullConfig | null = null;
testOutput = new Map<string, Array<[Writable, string]>>();
passedCount = 0;
skippedCount = 0;
failedTests: TestCase[] = [];
timedOutTests: TestCase[] = [];

Expand All @@ -31,45 +32,56 @@ class CoderReporter implements Reporter {
}

onStdOut(chunk: string, test?: TestCase, _?: TestResult): void {
for (const line of filteredServerLogLines(chunk)) {
console.log(`[stdout] ${line}`);
}
// If there's no associated test, just print it now
if (!test) {
for (const line of logLines(chunk)) {
console.log(`[stdout] ${line}`);
}
return;
}
// Will be printed if the test fails
this.testOutput.get(test.id)!.push([process.stdout, chunk]);
}

onStdErr(chunk: string, test?: TestCase, _?: TestResult): void {
for (const line of filteredServerLogLines(chunk)) {
console.error(`[stderr] ${line}`);
}
// If there's no associated test, just print it now
if (!test) {
for (const line of logLines(chunk)) {
console.error(`[stderr] ${line}`);
}
return;
}
// Will be printed if the test fails
this.testOutput.get(test.id)!.push([process.stderr, chunk]);
}

async onTestEnd(test: TestCase, result: TestResult) {
console.log(`==> Finished test ${test.title}: ${result.status}`);
try {
if (test.expectedStatus === "skipped") {
console.log(`==> Skipping test ${test.title}`);
this.skippedCount++;
return;
}

if (result.status === "passed") {
this.passedCount++;
}
console.log(`==> Finished test ${test.title}: ${result.status}`);

if (result.status === "failed") {
this.failedTests.push(test);
}
if (result.status === "passed") {
this.passedCount++;
return;
}

if (result.status === "timedOut") {
this.timedOutTests.push(test);
}
if (result.status === "failed") {
this.failedTests.push(test);
}

if (result.status === "timedOut") {
this.timedOutTests.push(test);
}

const fsTestTitle = test.title.replaceAll(" ", "-");
const outputFile = `test-results/debug-pprof-goroutine-${fsTestTitle}.txt`;
await exportDebugPprof(outputFile);
const fsTestTitle = test.title.replaceAll(" ", "-");
const outputFile = `test-results/debug-pprof-goroutine-${fsTestTitle}.txt`;
await exportDebugPprof(outputFile);

if (result.status !== "passed") {
console.log(`Data from pprof has been saved to ${outputFile}`);
console.log("==> Output");
const output = this.testOutput.get(test.id)!;
Expand All @@ -90,13 +102,22 @@ class CoderReporter implements Reporter {
console.log(attachment);
}
}
} finally {
this.testOutput.delete(test.id);
}
this.testOutput.delete(test.id);
}

onEnd(result: FullResult) {
console.log(`==> Tests ${result.status}`);
if (!enterpriseLicense) {
console.log(
"==> Enterprise tests were skipped, because no license was provided",
);
}
console.log(`${this.passedCount} passed`);
if (this.skippedCount > 0) {
console.log(`${this.skippedCount} skipped`);
}
if (this.failedTests.length > 0) {
console.log(`${this.failedTests.length} failed`);
for (const test of this.failedTests) {
Expand All @@ -112,11 +133,7 @@ class CoderReporter implements Reporter {
}
}

const shouldPrintLine = (line: string) =>
[" error=EOF", "coderd: audit_log"].every((noise) => !line.includes(noise));

const filteredServerLogLines = (chunk: string): string[] =>
chunk.trimEnd().split("\n").filter(shouldPrintLine);
const logLines = (chunk: string): string[] => chunk.trimEnd().split("\n");

const exportDebugPprof = async (outputFile: string) => {
const response = await axios.get(
Expand Down
10 changes: 10 additions & 0 deletions site/e2e/tests/enterprise.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { expect, test } from "@playwright/test";
import { requiresEnterpriseLicense } from "../helpers";

test("license was added successfully", async ({ page }) => {
requiresEnterpriseLicense();

await page.goto("/deployment/licenses", { waitUntil: "domcontentloaded" });
const license = page.locator(".MuiPaper-root", { hasText: "#1" });
await expect(license).toBeVisible();
});