Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
gitpod-io
GitHub Repository: gitpod-io/gitpod
Path: blob/main/test/tests/components/ws-manager/content_test.go
2500 views
1
// Copyright (c) 2020 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 wsmanager
6
7
import (
8
"context"
9
"fmt"
10
"path/filepath"
11
"testing"
12
"time"
13
14
"sigs.k8s.io/e2e-framework/pkg/envconf"
15
"sigs.k8s.io/e2e-framework/pkg/features"
16
17
csapi "github.com/gitpod-io/gitpod/content-service/api"
18
agent "github.com/gitpod-io/gitpod/test/pkg/agent/workspace/api"
19
"github.com/gitpod-io/gitpod/test/pkg/integration"
20
wsmanapi "github.com/gitpod-io/gitpod/ws-manager/api"
21
)
22
23
// TestBackup tests a basic start/modify/restart cycle
24
func TestBackup(t *testing.T) {
25
f := features.New("backup").
26
WithLabel("component", "ws-manager").
27
Assess("it should start a workspace, create a file and successfully create a backup", func(testCtx context.Context, t *testing.T, cfg *envconf.Config) context.Context {
28
tests := []struct {
29
Name string
30
ContextURL string
31
WorkspaceRoot string
32
CheckoutLocation string
33
FF []wsmanapi.WorkspaceFeatureFlag
34
}{
35
{
36
Name: "classic",
37
ContextURL: "https://github.com/gitpod-io/empty",
38
WorkspaceRoot: "/workspace/empty",
39
CheckoutLocation: "empty",
40
},
41
}
42
for _, test := range tests {
43
test := test
44
t.Run(test.Name, func(t *testing.T) {
45
t.Parallel()
46
47
ctx, cancel := context.WithTimeout(testCtx, time.Duration(10*len(tests))*time.Minute)
48
defer cancel()
49
50
api := integration.NewComponentAPI(ctx, cfg.Namespace(), kubeconfig, cfg.Client())
51
t.Cleanup(func() {
52
api.Done(t)
53
})
54
55
// TODO: change to use server API to launch the workspace, so we could run the integration test as the user code flow
56
// which is client -> server -> ws-manager rather than client -> ws-manager directly
57
ws1, stopWs1, err := integration.LaunchWorkspaceDirectly(t, ctx, api, integration.WithRequestModifier(func(w *wsmanapi.StartWorkspaceRequest) error {
58
w.Spec.FeatureFlags = test.FF
59
w.Spec.Initializer = &csapi.WorkspaceInitializer{
60
Spec: &csapi.WorkspaceInitializer_Git{
61
Git: &csapi.GitInitializer{
62
RemoteUri: test.ContextURL,
63
CheckoutLocation: test.CheckoutLocation,
64
Config: &csapi.GitConfig{},
65
},
66
},
67
}
68
w.Spec.WorkspaceLocation = test.CheckoutLocation
69
return nil
70
}))
71
if err != nil {
72
t.Fatal(err)
73
}
74
t.Cleanup(func() {
75
if err != nil {
76
sctx, scancel := context.WithTimeout(context.Background(), 5*time.Minute)
77
defer scancel()
78
79
sapi := integration.NewComponentAPI(sctx, cfg.Namespace(), kubeconfig, cfg.Client())
80
defer sapi.Done(t)
81
82
_, err = stopWs1(true, sapi)
83
if err != nil {
84
t.Fatal(err)
85
}
86
}
87
})
88
89
rsa, closer, err := integration.Instrument(integration.ComponentWorkspace, "workspace", cfg.Namespace(), kubeconfig, cfg.Client(),
90
integration.WithInstanceID(ws1.Req.Id),
91
integration.WithContainer("workspace"),
92
integration.WithWorkspacekitLift(true),
93
)
94
if err != nil {
95
t.Fatal(err)
96
}
97
integration.DeferCloser(t, closer)
98
99
var resp agent.WriteFileResponse
100
err = rsa.Call("WorkspaceAgent.WriteFile", &agent.WriteFileRequest{
101
Path: fmt.Sprintf("%s/foobar.txt", test.WorkspaceRoot),
102
Content: []byte("hello world"),
103
Mode: 0644,
104
}, &resp)
105
rsa.Close()
106
if err != nil {
107
if _, serr := stopWs1(true, api); serr != nil {
108
t.Errorf("cannot stop workspace: %q", serr)
109
}
110
t.Fatal(err)
111
}
112
113
_, err = stopWs1(true, api)
114
if err != nil {
115
t.Fatal(err)
116
}
117
118
ws2, stopWs2, err := integration.LaunchWorkspaceDirectly(t, ctx, api,
119
integration.WithRequestModifier(func(w *wsmanapi.StartWorkspaceRequest) error {
120
w.ServicePrefix = ws1.Req.ServicePrefix
121
w.Metadata.MetaId = ws1.Req.Metadata.MetaId
122
w.Metadata.Owner = ws1.Req.Metadata.Owner
123
w.Spec.FeatureFlags = ws1.Req.Spec.FeatureFlags
124
w.Spec.Initializer = ws1.Req.Spec.Initializer
125
w.Spec.WorkspaceLocation = ws1.Req.Spec.WorkspaceLocation
126
127
return nil
128
}),
129
)
130
if err != nil {
131
t.Fatal(err)
132
}
133
t.Cleanup(func() {
134
sctx, scancel := context.WithTimeout(context.Background(), 10*time.Minute)
135
defer scancel()
136
137
sapi := integration.NewComponentAPI(sctx, cfg.Namespace(), kubeconfig, cfg.Client())
138
defer sapi.Done(t)
139
140
_, err = stopWs2(true, sapi)
141
if err != nil {
142
t.Errorf("cannot stop workspace: %q", err)
143
}
144
})
145
146
rsa, closer, err = integration.Instrument(integration.ComponentWorkspace, "workspace", cfg.Namespace(), kubeconfig, cfg.Client(),
147
integration.WithInstanceID(ws2.Req.Id),
148
)
149
if err != nil {
150
t.Fatal(err)
151
}
152
integration.DeferCloser(t, closer)
153
154
var ls agent.ListDirResponse
155
err = rsa.Call("WorkspaceAgent.ListDir", &agent.ListDirRequest{
156
Dir: test.WorkspaceRoot,
157
}, &ls)
158
if err != nil {
159
t.Fatal(err)
160
}
161
rsa.Close()
162
163
var found bool
164
for _, f := range ls.Files {
165
if filepath.Base(f) == "foobar.txt" {
166
t.Log("found the target file")
167
found = true
168
break
169
}
170
}
171
if !found {
172
t.Fatal("did not find foobar.txt from previous workspace instance")
173
}
174
})
175
}
176
return testCtx
177
}).
178
Feature()
179
180
testEnv.Test(t, f)
181
182
}
183
184
// TestMissingBackup ensures workspaces fail if they should have a backup but don't have one
185
func TestMissingBackup(t *testing.T) {
186
f := features.New("CreateWorkspace").
187
WithLabel("component", "ws-manager").
188
Assess("it ensures workspace fail if they should have a backup but don't have one", func(testCtx context.Context, t *testing.T, cfg *envconf.Config) context.Context {
189
ctx, cancel := context.WithTimeout(testCtx, 5*time.Minute)
190
defer cancel()
191
192
api := integration.NewComponentAPI(ctx, cfg.Namespace(), kubeconfig, cfg.Client())
193
t.Cleanup(func() {
194
api.Done(t)
195
})
196
197
ws, stopWs, err := integration.LaunchWorkspaceDirectly(t, ctx, api)
198
if err != nil {
199
t.Fatal(err)
200
}
201
202
_, err = stopWs(true, api)
203
if err != nil {
204
t.Fatal(err)
205
}
206
207
contentSvc, err := api.ContentService()
208
if err != nil {
209
t.Fatal(err)
210
}
211
212
_, err = contentSvc.DeleteWorkspace(ctx, &csapi.DeleteWorkspaceRequest{
213
OwnerId: ws.Req.Metadata.Owner,
214
WorkspaceId: ws.Req.Metadata.MetaId,
215
})
216
if err != nil {
217
t.Fatal(err)
218
}
219
220
tests := []struct {
221
Name string
222
FF []wsmanapi.WorkspaceFeatureFlag
223
}{
224
{Name: "classic"},
225
}
226
for _, test := range tests {
227
test := test
228
t.Run(test.Name+"_backup_init", func(t *testing.T) {
229
t.Parallel()
230
231
ctx, cancel := context.WithTimeout(context.Background(), time.Duration(5*len(tests))*time.Minute)
232
defer cancel()
233
234
testws, stopWs2, err := integration.LaunchWorkspaceDirectly(t, ctx, api, integration.WithRequestModifier(func(w *wsmanapi.StartWorkspaceRequest) error {
235
w.ServicePrefix = ws.Req.ServicePrefix
236
w.Metadata.MetaId = ws.Req.Metadata.MetaId
237
w.Metadata.Owner = ws.Req.Metadata.Owner
238
w.Spec.Initializer = &csapi.WorkspaceInitializer{
239
Spec: &csapi.WorkspaceInitializer_Backup{
240
Backup: &csapi.FromBackupInitializer{},
241
},
242
}
243
w.Spec.FeatureFlags = test.FF
244
return nil
245
}), integration.WithWaitWorkspaceForOpts(integration.WorkspaceCanFail, integration.WaitForStopped))
246
if err != nil {
247
t.Fatal(err)
248
}
249
250
t.Cleanup(func() {
251
sctx, scancel := context.WithTimeout(context.Background(), 5*time.Minute)
252
defer scancel()
253
254
sapi := integration.NewComponentAPI(sctx, cfg.Namespace(), kubeconfig, cfg.Client())
255
defer sapi.Done(t)
256
257
_, err := stopWs2(true, sapi)
258
if err != nil {
259
t.Fatal(err)
260
}
261
})
262
263
if testws.LastStatus == nil {
264
t.Fatal("did not receive a last status")
265
return
266
}
267
if testws.LastStatus.Conditions.Failed == "" {
268
t.Errorf("restarted workspace did not fail despite missing backup, %v", testws)
269
}
270
271
})
272
}
273
return testCtx
274
}).
275
Feature()
276
277
testEnv.Test(t, f)
278
}
279
280