forked from openshift/origin
-
Notifications
You must be signed in to change notification settings - Fork 0
/
start.go
288 lines (252 loc) · 12.6 KB
/
start.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
package builds
import (
"fmt"
"os/exec"
"strings"
"sync"
"time"
"k8s.io/kubernetes/pkg/util/wait"
g "github.com/onsi/ginkgo"
o "github.com/onsi/gomega"
buildapi "github.com/openshift/origin/pkg/build/api"
exutil "github.com/openshift/origin/test/extended/util"
)
var _ = g.Describe("[builds][Slow] starting a build using CLI", func() {
defer g.GinkgoRecover()
var (
buildFixture = exutil.FixturePath("testdata", "test-build.json")
exampleGemfile = exutil.FixturePath("testdata", "test-build-app", "Gemfile")
exampleBuild = exutil.FixturePath("testdata", "test-build-app")
exampleGemfileURL = "https://raw.githubusercontent.com/openshift/ruby-hello-world/master/Gemfile"
exampleArchiveURL = "https://github.com/openshift/ruby-hello-world/archive/master.zip"
oc = exutil.NewCLI("cli-start-build", exutil.KubeConfigPath())
)
g.JustBeforeEach(func() {
g.By("waiting for builder service account")
err := exutil.WaitForBuilderAccount(oc.KubeClient().Core().ServiceAccounts(oc.Namespace()))
o.Expect(err).NotTo(o.HaveOccurred())
oc.Run("create").Args("-f", buildFixture).Execute()
})
g.Describe("oc start-build --wait", func() {
g.It("should start a build and wait for the build to complete", func() {
g.By("starting the build with --wait flag")
br, err := exutil.StartBuildAndWait(oc, "sample-build", "--wait")
o.Expect(err).NotTo(o.HaveOccurred())
br.AssertSuccess()
})
g.It("should start a build and wait for the build to fail", func() {
g.By("starting the build with --wait flag but wrong --commit")
br, _ := exutil.StartBuildAndWait(oc, "sample-build", "--wait", "--commit=fffffff")
br.AssertFailure()
o.Expect(br.StartBuildErr).To(o.HaveOccurred()) // start-build should detect the build error with --wait flag
o.Expect(br.StartBuildStdErr).Should(o.ContainSubstring(`status is "Failed"`))
})
})
g.Describe("override environment", func() {
g.It("should accept environment variables", func() {
g.By("starting the build with -e FOO=bar,VAR=test")
br, err := exutil.StartBuildAndWait(oc, "sample-build", "-e", "FOO=bar,VAR=test")
br.AssertSuccess()
buildLog, err := br.Logs()
o.Expect(err).NotTo(o.HaveOccurred())
g.By(fmt.Sprintf("verifying the build output contains the env vars"))
o.Expect(buildLog).To(o.ContainSubstring("FOO=bar"))
o.Expect(buildLog).To(o.ContainSubstring("VAR=test"))
g.By(fmt.Sprintf("verifying the build output contains inherited env vars"))
// This variable is not set and thus inherited from the original build config
o.Expect(buildLog).To(o.ContainSubstring("BAR=test"))
})
g.It("BUILD_LOGLEVEL in buildconfig should create verbose output", func() {
g.By("starting the build with buildconfig strategy env BUILD_LOGLEVEL=5")
br, err := exutil.StartBuildAndWait(oc, "sample-verbose-build")
br.AssertSuccess()
buildLog, err := br.Logs()
o.Expect(err).NotTo(o.HaveOccurred())
g.By(fmt.Sprintf("verifying the build output is verbose"))
o.Expect(buildLog).To(o.ContainSubstring("Creating a new S2I builder"))
})
g.It("BUILD_LOGLEVEL in buildconfig can be overridden by build-loglevel", func() {
g.By("starting the build with buildconfig strategy env BUILD_LOGLEVEL=5 but build-loglevel=1")
br, err := exutil.StartBuildAndWait(oc, "sample-verbose-build", "--build-loglevel=1")
br.AssertSuccess()
buildLog, err := br.Logs()
o.Expect(err).NotTo(o.HaveOccurred())
g.By(fmt.Sprintf("verifying the build output is not verbose"))
o.Expect(buildLog).NotTo(o.ContainSubstring("Creating a new S2I builder"))
})
})
g.Describe("binary builds", func() {
var commit string
// do a best effort to initialize the repo in case it is a raw checkout or temp dir
tryRepoInit := func(exampleBuild string) {
out, err := exec.Command("bash", "-c", fmt.Sprintf("cd %q; if ! git rev-parse --git-dir; then git init .; git add .; git commit -m 'first'; touch foo; git add .; git commit -m 'second'; fi; true", exampleBuild)).CombinedOutput()
fmt.Fprintf(g.GinkgoWriter, "Tried to init git repo: %v\n%s\n", err, string(out))
}
g.It("should accept --from-file as input", func() {
g.By("starting the build with a Dockerfile")
br, err := exutil.StartBuildAndWait(oc, "sample-build", fmt.Sprintf("--from-file=%s", exampleGemfile))
br.AssertSuccess()
buildLog, err := br.Logs()
o.Expect(err).NotTo(o.HaveOccurred())
g.By(fmt.Sprintf("verifying the build %q status", br.BuildPath))
o.Expect(br.StartBuildStdErr).To(o.ContainSubstring("Uploading file"))
o.Expect(br.StartBuildStdErr).To(o.ContainSubstring("as binary input for the build ..."))
o.Expect(buildLog).To(o.ContainSubstring("Your bundle is complete"))
})
g.It("should accept --from-dir as input", func() {
g.By("starting the build with a directory")
br, err := exutil.StartBuildAndWait(oc, "sample-build", fmt.Sprintf("--from-dir=%s", exampleBuild))
br.AssertSuccess()
buildLog, err := br.Logs()
o.Expect(err).NotTo(o.HaveOccurred())
g.By(fmt.Sprintf("verifying the build %q status", br.BuildPath))
o.Expect(br.StartBuildStdErr).To(o.ContainSubstring("Uploading directory"))
o.Expect(br.StartBuildStdErr).To(o.ContainSubstring("as binary input for the build ..."))
o.Expect(buildLog).To(o.ContainSubstring("Your bundle is complete"))
})
g.It("should accept --from-repo as input", func() {
g.By("starting the build with a Git repository")
tryRepoInit(exampleBuild)
br, err := exutil.StartBuildAndWait(oc, "sample-build", fmt.Sprintf("--from-repo=%s", exampleBuild))
br.AssertSuccess()
buildLog, err := br.Logs()
o.Expect(err).NotTo(o.HaveOccurred())
o.Expect(br.StartBuildStdErr).To(o.ContainSubstring("Uploading"))
o.Expect(br.StartBuildStdErr).To(o.ContainSubstring(`at commit "HEAD"`))
o.Expect(br.StartBuildStdErr).To(o.ContainSubstring("as binary input for the build ..."))
o.Expect(buildLog).To(o.ContainSubstring("Your bundle is complete"))
})
g.It("should accept --from-repo with --commit as input", func() {
g.By("starting the build with a Git repository")
tryRepoInit(exampleBuild)
gitCmd := exec.Command("git", "rev-parse", "HEAD~1")
gitCmd.Dir = exampleBuild
commitByteArray, err := gitCmd.CombinedOutput()
commit = strings.TrimSpace(string(commitByteArray[:]))
o.Expect(err).NotTo(o.HaveOccurred())
br, err := exutil.StartBuildAndWait(oc, "sample-build", fmt.Sprintf("--commit=%s", commit), fmt.Sprintf("--from-repo=%s", exampleBuild))
br.AssertSuccess()
buildLog, err := br.Logs()
o.Expect(err).NotTo(o.HaveOccurred())
o.Expect(br.StartBuildStdErr).To(o.ContainSubstring("Uploading"))
o.Expect(br.StartBuildStdErr).To(o.ContainSubstring(fmt.Sprintf("at commit \"%s\"", commit)))
o.Expect(br.StartBuildStdErr).To(o.ContainSubstring("as binary input for the build ..."))
o.Expect(buildLog).To(o.ContainSubstring(fmt.Sprintf("\"commit\":\"%s\"", commit)))
o.Expect(buildLog).To(o.ContainSubstring("Your bundle is complete"))
})
// run one valid binary build so we can do --from-build later
g.It("should reject binary build requests without a --from-xxxx value", func() {
g.By("starting a valid build with a directory")
br, err := exutil.StartBuildAndWait(oc, "sample-build-binary", "--follow", fmt.Sprintf("--from-dir=%s", exampleBuild))
br.AssertSuccess()
buildLog, err := br.Logs()
o.Expect(err).NotTo(o.HaveOccurred())
o.Expect(br.StartBuildStdErr).To(o.ContainSubstring("Uploading directory"))
o.Expect(br.StartBuildStdErr).To(o.ContainSubstring("as binary input for the build ..."))
o.Expect(buildLog).To(o.ContainSubstring("Your bundle is complete"))
g.By("starting a build without a --from-xxxx value")
br, err = exutil.StartBuildAndWait(oc, "sample-build-binary")
o.Expect(br.StartBuildErr).To(o.HaveOccurred())
o.Expect(br.StartBuildStdErr).To(o.ContainSubstring("has no valid source inputs"))
g.By("starting a build from an existing binary build")
br, err = exutil.StartBuildAndWait(oc, "sample-build-binary", fmt.Sprintf("--from-build=%s", "sample-build-binary-1"))
o.Expect(br.StartBuildErr).To(o.HaveOccurred())
o.Expect(br.StartBuildStdErr).To(o.ContainSubstring("has no valid source inputs"))
})
g.It("shoud accept --from-file with https URL as an input", func() {
g.By("starting a valid build with input file served by https")
br, err := exutil.StartBuildAndWait(oc, "sample-build", fmt.Sprintf("--from-file=%s", exampleGemfileURL))
br.AssertSuccess()
buildLog, err := br.Logs()
o.Expect(err).NotTo(o.HaveOccurred())
o.Expect(br.StartBuildStdErr).To(o.ContainSubstring(fmt.Sprintf("Uploading file from %q as binary input for the build", exampleGemfileURL)))
o.Expect(buildLog).To(o.ContainSubstring("Your bundle is complete"))
})
g.It("shoud accept --from-archive with https URL as an input", func() {
g.By("starting a valid build with input archive served by https")
// can't use sample-build-binary because we need contextDir due to github archives containing the top-level directory
br, err := exutil.StartBuildAndWait(oc, "sample-build-github-archive", fmt.Sprintf("--from-archive=%s", exampleArchiveURL))
br.AssertSuccess()
buildLog, err := br.Logs()
o.Expect(err).NotTo(o.HaveOccurred())
o.Expect(br.StartBuildStdErr).To(o.ContainSubstring(fmt.Sprintf("Uploading archive from %q as binary input for the build", exampleArchiveURL)))
o.Expect(buildLog).To(o.ContainSubstring("Your bundle is complete"))
})
})
g.Describe("cancel a binary build that doesn't start running in 5 minutes", func() {
g.It("should start a build and wait for the build to be cancelled", func() {
g.By("starting a build with a nodeselector that can't be matched")
go func() {
exutil.StartBuild(oc, "sample-build-binary-invalidnodeselector", fmt.Sprintf("--from-file=%s", exampleGemfile))
}()
build := &buildapi.Build{}
cancelFn := func(b *buildapi.Build) bool {
build = b
return exutil.CheckBuildCancelledFn(b)
}
err := exutil.WaitForABuild(oc.Client().Builds(oc.Namespace()), "sample-build-binary-invalidnodeselector-1", nil, nil, cancelFn)
o.Expect(err).NotTo(o.HaveOccurred())
o.Expect(build.Status.Phase).To(o.Equal(buildapi.BuildPhaseCancelled))
})
})
g.Describe("cancelling build started by oc start-build --wait", func() {
g.It("should start a build and wait for the build to cancel", func() {
g.By("starting the build with --wait flag")
var wg sync.WaitGroup
wg.Add(1)
go func() {
defer g.GinkgoRecover()
defer wg.Done()
_, stderr, err := exutil.StartBuild(oc, "sample-build", "--wait")
o.Expect(err).To(o.HaveOccurred())
o.Expect(stderr).Should(o.ContainSubstring(`status is "Cancelled"`))
}()
g.By("getting the build name")
var buildName string
wait.Poll(time.Duration(100*time.Millisecond), 1*time.Minute, func() (bool, error) {
out, err := oc.Run("get").
Args("build", "--template", "{{ (index .items 0).metadata.name }}").Output()
// Give it second chance in case the build resource was not created yet
if err != nil || len(out) == 0 {
return false, nil
}
buildName = out
return true, nil
})
o.Expect(buildName).ToNot(o.BeEmpty())
g.By(fmt.Sprintf("cancelling the build %q", buildName))
err := oc.Run("cancel-build").Args(buildName).Execute()
o.Expect(err).ToNot(o.HaveOccurred())
wg.Wait()
})
})
g.Describe("Setting build-args on Docker builds", func() {
g.It("Should copy build args from BuildConfig to Build", func() {
g.By("starting the build without --build-arg flag")
br, _ := exutil.StartBuildAndWait(oc, "sample-build-docker-args-preset")
br.AssertSuccess()
buildLog, err := br.Logs()
o.Expect(err).NotTo(o.HaveOccurred())
g.By("verifying the build output contains the build args from the BuildConfig.")
o.Expect(buildLog).To(o.ContainSubstring("default"))
})
g.It("Should accept build args that are specified in the Dockerfile", func() {
g.By("starting the build with --build-arg flag")
br, _ := exutil.StartBuildAndWait(oc, "sample-build-docker-args", "--build-arg=foo=bar")
br.AssertSuccess()
buildLog, err := br.Logs()
o.Expect(err).NotTo(o.HaveOccurred())
g.By("verifying the build output contains the changes.")
o.Expect(buildLog).To(o.ContainSubstring("bar"))
})
g.It("Should fail on non-existent build-arg", func() {
g.By("starting the build with --build-arg flag")
br, _ := exutil.StartBuildAndWait(oc, "sample-build-docker-args", "--build-arg=bar=foo")
br.AssertFailure()
buildLog, err := br.Logs()
o.Expect(err).NotTo(o.HaveOccurred())
g.By("verifying the build failed due to Docker.")
o.Expect(buildLog).To(o.ContainSubstring("One or more build-args [bar] were not consumed, failing build"))
})
})
})