Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
gitpod-io
GitHub Repository: gitpod-io/gitpod
Path: blob/main/test/tests/components/ws-manager/dotfiles_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 wsmanager
6
7
import (
8
"context"
9
"encoding/json"
10
"fmt"
11
"os"
12
"strings"
13
"testing"
14
"time"
15
16
corev1 "k8s.io/api/core/v1"
17
"sigs.k8s.io/e2e-framework/klient"
18
"sigs.k8s.io/e2e-framework/pkg/envconf"
19
"sigs.k8s.io/e2e-framework/pkg/features"
20
21
csapi "github.com/gitpod-io/gitpod/content-service/api"
22
agent "github.com/gitpod-io/gitpod/test/pkg/agent/workspace/api"
23
"github.com/gitpod-io/gitpod/test/pkg/integration"
24
wsmanapi "github.com/gitpod-io/gitpod/ws-manager/api"
25
)
26
27
func TestDotfiles(t *testing.T) {
28
userToken, _ := os.LookupEnv("USER_TOKEN")
29
integration.SkipWithoutUsername(t, username)
30
integration.SkipWithoutUserToken(t, userToken)
31
32
f := features.New("dotfiles").WithLabel("component", "ws-manager").Assess("ensure dotfiles are loaded", func(testCtx context.Context, t *testing.T, cfg *envconf.Config) context.Context {
33
t.Parallel()
34
35
ctx, cancel := context.WithTimeout(testCtx, 5*time.Minute)
36
defer cancel()
37
38
api := integration.NewComponentAPI(ctx, cfg.Namespace(), kubeconfig, cfg.Client())
39
t.Cleanup(func() {
40
api.Done(t)
41
})
42
43
userId, err := api.CreateUser(username, userToken)
44
if err != nil {
45
t.Fatal(err)
46
}
47
48
// Scopes should larger than https://github.com/gitpod-io/gitpod/blob/main/components/supervisor/pkg/serverapi/publicapi.go#L99-L109
49
tokenId, err := api.CreateOAuth2Token(username, []string{
50
"function:getToken",
51
"function:openPort",
52
"function:getOpenPorts",
53
"function:guessGitTokenScopes",
54
"function:getWorkspace",
55
"function:sendHeartBeat",
56
"function:trackEvent",
57
"resource:token::*::get",
58
})
59
if err != nil {
60
t.Fatal(err)
61
}
62
63
swr := func(req *wsmanapi.StartWorkspaceRequest) error {
64
req.Spec.Envvars = append(req.Spec.Envvars,
65
&wsmanapi.EnvironmentVariable{
66
Name: "SUPERVISOR_DOTFILE_REPO",
67
Value: "https://github.com/gitpod-io/test-dotfiles-support",
68
},
69
&wsmanapi.EnvironmentVariable{
70
Name: "THEIA_SUPERVISOR_TOKENS",
71
Value: fmt.Sprintf(`[{
72
"token": "%v",
73
"kind": "gitpod",
74
"host": "%v",
75
"scope": ["function:getToken", "function:openPort", "function:sendHeartBeat", "function:getOpenPorts", "function:guessGitTokenScopes", "function:getWorkspace", "function:trackEvent", "resource:token::*::get"],
76
"expiryDate": "2026-10-26T10:38:05.232Z",
77
"reuse": 4
78
}]`, tokenId, getHostUrl(ctx, t, cfg.Client(), cfg.Namespace())),
79
},
80
)
81
82
req.Spec.Initializer = &csapi.WorkspaceInitializer{
83
Spec: &csapi.WorkspaceInitializer_Git{
84
Git: &csapi.GitInitializer{
85
RemoteUri: "https://github.com/gitpod-io/empty",
86
CheckoutLocation: "empty",
87
Config: &csapi.GitConfig{},
88
},
89
},
90
}
91
92
req.Metadata.Owner = userId
93
req.Spec.WorkspaceLocation = "empty"
94
return nil
95
}
96
97
ws, stopWs, err := integration.LaunchWorkspaceDirectly(t, ctx, api, integration.WithRequestModifier(swr))
98
if err != nil {
99
t.Fatal(err)
100
}
101
102
defer func() {
103
sctx, scancel := context.WithTimeout(context.Background(), 5*time.Minute)
104
defer scancel()
105
106
sapi := integration.NewComponentAPI(sctx, cfg.Namespace(), kubeconfig, cfg.Client())
107
defer sapi.Done(t)
108
109
_, err = stopWs(true, sapi)
110
if err != nil {
111
t.Errorf("cannot stop workspace: %q", err)
112
}
113
}()
114
115
rsa, closer, err := integration.Instrument(integration.ComponentWorkspace, "workspace", cfg.Namespace(), kubeconfig, cfg.Client(),
116
integration.WithInstanceID(ws.Req.Id),
117
integration.WithContainer("workspace"),
118
integration.WithWorkspacekitLift(true),
119
)
120
if err != nil {
121
t.Fatal(err)
122
}
123
124
integration.DeferCloser(t, closer)
125
defer rsa.Close()
126
127
assertDotfiles(t, rsa)
128
129
return testCtx
130
}).Feature()
131
132
testEnv.Test(t, f)
133
}
134
135
func getHostUrl(ctx context.Context, t *testing.T, k8sClient klient.Client, namespace string) string {
136
var configmap corev1.ConfigMap
137
if err := k8sClient.Resources().Get(ctx, "server-config", namespace, &configmap); err != nil {
138
t.Fatal(err)
139
}
140
141
config, ok := configmap.Data["config.json"]
142
if !ok {
143
t.Fatal("server config map does not contain config.json")
144
}
145
146
c := make(map[string]json.RawMessage)
147
if err := json.Unmarshal([]byte(config), &c); err != nil {
148
t.Fatal(err)
149
}
150
151
hostUrlRaw, ok := c["hostUrl"]
152
if !ok {
153
t.Fatal("server config map does not contain host url")
154
}
155
156
return strings.TrimPrefix(strings.Trim(string(hostUrlRaw), "\""), "https://")
157
}
158
159
func assertDotfiles(t *testing.T, rsa *integration.RpcClient) error {
160
var ls agent.ListDirResponse
161
err := rsa.Call("WorkspaceAgent.ListDir", &agent.ListDirRequest{
162
Dir: "/home/gitpod/.dotfiles",
163
}, &ls)
164
165
if err != nil {
166
t.Fatal(err)
167
}
168
169
dotfiles := map[string]bool{
170
"bash_aliases": false,
171
"git": false,
172
}
173
174
for _, dir := range ls.Files {
175
delete(dotfiles, dir)
176
}
177
178
if len(dotfiles) > 0 {
179
var cat agent.ExecResponse
180
err := rsa.Call("WorkspaceAgent.Exec", &agent.ExecRequest{
181
Dir: "/",
182
Command: "cat",
183
Args: []string{"/home/gitpod/.dotfiles.log"},
184
}, &cat)
185
if err == nil {
186
t.Fatalf("dotfiles were not installed successfully: %+v, .dotfiles.log: %s", dotfiles, cat.Stdout)
187
}
188
t.Fatalf("dotfiles were not installed successfully: %+v", dotfiles)
189
}
190
191
return nil
192
}
193
194