From d2673f96d3a915d72bac8e5d5d6daaa6a50fa483 Mon Sep 17 00:00:00 2001 From: Ilya Dmitrichenko Date: Thu, 30 Aug 2018 15:10:41 +0100 Subject: [PATCH] Wrap up integration tests --- Makefile | 11 +- .../create_get_delete/integration_test.go | 146 +++++++++++------- .../create_get_delete/nginx-deployment.yaml | 21 --- .../create_get_delete/podinfo.yaml | 47 ++++++ 4 files changed, 151 insertions(+), 74 deletions(-) delete mode 100644 tests/integration/create_get_delete/nginx-deployment.yaml create mode 100644 tests/integration/create_get_delete/podinfo.yaml diff --git a/Makefile b/Makefile index f9dec06430..884c3bda9c 100644 --- a/Makefile +++ b/Makefile @@ -17,9 +17,18 @@ test: @go test -v -covermode=count -coverprofile=coverage.out ./pkg/... ./cmd/... @test -z $(COVERALLS_TOKEN) || goveralls -coverprofile=coverage.out -service=circle-ci +.PHONY: integration-test-dev +integration-test-dev: build + @go test -tags integration -v -timeout 21m ./tests/integration/... \ + -args \ + -eksctl.cluster=integration-test-dev \ + -eksctl.create=false \ + -eksctl.delete=false \ + -eksctl.kubeconfig=$(HOME)/.kube/eksctl/clusters/integration-test-dev + .PHONY: integration-test integration-test: build - @go test -tags integration -v -timeout 21m ./tests/integration/... -args -skip-creation false + @go test -tags integration -v -timeout 21m ./tests/integration/... .PHONY: generated generate: diff --git a/tests/integration/create_get_delete/integration_test.go b/tests/integration/create_get_delete/integration_test.go index 0ae2cae6cf..2ce7aa7fcd 100644 --- a/tests/integration/create_get_delete/integration_test.go +++ b/tests/integration/create_get_delete/integration_test.go @@ -12,31 +12,36 @@ import ( "time" awseks "github.com/aws/aws-sdk-go/service/eks" + "k8s.io/client-go/tools/clientcmd" + harness "github.com/dlespiau/kube-test-harness" "github.com/dlespiau/kube-test-harness/logger" + . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" "github.com/onsi/gomega/gexec" + "github.com/weaveworks/eksctl/pkg/testutils/aws" . "github.com/weaveworks/eksctl/pkg/testutils/matchers" + "github.com/weaveworks/eksctl/pkg/utils" "github.com/weaveworks/eksctl/tests/integration" - //"k8s.io/client-go/tools/clientcmd" ) const ( - clusterName = "int-cluster" - createTimeoutInMins = 20 - eksRegion = "us-west-2" + createTimeout = 20 + region = "us-west-2" ) var ( - pathToEksCtl string - autoGeneratedConf bool + eksctlPath string - // Flags to help with developing the integration tests - skipCreation bool - skipCleanup bool - pathKubeCtlConf string + // Flags to help with the development of the integration tests + clusterName string + doCreate bool + doDelete bool + kubeconfigPath string + + kubeconfigTemp bool ) func TestCreateIntegration(t *testing.T) { @@ -44,25 +49,48 @@ func TestCreateIntegration(t *testing.T) { RunSpecs(t, "Integration - Create Suite") } +type tInterface interface { + GinkgoTInterface + Helper() +} + +type tHelper struct{ GinkgoTInterface } + +func (t *tHelper) Helper() { return } +func (t *tHelper) Name() string { return "eksctl-test" } + +func newKubeTest() (*harness.Test, error) { + t := &tHelper{GinkgoT()} + l := &logger.TestLogger{} + h := harness.New(harness.Options{Logger: l.ForTest(t)}) + if err := h.Setup(); err != nil { + return nil, err + } + if err := h.SetKubeconfig(kubeconfigPath); err != nil { + return nil, err + } + return h.NewTest(t), nil +} + var _ = Describe("Create (Integration)", func() { BeforeSuite(func() { - if pathKubeCtlConf == "" { - currentdir, _ := os.Getwd() - tempFile, _ := ioutil.TempFile(currentdir, "kubeconf") - pathKubeCtlConf = tempFile.Name() - autoGeneratedConf = true + kubeconfigTemp = false + if kubeconfigPath == "" { + wd, _ := os.Getwd() + f, _ := ioutil.TempFile(wd, "kubeconfig-") + kubeconfigPath = f.Name() + kubeconfigTemp = true } - fmt.Printf("Using kubeconfig: %s\n", pathKubeCtlConf) }) AfterSuite(func() { gexec.KillAndWait() - if !skipCleanup { - integration.CleanupAws(clusterName, eksRegion) - if autoGeneratedConf { - os.Remove(pathKubeCtlConf) - } + if kubeconfigTemp { + os.Remove(kubeconfigPath) + } + if doCreate && doDelete { + integration.CleanupAws(clusterName, region) } }) @@ -73,31 +101,37 @@ var _ = Describe("Create (Integration)", func() { ) It("should not return an error", func() { - if skipCreation { - fmt.Printf("Creation test skip: %t\n", skipCreation) + if !doCreate { + fmt.Fprintf(GinkgoWriter, "will use existing cluster %s", clusterName) return } - args := []string{"create", "cluster", "-n", clusterName, "-t", "t2.medium", "-N", "1", "-r", eksRegion, "--kubeconfig", pathToEksCtl} + fmt.Fprintf(GinkgoWriter, "Using kubeconfig: %s\n", kubeconfigPath) - command := exec.Command(pathToEksCtl, args...) + if clusterName == "" { + clusterName = utils.ClusterName("", "") + } + + args := []string{"create", "cluster", "--name", clusterName, "--node-type", "t2.medium", "--nodes", "1", "--region", region, "--kubeconfig", kubeconfigPath} + + command := exec.Command(eksctlPath, args...) session, err = gexec.Start(command, GinkgoWriter, GinkgoWriter) if err != nil { Fail(fmt.Sprintf("error starting process: %v", err), 1) } - session.Wait(createTimeoutInMins * time.Minute) + session.Wait(createTimeout * time.Minute) Expect(session.ExitCode()).Should(Equal(0)) }) It("should have created an EKS cluster", func() { - session := aws.NewSession(eksRegion) + session := aws.NewSession(region) Expect(session).To(HaveEksCluster(clusterName, awseks.ClusterStatusActive, "1.10")) }) It("should have the required cloudformation stacks", func() { - session := aws.NewSession(eksRegion) + session := aws.NewSession(region) Expect(session).To(HaveCfnStack(fmt.Sprintf("EKS-%s-VPC", clusterName))) Expect(session).To(HaveCfnStack(fmt.Sprintf("EKS-%s-ControlPlane", clusterName))) @@ -105,43 +139,50 @@ var _ = Describe("Create (Integration)", func() { Expect(session).To(HaveCfnStack(fmt.Sprintf("EKS-%s-DefaultNodeGroup", clusterName))) }) - /*It("should have created a valid kubectl config file", func() { - config, err := clientcmd.LoadFromFile(pathKubeCtlConf) + It("should have created a valid kubectl config file", func() { + config, err := clientcmd.LoadFromFile(kubeconfigPath) Expect(err).ShouldNot(HaveOccurred()) err = clientcmd.ConfirmUsable(*config, "") Expect(err).ShouldNot(HaveOccurred()) Expect(config.CurrentContext).To(ContainSubstring("eksctl")) - })*/ + Expect(config.CurrentContext).To(ContainSubstring(clusterName)) + Expect(config.CurrentContext).To(ContainSubstring(region)) + }) Context("and we create a deployment using kubectl", func() { - var ( - kube *harness.Harness - ) + var test *harness.Test BeforeEach(func() { - opts := harness.Options{ - Kubeconfig: pathKubeCtlConf, - Logger: &logger.TestLogger{}, - } - kube = harness.New(opts) + test, err = newKubeTest() + Expect(err).ShouldNot(HaveOccurred()) + test.CreateNamespace(test.Namespace) }) - It("should deploy the service to the cluster", func() { - test := kube.NewTest(GinkgoT()).Setup() - defer test.Close() + AfterEach(func() { + test.Close() + }) - d := test.CreateDeploymentFromFile("default", "nginx-deployment.yaml") + It("should deploy the service to the cluster", func() { + d := test.CreateDeploymentFromFile(test.Namespace, "podinfo.yaml") test.WaitForDeploymentReady(d, 1*time.Minute) + pods := test.ListPodsFromDeployment(d) + Expect(len(pods.Items)).To(Equal(2)) + // For each pod of the Deployment, check we receive a sensible response to a - // GET request on /. - for _, pod := range test.ListPodsFromDeployment(d).Items { - _, err := test.PodProxyGet(&pod, "80", "/").DoRaw() + // GET request on /version. + for _, pod := range pods.Items { + Expect(pod.Namespace).To(Equal(test.Namespace)) + + req := test.PodProxyGet(&pod, "", "/version") + fmt.Fprintf(GinkgoWriter, "url = %#v", req.URL()) + + var js interface{} + test.PodProxyGetJSON(&pod, "", "/version", &js) - Expect(err).ShouldNot(HaveOccurred()) - //TODO: compare response??? + Expect(js.(map[string]interface{})).To(HaveKeyWithValue("version", "1.0.1")) } }) }) @@ -149,10 +190,11 @@ var _ = Describe("Create (Integration)", func() { }) func init() { - flag.StringVar(&pathToEksCtl, "eksctl-path", "./eksctl", "Path to eksctl") + flag.StringVar(&eksctlPath, "eksctl.path", "../../../eksctl", "Path to eksctl") // Flags to help with the development of the integration tests - flag.BoolVar(&skipCreation, "skip-creation", false, "Skip the creation tests. Useful for debugging the tests") - flag.BoolVar(&skipCleanup, "skip-cleanup", false, "Skip the cleanup after the tests have run") - flag.StringVar(&pathKubeCtlConf, "kubeconf-path", "", "Path to kubectl config. Default is to create a temporary file") + flag.StringVar(&clusterName, "eksctl.cluster", "", "Cluster name (default: generate one)") + flag.BoolVar(&doCreate, "eksctl.create", true, "Skip the creation tests. Useful for debugging the tests") + flag.BoolVar(&doDelete, "eksctl.delete", true, "Skip the cleanup after the tests have run") + flag.StringVar(&kubeconfigPath, "eksctl.kubeconfig", "", "Path to kubeconfig (default: create it a temporary file)") } diff --git a/tests/integration/create_get_delete/nginx-deployment.yaml b/tests/integration/create_get_delete/nginx-deployment.yaml deleted file mode 100644 index 296c864e8a..0000000000 --- a/tests/integration/create_get_delete/nginx-deployment.yaml +++ /dev/null @@ -1,21 +0,0 @@ - -apiVersion: apps/v1 -kind: Deployment -metadata: - name: nginx -spec: - selector: - matchLabels: - app: nginx - replicas: 2 - template: - metadata: - - labels: - app: nginx - spec: - containers: - - name: nginx - image: nginx:1.7.9 - ports: - - containerPort: 80 \ No newline at end of file diff --git a/tests/integration/create_get_delete/podinfo.yaml b/tests/integration/create_get_delete/podinfo.yaml new file mode 100644 index 0000000000..5fc3c69012 --- /dev/null +++ b/tests/integration/create_get_delete/podinfo.yaml @@ -0,0 +1,47 @@ +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: podinfo + labels: + app: podinfo +spec: + replicas: 2 + selector: + matchLabels: + app: podinfo + template: + metadata: + labels: + app: podinfo + annotations: + prometheus.io/scrape: 'true' + spec: + containers: + - name: podinfod + image: quay.io/stefanprodan/podinfo:1.0.1 + command: + - ./podinfo + - --port=8080 + ports: + - name: http + containerPort: 8080 + protocol: TCP + readinessProbe: + httpGet: + path: /readyz + port: 8080 + initialDelaySeconds: 1 + periodSeconds: 5 + failureThreshold: 1 + livenessProbe: + httpGet: + path: /healthz + port: 8080 + initialDelaySeconds: 1 + periodSeconds: 10 + failureThreshold: 2 + resources: + requests: + memory: "32Mi" + cpu: "10m" \ No newline at end of file