Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
gitpod-io
GitHub Repository: gitpod-io/gitpod
Path: blob/main/install/installer/pkg/common/render_test.go
2500 views
1
// Copyright (c) 2022 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 common_test
6
7
import (
8
"testing"
9
10
"github.com/google/go-cmp/cmp"
11
"github.com/stretchr/testify/require"
12
corev1 "k8s.io/api/core/v1"
13
"k8s.io/apimachinery/pkg/api/resource"
14
"k8s.io/apimachinery/pkg/runtime"
15
"k8s.io/utils/pointer"
16
17
"github.com/gitpod-io/gitpod/installer/pkg/common"
18
content_service "github.com/gitpod-io/gitpod/installer/pkg/components/content-service"
19
"github.com/gitpod-io/gitpod/installer/pkg/components/dashboard"
20
"github.com/gitpod-io/gitpod/installer/pkg/components/server"
21
config "github.com/gitpod-io/gitpod/installer/pkg/config/v1"
22
"github.com/gitpod-io/gitpod/installer/pkg/config/versions"
23
)
24
25
func TestCompositeRenderFunc_NilObjectsNilError(t *testing.T) {
26
f := common.CompositeRenderFunc(
27
func(cfg *common.RenderContext) ([]runtime.Object, error) {
28
return nil, nil
29
})
30
31
ctx, err := common.NewRenderContext(config.Config{}, versions.Manifest{}, "test_namespace")
32
require.NoError(t, err)
33
34
objects, err := f(ctx)
35
require.NoError(t, err)
36
require.Len(t, objects, 0)
37
}
38
39
func TestReplicas(t *testing.T) {
40
testCases := []struct {
41
Component string
42
Name string
43
ExpectedReplicas int32
44
}{
45
{
46
Component: server.Component,
47
Name: "server takes replica count from common config",
48
ExpectedReplicas: 123,
49
},
50
{
51
Component: dashboard.Component,
52
Name: "dashboard takes replica count from common config",
53
ExpectedReplicas: 456,
54
},
55
{
56
Component: content_service.Component,
57
Name: "content_service takes default replica count",
58
ExpectedReplicas: 1,
59
},
60
}
61
ctx, err := common.NewRenderContext(config.Config{
62
Components: &config.Components{
63
PodConfig: map[string]*config.PodConfig{
64
"server": {Replicas: pointer.Int32(123)},
65
"dashboard": {Replicas: pointer.Int32(456)},
66
},
67
},
68
}, versions.Manifest{}, "test_namespace")
69
require.NoError(t, err)
70
71
for _, testCase := range testCases {
72
t.Run(testCase.Name, func(t *testing.T) {
73
actualReplicas := common.Replicas(ctx, testCase.Component)
74
75
if *actualReplicas != testCase.ExpectedReplicas {
76
t.Errorf("expected %d replicas for %q component, but got %d",
77
testCase.ExpectedReplicas, testCase.Component, *actualReplicas)
78
}
79
})
80
}
81
}
82
83
func TestResourceRequirements(t *testing.T) {
84
defaultResources := corev1.ResourceRequirements{
85
Requests: corev1.ResourceList{
86
"cpu": resource.MustParse("200m"),
87
"memory": resource.MustParse("200Mi"),
88
},
89
Limits: corev1.ResourceList{
90
"cpu": resource.MustParse("200m"),
91
"memory": resource.MustParse("200Mi"),
92
},
93
}
94
95
serverResources := corev1.ResourceRequirements{
96
Requests: corev1.ResourceList{
97
"cpu": resource.MustParse("50m"),
98
"memory": resource.MustParse("100Mi"),
99
},
100
Limits: corev1.ResourceList{
101
"cpu": resource.MustParse("500m"),
102
"memory": resource.MustParse("800Mi"),
103
},
104
}
105
106
dashboardResources := corev1.ResourceRequirements{
107
Requests: corev1.ResourceList{
108
"cpu": resource.MustParse("60m"),
109
"memory": resource.MustParse("100Mi"),
110
},
111
Limits: corev1.ResourceList{
112
"cpu": resource.MustParse("100m"),
113
"memory": resource.MustParse("500Mi"),
114
},
115
}
116
117
testCases := []struct {
118
Component string
119
ContainerName string
120
Name string
121
ExpectedResources corev1.ResourceRequirements
122
}{
123
{
124
Component: server.Component,
125
ContainerName: server.Component,
126
Name: "server takes resource requirements from config",
127
ExpectedResources: serverResources,
128
},
129
{
130
Component: dashboard.Component,
131
ContainerName: dashboard.Component,
132
Name: "dashboard takes resource requirements from config",
133
ExpectedResources: dashboardResources,
134
},
135
{
136
Component: content_service.Component,
137
Name: "content_service takes default resource requirements",
138
ExpectedResources: defaultResources,
139
},
140
}
141
ctx, err := common.NewRenderContext(config.Config{
142
Components: &config.Components{
143
PodConfig: map[string]*config.PodConfig{
144
server.Component: {
145
Resources: map[string]*corev1.ResourceRequirements{
146
server.Component: &serverResources,
147
},
148
},
149
dashboard.Component: {
150
Resources: map[string]*corev1.ResourceRequirements{
151
dashboard.Component: &dashboardResources,
152
},
153
},
154
},
155
},
156
}, versions.Manifest{}, "test_namespace")
157
require.NoError(t, err)
158
159
for _, testCase := range testCases {
160
t.Run(testCase.Name, func(t *testing.T) {
161
actualResources := common.ResourceRequirements(ctx, testCase.Component, testCase.ContainerName, defaultResources)
162
163
if actualResources.Limits["cpu"] != testCase.ExpectedResources.Limits["cpu"] {
164
t.Errorf("expected cpu limits for container %q in component %q to be %+v, but got %+v",
165
testCase.Component, testCase.ContainerName, testCase.ExpectedResources.Limits["cpu"], actualResources.Limits["cpu"])
166
}
167
if actualResources.Limits["memory"] != testCase.ExpectedResources.Limits["memory"] {
168
t.Errorf("expected memory limits for container %q in component %q to be %+v, but got %+v",
169
testCase.Component, testCase.ContainerName, testCase.ExpectedResources.Limits["memory"], actualResources.Limits["memory"])
170
}
171
if actualResources.Requests["cpu"] != testCase.ExpectedResources.Requests["cpu"] {
172
t.Errorf("expected cpu requests for container %q in component %q to be %+v, but got %+v",
173
testCase.Component, testCase.ContainerName, testCase.ExpectedResources.Requests["cpu"], actualResources.Requests["cpu"])
174
}
175
if actualResources.Requests["memory"] != testCase.ExpectedResources.Requests["memory"] {
176
t.Errorf("expected memory requests for container %q in component %q to be %+v, but got %+v",
177
testCase.Component, testCase.ContainerName, testCase.ExpectedResources.Requests["memory"], actualResources.Requests["memory"])
178
}
179
})
180
}
181
}
182
183
func TestRepoName(t *testing.T) {
184
type Expectation struct {
185
Result string
186
Panics bool
187
}
188
tests := []struct {
189
Repo string
190
Name string
191
Expectation Expectation
192
CfgRepo string
193
DropImageRepo *bool
194
}{
195
{
196
Name: "gitpod-io/workspace-full",
197
Expectation: Expectation{
198
Result: "docker.io/gitpod-io/workspace-full",
199
},
200
},
201
{
202
Repo: "some-repo.com",
203
Name: "some-image",
204
Expectation: Expectation{
205
Result: "some-repo.com/some-image",
206
},
207
},
208
{
209
Repo: "some-repo",
210
Name: "not@avalid#image-name",
211
Expectation: Expectation{
212
Panics: true,
213
},
214
},
215
// Drop repo, no namespace
216
{
217
Name: "gitpod-io/workspace-full",
218
Expectation: Expectation{
219
Result: "some.registry.com/workspace-full",
220
},
221
CfgRepo: "some.registry.com",
222
DropImageRepo: pointer.Bool(true),
223
},
224
{
225
Repo: "some-repo.com",
226
Name: "some-image",
227
Expectation: Expectation{
228
Result: "some.registry.com/some-image",
229
},
230
CfgRepo: "some.registry.com",
231
DropImageRepo: pointer.Bool(true),
232
},
233
{
234
Repo: "some-repo",
235
Name: "not@avalid#image-name",
236
Expectation: Expectation{
237
Panics: true,
238
},
239
CfgRepo: "some.registry.com",
240
DropImageRepo: pointer.Bool(true),
241
},
242
// Drop repo, namespace
243
{
244
Name: "gitpod-io/workspace-full",
245
Expectation: Expectation{
246
Result: "some.registry.com/gitpod/workspace-full",
247
},
248
CfgRepo: "some.registry.com/gitpod",
249
DropImageRepo: pointer.Bool(true),
250
},
251
{
252
Repo: "some-repo.com",
253
Name: "some-image",
254
Expectation: Expectation{
255
Result: "some.registry.com/gitpod/some-image",
256
},
257
CfgRepo: "some.registry.com/gitpod",
258
DropImageRepo: pointer.Bool(true),
259
},
260
{
261
Repo: "some-repo",
262
Name: "not@avalid#image-name",
263
Expectation: Expectation{
264
Panics: true,
265
},
266
CfgRepo: "some.registry.com/gitpod",
267
DropImageRepo: pointer.Bool(true),
268
},
269
}
270
271
for _, test := range tests {
272
t.Run(test.Repo+"/"+test.Name, func(t *testing.T) {
273
var act Expectation
274
func() {
275
defer func() {
276
if recover() != nil {
277
act.Panics = true
278
}
279
}()
280
281
ctx, err := common.NewRenderContext(config.Config{
282
DropImageRepo: test.DropImageRepo,
283
Repository: test.CfgRepo,
284
}, versions.Manifest{}, "test_namespace")
285
require.NoError(t, err)
286
287
act.Result = ctx.RepoName(test.Repo, test.Name)
288
}()
289
290
if diff := cmp.Diff(test.Expectation, act); diff != "" {
291
t.Errorf("RepoName() mismatch (-want +got):\n%s", diff)
292
}
293
})
294
}
295
}
296
297