Skip to content

Commit a3a7137

Browse files
committed
test: add new test TestPrebuildAndRegularWorkspaceDifferentWorkspaceClass
Test prebuild and regular workspace with different workspace class Signed-off-by: JenTing Hsiao <[email protected]>
1 parent 98f5813 commit a3a7137

File tree

1 file changed

+256
-87
lines changed

1 file changed

+256
-87
lines changed

test/tests/components/ws-manager/prebuild_test.go

Lines changed: 256 additions & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88
"context"
99
"encoding/json"
1010
"fmt"
11+
"net/rpc"
1112
"path/filepath"
1213
"reflect"
1314
"strings"
@@ -312,95 +313,11 @@ func TestOpenWorkspaceFromPrebuild(t *testing.T) {
312313
})
313314
integration.DeferCloser(t, closer)
314315

315-
// check prebuild log message exists
316-
// since the message '🤙 This task ran as a workspace prebuild' is generated by
317-
// a prebuild workspace supervisor, so we add a retry mechanism to make sure that we
318-
// won't check the message too earlier before the supervisor generated it.
319-
var grepResp agent.ExecResponse
320-
var checkPrebuildLog bool
321-
for i := 0; i < 10; i++ {
322-
err = rsa.Call("WorkspaceAgent.Exec", &agent.ExecRequest{
323-
Dir: prebuildLogPath,
324-
Command: "bash",
325-
Args: []string{
326-
"-c",
327-
fmt.Sprintf("grep %s *", prebuildLog),
328-
},
329-
}, &grepResp)
330-
if err == nil && grepResp.ExitCode == 0 && strings.Trim(grepResp.Stdout, " \t\n") != "" {
331-
checkPrebuildLog = true
332-
break
333-
}
334-
t.Logf("[%d] retry...", i)
335-
time.Sleep(3 * time.Second)
336-
}
337-
338-
if !checkPrebuildLog {
339-
t.Logf("cannot found the prebuild message %s in %s, err:%v, exitCode:%d, stdout:%s", prebuildLog, prebuildLogPath, err, grepResp.ExitCode, grepResp.Stdout)
340-
341-
// somehow, the prebuild log message '🤙 This task ran as a workspace prebuild' does not exists
342-
// we fall back to check the the init task message within the /workspace/.gitpod/prebuild-log-* or not
343-
var grepResp agent.ExecResponse
344-
var checkInitTaskMsg bool
345-
err = rsa.Call("WorkspaceAgent.Exec", &agent.ExecRequest{
346-
Dir: prebuildLogPath,
347-
Command: "bash",
348-
Args: []string{
349-
"-c",
350-
fmt.Sprintf("grep %q *", initTask),
351-
},
352-
}, &grepResp)
353-
if err == nil && grepResp.ExitCode == 0 && strings.Trim(grepResp.Stdout, " \t\n") != "" {
354-
checkInitTaskMsg = true
355-
}
356-
357-
if !checkInitTaskMsg {
358-
t.Logf("cannot found the init task message %s in %s, err:%v, exitCode:%d, stdout:%s", initTask, prebuildLogPath, err, grepResp.ExitCode, grepResp.Stdout)
359-
360-
// somehow, the init task message does not exist within the /workspace/.gitpod/prebuild-log-*
361-
// we fall back to check the file exists or not
362-
var ls agent.ListDirResponse
363-
err = rsa.Call("WorkspaceAgent.ListDir", &agent.ListDirRequest{
364-
Dir: test.WorkspaceRoot,
365-
}, &ls)
366-
if err != nil {
367-
t.Fatal(err)
368-
}
369-
370-
var found bool
371-
for _, f := range ls.Files {
372-
if filepath.Base(f) == "someFile" {
373-
found = true
374-
break
375-
}
376-
}
377-
if !found {
378-
t.Fatal("did not find someFile from previous workspace instance")
379-
}
380-
}
381-
}
316+
// checkPrebuildLogExist checks the prebuild log message exists
317+
checkPrebuildLogExist(t, cfg, rsa, ws, test.WorkspaceRoot)
382318

383319
// check the files/folders permission under .git/ is not root
384-
var findUserResp agent.ExecResponse
385-
var gitDir string = fmt.Sprintf("%s/%s", test.WorkspaceRoot, ".git")
386-
err = rsa.Call("WorkspaceAgent.Exec", &agent.ExecRequest{
387-
Dir: gitDir,
388-
Command: "find",
389-
Args: []string{"-user", "root"},
390-
}, &findUserResp)
391-
if err != nil || findUserResp.ExitCode != 0 || strings.Trim(findUserResp.Stdout, " \t\n") != "" {
392-
t.Fatalf("incorrect file perimssion under %s folder, err:%v, exitCode:%d, stdout:%s", gitDir, err, findUserResp.ExitCode, findUserResp.Stdout)
393-
}
394-
395-
var findGroupResp agent.ExecResponse
396-
err = rsa.Call("WorkspaceAgent.Exec", &agent.ExecRequest{
397-
Dir: gitDir,
398-
Command: "find",
399-
Args: []string{"-group", "root"},
400-
}, &findGroupResp)
401-
if err != nil || findGroupResp.ExitCode != 0 || strings.Trim(findGroupResp.Stdout, " \t\n") != "" {
402-
t.Fatalf("incorrect group perimssion under %s folder, err:%v, exitCode:%d, stdout:%s", gitDir, err, findGroupResp.ExitCode, findGroupResp.Stdout)
403-
}
320+
checkGitFolderPermission(t, rsa, test.WorkspaceRoot)
404321

405322
// write file foobar.txt and stop the workspace
406323
var writeFileResp agent.ExecResponse
@@ -491,6 +408,258 @@ func TestOpenWorkspaceFromPrebuild(t *testing.T) {
491408
testEnv.Test(t, f)
492409
}
493410

411+
// TestPrebuildAndRegularWorkspaceDifferentWorkspaceClass
412+
// - create a prebuild with small/large workspace class (20Gi/30Gi disk)
413+
// - the user preference is large workspace class (30Gi disk)
414+
// - open the workspace from prebuild
415+
// - make sure either one of the condition mets
416+
// - the prebuild log message exists
417+
// - the init task message exists
418+
// - the init task generated file exists
419+
//
420+
// - make sure the .git/ folder with correct permission
421+
// - make sure the user disk size is 30Gi
422+
func TestPrebuildAndRegularWorkspaceDifferentWorkspaceClass(t *testing.T) {
423+
f := features.New("prebuild").
424+
WithLabel("component", "ws-manager").
425+
Assess("it should open workspace with different workspace class", func(_ context.Context, t *testing.T, cfg *envconf.Config) context.Context {
426+
tests := []struct {
427+
Name string
428+
PrebuildWorkspaceClass string
429+
RegularWorkspaceClass string
430+
ContextURL string
431+
WorkspaceRoot string
432+
CheckoutLocation string
433+
ShouldFailToOpenRegularWorkspace bool
434+
}{
435+
{
436+
Name: "prebuild-small-regular-large-workspace-class",
437+
// TODO: do not use hard-code workspace class name to prevent if we change to different environment to run the test
438+
PrebuildWorkspaceClass: "small",
439+
RegularWorkspaceClass: "default",
440+
//
441+
ContextURL: "https://github.com/gitpod-io/empty",
442+
CheckoutLocation: "empty",
443+
WorkspaceRoot: "/workspace/empty",
444+
},
445+
{
446+
Name: "prebuild-large-regular-small-workspace-class",
447+
// TODO: do not use hard-code workspace class name to prevent if we change to different environment to run the test
448+
PrebuildWorkspaceClass: "default",
449+
RegularWorkspaceClass: "small",
450+
//
451+
ContextURL: "https://github.com/gitpod-io/empty",
452+
CheckoutLocation: "empty",
453+
WorkspaceRoot: "/workspace/empty",
454+
ShouldFailToOpenRegularWorkspace: true,
455+
},
456+
}
457+
458+
ctx, cancel := context.WithTimeout(context.Background(), time.Duration(10*len(tests))*time.Minute)
459+
defer cancel()
460+
461+
for _, test := range tests {
462+
t.Run(test.Name, func(t *testing.T) {
463+
api := integration.NewComponentAPI(ctx, cfg.Namespace(), kubeconfig, cfg.Client())
464+
t.Cleanup(func() {
465+
api.Done(t)
466+
})
467+
468+
// create a prebuild and stop workspace
469+
_, prebuildStopWs, err := integration.LaunchWorkspaceDirectly(t, ctx, api, integration.WithRequestModifier(func(req *wsmanapi.StartWorkspaceRequest) error {
470+
req.Type = wsmanapi.WorkspaceType_PREBUILD
471+
req.Spec.Class = test.PrebuildWorkspaceClass
472+
req.Spec.Envvars = append(req.Spec.Envvars, &wsmanapi.EnvironmentVariable{
473+
Name: "GITPOD_TASKS",
474+
Value: fmt.Sprintf(`[{ "init": %q }]`, initTask),
475+
})
476+
req.Spec.FeatureFlags = []wsmanapi.WorkspaceFeatureFlag{wsmanapi.WorkspaceFeatureFlag_PERSISTENT_VOLUME_CLAIM}
477+
req.Spec.Initializer = &csapi.WorkspaceInitializer{
478+
Spec: &csapi.WorkspaceInitializer_Git{
479+
Git: &csapi.GitInitializer{
480+
RemoteUri: test.ContextURL,
481+
CheckoutLocation: test.CheckoutLocation,
482+
Config: &csapi.GitConfig{},
483+
},
484+
},
485+
}
486+
req.Spec.WorkspaceLocation = test.CheckoutLocation
487+
return nil
488+
}))
489+
if err != nil {
490+
t.Fatalf("cannot launch a workspace: %q", err)
491+
}
492+
493+
prebuildSnapshot, vsInfo, err := stopWorkspaceAndFindSnapshot(prebuildStopWs, api)
494+
if err != nil {
495+
t.Fatalf("stop workspace and find snapshot error: %v", err)
496+
}
497+
498+
t.Logf("prebuild snapshot: %s", prebuildSnapshot)
499+
if vsInfo != nil {
500+
t.Logf("vsName: %s, vsHandle: %s", vsInfo.VolumeSnapshotName, vsInfo.VolumeSnapshotHandle)
501+
}
502+
503+
// launch the workspace from prebuild
504+
ws, stopWs, err := integration.LaunchWorkspaceDirectly(t, ctx, api, integration.WithRequestModifier(func(req *wsmanapi.StartWorkspaceRequest) error {
505+
req.Spec.Class = test.RegularWorkspaceClass
506+
req.Spec.FeatureFlags = []wsmanapi.WorkspaceFeatureFlag{wsmanapi.WorkspaceFeatureFlag_PERSISTENT_VOLUME_CLAIM}
507+
req.Spec.Initializer = &csapi.WorkspaceInitializer{
508+
Spec: &csapi.WorkspaceInitializer_Prebuild{
509+
Prebuild: &csapi.PrebuildInitializer{
510+
Prebuild: &csapi.SnapshotInitializer{
511+
Snapshot: prebuildSnapshot,
512+
FromVolumeSnapshot: true,
513+
},
514+
Git: []*csapi.GitInitializer{
515+
{
516+
RemoteUri: test.ContextURL,
517+
CheckoutLocation: test.CheckoutLocation,
518+
Config: &csapi.GitConfig{},
519+
},
520+
},
521+
},
522+
},
523+
}
524+
req.Spec.VolumeSnapshot = vsInfo
525+
req.Spec.WorkspaceLocation = test.CheckoutLocation
526+
return nil
527+
}))
528+
if err != nil {
529+
if test.ShouldFailToOpenRegularWorkspace {
530+
return
531+
}
532+
t.Fatalf("cannot launch a workspace: %q", err)
533+
}
534+
535+
defer func() {
536+
// stop workspace in defer function to prevent we forget to stop the workspace
537+
if err := stopWorkspace(t, cfg, stopWs); err != nil {
538+
t.Errorf("cannot stop workspace: %q", err)
539+
}
540+
}()
541+
542+
rsa, closer, err := integration.Instrument(integration.ComponentWorkspace, "workspace", cfg.Namespace(), kubeconfig, cfg.Client(),
543+
integration.WithInstanceID(ws.Req.Id),
544+
)
545+
if err != nil {
546+
t.Fatal(err)
547+
}
548+
t.Cleanup(func() {
549+
rsa.Close()
550+
})
551+
integration.DeferCloser(t, closer)
552+
553+
// checkPrebuildLogExist checks the prebuild log message exists
554+
checkPrebuildLogExist(t, cfg, rsa, ws, test.WorkspaceRoot)
555+
556+
// check the files/folders permission under .git/ is not root
557+
checkGitFolderPermission(t, rsa, test.WorkspaceRoot)
558+
})
559+
}
560+
return ctx
561+
}).
562+
Feature()
563+
564+
testEnv.Test(t, f)
565+
}
566+
567+
// checkPrebuildLogExist checks the prebuild log message exists
568+
func checkPrebuildLogExist(t *testing.T, cfg *envconf.Config, rsa *rpc.Client, ws *integration.LaunchWorkspaceDirectlyResult, wsRoot string) {
569+
// since the message '🤙 This task ran as a workspace prebuild' is generated by
570+
// a prebuild workspace supervisor, so we add a retry mechanism to make sure that we
571+
// won't check the message too earlier before the supervisor generated it.
572+
var (
573+
err error
574+
grepResp agent.ExecResponse
575+
checkPrebuildLog bool
576+
)
577+
err = rsa.Call("WorkspaceAgent.Exec", &agent.ExecRequest{
578+
Dir: prebuildLogPath,
579+
Command: "bash",
580+
Args: []string{
581+
"-c",
582+
fmt.Sprintf("grep %s *", prebuildLog),
583+
},
584+
}, &grepResp)
585+
if err == nil && grepResp.ExitCode == 0 && strings.Trim(grepResp.Stdout, " \t\n") != "" {
586+
checkPrebuildLog = true
587+
}
588+
if checkPrebuildLog {
589+
return
590+
}
591+
592+
t.Logf("cannot found the prebuild message %s in %s, err:%v, exitCode:%d, stdout:%s", prebuildLog, prebuildLogPath, err, grepResp.ExitCode, grepResp.Stdout)
593+
594+
// somehow, the prebuild log message '🤙 This task ran as a workspace prebuild' does not exists
595+
// we fall back to check the the init task message within the /workspace/.gitpod/prebuild-log-* or not
596+
var grepResp1 agent.ExecResponse
597+
var checkInitTaskMsg bool
598+
err = rsa.Call("WorkspaceAgent.Exec", &agent.ExecRequest{
599+
Dir: prebuildLogPath,
600+
Command: "bash",
601+
Args: []string{
602+
"-c",
603+
fmt.Sprintf("grep %q *", initTask),
604+
},
605+
}, &grepResp1)
606+
if err == nil && grepResp1.ExitCode == 0 && strings.Trim(grepResp1.Stdout, " \t\n") != "" {
607+
checkInitTaskMsg = true
608+
}
609+
if checkInitTaskMsg {
610+
return
611+
}
612+
613+
t.Logf("cannot found the init task message %s in %s, err:%v, exitCode:%d, stdout:%s", initTask, prebuildLogPath, err, grepResp.ExitCode, grepResp.Stdout)
614+
615+
// somehow, the init task message does not exist within the /workspace/.gitpod/prebuild-log-*
616+
// we fall back to check the file exists or not
617+
var ls agent.ListDirResponse
618+
err = rsa.Call("WorkspaceAgent.ListDir", &agent.ListDirRequest{
619+
Dir: wsRoot,
620+
}, &ls)
621+
if err != nil {
622+
t.Fatal(err)
623+
}
624+
625+
var found bool
626+
for _, f := range ls.Files {
627+
if filepath.Base(f) == "someFile" {
628+
found = true
629+
break
630+
}
631+
}
632+
if found {
633+
return
634+
}
635+
t.Fatal("did not find someFile from previous workspace instance")
636+
}
637+
638+
// checkGitFolderPermission checks the files/folders permission under .git/ is not root
639+
func checkGitFolderPermission(t *testing.T, rsa *rpc.Client, workspaceRoot string) {
640+
var findUserResp agent.ExecResponse
641+
var gitDir string = fmt.Sprintf("%s/%s", workspaceRoot, ".git")
642+
643+
err := rsa.Call("WorkspaceAgent.Exec", &agent.ExecRequest{
644+
Dir: gitDir,
645+
Command: "find",
646+
Args: []string{"-user", "root"},
647+
}, &findUserResp)
648+
if err != nil || findUserResp.ExitCode != 0 || strings.Trim(findUserResp.Stdout, " \t\n") != "" {
649+
t.Fatalf("incorrect file perimssion under %s folder, err:%v, exitCode:%d, stdout:%s", gitDir, err, findUserResp.ExitCode, findUserResp.Stdout)
650+
}
651+
652+
var findGroupResp agent.ExecResponse
653+
err = rsa.Call("WorkspaceAgent.Exec", &agent.ExecRequest{
654+
Dir: gitDir,
655+
Command: "find",
656+
Args: []string{"-group", "root"},
657+
}, &findGroupResp)
658+
if err != nil || findGroupResp.ExitCode != 0 || strings.Trim(findGroupResp.Stdout, " \t\n") != "" {
659+
t.Fatalf("incorrect group perimssion under %s folder, err:%v, exitCode:%d, stdout:%s", gitDir, err, findGroupResp.ExitCode, findGroupResp.Stdout)
660+
}
661+
}
662+
494663
func stopWorkspaceAndFindSnapshot(StopWorkspaceFunc integration.StopWorkspaceFunc, api *integration.ComponentAPI) (string, *wsmanapi.VolumeSnapshotInfo, error) {
495664
lastStatus, err := StopWorkspaceFunc(true, api)
496665
if err != nil {

0 commit comments

Comments
 (0)