Skip to content

Commit 2413690

Browse files
author
Mengqi Yu
committed
🏃 enable travis e2e tests
1 parent e096922 commit 2413690

File tree

17 files changed

+498
-10
lines changed

17 files changed

+498
-10
lines changed

.travis.yml

+7-2
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,17 @@ git:
1818

1919
go_import_path: sigs.k8s.io/kubebuilder
2020

21+
services:
22+
- docker
23+
2124
before_install:
2225
- go get -u github.com/golang/dep/cmd/dep
2326
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then curl -sL https://github.com/git-lfs/git-lfs/releases/download/v2.7.2/git-lfs-darwin-amd64-v2.7.2.tar.gz | tar -xz git-lfs; fi
27+
- if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then GO111MODULE=on scripts/install_and_setup.sh; fi
2428

2529
before_script:
26-
- git lfs install
27-
- git lfs pull
30+
- git lfs install
31+
- git lfs pull
2832

2933
# Install must be set to prevent default `go get` to run.
3034
# The dependencies have already been vendored by `dep` so
@@ -33,6 +37,7 @@ install:
3337
-
3438

3539
script:
40+
- if [ "$TRAVIS_OS_NAME" = "linux" ]; then GO111MODULE=on TRACE=1 PATH=$PATH:$(pwd) ./test_e2e.sh ; fi
3641
- GO111MODULE=on TRACE=1 ./test.sh
3742
- ./scripts/install_test.sh
3843

common.sh

+1
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,7 @@ function setup_envs {
157157
export TEST_ASSET_KUBE_APISERVER=$tmp_root/kubebuilder/bin/kube-apiserver
158158
export TEST_ASSET_ETCD=$tmp_root/kubebuilder/bin/etcd
159159
export TEST_DEP=$tmp_root/kubebuilder/init_project
160+
export KUBECONFIG="$(kind get kubeconfig-path --name="kind")"
160161
}
161162

162163
function restore_go_deps {

generate_vendor.sh

+1-1
Original file line numberDiff line numberDiff line change
@@ -58,4 +58,4 @@ generate_vendor() {
5858
}
5959

6060
build_kb && \
61-
generate_vendor $1
61+
generate_vendor 1

go.mod

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ require (
1212
github.com/spf13/afero v1.2.2
1313
github.com/spf13/cobra v0.0.3
1414
github.com/spf13/pflag v1.0.3
15-
golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c // indirect
15+
golang.org/x/net v0.0.0-20190514140710-3ec191127204 // indirect
1616
golang.org/x/sys v0.0.0-20190506115046-ca7f33d4116e // indirect
1717
golang.org/x/text v0.3.2 // indirect
1818
golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c

go.sum

+2-2
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,8 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2 h1:VklqNMn3ovrHsnt90Pveol
4747
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
4848
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
4949
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
50-
golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c h1:uOCk1iQW6Vc18bnC13MfzScl+wdKBmM9Y9kU7Z83/lw=
51-
golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
50+
golang.org/x/net v0.0.0-20190514140710-3ec191127204 h1:4yG6GqBtw9C+UrLp6s2wtSniayy/Vd/3F7ffLE427XI=
51+
golang.org/x/net v0.0.0-20190514140710-3ec191127204/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
5252
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
5353
golang.org/x/sync v0.0.0-20190423024810-112230192c58 h1:8gQV6CLnAEikrhgkHFbMAEhagSSnXWGV915qUMm9mrU=
5454
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=

pkg/scaffold/v1/manager/config.go

-1
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,6 @@ spec:
8989
- command:
9090
- /manager
9191
image: {{ .Image }}
92-
imagePullPolicy: Always
9392
name: manager
9493
env:
9594
- name: POD_NAMESPACE

pkg/scaffold/v2/manager/config.go

-1
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,6 @@ spec:
8989
- command:
9090
- /manager
9191
image: {{ .Image }}
92-
imagePullPolicy: Always
9392
name: manager
9493
resources:
9594
limits:

scripts/install_and_setup.sh

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
#!/bin/sh
2+
3+
# Copyright 2019 The Kubernetes Authors.
4+
#
5+
# Licensed under the Apache License, Version 2.0 (the "License");
6+
# you may not use this file except in compliance with the License.
7+
# You may obtain a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing, software
12+
# distributed under the License is distributed on an "AS IS" BASIS,
13+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
# See the License for the specific language governing permissions and
15+
# limitations under the License.
16+
17+
go get sigs.k8s.io/kind@v0.3.0
18+
# TODO(mengqiy): use a released version after v2.1.0 is out.
19+
go get sigs.k8s.io/kustomize@f9c631e9eec7a2d6e46eb9e1bf5122f68b97d12d
20+
21+
# You can use --image flag to specify the cluster version you want, e.g --image=kindest/node:v1.13.6, the supported version are listed at https://hub.docker.com/r/kindest/node/tags
22+
kind create cluster --config test/kind-config.yaml --image=kindest/node:v1.14.1

test/e2e/config.go

+50
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
/*
2+
Copyright 2018 The Kubernetes Authors.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package e2e
18+
19+
import (
20+
"path/filepath"
21+
)
22+
23+
// runtime config specified to run e2e tests
24+
type config struct {
25+
domain string
26+
group string
27+
version string
28+
kind string
29+
controllerImageName string
30+
workDir string
31+
}
32+
33+
// configWithSuffix init with a random suffix for test config stuff,
34+
// to avoid conflict when running tests synchronously.
35+
func configWithSuffix(testSuffix string) (*config, error) {
36+
testGroup := "bar" + testSuffix
37+
path, err := filepath.Abs("e2e-" + testSuffix)
38+
if err != nil {
39+
return nil, err
40+
}
41+
42+
return &config{
43+
domain: "example.com" + testSuffix,
44+
group: testGroup,
45+
version: "v1alpha1",
46+
kind: "Foo" + testSuffix,
47+
controllerImageName: "e2e-test/controller-manager:" + testSuffix,
48+
workDir: path,
49+
}, nil
50+
}

test/e2e/e2e_test.go

+32
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
/*
2+
Copyright 2018 The Kubernetes Authors.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package e2e
18+
19+
import (
20+
"fmt"
21+
"testing"
22+
23+
. "github.com/onsi/ginkgo"
24+
. "github.com/onsi/gomega"
25+
)
26+
27+
// Run e2e tests using the Ginkgo runner.
28+
func TestE2E(t *testing.T) {
29+
RegisterFailHandler(Fail)
30+
fmt.Fprintf(GinkgoWriter, "Starting kubebuilder suite\n")
31+
RunSpecs(t, "Kubebuilder e2e suite")
32+
}

test/e2e/e2ev1.go

+179
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,179 @@
1+
/*
2+
Copyright 2018 The Kubernetes Authors.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package e2e
18+
19+
import (
20+
"fmt"
21+
"os"
22+
"os/exec"
23+
"path/filepath"
24+
"strings"
25+
"time"
26+
27+
. "github.com/onsi/ginkgo"
28+
. "github.com/onsi/gomega"
29+
)
30+
31+
var _ = Describe("kubebuilder", func() {
32+
Context("with v1 scaffolding", func() {
33+
imageName := "controller:v0.0.1"
34+
var testSuffix string
35+
var c *config
36+
var kbTest *kubebuilderTest
37+
38+
BeforeEach(func() {
39+
var err error
40+
testSuffix, err = randomSuffix()
41+
Expect(err).NotTo(HaveOccurred())
42+
c, err = configWithSuffix(testSuffix)
43+
Expect(err).NotTo(HaveOccurred())
44+
kbTest = &kubebuilderTest{
45+
Dir: c.workDir,
46+
Env: []string{"GO111MODULE=off"},
47+
}
48+
prepare(c.workDir)
49+
})
50+
51+
AfterEach(func() {
52+
By("clean up created API objects during test process")
53+
resources, err := kbTest.RunKustomizeCommand("build", filepath.Join("config", "default"))
54+
if err != nil {
55+
fmt.Fprintf(GinkgoWriter, "error when running kustomize build during cleaning up: %v\n", err)
56+
}
57+
if _, err = kbTest.RunKubectlCommandWithInput(resources, "delete", "--recursive", "-f", "-"); err != nil {
58+
fmt.Fprintf(GinkgoWriter, "error when running kubectl delete during cleaning up: %v\n", err)
59+
}
60+
if _, err = kbTest.RunKubectlCommand(
61+
"delete", "--recursive",
62+
"-f", filepath.Join("config", "crds"),
63+
); err != nil {
64+
fmt.Fprintf(GinkgoWriter, "error when running kubectl delete during cleaning up crd: %v\n", err)
65+
}
66+
67+
By("remove container image created during test")
68+
kbTest.CleanupImage(c.controllerImageName)
69+
70+
By("remove test work dir")
71+
os.RemoveAll(c.workDir)
72+
})
73+
74+
It("should generate a runnable project", func() {
75+
// prepare v1 vendor
76+
By("untar the vendor tarball")
77+
cmd := exec.Command("tar", "-zxf", "../../../testdata/vendor.v1.tgz")
78+
cmd.Dir = c.workDir
79+
err := cmd.Run()
80+
Expect(err).Should(Succeed())
81+
82+
var controllerPodName string
83+
84+
By("init v1 project")
85+
err = kbTest.Init(
86+
"--project-version", "1",
87+
"--domain", c.domain,
88+
"--dep=false")
89+
Expect(err).Should(Succeed())
90+
91+
By("creating api definition")
92+
err = kbTest.CreateAPI(
93+
"--group", c.group,
94+
"--version", c.version,
95+
"--kind", c.kind,
96+
"--namespaced",
97+
"--resource",
98+
"--controller",
99+
"--make=false")
100+
Expect(err).Should(Succeed())
101+
102+
By("creating core-type resource controller")
103+
err = kbTest.CreateAPI(
104+
"--group", "apps",
105+
"--version", "v1",
106+
"--kind", "Deployment",
107+
"--namespaced",
108+
"--resource=false",
109+
"--controller",
110+
"--make=false")
111+
Expect(err).Should(Succeed())
112+
113+
By("building image")
114+
err = kbTest.Make("docker-build", "IMG="+imageName)
115+
Expect(err).Should(Succeed())
116+
117+
By("loading docker image into kind cluster")
118+
err = kbTest.LoadImageToKindCluster(imageName)
119+
Expect(err).Should(Succeed())
120+
121+
// NOTE: If you want to run the test against a GKE cluster, you will need to grant yourself permission.
122+
// Otherwise, you may see "... is forbidden: attempt to grant extra privileges"
123+
// $ kubectl create clusterrolebinding myname-cluster-admin-binding --clusterrole=cluster-admin --user=myname@mycompany.com
124+
// https://cloud.google.com/kubernetes-engine/docs/how-to/role-based-access-control
125+
By("deploying controller manager")
126+
err = kbTest.Make("deploy")
127+
Expect(err).Should(Succeed())
128+
129+
By("validate the controller-manager pod running as expected")
130+
verifyControllerUp := func() error {
131+
// Get pod name
132+
podOutput, err := kbTest.RunKubectlGetPodsInNamespace(
133+
testSuffix,
134+
"-l", "control-plane=controller-manager",
135+
"-o", "go-template={{ range .items }}{{ if not .metadata.deletionTimestamp }}{{ .metadata.name }}{{ \"\\n\" }}{{ end }}{{ end }}",
136+
)
137+
Expect(err).NotTo(HaveOccurred())
138+
podNames := getNonEmptyLines(podOutput)
139+
if len(podNames) != 1 {
140+
return fmt.Errorf("expect 1 controller pods running, but got %d", len(podNames))
141+
}
142+
controllerPodName = podNames[0]
143+
Expect(controllerPodName).Should(ContainSubstring("controller-manager"))
144+
145+
// Validate pod status
146+
status, err := kbTest.RunKubectlGetPodsInNamespace(
147+
testSuffix,
148+
controllerPodName, "-o", "jsonpath={.status.phase}",
149+
)
150+
Expect(err).NotTo(HaveOccurred())
151+
if status != "Running" {
152+
return fmt.Errorf("controller pod in %s status", status)
153+
}
154+
155+
return nil
156+
}
157+
Eventually(verifyControllerUp, 2*time.Minute, time.Second).Should(Succeed())
158+
159+
By("creating an instance of CR")
160+
inputFile := filepath.Join("config", "samples", fmt.Sprintf("%s_%s_%s.yaml", c.group, c.version, strings.ToLower(c.kind)))
161+
_, err = kbTest.RunKubectlCommand("apply", "-f", inputFile)
162+
Expect(err).NotTo(HaveOccurred())
163+
164+
By("validate the created resource object gets reconciled in controller")
165+
controllerContainerLogs := func() string {
166+
// Check container log to validate that the created resource object gets reconciled in controller
167+
logOutput, err := kbTest.RunKubectlCommand(
168+
"logs", controllerPodName,
169+
"-c", "manager",
170+
"-n", fmt.Sprintf("e2e-%s-system", testSuffix),
171+
)
172+
Expect(err).NotTo(HaveOccurred())
173+
174+
return logOutput
175+
}
176+
Eventually(controllerContainerLogs, 2*time.Minute, time.Second).Should(ContainSubstring("Updating"))
177+
})
178+
})
179+
})

0 commit comments

Comments
 (0)