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