@@ -7,6 +7,7 @@ package wsmanager
7
7
import (
8
8
"context"
9
9
"encoding/json"
10
+ "errors"
10
11
"fmt"
11
12
"path/filepath"
12
13
"reflect"
@@ -180,8 +181,22 @@ func TestPrebuildWorkspaceTaskFail(t *testing.T) {
180
181
const (
181
182
prebuildLogPath string = "/workspace/.gitpod"
182
183
prebuildLog string = "'🤙 This task ran as a workspace prebuild'"
184
+ initTask string = "echo \" some output\" > someFile; sleep 20; exit 0;"
183
185
)
184
186
187
+ // TestOpenWorkspaceFromPrebuild
188
+ // - create a prebuild
189
+ // - open the workspace from prebuild
190
+ // - make sure the .git/ folder with correct permission
191
+ // - make sure either one of the condition mets
192
+ // - the prebuild log message exists
193
+ // - the init task message exists
194
+ // - the init task generated file exists
195
+ //
196
+ // - write a new file foobar.txt
197
+ // - stop the workspace
198
+ // - relaunch the workspace
199
+ // - make sure the file foobar.txt exists
185
200
func TestOpenWorkspaceFromPrebuild (t * testing.T ) {
186
201
f := features .New ("prebuild" ).
187
202
WithLabel ("component" , "ws-manager" ).
@@ -208,7 +223,7 @@ func TestOpenWorkspaceFromPrebuild(t *testing.T) {
208
223
},
209
224
}
210
225
211
- ctx , cancel := context .WithTimeout (context .Background (), time .Duration (10 * len (tests ))* time .Minute )
226
+ ctx , cancel := context .WithTimeout (context .Background (), time .Duration (15 * len (tests ))* time .Minute )
212
227
defer cancel ()
213
228
214
229
for _ , test := range tests {
@@ -223,7 +238,7 @@ func TestOpenWorkspaceFromPrebuild(t *testing.T) {
223
238
req .Type = wsmanapi .WorkspaceType_PREBUILD
224
239
req .Spec .Envvars = append (req .Spec .Envvars , & wsmanapi.EnvironmentVariable {
225
240
Name : "GITPOD_TASKS" ,
226
- Value : `[{ "init": "echo \"some output\" > someFile; sleep 60; exit 0;" }]` ,
241
+ Value : fmt . Sprintf ( `[{ "init": %q }]` , initTask ) ,
227
242
})
228
243
req .Spec .FeatureFlags = test .FF
229
244
req .Spec .Initializer = & csapi.WorkspaceInitializer {
@@ -248,6 +263,7 @@ func TestOpenWorkspaceFromPrebuild(t *testing.T) {
248
263
if err != nil {
249
264
t .Fatalf ("stop workspace and find snapshot error: %v" , err )
250
265
}
266
+ t .Logf ("prebuild snapshot: %s, vsName: %s, vsHandle: %s" , prebuildSnapshot , vsInfo .VolumeSnapshotName , vsInfo .VolumeSnapshotHandle )
251
267
252
268
// launch the workspace from prebuild
253
269
ws , stopWs , err := integration .LaunchWorkspaceDirectly (t , ctx , api , integration .WithRequestModifier (func (req * wsmanapi.StartWorkspaceRequest ) error {
@@ -297,9 +313,32 @@ func TestOpenWorkspaceFromPrebuild(t *testing.T) {
297
313
})
298
314
integration .DeferCloser (t , closer )
299
315
300
- // check prebuild log message exists
316
+ // check the files/folders permission under .git/
301
317
var resp agent.ExecResponse
302
- var checkPrebuildSuccess bool
318
+ var gitDir string = fmt .Sprintf ("%s/%s" , test .WorkspaceRoot , ".git" )
319
+ err = rsa .Call ("WorkspaceAgent.Exec" , & agent.ExecRequest {
320
+ Dir : gitDir ,
321
+ Command : "find" ,
322
+ Args : []string {"-user" , "root" },
323
+ }, & resp )
324
+ if err != nil || resp .ExitCode != 0 || strings .Trim (resp .Stdout , " \t \n " ) != "" {
325
+ t .Fatalf ("incorrect file perimssion under %s folder, err:%v, exitCode:%d, stdout:%s" , gitDir , err , resp .ExitCode , resp .Stdout )
326
+ }
327
+
328
+ err = rsa .Call ("WorkspaceAgent.Exec" , & agent.ExecRequest {
329
+ Dir : gitDir ,
330
+ Command : "find" ,
331
+ Args : []string {"-group" , "root" },
332
+ }, & resp )
333
+ if err != nil || resp .ExitCode != 0 || strings .Trim (resp .Stdout , " \t \n " ) != "" {
334
+ t .Fatalf ("incorrect group perimssion under %s folder, err:%v, exitCode:%d, stdout:%s" , gitDir , err , resp .ExitCode , resp .Stdout )
335
+ }
336
+
337
+ // check prebuild log message exists
338
+ // since the message '🤙 This task ran as a workspace prebuild' is generated by
339
+ // a regular workspace supervisor, so we add a retry mechanism to make sure that we
340
+ // won't check the message too earlier before the supervisor generated it.
341
+ var checkPrebuildLog bool
303
342
for i := 0 ; i < 10 ; i ++ {
304
343
err = rsa .Call ("WorkspaceAgent.Exec" , & agent.ExecRequest {
305
344
Dir : prebuildLogPath ,
@@ -310,16 +349,55 @@ func TestOpenWorkspaceFromPrebuild(t *testing.T) {
310
349
},
311
350
}, & resp )
312
351
if err == nil && resp .ExitCode == 0 && strings .Trim (resp .Stdout , " \t \n " ) != "" {
313
- checkPrebuildSuccess = true
352
+ checkPrebuildLog = true
314
353
break
315
354
}
316
-
317
- // wait 3 seconds and check
318
- time .Sleep (3 * time .Second )
355
+ time .Sleep (6 * time .Second )
319
356
}
320
357
321
- if ! checkPrebuildSuccess {
322
- t .Fatalf ("cannot found the prebuild message %s in %s, err:%v, exitCode:%d, stdout:%s" , prebuildLog , prebuildLogPath , err , resp .ExitCode , resp .Stdout )
358
+ if ! checkPrebuildLog {
359
+ // somehow, the prebuild log message '🤙 This task ran as a workspace prebuild' does not exists
360
+ // we fall back to check the the init task message within the /workspace/.gitpod/prebuild-log-* or not
361
+ t .Logf ("cannot found the prebuild message %s in %s, err:%v, exitCode:%d, stdout:%s" , prebuildLog , prebuildLogPath , err , resp .ExitCode , resp .Stdout )
362
+
363
+ // check the init task message exists
364
+ var checkInitTaskMsg bool
365
+ err = rsa .Call ("WorkspaceAgent.Exec" , & agent.ExecRequest {
366
+ Dir : prebuildLogPath ,
367
+ Command : "bash" ,
368
+ Args : []string {
369
+ "-c" ,
370
+ fmt .Sprintf ("grep %q *" , initTask ),
371
+ },
372
+ }, & resp )
373
+ if err == nil && resp .ExitCode == 0 && strings .Trim (resp .Stdout , " \t \n " ) != "" {
374
+ checkInitTaskMsg = true
375
+ }
376
+
377
+ if ! checkInitTaskMsg {
378
+ t .Logf ("cannot found the init task message %s in %s, err:%v, exitCode:%d, stdout:%s" , initTask , prebuildLogPath , err , resp .ExitCode , resp .Stdout )
379
+
380
+ // somehow, the init task message does not exist within the /workspace/.gitpod/prebuild-log-*
381
+ // we fall back to check the file exists or not
382
+ var ls agent.ListDirResponse
383
+ err = rsa .Call ("WorkspaceAgent.ListDir" , & agent.ListDirRequest {
384
+ Dir : test .WorkspaceRoot ,
385
+ }, & ls )
386
+ if err != nil {
387
+ t .Fatal (err )
388
+ }
389
+
390
+ var found bool
391
+ for _ , f := range ls .Files {
392
+ if filepath .Base (f ) == "someFile" {
393
+ found = true
394
+ break
395
+ }
396
+ }
397
+ if ! found {
398
+ t .Fatal ("did not find someFile from previous workspace instance" )
399
+ }
400
+ }
323
401
}
324
402
325
403
// write file foobar.txt and stop the workspace
@@ -343,6 +421,7 @@ func TestOpenWorkspaceFromPrebuild(t *testing.T) {
343
421
if err != nil {
344
422
t .Fatal (err )
345
423
}
424
+ t .Logf ("prebuild snapshot: %s, vsName: %s, vsHandle: %s" , prebuildSnapshot , vsInfo .VolumeSnapshotName , vsInfo .VolumeSnapshotHandle )
346
425
347
426
// reopen the workspace and make sure the file foobar.txt exists
348
427
ws1 , stopWs1 , err := integration .LaunchWorkspaceDirectly (t , ctx , api , integration .WithRequestModifier (func (req * wsmanapi.StartWorkspaceRequest ) error {
@@ -414,8 +493,8 @@ func stopWorkspaceAndFindSnapshot(StopWorkspaceFunc integration.StopWorkspaceFun
414
493
if err != nil {
415
494
return "" , nil , err
416
495
}
417
- if lastStatus == nil && lastStatus .Conditions == nil {
418
- return "" , nil , nil
496
+ if lastStatus == nil || lastStatus .Conditions == nil || lastStatus . Conditions . VolumeSnapshot == nil {
497
+ return "" , nil , errors . New ( "cannot find the last snapshot" )
419
498
}
420
499
return lastStatus .Conditions .Snapshot , lastStatus .Conditions .VolumeSnapshot , nil
421
500
}
0 commit comments