Path: blob/main/components/ws-manager-bridge/src/prebuild-state-mapper.spec.ts
2498 views
/**1* Copyright (c) 2022 Gitpod GmbH. All rights reserved.2* Licensed under the GNU Affero General Public License (AGPL).3* See License.AGPL.txt in the project root for license information.4*/56import { suite, test } from "@testdeck/mocha";7import * as chai from "chai";8import { PrebuildStateMapper } from "./prebuild-state-mapper";9import { WorkspaceConditionBool, WorkspacePhase, WorkspaceStatus } from "@gitpod/ws-manager/lib";10import { PrebuiltWorkspace } from "@gitpod/gitpod-protocol";1112const expect = chai.expect;1314const mockExperimentsClient = (returnValue: boolean) => {15return {16getValueAsync: async <T>() => {17return returnValue as unknown as T;18},19dispose: () => {},20};21};2223@suite24class TestPrebuildStateMapper {25// Tests with ws_manager_bridge_stopped_prebuild_statuses disabled26@test public async testWsManagerBridgeStoppedDisabled() {27const id = "12345";28const snapshot = "some-valid-snapshot";29const failed = "some system error";30const headlessTaskFailed = "some user/content error";3132const table: {33name: string;34status: Pick<WorkspaceStatus.AsObject, "id" | "phase"> & {35conditions: Partial<WorkspaceStatus.AsObject["conditions"]>;36};37expected: (Omit<Partial<PrebuiltWorkspace>, "error"> & { hasError?: boolean }) | undefined;38}[] = [39{40name: "STOPPED",41expected: undefined,42status: {43id,44phase: WorkspacePhase.STOPPED,45conditions: {46snapshot,47},48},49},50{51name: "failed",52expected: {53state: "failed",54hasError: true,55},56status: {57id,58phase: WorkspacePhase.STOPPING,59conditions: {60failed,61},62},63},64{65name: "Stopping and no snapshot yet",66expected: undefined,67status: {68id,69phase: WorkspacePhase.STOPPING,70conditions: {71snapshot: "",72},73},74},75{76name: "aborted",77expected: {78state: "aborted",79hasError: true,80},81status: {82id,83phase: WorkspacePhase.STOPPING,84conditions: {85stoppedByRequest: WorkspaceConditionBool.TRUE,86},87},88},89{90name: "user/content error",91expected: {92state: "available",93hasError: true,94snapshot,95},96status: {97id,98phase: WorkspacePhase.STOPPING,99conditions: {100headlessTaskFailed,101snapshot,102},103},104},105{106name: "available and no error",107expected: {108state: "available",109hasError: false,110snapshot,111},112status: {113id,114phase: WorkspacePhase.STOPPING,115conditions: {116snapshot,117},118},119},120];121122for (const test of table) {123const cut = new PrebuildStateMapper(mockExperimentsClient(false));124const actual = await cut.mapWorkspaceStatusToPrebuild(test.status as WorkspaceStatus.AsObject);125expect(!!actual?.update.error, test.name + ": hasError").to.be.equal(!!test.expected?.hasError);126delete actual?.update.error;127delete test.expected?.hasError;128expect(actual?.update, test.name).to.deep.equal(test.expected);129}130}131// Tests with ws_manager_bridge_stopped_prebuild_statuses enabled132@test public async testWsManagerBridgeStoppedEnabled() {133const id = "12345";134const snapshot = "some-valid-snapshot";135const failed = "some system error";136const headlessTaskFailed = "some user/content error";137138const table: {139name: string;140status: Pick<WorkspaceStatus.AsObject, "id" | "phase"> & {141conditions: Partial<WorkspaceStatus.AsObject["conditions"]>;142};143expected: (Omit<Partial<PrebuiltWorkspace>, "error"> & { hasError?: boolean }) | undefined;144}[] = [145{146name: "STOPPED, finished",147expected: {148state: "available",149snapshot,150},151status: {152id,153phase: WorkspacePhase.STOPPED,154conditions: {155snapshot,156},157},158},159{160name: "failed",161expected: {162state: "building",163hasError: false,164},165status: {166id,167phase: WorkspacePhase.STOPPING,168conditions: {169failed,170},171},172},173{174name: "Stopping and no snapshot yet",175expected: {176state: "building",177},178status: {179id,180phase: WorkspacePhase.STOPPING,181conditions: {182snapshot: "",183},184},185},186{187name: "aborted",188expected: {189state: "aborted",190hasError: true,191},192status: {193id,194phase: WorkspacePhase.STOPPED,195conditions: {196stoppedByRequest: WorkspaceConditionBool.TRUE,197},198},199},200{201name: "user/content error",202expected: {203state: "available",204hasError: true,205snapshot,206},207status: {208id,209phase: WorkspacePhase.STOPPED,210conditions: {211headlessTaskFailed,212snapshot,213},214},215},216{217name: "user/content error too early",218expected: {219state: "building",220},221status: {222id,223phase: WorkspacePhase.STOPPING,224conditions: {225headlessTaskFailed,226snapshot,227},228},229},230{231name: "available and no error",232expected: {233state: "available",234hasError: false,235snapshot,236},237status: {238id,239phase: WorkspacePhase.STOPPED,240conditions: {241snapshot,242},243},244},245];246247for (const test of table) {248const cut = new PrebuildStateMapper(mockExperimentsClient(true));249const actual = await cut.mapWorkspaceStatusToPrebuild(test.status as WorkspaceStatus.AsObject);250expect(!!actual?.update.error, test.name + ": hasError").to.be.equal(!!test.expected?.hasError);251delete actual?.update.error;252delete test.expected?.hasError;253expect(actual?.update, test.name).to.deep.equal(test.expected);254}255}256}257module.exports = new TestPrebuildStateMapper(); // Only to circumvent no usage warning :-/258259260