Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
gitpod-io
GitHub Repository: gitpod-io/gitpod
Path: blob/main/test/tests/components/ws-manager/maintenence_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
"encoding/json"
10
"errors"
11
"testing"
12
"time"
13
14
"google.golang.org/grpc/codes"
15
"google.golang.org/grpc/status"
16
corev1 "k8s.io/api/core/v1"
17
apierrors "k8s.io/apimachinery/pkg/api/errors"
18
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
19
"sigs.k8s.io/e2e-framework/klient"
20
"sigs.k8s.io/e2e-framework/pkg/envconf"
21
"sigs.k8s.io/e2e-framework/pkg/features"
22
23
csapi "github.com/gitpod-io/gitpod/content-service/api"
24
"github.com/gitpod-io/gitpod/test/pkg/integration"
25
wsmanapi "github.com/gitpod-io/gitpod/ws-manager/api"
26
"github.com/gitpod-io/gitpod/ws-manager/api/config"
27
)
28
29
func TestMaintenance(t *testing.T) {
30
testRepo := "https://github.com/gitpod-io/empty"
31
testRepoName := "empty"
32
33
f1 := features.New("maintenance").
34
WithLabel("component", "ws-manager").
35
WithLabel("type", "maintenance").
36
Assess("should display maintenance message", func(testCtx context.Context, t *testing.T, cfg *envconf.Config) context.Context {
37
kubeClient, err := cfg.NewClient()
38
if err != nil {
39
t.Fatal(err)
40
}
41
42
untilTime := time.Now().Add(1 * time.Hour)
43
err = configureMaintenanceMode(testCtx, &untilTime, kubeClient)
44
if err != nil {
45
t.Fatal(err)
46
}
47
48
t.Cleanup(func() {
49
err = configureMaintenanceMode(testCtx, nil, kubeClient)
50
if err != nil {
51
t.Error(err)
52
}
53
})
54
55
ctx, cancel := context.WithTimeout(testCtx, time.Duration(5*time.Minute))
56
defer cancel()
57
58
api := integration.NewComponentAPI(ctx, cfg.Namespace(), kubeconfig, cfg.Client())
59
t.Cleanup(func() {
60
api.Done(t)
61
})
62
63
customizeWorkspace := func(swr *wsmanapi.StartWorkspaceRequest) error {
64
swr.Spec.Initializer = &csapi.WorkspaceInitializer{
65
Spec: &csapi.WorkspaceInitializer_Git{
66
Git: &csapi.GitInitializer{
67
RemoteUri: testRepo,
68
CheckoutLocation: testRepoName,
69
Config: &csapi.GitConfig{},
70
},
71
},
72
}
73
swr.Spec.WorkspaceLocation = testRepoName
74
return nil
75
}
76
77
_, _, err = integration.LaunchWorkspaceDirectly(t, ctx, api, integration.WithRequestModifier(customizeWorkspace))
78
if err == nil {
79
t.Fatalf("expected under maintenance error")
80
} else {
81
if !errors.Is(err, status.Error(codes.FailedPrecondition, "under maintenance")) {
82
t.Fatal(err)
83
}
84
}
85
86
return testCtx
87
}).
88
Feature()
89
90
f2 := features.New("maintenance-configuration").
91
WithLabel("component", "ws-manager").
92
WithLabel("type", "maintenance").
93
Assess("should display a maintenance message when configured and not when disabled", func(testCtx context.Context, t *testing.T, cfg *envconf.Config) context.Context {
94
kubeClient, err := cfg.NewClient()
95
if err != nil {
96
t.Fatal(err)
97
}
98
99
defer func() {
100
err := configureMaintenanceMode(testCtx, nil, kubeClient)
101
if err != nil {
102
t.Error(err)
103
}
104
}()
105
106
untilTime := time.Now().Add(1 * time.Hour)
107
err = configureMaintenanceMode(testCtx, &untilTime, kubeClient)
108
if err != nil {
109
t.Fatal(err)
110
}
111
112
ctx, cancel := context.WithTimeout(testCtx, time.Duration(5*time.Minute))
113
defer cancel()
114
115
api := integration.NewComponentAPI(ctx, cfg.Namespace(), kubeconfig, cfg.Client())
116
t.Cleanup(func() {
117
api.Done(t)
118
})
119
120
_, _, err = integration.LaunchWorkspaceDirectly(t, ctx, api, integration.WithRequestModifier(func(swr *wsmanapi.StartWorkspaceRequest) error {
121
swr.Spec.Initializer = &csapi.WorkspaceInitializer{
122
Spec: &csapi.WorkspaceInitializer_Git{
123
Git: &csapi.GitInitializer{
124
RemoteUri: testRepo,
125
CheckoutLocation: testRepoName,
126
Config: &csapi.GitConfig{},
127
},
128
},
129
}
130
swr.Spec.WorkspaceLocation = testRepoName
131
return nil
132
}))
133
if err == nil {
134
t.Fatalf("expected under maintenance error")
135
} else {
136
if !errors.Is(err, status.Error(codes.FailedPrecondition, "under maintenance")) {
137
t.Fatal(err)
138
}
139
}
140
141
err = configureMaintenanceMode(testCtx, nil, kubeClient)
142
if err != nil {
143
t.Fatal(err)
144
}
145
146
time.Sleep(1 * time.Second)
147
148
_, stopWs, err := integration.LaunchWorkspaceDirectly(t, ctx, api, integration.WithRequestModifier(func(swr *wsmanapi.StartWorkspaceRequest) error {
149
swr.Spec.Initializer = &csapi.WorkspaceInitializer{
150
Spec: &csapi.WorkspaceInitializer_Git{
151
Git: &csapi.GitInitializer{
152
RemoteUri: testRepo,
153
CheckoutLocation: testRepoName,
154
Config: &csapi.GitConfig{},
155
},
156
},
157
}
158
swr.Spec.WorkspaceLocation = testRepoName
159
return nil
160
}))
161
if err != nil {
162
t.Fatal(err)
163
}
164
165
if err := stopWorkspace(t, cfg, stopWs); err != nil {
166
t.Errorf("cannot stop workspace: %q", err)
167
}
168
169
return testCtx
170
}).
171
Feature()
172
173
testEnv.Test(t, f1, f2)
174
}
175
176
func configureMaintenanceMode(ctx context.Context, untilTime *time.Time, kubeClient klient.Client) error {
177
cmap, err := maintenanceConfigmap(untilTime)
178
if err != nil {
179
return err
180
}
181
182
err = kubeClient.Resources().Create(ctx, cmap)
183
if err != nil {
184
if apierrors.IsAlreadyExists(err) {
185
err = kubeClient.Resources().Update(ctx, cmap)
186
if err != nil {
187
return err
188
}
189
}
190
191
return err
192
}
193
194
return nil
195
}
196
197
func maintenanceConfigmap(untilTime *time.Time) (*corev1.ConfigMap, error) {
198
mcfg := config.MaintenanceConfig{}
199
if untilTime != nil {
200
mcfg.EnabledUntil = untilTime
201
}
202
203
data, err := json.Marshal(mcfg)
204
if err != nil {
205
return nil, err
206
}
207
208
return &corev1.ConfigMap{
209
ObjectMeta: metav1.ObjectMeta{
210
Name: "ws-manager-mk2-maintenance-mode",
211
Namespace: "default",
212
},
213
Data: map[string]string{
214
"config.json": string(data),
215
},
216
}, nil
217
}
218
219