Skip to content

Commit 80bf4b5

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 cb9e902 commit 80bf4b5

File tree

1 file changed

+254
-67
lines changed

1 file changed

+254
-67
lines changed

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

Lines changed: 254 additions & 67 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,73 +313,7 @@ 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(t, cfg, rsa, ws, test.WorkspaceRoot)
382317

383318
// check the files/folders permission under .git/ is not root
384319
var findUserResp agent.ExecResponse
@@ -491,6 +426,258 @@ func TestOpenWorkspaceFromPrebuild(t *testing.T) {
491426
testEnv.Test(t, f)
492427
}
493428

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

0 commit comments

Comments
 (0)