Skip to content

test: fix flaky test TestOpenWorkspaceFromPrebuild #13170

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Sep 23, 2022
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
106 changes: 94 additions & 12 deletions test/tests/components/ws-manager/prebuild_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -180,8 +180,22 @@ func TestPrebuildWorkspaceTaskFail(t *testing.T) {
const (
prebuildLogPath string = "/workspace/.gitpod"
prebuildLog string = "'🤙 This task ran as a workspace prebuild'"
initTask string = "echo \"some output\" > someFile; sleep 90;"
)

// TestOpenWorkspaceFromPrebuild
// - create a prebuild
// - open the workspace from prebuild
// - make sure the .git/ folder with correct permission
// - make sure either one of the condition mets
// - the prebuild log message exists
// - the init task message exists
// - the init task generated file exists
//
// - write a new file foobar.txt
// - stop the workspace
// - relaunch the workspace
// - make sure the file foobar.txt exists
Comment on lines +186 to +198
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add the test steps here, so we could more easily understand the test steps without tracing the code.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great!

func TestOpenWorkspaceFromPrebuild(t *testing.T) {
f := features.New("prebuild").
WithLabel("component", "ws-manager").
Expand Down Expand Up @@ -223,7 +237,7 @@ func TestOpenWorkspaceFromPrebuild(t *testing.T) {
req.Type = wsmanapi.WorkspaceType_PREBUILD
req.Spec.Envvars = append(req.Spec.Envvars, &wsmanapi.EnvironmentVariable{
Name: "GITPOD_TASKS",
Value: `[{ "init": "echo \"some output\" > someFile; sleep 60; exit 0;" }]`,
Value: fmt.Sprintf(`[{ "init": %q }]`, initTask),
})
req.Spec.FeatureFlags = test.FF
req.Spec.Initializer = &csapi.WorkspaceInitializer{
Expand All @@ -248,6 +262,7 @@ func TestOpenWorkspaceFromPrebuild(t *testing.T) {
if err != nil {
t.Fatalf("stop workspace and find snapshot error: %v", err)
}
t.Logf("prebuild snapshot: %s, vsName: %s, vsHandle: %s", prebuildSnapshot, vsInfo.VolumeSnapshotName, vsInfo.VolumeSnapshotHandle)

// launch the workspace from prebuild
ws, stopWs, err := integration.LaunchWorkspaceDirectly(t, ctx, api, integration.WithRequestModifier(func(req *wsmanapi.StartWorkspaceRequest) error {
Expand Down Expand Up @@ -298,8 +313,11 @@ func TestOpenWorkspaceFromPrebuild(t *testing.T) {
integration.DeferCloser(t, closer)

// check prebuild log message exists
var resp agent.ExecResponse
var checkPrebuildSuccess bool
// since the message '🤙 This task ran as a workspace prebuild' is generated by
// a prebuild workspace supervisor, so we add a retry mechanism to make sure that we
// won't check the message too earlier before the supervisor generated it.
var grepResp agent.ExecResponse
var checkPrebuildLog bool
for i := 0; i < 10; i++ {
err = rsa.Call("WorkspaceAgent.Exec", &agent.ExecRequest{
Dir: prebuildLogPath,
Expand All @@ -308,26 +326,89 @@ func TestOpenWorkspaceFromPrebuild(t *testing.T) {
"-c",
fmt.Sprintf("grep %s *", prebuildLog),
},
}, &resp)
if err == nil && resp.ExitCode == 0 && strings.Trim(resp.Stdout, " \t\n") != "" {
checkPrebuildSuccess = true
}, &grepResp)
if err == nil && grepResp.ExitCode == 0 && strings.Trim(grepResp.Stdout, " \t\n") != "" {
checkPrebuildLog = true
break
}

// wait 3 seconds and check
t.Logf("[%d] retry...", i)
time.Sleep(3 * time.Second)
}

if !checkPrebuildSuccess {
t.Fatalf("cannot found the prebuild message %s in %s, err:%v, exitCode:%d, stdout:%s", prebuildLog, prebuildLogPath, err, resp.ExitCode, resp.Stdout)
if !checkPrebuildLog {
t.Logf("cannot found the prebuild message %s in %s, err:%v, exitCode:%d, stdout:%s", prebuildLog, prebuildLogPath, err, grepResp.ExitCode, grepResp.Stdout)

// somehow, the prebuild log message '🤙 This task ran as a workspace prebuild' does not exists
// we fall back to check the the init task message within the /workspace/.gitpod/prebuild-log-* or not
var grepResp agent.ExecResponse
var checkInitTaskMsg bool
err = rsa.Call("WorkspaceAgent.Exec", &agent.ExecRequest{
Dir: prebuildLogPath,
Command: "bash",
Args: []string{
"-c",
fmt.Sprintf("grep %q *", initTask),
},
}, &grepResp)
if err == nil && grepResp.ExitCode == 0 && strings.Trim(grepResp.Stdout, " \t\n") != "" {
checkInitTaskMsg = true
}

if !checkInitTaskMsg {
t.Logf("cannot found the init task message %s in %s, err:%v, exitCode:%d, stdout:%s", initTask, prebuildLogPath, err, grepResp.ExitCode, grepResp.Stdout)

// somehow, the init task message does not exist within the /workspace/.gitpod/prebuild-log-*
// we fall back to check the file exists or not
var ls agent.ListDirResponse
err = rsa.Call("WorkspaceAgent.ListDir", &agent.ListDirRequest{
Dir: test.WorkspaceRoot,
}, &ls)
if err != nil {
t.Fatal(err)
}

var found bool
for _, f := range ls.Files {
if filepath.Base(f) == "someFile" {
found = true
break
}
}
if !found {
t.Fatal("did not find someFile from previous workspace instance")
}
}
}

// check the files/folders permission under .git/ is not root
var findUserResp agent.ExecResponse
var gitDir string = fmt.Sprintf("%s/%s", test.WorkspaceRoot, ".git")
err = rsa.Call("WorkspaceAgent.Exec", &agent.ExecRequest{
Dir: gitDir,
Command: "find",
Args: []string{"-user", "root"},
}, &findUserResp)
if err != nil || findUserResp.ExitCode != 0 || strings.Trim(findUserResp.Stdout, " \t\n") != "" {
t.Fatalf("incorrect file perimssion under %s folder, err:%v, exitCode:%d, stdout:%s", gitDir, err, findUserResp.ExitCode, findUserResp.Stdout)
}

var findGroupResp agent.ExecResponse
err = rsa.Call("WorkspaceAgent.Exec", &agent.ExecRequest{
Dir: gitDir,
Command: "find",
Args: []string{"-group", "root"},
}, &findGroupResp)
if err != nil || findGroupResp.ExitCode != 0 || strings.Trim(findGroupResp.Stdout, " \t\n") != "" {
t.Fatalf("incorrect group perimssion under %s folder, err:%v, exitCode:%d, stdout:%s", gitDir, err, findGroupResp.ExitCode, findGroupResp.Stdout)
}

// write file foobar.txt and stop the workspace
var writeFileResp agent.ExecResponse
err = rsa.Call("WorkspaceAgent.WriteFile", &agent.WriteFileRequest{
Path: fmt.Sprintf("%s/foobar.txt", test.WorkspaceRoot),
Content: []byte("hello world"),
Mode: 0644,
}, &resp)
}, &writeFileResp)
if err != nil {
t.Fatalf("cannot write file %s", fmt.Sprintf("%s/foobar.txt", test.WorkspaceRoot))
}
Expand All @@ -343,6 +424,7 @@ func TestOpenWorkspaceFromPrebuild(t *testing.T) {
if err != nil {
t.Fatal(err)
}
t.Logf("vsName: %s, vsHandle: %s", vsInfo.VolumeSnapshotName, vsInfo.VolumeSnapshotHandle)

// reopen the workspace and make sure the file foobar.txt exists
ws1, stopWs1, err := integration.LaunchWorkspaceDirectly(t, ctx, api, integration.WithRequestModifier(func(req *wsmanapi.StartWorkspaceRequest) error {
Expand Down Expand Up @@ -414,7 +496,7 @@ func stopWorkspaceAndFindSnapshot(StopWorkspaceFunc integration.StopWorkspaceFun
if err != nil {
return "", nil, err
}
if lastStatus == nil && lastStatus.Conditions == nil {
if lastStatus == nil || lastStatus.Conditions == nil || lastStatus.Conditions.VolumeSnapshot == nil {
return "", nil, nil
}
return lastStatus.Conditions.Snapshot, lastStatus.Conditions.VolumeSnapshot, nil
Expand Down