Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

E2E test improvements #159

Merged
merged 1 commit into from
Feb 20, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,20 @@ go_import_path: sigs.k8s.io/application
install:
-

before_script:
# create Kind cluster
- if [ "$TRAVIS_OS_NAME" = "linux" ]; then make e2e-setup; fi

script:
# Ensure Build works and unit tests pass
- make
# Run e2e tests
- if [ "$TRAVIS_OS_NAME" = "linux" ]; then make e2e-test; fi

after_script:
# Delete Kind cluster
- if [ "$TRAVIS_OS_NAME" = "linux" ]; then make e2e-cleanup; fi

# TBD. Suppressing for now.
notifications:
email: false
53 changes: 36 additions & 17 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ COVER_FILE ?= cover.out

.DEFAULT_GOAL := all
.PHONY: all
all: generate license fix vet fmt manifests test lint misspell tidy bin/manager
all: generate fix vet fmt manifests test lint license misspell tidy bin/manager

## --------------------------------------
## Tooling Binaries
Expand Down Expand Up @@ -88,9 +88,23 @@ test: $(TOOLBIN)/etcd $(TOOLBIN)/kube-apiserver $(TOOLBIN)/kubectl
go test -v ./api/... ./controllers/... -coverprofile $(COVER_FILE)

# Run e2e-tests
K8S_VERSION := "v1.16.4"

.PHONY: e2e-setup
e2e-setup: $(TOOLBIN)/kind
KUBECONFIG=$(shell $(TOOLBIN)/kind get kubeconfig-path --name="kind") \
$(TOOLBIN)/kind create cluster \
-v 4 --retain --wait=1m \
--config e2e/kind-config.yaml \
--image=kindest/node:$(K8S_VERSION)

.PHONY: e2e-cleanup
e2e-cleanup: $(TOOLBIN)/kind
$(TOOLBIN)/kind delete cluster

.PHONY: e2e-test
e2e-test: generate fmt vet manifests $(TOOLBIN)/kind
BIN=$(TOOLBIN) ./e2e/test_e2e.sh
e2e-test: generate fmt vet manifests $(TOOLBIN)/kind $(TOOLBIN)/kustomize $(TOOLBIN)/kubectl
go test -v ./e2e/main_test.go

## --------------------------------------
## Build and run
Expand All @@ -100,10 +114,15 @@ e2e-test: generate fmt vet manifests $(TOOLBIN)/kind
bin/manager: main.go generate fmt vet manifests
go build -o bin/manager main.go

# Run against the configured Kubernetes cluster in ~/.kube/config
.PHONY: runbg
runbg: bin/manager
bin/manager --metrics-addr ":8083" >& manager.log & echo $$! > manager.pid

# Run against the configured Kubernetes cluster in ~/.kube/config
.PHONY: run
run: generate fmt vet manifests
go run ./main.go
run: bin/manager
bin/manager

# Debug using the configured Kubernetes cluster in ~/.kube/config
.PHONY: debug
Expand Down Expand Up @@ -153,36 +172,36 @@ misspell-fix: $(TOOLBIN)/misspell

# Install CRDs into a cluster
.PHONY: install
install: $(TOOLBIN)/kustomize
$(TOOLBIN)/kustomize build config/crd| kubectl apply -f -
install: $(TOOLBIN)/kustomize $(TOOLBIN)/kubectl
$(TOOLBIN)/kustomize build config/crd| $(TOOLBIN)/kubectl apply -f -

# Uninstall CRDs from a cluster
.PHONY: uninstall
uninstall: $(TOOLBIN)/kustomize
$(TOOLBIN)/kustomize build config/crd| kubectl delete -f -
uninstall: $(TOOLBIN)/kustomize $(TOOLBIN)/kubectl
$(TOOLBIN)/kustomize build config/crd| $(TOOLBIN)/kubectl delete -f -

# Deploy controller in the configured Kubernetes cluster in ~/.kube/config
.PHONY: deploy
deploy: $(TOOLBIN)/kustomize
cd config/manager && $(TOOLBIN)/kustomize edit set image controller=$(CONTROLLER_IMG)
$(TOOLBIN)/kustomize build config/default | kubectl apply -f -
$(TOOLBIN)/kustomize build config/default | $(TOOLBIN)/kubectl apply -f -

# unDeploy controller in the configured Kubernetes cluster in ~/.kube/config
.PHONY: undeploy
undeploy: $(TOOLBIN)/kustomize
$(TOOLBIN)/kustomize build config/default | kubectl delete -f -
undeploy: $(TOOLBIN)/kustomize $(TOOLBIN)/kubectl
$(TOOLBIN)/kustomize build config/default | $(TOOLBIN)/kubectl delete -f -

# Deploy wordpress
.PHONY: deploy-wordpress
deploy-wordpress: $(TOOLBIN)/kustomize
deploy-wordpress: $(TOOLBIN)/kustomize $(TOOLBIN)/kubectl
mkdir -p /tmp/data1 /tmp/data2
$(TOOLBIN)/kustomize build docs/examples/wordpress | kubectl apply -f -
$(TOOLBIN)/kustomize build docs/examples/wordpress | $(TOOLBIN)/kubectl apply -f -

# Uneploy wordpress
.PHONY: undeploy-wordpress
undeploy-wordpress: $(TOOLBIN)/kustomize
$(TOOLBIN)/kustomize build docs/examples/wordpress | kubectl delete -f -
# kubectl delete pvc --all
undeploy-wordpress: $(TOOLBIN)/kustomize $(TOOLBIN)/kubectl
$(TOOLBIN)/kustomize build docs/examples/wordpress | $(TOOLBIN)/kubectl delete -f -
# $(TOOLBIN)/kubectl delete pvc --all
# sudo rm -fr /tmp/data1 /tmp/data2

## --------------------------------------
Expand Down
3 changes: 3 additions & 0 deletions e2e/kind-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,6 @@ kind: Cluster
apiVersion: kind.sigs.k8s.io/v1alpha3
nodes:
- role: control-plane
- role: worker
- role: worker
- role: worker
138 changes: 137 additions & 1 deletion e2e/main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,26 @@
package main

import (
"bytes"
"context"
"io"
"log"
"os"
"os/exec"
"path"
"testing"
"time"

. "github.com/onsi/ginkgo"
"github.com/onsi/ginkgo/reporters"
. "github.com/onsi/gomega"
apiextcs "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/types"
"k8s.io/apimachinery/pkg/util/wait"
"k8s.io/client-go/kubernetes/scheme"
_ "k8s.io/client-go/plugin/pkg/client/auth/gcp"
"k8s.io/client-go/rest"
Expand Down Expand Up @@ -46,7 +56,7 @@ const (
applicationPath = "../config/samples/app_v1beta1_application.yaml"
)

var _ = Describe("Application CRD should install correctly", func() {
var _ = Describe("Application CRD e2e", func() {
s := scheme.Scheme
_ = appv1beta1.AddToScheme(s)

Expand All @@ -65,6 +75,12 @@ var _ = Describe("Application CRD should install correctly", func() {
log.Fatal("Unable to construct extensions client", err)
}

var managerStdout bytes.Buffer
var managerStderr bytes.Buffer
managerCmd := exec.Command("../bin/manager", "--sync-period", "30")
managerCmd.Stdout = &managerStdout
managerCmd.Stderr = &managerStderr

It("should create CRD", func() {
err = testutil.CreateCRD(extClient, crd)
Expect(err).NotTo(HaveOccurred())
Expand All @@ -84,8 +100,128 @@ var _ = Describe("Application CRD should install correctly", func() {
Expect(err).NotTo(HaveOccurred())
})

It("should start the controller", func() {
err = managerCmd.Start()
Expect(err).NotTo(HaveOccurred())
})

It("should create the wordpress application", func() {
err = applyKustomize("../docs/examples/wordpress")
Expect(err).NotTo(HaveOccurred())
})

It("should update application status", func() {
kubeClient := getKubeClientOrDie(config, s)
application := &appv1beta1.Application{}
objectKey := types.NamespacedName{
Namespace: metav1.NamespaceDefault,
Name: "wordpress-01",
}
waitForApplicationStatusUpdated(kubeClient, objectKey, application)
Expect(application.Status.ObservedGeneration).To(BeNumerically("<=", 5))
Expect(application.Status.ComponentList.Objects).To(HaveLen(5))
})

It("should add ownerReference to components", func() {
kubeClient := getKubeClientOrDie(config, s)
matchingLabels := map[string]string{"app.kubernetes.io/name": "wordpress-01"}

list := &unstructured.UnstructuredList{}
list.SetGroupVersionKind(schema.GroupVersionKind{
Group: "",
Kind: "Service",
})
validateComponentOwnerReferences(kubeClient, list, matchingLabels)

list.SetGroupVersionKind(schema.GroupVersionKind{
Group: "apps",
Kind: "StatefulSet",
})
validateComponentOwnerReferences(kubeClient, list, matchingLabels)
})

It("should stop the controller", func() {
err = managerCmd.Process.Signal(os.Interrupt)
_, _ = io.Copy(os.Stderr, &managerStderr)
_, _ = io.Copy(os.Stdout, &managerStdout)
Expect(err).NotTo(HaveOccurred())
})

It("should delete application CRD", func() {
err = testutil.DeleteCRD(extClient, crd.Name)
Expect(err).NotTo(HaveOccurred())
})
})

func validateComponentOwnerReferences(kubeClient client.Client, list *unstructured.UnstructuredList, matchedingLabels map[string]string) {
componentsUpdated := false
_ = wait.PollImmediate(time.Second, time.Second*30, func() (bool, error) {

if err := kubeClient.List(context.TODO(), list, client.InNamespace(metav1.NamespaceDefault), client.MatchingLabels(matchedingLabels)); err != nil {
return false, err
}

updated := true
for _, item := range list.Items {
if item.GetOwnerReferences() == nil || len(item.GetOwnerReferences()) < 1 || item.GetOwnerReferences()[0].Name != "wordpress-01" {
updated = false
}
}
componentsUpdated = updated
return updated, nil
})
Expect(componentsUpdated).To(BeTrue())
}

func waitForApplicationStatusUpdated(kubeClient client.Client, key client.ObjectKey, app *appv1beta1.Application) {
_ = wait.PollImmediate(time.Second, time.Second*180, func() (bool, error) {
if err := kubeClient.Get(context.TODO(), key, app); err != nil {
return false, err
}

if app.Status.ComponentList.Objects != nil && len(app.Status.ComponentList.Objects) == 5 && app.Status.Conditions != nil {
return true, nil
}
return false, nil
})
}

func applyKustomize(path string) error {
var err error
var kubectlOP bytes.Buffer
var kubectlError bytes.Buffer
var kustError bytes.Buffer

kustomize := exec.Command("../hack/tools/bin/kustomize", "build", path)
kubectl := exec.Command("../hack/tools/bin/kubectl", "apply", "-f", "-")

r, w := io.Pipe()
kustomize.Stdout = w
kustomize.Stderr = &kustError
kubectl.Stdin = r
kubectl.Stderr = &kubectlError
kubectl.Stdout = &kubectlOP

err = kustomize.Start()
if err != nil {
return err
}
err = kubectl.Start()
if err != nil {
return err
}
err = kustomize.Wait()
if err != nil {
_, _ = io.Copy(os.Stdout, &kustError)
return err
}
w.Close()
err = kubectl.Wait()
if err != nil {
_, _ = io.Copy(os.Stdout, &kubectlError)
return err
}
_, _ = io.Copy(os.Stdout, &kubectlOP)

return nil
}
24 changes: 0 additions & 24 deletions e2e/test_e2e.sh

This file was deleted.

Loading