@@ -7,6 +7,8 @@ package wsmanager
7
7
import (
8
8
"context"
9
9
"encoding/json"
10
+ "fmt"
11
+ "strings"
10
12
"testing"
11
13
"time"
12
14
@@ -15,6 +17,7 @@ import (
15
17
16
18
csapi "github.com/gitpod-io/gitpod/content-service/api"
17
19
gitpod "github.com/gitpod-io/gitpod/gitpod-protocol"
20
+ agent "github.com/gitpod-io/gitpod/test/pkg/agent/workspace/api"
18
21
"github.com/gitpod-io/gitpod/test/pkg/integration"
19
22
wsmanapi "github.com/gitpod-io/gitpod/ws-manager/api"
20
23
)
@@ -171,3 +174,166 @@ func TestPrebuildWorkspaceTaskFail(t *testing.T) {
171
174
172
175
testEnv .Test (t , f )
173
176
}
177
+
178
+ const (
179
+ prebuildLogPath string = "/workspace/.gitpod"
180
+ prebuildLog string = "'🤙 This task ran as a workspace prebuild'"
181
+ )
182
+
183
+ func TestOpenWorkspaceFromPrebuild (t * testing.T ) {
184
+ f := features .New ("prebuild" ).
185
+ WithLabel ("component" , "ws-manager" ).
186
+ Assess ("it should open workspace from prebuild successfully" , func (_ context.Context , t * testing.T , cfg * envconf.Config ) context.Context {
187
+ tests := []struct {
188
+ Name string
189
+ ContextURL string
190
+ WorkspaceRoot string
191
+ CheckoutLocation string
192
+ FF []wsmanapi.WorkspaceFeatureFlag
193
+ }{
194
+ {
195
+ Name : "classic" ,
196
+ ContextURL : "https://github.com/gitpod-io/empty" ,
197
+ CheckoutLocation : "empty" ,
198
+ WorkspaceRoot : "/workspace/empty" ,
199
+ },
200
+ {
201
+ Name : "pvc" ,
202
+ ContextURL : "https://github.com/gitpod-io/empty" ,
203
+ CheckoutLocation : "empty" ,
204
+ WorkspaceRoot : "/workspace/empty" ,
205
+ FF : []wsmanapi.WorkspaceFeatureFlag {wsmanapi .WorkspaceFeatureFlag_PERSISTENT_VOLUME_CLAIM },
206
+ },
207
+ }
208
+
209
+ ctx , cancel := context .WithTimeout (context .Background (), time .Duration (10 * len (tests ))* time .Minute )
210
+ defer cancel ()
211
+
212
+ for _ , test := range tests {
213
+ t .Run (test .Name , func (t * testing.T ) {
214
+ api := integration .NewComponentAPI (ctx , cfg .Namespace (), kubeconfig , cfg .Client ())
215
+ t .Cleanup (func () {
216
+ api .Done (t )
217
+ })
218
+
219
+ // create a prebuild
220
+ _ , prebuildStopWs , err := integration .LaunchWorkspaceDirectly (t , ctx , api , integration .WithRequestModifier (func (req * wsmanapi.StartWorkspaceRequest ) error {
221
+ req .Type = wsmanapi .WorkspaceType_PREBUILD
222
+ req .Spec .Envvars = append (req .Spec .Envvars , & wsmanapi.EnvironmentVariable {
223
+ Name : "GITPOD_TASKS" ,
224
+ Value : `[{ "init": "echo \"some output\" > someFile; sleep 20; exit 0;" }]` ,
225
+ })
226
+ req .Spec .FeatureFlags = test .FF
227
+ req .Spec .Initializer = & csapi.WorkspaceInitializer {
228
+ Spec : & csapi.WorkspaceInitializer_Git {
229
+ Git : & csapi.GitInitializer {
230
+ RemoteUri : test .ContextURL ,
231
+ TargetMode : csapi .CloneTargetMode_REMOTE_BRANCH ,
232
+ CloneTaget : "main" ,
233
+ CheckoutLocation : test .CheckoutLocation ,
234
+ Config : & csapi.GitConfig {},
235
+ },
236
+ },
237
+ }
238
+ req .Spec .WorkspaceLocation = test .CheckoutLocation
239
+ return nil
240
+ }))
241
+ if err != nil {
242
+ t .Fatalf ("cannot launch a workspace: %q" , err )
243
+ }
244
+
245
+ prebuildLastStatus , err := prebuildStopWs (true , api )
246
+ if err != nil {
247
+ t .Errorf ("cannot stop workspace: %q" , err )
248
+ }
249
+
250
+ var (
251
+ prebuildSnapshot string
252
+ fromVolumeSnapshot bool
253
+ volumeSnapshotInfo * wsmanapi.VolumeSnapshotInfo
254
+ )
255
+ if prebuildLastStatus != nil && prebuildLastStatus .Conditions != nil {
256
+ if prebuildLastStatus .Conditions .Snapshot != "" {
257
+ prebuildSnapshot = prebuildLastStatus .Conditions .Snapshot
258
+ }
259
+
260
+ if prebuildLastStatus .Conditions .VolumeSnapshot != nil &&
261
+ prebuildLastStatus .Conditions .VolumeSnapshot .VolumeSnapshotName != "" &&
262
+ prebuildLastStatus .Conditions .VolumeSnapshot .VolumeSnapshotHandle != "" {
263
+ fromVolumeSnapshot = true
264
+ volumeSnapshotInfo = prebuildLastStatus .Conditions .VolumeSnapshot
265
+ }
266
+ }
267
+
268
+ // launch the workspace from prebuild
269
+ ws , stopWs , err := integration .LaunchWorkspaceDirectly (t , ctx , api , integration .WithRequestModifier (func (req * wsmanapi.StartWorkspaceRequest ) error {
270
+ req .Spec .FeatureFlags = test .FF
271
+ req .Spec .Initializer = & csapi.WorkspaceInitializer {
272
+ Spec : & csapi.WorkspaceInitializer_Prebuild {
273
+ Prebuild : & csapi.PrebuildInitializer {
274
+ Prebuild : & csapi.SnapshotInitializer {Snapshot : prebuildSnapshot , FromVolumeSnapshot : fromVolumeSnapshot },
275
+ Git : []* csapi.GitInitializer {
276
+ {
277
+ RemoteUri : test .ContextURL ,
278
+ TargetMode : csapi .CloneTargetMode_REMOTE_BRANCH ,
279
+ CloneTaget : "main" ,
280
+ CheckoutLocation : test .CheckoutLocation ,
281
+ Config : & csapi.GitConfig {},
282
+ },
283
+ },
284
+ },
285
+ },
286
+ }
287
+ req .Spec .VolumeSnapshot = volumeSnapshotInfo
288
+ req .Spec .WorkspaceLocation = test .CheckoutLocation
289
+ return nil
290
+ }))
291
+ if err != nil {
292
+ t .Fatalf ("cannot launch a workspace: %q" , err )
293
+ }
294
+
295
+ defer func () {
296
+ sctx , scancel := context .WithTimeout (context .Background (), 5 * time .Minute )
297
+ defer scancel ()
298
+
299
+ sapi := integration .NewComponentAPI (sctx , cfg .Namespace (), kubeconfig , cfg .Client ())
300
+ defer sapi .Done (t )
301
+
302
+ _ , err = stopWs (true , sapi )
303
+ if err != nil {
304
+ t .Errorf ("cannot stop workspace: %q" , err )
305
+ }
306
+ }()
307
+
308
+ rsa , closer , err := integration .Instrument (integration .ComponentWorkspace , "workspace" , cfg .Namespace (), kubeconfig , cfg .Client (), integration .WithInstanceID (ws .Req .Id ))
309
+ if err != nil {
310
+ t .Error (err )
311
+ }
312
+ integration .DeferCloser (t , closer )
313
+
314
+ var resp agent.ExecResponse
315
+ err = rsa .Call ("WorkspaceAgent.Exec" , & agent.ExecRequest {
316
+ Dir : prebuildLogPath ,
317
+ Command : "bash" ,
318
+ Args : []string {
319
+ "-c" ,
320
+ fmt .Sprintf ("grep %s *" , prebuildLog ),
321
+ },
322
+ }, & resp )
323
+ rsa .Close ()
324
+ if err != nil || resp .ExitCode != 0 {
325
+ t .Errorf ("cannot grep %s: exit code %d" , prebuildLogPath , resp .ExitCode )
326
+ return
327
+ }
328
+ if strings .Trim (resp .Stdout , " \t \n " ) == "" {
329
+ t .Errorf ("cannot found message %s in %s" , prebuildLog , prebuildLogPath )
330
+ return
331
+ }
332
+ })
333
+ }
334
+ return ctx
335
+ }).
336
+ Feature ()
337
+
338
+ testEnv .Test (t , f )
339
+ }
0 commit comments