Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
gitpod-io
GitHub Repository: gitpod-io/gitpod
Path: blob/main/components/local-app/pkg/helper/workspace_test.go
2500 views
1
// Copyright (c) 2023 Gitpod GmbH. All rights reserved.
2
// Licensed under the GNU Affero General Public License (AGPL).
3
// See License.AGPL.txt in the project root for license information.
4
5
package helper
6
7
import (
8
"context"
9
"fmt"
10
"net/http"
11
"net/http/httptest"
12
"testing"
13
14
"github.com/bufbuild/connect-go"
15
"github.com/gitpod-io/gitpod/components/public-api/go/client"
16
v1 "github.com/gitpod-io/gitpod/components/public-api/go/experimental/v1"
17
gitpod_experimental_v1connect "github.com/gitpod-io/gitpod/components/public-api/go/experimental/v1/v1connect"
18
"github.com/gitpod-io/local-app/pkg/prettyprint"
19
"github.com/google/go-cmp/cmp"
20
)
21
22
func TestObserveWorkspaceUntilStarted(t *testing.T) {
23
workspaceWithStatus := func(id string, phase v1.WorkspaceInstanceStatus_Phase) *v1.Workspace {
24
return &v1.Workspace{
25
WorkspaceId: id,
26
Status: &v1.WorkspaceStatus{
27
Instance: &v1.WorkspaceInstance{
28
WorkspaceId: id,
29
Status: &v1.WorkspaceInstanceStatus{
30
Phase: phase,
31
},
32
},
33
},
34
}
35
}
36
37
type Expectation struct {
38
Error string
39
SystemException bool
40
}
41
tests := []struct {
42
Name string
43
Expectation Expectation
44
PrepServer func(mux *http.ServeMux)
45
WorkspaceID string
46
}{
47
{
48
Name: "stream retry",
49
PrepServer: func(mux *http.ServeMux) {
50
mux.Handle(gitpod_experimental_v1connect.NewWorkspacesServiceHandler(&TestWorkspaceService{
51
Workspaces: []*v1.Workspace{
52
workspaceWithStatus("workspaceID", v1.WorkspaceInstanceStatus_PHASE_PENDING),
53
workspaceWithStatus("workspaceID", v1.WorkspaceInstanceStatus_PHASE_CREATING),
54
nil,
55
workspaceWithStatus("workspaceID", v1.WorkspaceInstanceStatus_PHASE_RUNNING),
56
},
57
}))
58
},
59
},
60
{
61
Name: "stream ends early",
62
PrepServer: func(mux *http.ServeMux) {
63
mux.Handle(gitpod_experimental_v1connect.NewWorkspacesServiceHandler(&TestWorkspaceService{
64
Workspaces: []*v1.Workspace{
65
workspaceWithStatus("workspaceID", v1.WorkspaceInstanceStatus_PHASE_CREATING),
66
},
67
}))
68
},
69
Expectation: Expectation{
70
Error: "workspace stream ended unexpectedly",
71
SystemException: true,
72
},
73
},
74
{
75
Name: "workspace starts",
76
PrepServer: func(mux *http.ServeMux) {
77
mux.Handle(gitpod_experimental_v1connect.NewWorkspacesServiceHandler(&TestWorkspaceService{
78
Workspaces: []*v1.Workspace{
79
workspaceWithStatus("workspaceID", v1.WorkspaceInstanceStatus_PHASE_PENDING),
80
workspaceWithStatus("workspaceID", v1.WorkspaceInstanceStatus_PHASE_CREATING),
81
workspaceWithStatus("workspaceID", v1.WorkspaceInstanceStatus_PHASE_RUNNING),
82
},
83
}))
84
},
85
},
86
}
87
88
for _, test := range tests {
89
t.Run(test.Name, func(t *testing.T) {
90
var act Expectation
91
92
mux := http.NewServeMux()
93
if test.PrepServer != nil {
94
test.PrepServer(mux)
95
}
96
97
apisrv := httptest.NewServer(mux)
98
t.Cleanup(apisrv.Close)
99
100
clnt, err := client.New(client.WithURL(apisrv.URL), client.WithCredentials("hello world"))
101
if err != nil {
102
t.Fatal(err)
103
}
104
105
_, err = ObserveWorkspaceUntilStarted(context.Background(), clnt, test.WorkspaceID)
106
if err != nil {
107
act.Error = err.Error()
108
_, act.SystemException = err.(*prettyprint.ErrSystemException)
109
}
110
111
if diff := cmp.Diff(test.Expectation, act); diff != "" {
112
t.Errorf("ObserveWorkspaceUntilStarted() mismatch (-want +got):\n%s", diff)
113
}
114
})
115
}
116
}
117
118
type TestWorkspaceService struct {
119
gitpod_experimental_v1connect.WorkspacesServiceHandler
120
121
Workspaces []*v1.Workspace
122
Pos int
123
}
124
125
func (srv *TestWorkspaceService) GetWorkspace(context.Context, *connect.Request[v1.GetWorkspaceRequest]) (*connect.Response[v1.GetWorkspaceResponse], error) {
126
if srv.Pos >= len(srv.Workspaces) {
127
return nil, connect.NewError(connect.CodeNotFound, fmt.Errorf("not found"))
128
}
129
130
resp := &connect.Response[v1.GetWorkspaceResponse]{
131
Msg: &v1.GetWorkspaceResponse{
132
Result: srv.Workspaces[srv.Pos],
133
},
134
}
135
srv.Pos++
136
return resp, nil
137
}
138
139
func (srv *TestWorkspaceService) StreamWorkspaceStatus(ctx context.Context, req *connect.Request[v1.StreamWorkspaceStatusRequest], resp *connect.ServerStream[v1.StreamWorkspaceStatusResponse]) error {
140
if srv.Pos >= len(srv.Workspaces) {
141
return nil
142
}
143
if srv.Workspaces[srv.Pos] == nil {
144
srv.Pos++
145
return nil
146
}
147
148
for ; srv.Pos < len(srv.Workspaces); srv.Pos++ {
149
ws := srv.Workspaces[srv.Pos]
150
if ws == nil {
151
return nil
152
}
153
err := resp.Send(&v1.StreamWorkspaceStatusResponse{
154
Result: ws.Status,
155
})
156
if err != nil {
157
return err
158
}
159
}
160
return nil
161
}
162
163