Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
gitpod-io
GitHub Repository: gitpod-io/gitpod
Path: blob/main/test/tests/components/image-builder/builder_test.go
2499 views
1
// Copyright (c) 2021 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 imagebuilder
6
7
import (
8
"context"
9
"errors"
10
"io"
11
"testing"
12
"time"
13
14
"golang.org/x/sync/errgroup"
15
"golang.org/x/xerrors"
16
"google.golang.org/grpc/codes"
17
"google.golang.org/grpc/status"
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
imgapi "github.com/gitpod-io/gitpod/image-builder/api"
23
"github.com/gitpod-io/gitpod/test/pkg/integration"
24
)
25
26
func TestBaseImageBuild(t *testing.T) {
27
f := features.New("database").
28
WithLabel("component", "image-builder").
29
Assess("it should build a base image", func(testCtx context.Context, t *testing.T, cfg *envconf.Config) context.Context {
30
t.Parallel()
31
32
ctx, cancel := context.WithTimeout(testCtx, 5*time.Minute)
33
defer cancel()
34
35
api := integration.NewComponentAPI(ctx, cfg.Namespace(), kubeconfig, cfg.Client())
36
t.Cleanup(func() {
37
api.Done(t)
38
})
39
40
client, err := api.ImageBuilder()
41
if err != nil {
42
t.Fatal("cannot start build", err)
43
}
44
45
bld, err := client.Build(ctx, &imgapi.BuildRequest{
46
ForceRebuild: true,
47
TriggeredBy: "integration-test",
48
Source: &imgapi.BuildSource{
49
From: &imgapi.BuildSource_File{
50
File: &imgapi.BuildSourceDockerfile{
51
DockerfileVersion: "some-version",
52
DockerfilePath: "test/tests/components/image-builder/test.Dockerfile",
53
ContextPath: ".",
54
Source: &csapi.WorkspaceInitializer{
55
Spec: &csapi.WorkspaceInitializer_Git{
56
Git: &csapi.GitInitializer{
57
RemoteUri: "https://github.com/gitpod-io/gitpod.git",
58
TargetMode: csapi.CloneTargetMode_REMOTE_BRANCH,
59
CloneTaget: "main",
60
Config: &csapi.GitConfig{
61
Authentication: csapi.GitAuthMethod_NO_AUTH,
62
},
63
},
64
},
65
},
66
},
67
},
68
},
69
})
70
if err != nil {
71
t.Fatal("cannot start build", err)
72
}
73
74
var ref string
75
for {
76
msg, err := bld.Recv()
77
if errors.Is(err, io.EOF) {
78
break
79
}
80
81
if err != nil {
82
if st, ok := status.FromError(err); ok && st.Code() == codes.Unavailable {
83
continue
84
}
85
t.Fatal(err)
86
}
87
88
ref = msg.Ref
89
if msg.Status == imgapi.BuildStatus_done_success {
90
break
91
} else if msg.Status == imgapi.BuildStatus_done_failure {
92
t.Fatalf("image build failed: %s", msg.Message)
93
} else {
94
t.Logf("build output: %s, %s", msg.Message, msg.Info)
95
}
96
}
97
if ref == "" {
98
t.Fatal("ref was empty")
99
}
100
101
return testCtx
102
}).
103
Feature()
104
105
testEnv.Test(t, f)
106
}
107
108
func TestParallelBaseImageBuild(t *testing.T) {
109
f := features.New("image-builder").
110
WithLabel("component", "image-builder").
111
Assess("it should allow parallel build of images", func(testCtx context.Context, t *testing.T, cfg *envconf.Config) context.Context {
112
t.Parallel()
113
114
ctx, cancel := context.WithTimeout(testCtx, 5*time.Minute)
115
defer cancel()
116
117
api := integration.NewComponentAPI(ctx, cfg.Namespace(), kubeconfig, cfg.Client())
118
t.Cleanup(func() {
119
api.Done(t)
120
})
121
122
client, err := api.ImageBuilder()
123
if err != nil {
124
t.Fatalf("cannot start build: %q", err)
125
}
126
127
req := &imgapi.BuildRequest{
128
ForceRebuild: true,
129
TriggeredBy: "integration-test",
130
Source: &imgapi.BuildSource{
131
From: &imgapi.BuildSource_File{
132
File: &imgapi.BuildSourceDockerfile{
133
DockerfileVersion: "some-version",
134
DockerfilePath: "test/tests/components/image-builder/test.Dockerfile",
135
ContextPath: ".",
136
Source: &csapi.WorkspaceInitializer{
137
Spec: &csapi.WorkspaceInitializer_Git{
138
Git: &csapi.GitInitializer{
139
RemoteUri: "https://github.com/gitpod-io/gitpod.git",
140
TargetMode: csapi.CloneTargetMode_REMOTE_BRANCH,
141
CloneTaget: "main",
142
Config: &csapi.GitConfig{
143
Authentication: csapi.GitAuthMethod_NO_AUTH,
144
},
145
},
146
},
147
},
148
},
149
},
150
},
151
}
152
153
bld0, err := client.Build(ctx, req)
154
if err != nil {
155
t.Fatalf("cannot start build: %v", err)
156
}
157
bld1, err := client.Build(ctx, req)
158
if err != nil {
159
t.Fatalf("cannot start build: %v", err)
160
}
161
162
watchBuild := func(cl imgapi.ImageBuilder_BuildClient) error {
163
for {
164
msg, err := cl.Recv()
165
if errors.Is(err, io.EOF) {
166
break
167
}
168
169
if err != nil {
170
return xerrors.Errorf("image builder error: %v", err)
171
}
172
if err := ctx.Err(); err != nil {
173
return xerrors.Errorf("context error: %v", err)
174
}
175
176
if msg.Status == imgapi.BuildStatus_done_success {
177
break
178
} else if msg.Status == imgapi.BuildStatus_done_failure {
179
return xerrors.Errorf("image build failed: %s", msg.Message)
180
} else {
181
t.Logf("build output: %s", msg.Message)
182
}
183
}
184
185
return nil
186
}
187
188
var eg errgroup.Group
189
eg.Go(func() error { return watchBuild(bld0) })
190
eg.Go(func() error { return watchBuild(bld1) })
191
192
/*
193
blds, err := client.ListBuilds(ctx, &imgapi.ListBuildsRequest{})
194
if err != nil {
195
t.Fatalf("cannot list builds: %v", err)
196
}
197
198
// TODO(cw): make this assertion resiliant against other on-going builds
199
if l := len(blds.Builds); l != 1 {
200
t.Errorf("image builder is running not just one build, but %d", l)
201
}
202
*/
203
err = eg.Wait()
204
if err != nil {
205
t.Fatal(err)
206
}
207
208
return testCtx
209
}).
210
Feature()
211
212
testEnv.Test(t, f)
213
}
214
215