Skip to content

Commit bd64c99

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 bd64c99

File tree

1 file changed

+261
-87
lines changed

1 file changed

+261
-87
lines changed

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

Lines changed: 261 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,263 @@ func TestOpenWorkspaceFromPrebuild(t *testing.T) {
491408
testEnv.Test(t, f)
492409
}
493410

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

0 commit comments

Comments
 (0)