Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
gitpod-io
GitHub Repository: gitpod-io/gitpod
Path: blob/main/components/supervisor/pkg/config/gitpod-config_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 config
6
7
import (
8
"context"
9
"fmt"
10
"os"
11
"testing"
12
"time"
13
14
"github.com/google/go-cmp/cmp"
15
"golang.org/x/sync/errgroup"
16
17
gitpod "github.com/gitpod-io/gitpod/gitpod-protocol"
18
)
19
20
func TestGitpodConfig(t *testing.T) {
21
tests := []struct {
22
Desc string
23
Content string
24
Expectation *gitpod.GitpodConfig
25
}{
26
{
27
Desc: "parsing",
28
Content: `
29
image: eu.gcr.io/gitpod-core-dev/dev/dev-environment:clu-yq4.1
30
workspaceLocation: gitpod/gitpod-ws.code-workspace
31
checkoutLocation: gitpod
32
ports:
33
- port: 1337
34
onOpen: open-preview
35
- port: 3000
36
onOpen: ignore
37
tasks:
38
- before: scripts/branch-namespace.sh
39
init: yarn --network-timeout 100000 && yarn build
40
- name: Go
41
init: leeway exec --filter-type go -v -- go get -v ./...
42
openMode: split-right
43
vscode:
44
extensions:
45
- [email protected]:UATTe2sTFfCYWQ3jw4IRsw==
46
- [email protected]:ZnPmyF/Pb8AIWeCqc83gPw==`,
47
Expectation: &gitpod.GitpodConfig{
48
Image: "eu.gcr.io/gitpod-core-dev/dev/dev-environment:clu-yq4.1",
49
WorkspaceLocation: "gitpod/gitpod-ws.code-workspace",
50
CheckoutLocation: "gitpod",
51
Ports: []*gitpod.PortsItems{
52
{
53
Port: 1337,
54
OnOpen: "open-preview",
55
}, {
56
Port: 3000,
57
OnOpen: "ignore",
58
},
59
},
60
Tasks: []*gitpod.TasksItems{
61
{
62
Before: "scripts/branch-namespace.sh",
63
Init: "yarn --network-timeout 100000 && yarn build",
64
},
65
{
66
Name: "Go",
67
Init: "leeway exec --filter-type go -v -- go get -v ./...",
68
OpenMode: "split-right",
69
},
70
},
71
Vscode: &gitpod.Vscode{
72
Extensions: []string{
73
"[email protected]:UATTe2sTFfCYWQ3jw4IRsw==",
74
"[email protected]:ZnPmyF/Pb8AIWeCqc83gPw==",
75
},
76
},
77
},
78
},
79
}
80
for _, test := range tests {
81
t.Run(test.Desc, func(t *testing.T) {
82
tempDir, err := os.MkdirTemp("", "test-gitpod-config-*")
83
if err != nil {
84
t.Fatal(err)
85
}
86
defer os.RemoveAll(tempDir)
87
88
locationReady := make(chan struct{})
89
configService := NewConfigService(tempDir+"/.gitpod.yml", locationReady)
90
ctx, cancel := context.WithCancel(context.Background())
91
defer cancel()
92
close(locationReady)
93
94
go configService.Watch(ctx)
95
96
var listeners []<-chan *gitpod.GitpodConfig
97
for i := 0; i < 10; i++ {
98
listeners = append(listeners, configService.Observe(ctx))
99
}
100
101
for i := 0; i < 2; i++ {
102
eg, _ := errgroup.WithContext(ctx)
103
for _, listener := range listeners {
104
l := listener
105
eg.Go(func() error {
106
config := <-l
107
if diff := cmp.Diff((*gitpod.GitpodConfig)(nil), config); diff != "" {
108
return fmt.Errorf("unexpected output (-want +got):\n%s", diff)
109
}
110
return nil
111
})
112
}
113
err = eg.Wait()
114
if err != nil {
115
t.Fatal(err)
116
}
117
118
err = os.WriteFile(configService.configLocation, []byte(test.Content), 0o600)
119
if err != nil {
120
t.Fatal(err)
121
}
122
123
eg, _ = errgroup.WithContext(ctx)
124
for _, listener := range listeners {
125
l := listener
126
eg.Go(func() error {
127
config := <-l
128
if diff := cmp.Diff(test.Expectation, config); diff != "" {
129
return fmt.Errorf("unexpected output (-want +got):\n%s", diff)
130
}
131
return nil
132
})
133
}
134
err = eg.Wait()
135
if err != nil {
136
t.Fatal(err)
137
}
138
139
err = os.Remove(configService.configLocation)
140
if err != nil {
141
t.Fatal(err)
142
}
143
}
144
})
145
}
146
}
147
148
func TestInvalidGitpodConfig(t *testing.T) {
149
tempDir, err := os.MkdirTemp("", "test-gitpod-config-*")
150
if err != nil {
151
t.Fatal(err)
152
}
153
defer os.RemoveAll(tempDir)
154
155
locationReady := make(chan struct{})
156
configService := NewConfigService(tempDir+"/.gitpod.yml", locationReady)
157
ctx, cancel := context.WithCancel(context.Background())
158
defer cancel()
159
close(locationReady)
160
161
go configService.Watch(ctx)
162
163
listener := configService.Observe(ctx)
164
165
config := <-listener
166
if diff := cmp.Diff((*gitpod.GitpodConfig)(nil), config); diff != "" {
167
t.Errorf("unexpected output (-want +got):\n%s", diff)
168
}
169
170
err = os.WriteFile(configService.configLocation, []byte(`
171
ports:
172
- port: 8080
173
174
tasks:
175
- command: echo "Hello World"
176
177
vscode:
178
extensions:
179
- foo.bar
180
`), 0o600)
181
if err != nil {
182
t.Fatal(err)
183
}
184
185
config = <-listener
186
if diff := cmp.Diff(&gitpod.GitpodConfig{
187
Ports: []*gitpod.PortsItems{{Port: 8080}},
188
Tasks: []*gitpod.TasksItems{{Command: "echo \"Hello World\""}},
189
Vscode: &gitpod.Vscode{Extensions: []string{"foo.bar"}},
190
}, config); diff != "" {
191
t.Errorf("unexpected output (-want +got):\n%s", diff)
192
}
193
194
err = os.WriteFile(configService.configLocation, []byte(`
195
ports:
196
- port:
197
visibility: private
198
- port: 8080
199
200
tasks:
201
- before:
202
- command: echo "Hello World"
203
204
vscode:
205
extensions:
206
-
207
`), 0o600)
208
if err != nil {
209
t.Fatal(err)
210
}
211
212
time.Sleep(configService.configWatcher.debounceDuration * 10)
213
214
err = os.WriteFile(configService.configLocation, []byte(`
215
ports:
216
- port: 8081
217
`), 0o600)
218
if err != nil {
219
t.Fatal(err)
220
}
221
222
config = <-listener
223
if diff := cmp.Diff(&gitpod.GitpodConfig{
224
Ports: []*gitpod.PortsItems{{Port: 8081}},
225
}, config); diff != "" {
226
t.Errorf("unexpected output (-want +got):\n%s", diff)
227
}
228
}
229
230
func TestWatchImageFile(t *testing.T) {
231
tempDir, err := os.MkdirTemp("", "test-gitpod-config-*")
232
if err != nil {
233
t.Fatal(err)
234
}
235
defer os.RemoveAll(tempDir)
236
237
locationReady := make(chan struct{})
238
configService := NewConfigService(tempDir+"/.gitpod.yml", locationReady)
239
ctx, cancel := context.WithCancel(context.Background())
240
defer cancel()
241
close(locationReady)
242
243
go configService.Watch(ctx)
244
245
listener := configService.ObserveImageFile(ctx)
246
247
err = os.WriteFile(configService.configLocation, []byte(`
248
image:
249
file: Dockerfile
250
`), 0o600)
251
if err != nil {
252
t.Fatal(err)
253
}
254
255
changes := <-listener
256
if diff := cmp.Diff((*struct{})(nil), changes); diff != "" {
257
t.Errorf("unexpected output (-want +got):\n%s", diff)
258
}
259
260
imageLocation := tempDir + "/Dockerfile"
261
err = os.WriteFile(imageLocation, []byte(`
262
FROM ubuntu
263
`), 0o600)
264
if err != nil {
265
t.Fatal(err)
266
}
267
268
changes = <-listener
269
if diff := cmp.Diff(&struct{}{}, changes); diff != "" {
270
t.Errorf("unexpected output (-want +got):\n%s", diff)
271
}
272
273
err = os.WriteFile(configService.configLocation, []byte(`
274
image: ubuntu
275
`), 0o600)
276
if err != nil {
277
t.Fatal(err)
278
}
279
280
changes = <-listener
281
if diff := cmp.Diff((*struct{})(nil), changes); diff != "" {
282
t.Errorf("unexpected output (-want +got):\n%s", diff)
283
}
284
285
err = os.WriteFile(configService.configLocation, []byte(`
286
image:
287
file: Dockerfile
288
`), 0o600)
289
if err != nil {
290
t.Fatal(err)
291
}
292
293
changes = <-listener
294
if diff := cmp.Diff(&struct{}{}, changes); diff != "" {
295
t.Errorf("unexpected output (-want +got):\n%s", diff)
296
}
297
298
err = os.WriteFile(imageLocation, []byte(`
299
FROM node
300
`), 0o600)
301
if err != nil {
302
t.Fatal(err)
303
}
304
305
changes = <-listener
306
if diff := cmp.Diff(&struct{}{}, changes); diff != "" {
307
t.Errorf("unexpected output (-want +got):\n%s", diff)
308
}
309
}
310
311