From 6b6658346cad80548a5c67bf0e0c67bf7b97eca2 Mon Sep 17 00:00:00 2001 From: Anthony TREUILLIER Date: Tue, 15 Oct 2024 07:25:15 +0200 Subject: [PATCH] test: initial commit for e2e tests Signed-off-by: Anthony TREUILLIER --- test/e2e/e2e_suite_test.go | 64 ++++++++++++ test/e2e/e2e_test.go | 191 ++++++++++++++++++++--------------- test/scripts/init_cluster.sh | 93 +++++++++++++++++ 3 files changed, 264 insertions(+), 84 deletions(-) create mode 100755 test/scripts/init_cluster.sh diff --git a/test/e2e/e2e_suite_test.go b/test/e2e/e2e_suite_test.go index 0ca46cd..6b32853 100644 --- a/test/e2e/e2e_suite_test.go +++ b/test/e2e/e2e_suite_test.go @@ -11,16 +11,80 @@ package e2e import ( + "context" "fmt" + "os" "testing" + "time" + + "k8s.io/client-go/kubernetes/scheme" + "k8s.io/client-go/tools/clientcmd" . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" + dnsv1alpha1 "github.com/orange-opensource/powerdns-operator/api/v1alpha1" + "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/log" ) +var k8sClient client.Client + // Run e2e tests using the Ginkgo runner. func TestE2E(t *testing.T) { RegisterFailHandler(Fail) fmt.Fprintf(GinkgoWriter, "Starting powerdns-operator suite\n") RunSpecs(t, "e2e suite") } + +// BeforeSuite run before any specs are run to perform the required actions for all e2e Go tests. +var _ = BeforeSuite(func() { + var err error + log := log.FromContext(context.Background()) + + // kbc, err := utils.NewTestContext(util.KubebuilderBinName, "GO111MODULE=on") + // Expect(err).NotTo(HaveOccurred()) + // + // By("installing the cert-manager bundle") + // Expect(kbc.InstallCertManager()).To(Succeed()) + // + // By("installing the Prometheus operator") + // Expect(kbc.InstallPrometheusOperManager()).To(Succeed()) + + path := os.Getenv("TESTCONFIG") + if path == "" { + path = fmt.Sprintf("%s/.kube/config", os.Getenv("HOME")) + } + + cfg, err := clientcmd.BuildConfigFromFlags("", path) + if err != nil { + log.Error(err, "Failed to build config") + return + } + Expect(err).NotTo(HaveOccurred()) + Expect(cfg).NotTo(BeNil()) + + err = dnsv1alpha1.AddToScheme(scheme.Scheme) + Expect(err).NotTo(HaveOccurred()) + + kc, err := client.New(cfg, client.Options{Scheme: scheme.Scheme}) + Expect(err).NotTo(HaveOccurred()) + + k8sClient = kc + Expect(k8sClient).NotTo(BeNil()) + + fmt.Fprintf(GinkgoWriter, time.Now().Format(time.StampMilli)+": Info: Setup Suite Execution\n") +}) + +// AfterSuite run after all the specs have run, regardless of whether any tests have failed to ensures that +// all be cleaned up +var _ = AfterSuite(func() { + // kbc, err := utils.NewTestContext(util.KubebuilderBinName, "GO111MODULE=on") + // Expect(err).NotTo(HaveOccurred()) + // Expect(kbc.Prepare()).To(Succeed()) + // + // By("uninstalling the Prometheus manager bundle") + // kbc.UninstallPrometheusOperManager() + // + // By("uninstalling the cert-manager bundle") + // kbc.UninstallCertManager() +}) diff --git a/test/e2e/e2e_test.go b/test/e2e/e2e_test.go index 856f2c4..537d788 100644 --- a/test/e2e/e2e_test.go +++ b/test/e2e/e2e_test.go @@ -11,106 +11,129 @@ package e2e import ( - "fmt" - "os/exec" - "time" + "context" . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" - "github.com/orange-opensource/powerdns-operator/test/utils" + dnsv1alpha1 "github.com/orange-opensource/powerdns-operator/api/v1alpha1" ) const namespace = "powerdns-operator-system" var _ = Describe("controller", Ordered, func() { - BeforeAll(func() { - By("installing prometheus operator") - Expect(utils.InstallPrometheusOperator()).To(Succeed()) + /* + BeforeAll(func() { + By("installing prometheus operator") + Expect(utils.InstallPrometheusOperator()).To(Succeed()) - By("installing the cert-manager") - Expect(utils.InstallCertManager()).To(Succeed()) + By("installing the cert-manager") + Expect(utils.InstallCertManager()).To(Succeed()) - By("creating manager namespace") - cmd := exec.Command("kubectl", "create", "ns", namespace) - _, _ = utils.Run(cmd) - }) + By("creating manager namespace") + cmd := exec.Command("kubectl", "create", "ns", namespace) + _, _ = utils.Run(cmd) + }) - AfterAll(func() { - By("uninstalling the Prometheus manager bundle") - utils.UninstallPrometheusOperator() + AfterAll(func() { + By("uninstalling the Prometheus manager bundle") + utils.UninstallPrometheusOperator() - By("uninstalling the cert-manager bundle") - utils.UninstallCertManager() + By("uninstalling the cert-manager bundle") + utils.UninstallCertManager() - By("removing manager namespace") - cmd := exec.Command("kubectl", "delete", "ns", namespace) - _, _ = utils.Run(cmd) - }) - - Context("Operator", func() { - It("should run successfully", func() { - var controllerPodName string - var err error - - // projectimage stores the name of the image used in the example - var projectimage = "example.com/powerdns-operator:v0.0.1" - - By("building the manager(Operator) image") - cmd := exec.Command("make", "docker-build", fmt.Sprintf("IMG=%s", projectimage)) - _, err = utils.Run(cmd) - ExpectWithOffset(1, err).NotTo(HaveOccurred()) - - By("loading the the manager(Operator) image on Kind") - err = utils.LoadImageToKindClusterWithName(projectimage) - ExpectWithOffset(1, err).NotTo(HaveOccurred()) - - By("installing CRDs") - cmd = exec.Command("make", "install") - _, err = utils.Run(cmd) - ExpectWithOffset(1, err).NotTo(HaveOccurred()) - - By("deploying the controller-manager") - cmd = exec.Command("make", "deploy", fmt.Sprintf("IMG=%s", projectimage)) - _, err = utils.Run(cmd) - ExpectWithOffset(1, err).NotTo(HaveOccurred()) - - By("validating that the controller-manager pod is running as expected") - verifyControllerUp := func() error { - // Get pod name - - cmd = exec.Command("kubectl", "get", - "pods", "-l", "control-plane=controller-manager", - "-o", "go-template={{ range .items }}"+ - "{{ if not .metadata.deletionTimestamp }}"+ - "{{ .metadata.name }}"+ - "{{ \"\\n\" }}{{ end }}{{ end }}", - "-n", namespace, - ) - - podOutput, err := utils.Run(cmd) - ExpectWithOffset(2, err).NotTo(HaveOccurred()) - podNames := utils.GetNonEmptyLines(string(podOutput)) - if len(podNames) != 1 { - return fmt.Errorf("expect 1 controller pods running, but got %d", len(podNames)) - } - controllerPodName = podNames[0] - ExpectWithOffset(2, controllerPodName).Should(ContainSubstring("controller-manager")) - - // Validate pod status - cmd = exec.Command("kubectl", "get", - "pods", controllerPodName, "-o", "jsonpath={.status.phase}", - "-n", namespace, - ) - status, err := utils.Run(cmd) - ExpectWithOffset(2, err).NotTo(HaveOccurred()) - if string(status) != "Running" { - return fmt.Errorf("controller pod in %s status", status) + By("removing manager namespace") + cmd := exec.Command("kubectl", "delete", "ns", namespace) + _, _ = utils.Run(cmd) + }) + */ + Context("On an existing PowerDNS cluster", func() { + It("should create the zone and RRsets successfully", func() { + ctx := context.Background() + zoneName := "example2.org" + zoneKind := "Native" + zoneNS1 := "ns1.example2.org" + zoneNS2 := "ns2.example2.org" + + By("Creating the Zone resource") + zone := &dnsv1alpha1.Zone{ + ObjectMeta: metav1.ObjectMeta{ + Name: zoneName, + }, + } + zone.SetResourceVersion("") + _, err := controllerutil.CreateOrUpdate(ctx, k8sClient, zone, func() error { + zone.Spec = dnsv1alpha1.ZoneSpec{ + Kind: zoneKind, + Nameservers: []string{zoneNS1, zoneNS2}, } return nil - } - EventuallyWithOffset(1, verifyControllerUp, time.Minute, time.Second).Should(Succeed()) - + }) + Expect(err).NotTo(HaveOccurred()) + + /* + var controllerPodName string + + // projectimage stores the name of the image used in the example + var projectimage = "example.com/powerdns-operator:v0.0.1" + + By("building the manager(Operator) image") + cmd := exec.Command("make", "docker-build", fmt.Sprintf("IMG=%s", projectimage)) + _, err = utils.Run(cmd) + ExpectWithOffset(1, err).NotTo(HaveOccurred()) + + By("loading the the manager(Operator) image on Kind") + err = utils.LoadImageToKindClusterWithName(projectimage) + ExpectWithOffset(1, err).NotTo(HaveOccurred()) + + By("installing CRDs") + cmd = exec.Command("make", "install") + _, err = utils.Run(cmd) + ExpectWithOffset(1, err).NotTo(HaveOccurred()) + + By("deploying the controller-manager") + cmd = exec.Command("make", "deploy", fmt.Sprintf("IMG=%s", projectimage)) + _, err = utils.Run(cmd) + ExpectWithOffset(1, err).NotTo(HaveOccurred()) + + By("validating that the controller-manager pod is running as expected") + verifyControllerUp := func() error { + // Get pod name + + cmd = exec.Command("kubectl", "get", + "pods", "-l", "control-plane=controller-manager", + "-o", "go-template={{ range .items }}"+ + "{{ if not .metadata.deletionTimestamp }}"+ + "{{ .metadata.name }}"+ + "{{ \"\\n\" }}{{ end }}{{ end }}", + "-n", namespace, + ) + + podOutput, err := utils.Run(cmd) + ExpectWithOffset(2, err).NotTo(HaveOccurred()) + podNames := utils.GetNonEmptyLines(string(podOutput)) + if len(podNames) != 1 { + return fmt.Errorf("expect 1 controller pods running, but got %d", len(podNames)) + } + controllerPodName = podNames[0] + ExpectWithOffset(2, controllerPodName).Should(ContainSubstring("controller-manager")) + + // Validate pod status + cmd = exec.Command("kubectl", "get", + "pods", controllerPodName, "-o", "jsonpath={.status.phase}", + "-n", namespace, + ) + status, err := utils.Run(cmd) + ExpectWithOffset(2, err).NotTo(HaveOccurred()) + if string(status) != "Running" { + return fmt.Errorf("controller pod in %s status", status) + } + return nil + } + EventuallyWithOffset(1, verifyControllerUp, time.Minute, time.Second).Should(Succeed()) + */ }) }) }) diff --git a/test/scripts/init_cluster.sh b/test/scripts/init_cluster.sh new file mode 100755 index 0000000..e0b70f0 --- /dev/null +++ b/test/scripts/init_cluster.sh @@ -0,0 +1,93 @@ +#!/bin/bash + +PROJECT_ROOT=$PWD +E2E_DIR=$(realpath $(dirname $0)/..) +CONTROLLER_NAMESPACE=powerdns-operator-system +IMAGE_TAG=`date "+%Y-%m-%d-%H-%M-%S"` +#VERSION=$(cat VERSION | tr -d " \t\n\r") + +function build_ginkgo_test() { + cd $E2E_DIR + ginkgo build -r e2e/ +} + +function cleanup() { + cd $PROJECT_ROOT +# kubectl delete -f manifests/setup/setup.yaml +# kubectl delete ns $CONTROLLER_NAMESPACE + kind delete cluster --name test && exit 0 +} + +function prepare_cluster() { + kind create cluster --name test + kubectl create ns $CONTROLLER_NAMESPACE + + echo "wait the control-plane ready..." + kubectl wait --for=condition=Ready node/test-control-plane --timeout=60s +} + +function build_image() { + cd $PROJECT_ROOT + make docker-build -e IMG=pdns/powerdns-operator:$IMAGE_TAG + kind load docker-image pdns/powerdns-operator:$IMAGE_TAG --name test +} + +function start_powerdns_operator() { + cd $PROJECT_ROOT + make deploy -e IMG=pdns/powerdns-operator:$IMAGE_TAG + kubectl -n $CONTROLLER_NAMESPACE wait --for=condition=available deployment/powerdns-operator-controller-manager --timeout=60s +} + +function deploy_powerdns(){ + kubectl create secret generic powerdns-operator-manager -n $CONTROLLER_NAMESPACE --from-literal=PDNS_API_URL=http://powerdns:8081 --from-literal=PDNS_API_KEY=sPowerDNSAPI --from-literal=PDNS_API_VHOST=localhost + helm install -n $CONTROLLER_NAMESPACE --version 0.1.3 --set mariadb.primary.persistence.enabled=false --set phpmyadmin.enabled=false --set powerdns-admin.enabled=false powerdns fsdrw08/powerdns + kubectl -n $CONTROLLER_NAMESPACE wait --for=condition=available deployment/powerdns --timeout=600s +} + +function run_test() { + # inspired by github.com/kubeedge/kubeedge/tests/e2e/scripts/helm_keadm_e2e.sh + :> /tmp/testcase.log + $E2E_DIR/e2e/e2e.test $debugflag 2>&1 | tee -a /tmp/testcase.log + + grep -e "Running Suite" -e "SUCCESS\!" -e "FAIL\!" /tmp/testcase.log | sed -r 's/\x1B\[([0-9];)?([0-9]{1,2}(;[0-9]{1,2})?)?[mGK]//g' | sed -r 's/\x1B\[([0-9]{1,2}(;[0-9]{1,2})?)?[mGK]//g' + echo "Integration Test Final Summary Report" + echo "=======================================================" + echo "Total Number of Test cases = `grep "Ran " /tmp/testcase.log | awk '{sum+=$2} END {print sum}'`" + passed=`grep -e "SUCCESS\!" -e "FAIL\!" /tmp/testcase.log | awk '{print $3}' | sed -r "s/\x1B\[([0-9];)?([0-9]{1,2}(;[0-9]{1,2})?)?[mGK]//g" | awk '{sum+=$1} END {print sum}'` + echo "Number of Test cases PASSED = $passed" + fail=`grep -e "SUCCESS\!" -e "FAIL\!" /tmp/testcase.log | awk '{print $6}' | sed -r "s/\x1B\[([0-9]{1,2}(;[0-9]{1,2})?)?[mGK]//g" | awk '{sum+=$1} END {print sum}'` + echo "Number of Test cases FAILED = $fail" + echo "==================Result Summary=======================" + + if [ "$fail" != "0" ];then + echo "Integration suite has failures, Please check !!" + exit 1 + else + echo "Integration suite successfully passed all the tests !!" + exit 0 + fi +} + +set -Ee +trap cleanup EXIT +trap cleanup ERR + +echo -e "\nBuilding testcases..." +build_ginkgo_test + +echo -e "\nPreparing cluster..." +prepare_cluster + +echo -e "\Deploying PowerDNS..." +deploy_powerdns + +echo -e "\nBuilding image..." +build_image + +echo -e "\nStart powerdns operator..." +start_powerdns_operator + +echo -e "\nRunning test..." +run_test + +read -t 120 -p "I am going to wait for 120 seconds only ..."