Skip to content

Commit

Permalink
🏃 enable travis e2e tests
Browse files Browse the repository at this point in the history
  • Loading branch information
Mengqi Yu committed Jun 4, 2019
1 parent e096922 commit 2413690
Show file tree
Hide file tree
Showing 17 changed files with 498 additions and 10 deletions.
9 changes: 7 additions & 2 deletions .travis.yml
Expand Up @@ -18,13 +18,17 @@ git:


go_import_path: sigs.k8s.io/kubebuilder go_import_path: sigs.k8s.io/kubebuilder


services:
- docker

before_install: before_install:
- go get -u github.com/golang/dep/cmd/dep - go get -u github.com/golang/dep/cmd/dep
- 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 - 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
- if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then GO111MODULE=on scripts/install_and_setup.sh; fi


before_script: before_script:
- git lfs install - git lfs install
- git lfs pull - git lfs pull


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


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


Expand Down
1 change: 1 addition & 0 deletions common.sh
Expand Up @@ -157,6 +157,7 @@ function setup_envs {
export TEST_ASSET_KUBE_APISERVER=$tmp_root/kubebuilder/bin/kube-apiserver export TEST_ASSET_KUBE_APISERVER=$tmp_root/kubebuilder/bin/kube-apiserver
export TEST_ASSET_ETCD=$tmp_root/kubebuilder/bin/etcd export TEST_ASSET_ETCD=$tmp_root/kubebuilder/bin/etcd
export TEST_DEP=$tmp_root/kubebuilder/init_project export TEST_DEP=$tmp_root/kubebuilder/init_project
export KUBECONFIG="$(kind get kubeconfig-path --name="kind")"
} }


function restore_go_deps { function restore_go_deps {
Expand Down
2 changes: 1 addition & 1 deletion generate_vendor.sh
Expand Up @@ -58,4 +58,4 @@ generate_vendor() {
} }


build_kb && \ build_kb && \
generate_vendor $1 generate_vendor 1
2 changes: 1 addition & 1 deletion go.mod
Expand Up @@ -12,7 +12,7 @@ require (
github.com/spf13/afero v1.2.2 github.com/spf13/afero v1.2.2
github.com/spf13/cobra v0.0.3 github.com/spf13/cobra v0.0.3
github.com/spf13/pflag v1.0.3 github.com/spf13/pflag v1.0.3
golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c // indirect golang.org/x/net v0.0.0-20190514140710-3ec191127204 // indirect
golang.org/x/sys v0.0.0-20190506115046-ca7f33d4116e // indirect golang.org/x/sys v0.0.0-20190506115046-ca7f33d4116e // indirect
golang.org/x/text v0.3.2 // indirect golang.org/x/text v0.3.2 // indirect
golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Expand Up @@ -47,8 +47,8 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2 h1:VklqNMn3ovrHsnt90Pveol
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c h1:uOCk1iQW6Vc18bnC13MfzScl+wdKBmM9Y9kU7Z83/lw= golang.org/x/net v0.0.0-20190514140710-3ec191127204 h1:4yG6GqBtw9C+UrLp6s2wtSniayy/Vd/3F7ffLE427XI=
golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190514140710-3ec191127204/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190423024810-112230192c58 h1:8gQV6CLnAEikrhgkHFbMAEhagSSnXWGV915qUMm9mrU= golang.org/x/sync v0.0.0-20190423024810-112230192c58 h1:8gQV6CLnAEikrhgkHFbMAEhagSSnXWGV915qUMm9mrU=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
Expand Down
1 change: 0 additions & 1 deletion pkg/scaffold/v1/manager/config.go
Expand Up @@ -89,7 +89,6 @@ spec:
- command: - command:
- /manager - /manager
image: {{ .Image }} image: {{ .Image }}
imagePullPolicy: Always
name: manager name: manager
env: env:
- name: POD_NAMESPACE - name: POD_NAMESPACE
Expand Down
1 change: 0 additions & 1 deletion pkg/scaffold/v2/manager/config.go
Expand Up @@ -89,7 +89,6 @@ spec:
- command: - command:
- /manager - /manager
image: {{ .Image }} image: {{ .Image }}
imagePullPolicy: Always
name: manager name: manager
resources: resources:
limits: limits:
Expand Down
22 changes: 22 additions & 0 deletions scripts/install_and_setup.sh
@@ -0,0 +1,22 @@
#!/bin/sh

# Copyright 2019 The Kubernetes Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

go get sigs.k8s.io/kind@v0.3.0
# TODO(mengqiy): use a released version after v2.1.0 is out.
go get sigs.k8s.io/kustomize@f9c631e9eec7a2d6e46eb9e1bf5122f68b97d12d

# 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
kind create cluster --config test/kind-config.yaml --image=kindest/node:v1.14.1
50 changes: 50 additions & 0 deletions test/e2e/config.go
@@ -0,0 +1,50 @@
/*
Copyright 2018 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package e2e

import (
"path/filepath"
)

// runtime config specified to run e2e tests
type config struct {
domain string
group string
version string
kind string
controllerImageName string
workDir string
}

// configWithSuffix init with a random suffix for test config stuff,
// to avoid conflict when running tests synchronously.
func configWithSuffix(testSuffix string) (*config, error) {
testGroup := "bar" + testSuffix
path, err := filepath.Abs("e2e-" + testSuffix)
if err != nil {
return nil, err
}

return &config{
domain: "example.com" + testSuffix,
group: testGroup,
version: "v1alpha1",
kind: "Foo" + testSuffix,
controllerImageName: "e2e-test/controller-manager:" + testSuffix,
workDir: path,
}, nil
}
32 changes: 32 additions & 0 deletions test/e2e/e2e_test.go
@@ -0,0 +1,32 @@
/*
Copyright 2018 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package e2e

import (
"fmt"
"testing"

. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
)

// Run e2e tests using the Ginkgo runner.
func TestE2E(t *testing.T) {
RegisterFailHandler(Fail)
fmt.Fprintf(GinkgoWriter, "Starting kubebuilder suite\n")
RunSpecs(t, "Kubebuilder e2e suite")
}
179 changes: 179 additions & 0 deletions test/e2e/e2ev1.go
@@ -0,0 +1,179 @@
/*
Copyright 2018 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package e2e

import (
"fmt"
"os"
"os/exec"
"path/filepath"
"strings"
"time"

. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
)

var _ = Describe("kubebuilder", func() {
Context("with v1 scaffolding", func() {
imageName := "controller:v0.0.1"
var testSuffix string
var c *config
var kbTest *kubebuilderTest

BeforeEach(func() {
var err error
testSuffix, err = randomSuffix()
Expect(err).NotTo(HaveOccurred())
c, err = configWithSuffix(testSuffix)
Expect(err).NotTo(HaveOccurred())
kbTest = &kubebuilderTest{
Dir: c.workDir,
Env: []string{"GO111MODULE=off"},
}
prepare(c.workDir)
})

AfterEach(func() {
By("clean up created API objects during test process")
resources, err := kbTest.RunKustomizeCommand("build", filepath.Join("config", "default"))
if err != nil {
fmt.Fprintf(GinkgoWriter, "error when running kustomize build during cleaning up: %v\n", err)
}
if _, err = kbTest.RunKubectlCommandWithInput(resources, "delete", "--recursive", "-f", "-"); err != nil {
fmt.Fprintf(GinkgoWriter, "error when running kubectl delete during cleaning up: %v\n", err)
}
if _, err = kbTest.RunKubectlCommand(
"delete", "--recursive",
"-f", filepath.Join("config", "crds"),
); err != nil {
fmt.Fprintf(GinkgoWriter, "error when running kubectl delete during cleaning up crd: %v\n", err)
}

By("remove container image created during test")
kbTest.CleanupImage(c.controllerImageName)

By("remove test work dir")
os.RemoveAll(c.workDir)
})

It("should generate a runnable project", func() {
// prepare v1 vendor
By("untar the vendor tarball")
cmd := exec.Command("tar", "-zxf", "../../../testdata/vendor.v1.tgz")
cmd.Dir = c.workDir
err := cmd.Run()
Expect(err).Should(Succeed())

var controllerPodName string

By("init v1 project")
err = kbTest.Init(
"--project-version", "1",
"--domain", c.domain,
"--dep=false")
Expect(err).Should(Succeed())

By("creating api definition")
err = kbTest.CreateAPI(
"--group", c.group,
"--version", c.version,
"--kind", c.kind,
"--namespaced",
"--resource",
"--controller",
"--make=false")
Expect(err).Should(Succeed())

By("creating core-type resource controller")
err = kbTest.CreateAPI(
"--group", "apps",
"--version", "v1",
"--kind", "Deployment",
"--namespaced",
"--resource=false",
"--controller",
"--make=false")
Expect(err).Should(Succeed())

By("building image")
err = kbTest.Make("docker-build", "IMG="+imageName)
Expect(err).Should(Succeed())

By("loading docker image into kind cluster")
err = kbTest.LoadImageToKindCluster(imageName)
Expect(err).Should(Succeed())

// NOTE: If you want to run the test against a GKE cluster, you will need to grant yourself permission.
// Otherwise, you may see "... is forbidden: attempt to grant extra privileges"
// $ kubectl create clusterrolebinding myname-cluster-admin-binding --clusterrole=cluster-admin --user=myname@mycompany.com
// https://cloud.google.com/kubernetes-engine/docs/how-to/role-based-access-control
By("deploying controller manager")
err = kbTest.Make("deploy")
Expect(err).Should(Succeed())

By("validate the controller-manager pod running as expected")
verifyControllerUp := func() error {
// Get pod name
podOutput, err := kbTest.RunKubectlGetPodsInNamespace(
testSuffix,
"-l", "control-plane=controller-manager",
"-o", "go-template={{ range .items }}{{ if not .metadata.deletionTimestamp }}{{ .metadata.name }}{{ \"\\n\" }}{{ end }}{{ end }}",
)
Expect(err).NotTo(HaveOccurred())
podNames := getNonEmptyLines(podOutput)
if len(podNames) != 1 {
return fmt.Errorf("expect 1 controller pods running, but got %d", len(podNames))
}
controllerPodName = podNames[0]
Expect(controllerPodName).Should(ContainSubstring("controller-manager"))

// Validate pod status
status, err := kbTest.RunKubectlGetPodsInNamespace(
testSuffix,
controllerPodName, "-o", "jsonpath={.status.phase}",
)
Expect(err).NotTo(HaveOccurred())
if status != "Running" {
return fmt.Errorf("controller pod in %s status", status)
}

return nil
}
Eventually(verifyControllerUp, 2*time.Minute, time.Second).Should(Succeed())

By("creating an instance of CR")
inputFile := filepath.Join("config", "samples", fmt.Sprintf("%s_%s_%s.yaml", c.group, c.version, strings.ToLower(c.kind)))
_, err = kbTest.RunKubectlCommand("apply", "-f", inputFile)
Expect(err).NotTo(HaveOccurred())

By("validate the created resource object gets reconciled in controller")
controllerContainerLogs := func() string {
// Check container log to validate that the created resource object gets reconciled in controller
logOutput, err := kbTest.RunKubectlCommand(
"logs", controllerPodName,
"-c", "manager",
"-n", fmt.Sprintf("e2e-%s-system", testSuffix),
)
Expect(err).NotTo(HaveOccurred())

return logOutput
}
Eventually(controllerContainerLogs, 2*time.Minute, time.Second).Should(ContainSubstring("Updating"))
})
})
})

0 comments on commit 2413690

Please sign in to comment.