From aa51f179bbbe36458b5331d063b587216197729e Mon Sep 17 00:00:00 2001 From: Priya Wadhwa Date: Mon, 20 Jul 2020 16:41:55 -0400 Subject: [PATCH] Add integration test to test against latest skaffold release This PR: 1. Adds an integration test to test minikube against the latest skaffold release 1. Adds in a sample skaffold app from the skaffold repo to test 1. Adds this test to the addons_certs_docker_ubuntu Github Actions test --- .github/workflows/pr.yml | 2 +- go.mod | 1 - test/integration/skaffold_test.go | 97 +++++++++++++++++++ test/integration/testdata/skaffold/README.md | 3 + .../testdata/skaffold/leeroy-app/Dockerfile | 10 ++ .../testdata/skaffold/leeroy-app/app.go | 17 ++++ .../leeroy-app/kubernetes/deployment.yaml | 35 +++++++ .../testdata/skaffold/leeroy-web/Dockerfile | 10 ++ .../leeroy-web/kubernetes/deployment.yaml | 21 ++++ .../testdata/skaffold/leeroy-web/web.go | 25 +++++ .../testdata/skaffold/skaffold.yaml | 18 ++++ 11 files changed, 237 insertions(+), 2 deletions(-) create mode 100644 test/integration/skaffold_test.go create mode 100644 test/integration/testdata/skaffold/README.md create mode 100644 test/integration/testdata/skaffold/leeroy-app/Dockerfile create mode 100644 test/integration/testdata/skaffold/leeroy-app/app.go create mode 100644 test/integration/testdata/skaffold/leeroy-app/kubernetes/deployment.yaml create mode 100644 test/integration/testdata/skaffold/leeroy-web/Dockerfile create mode 100644 test/integration/testdata/skaffold/leeroy-web/kubernetes/deployment.yaml create mode 100644 test/integration/testdata/skaffold/leeroy-web/web.go create mode 100644 test/integration/testdata/skaffold/skaffold.yaml diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml index 4711a151b8..2aa707153f 100644 --- a/.github/workflows/pr.yml +++ b/.github/workflows/pr.yml @@ -612,7 +612,7 @@ jobs: chmod a+x e2e-* chmod a+x minikube-* START_TIME=$(date -u +%s) - KUBECONFIG=$(pwd)/testhome/kubeconfig MINIKUBE_HOME=$(pwd)/testhome ./e2e-linux-amd64 -minikube-start-args=--driver=docker -test.run "(TestAddons|TestCertOptions)" -test.timeout=10m -test.v -timeout-multiplier=1.5 -binary=./minikube-linux-amd64 2>&1 | tee ./report/testout.txt + KUBECONFIG=$(pwd)/testhome/kubeconfig MINIKUBE_HOME=$(pwd)/testhome ./e2e-linux-amd64 -minikube-start-args=--driver=docker -test.run "(TestAddons|TestCertOptions|TestSkaffold)" -test.timeout=10m -test.v -timeout-multiplier=1.5 -binary=./minikube-linux-amd64 2>&1 | tee ./report/testout.txt END_TIME=$(date -u +%s) TIME_ELAPSED=$(($END_TIME-$START_TIME)) min=$((${TIME_ELAPSED}/60)) diff --git a/go.mod b/go.mod index 6bf39cab1d..b388606f14 100644 --- a/go.mod +++ b/go.mod @@ -74,7 +74,6 @@ require ( github.com/zchee/go-vmnet v0.0.0-20161021174912-97ebf9174097 golang.org/x/build v0.0.0-20190927031335-2835ba2e683f golang.org/x/crypto v0.0.0-20200510223506-06a226fb4e37 - golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6 // indirect golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a golang.org/x/sys v0.0.0-20200523222454-059865788121 golang.org/x/text v0.3.2 diff --git a/test/integration/skaffold_test.go b/test/integration/skaffold_test.go new file mode 100644 index 0000000000..d8639428c8 --- /dev/null +++ b/test/integration/skaffold_test.go @@ -0,0 +1,97 @@ +// +build integration + +/* +Copyright 2020 The Kubernetes Authors All rights reserved. + +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 integration + +import ( + "context" + "fmt" + "io/ioutil" + "os" + "os/exec" + "runtime" + "testing" + "time" + + "github.com/hashicorp/go-getter" + "k8s.io/minikube/pkg/util/retry" +) + +func TestSkaffold(t *testing.T) { + // get unique profile for test + MaybeParallel(t) + profile := UniqueProfileName("skaffold") + ctx, cancel := context.WithTimeout(context.Background(), Minutes(5)) + defer CleanupWithLogs(t, profile, cancel) + + // install latest skaffold release + tf, err := installSkaffold() + if err != nil { + t.Fatalf("skaffold release installation failed: %v", err) + } + defer os.Remove(tf.Name()) + + // start minikube cluster + args := append([]string{"start", "-p", profile, "--memory=2200"}, StartArgs()...) + rr, err := Run(t, exec.CommandContext(ctx, Target(), args...)) + if err != nil { + t.Fatalf("starting minikube: %v\n%s", err, rr.Output()) + } + + // make sure "skaffold run" exits without failure + cmd := exec.CommandContext(ctx, tf.Name(), "run", "--kube-context", profile, "--status-check=true", "--port-forward=false") + cmd.Dir = "testdata/skaffold" + rr, err = Run(t, cmd) + if err != nil { + t.Fatalf("error running skaffold: %v\n%s", err, rr.Output()) + } + + // make sure expected deployment is running + if _, err := PodWait(ctx, t, profile, "default", "app=leeroy-app", Minutes(1)); err != nil { + t.Fatalf("failed waiting for pod leeroy-app: %v", err) + } + if _, err := PodWait(ctx, t, profile, "default", "app=leeroy-web", Minutes(1)); err != nil { + t.Fatalf("failed waiting for pod leeroy-web: %v", err) + } +} + +// installSkaffold installs the latest release of skaffold +func installSkaffold() (f *os.File, err error) { + tf, err := ioutil.TempFile("", "skaffold.exe") + if err != nil { + return tf, err + } + tf.Close() + + url := "https://storage.googleapis.com/skaffold/releases/latest/skaffold-%s-amd64" + url = fmt.Sprintf(url, runtime.GOOS) + if runtime.GOOS == "windows" { + url += ".exe" + } + + if err := retry.Expo(func() error { return getter.GetFile(tf.Name(), url) }, 3*time.Second, Minutes(3)); err != nil { + return tf, err + } + + if runtime.GOOS != "windows" { + if err := os.Chmod(tf.Name(), 0700); err != nil { + return tf, err + } + } + return tf, nil +} diff --git a/test/integration/testdata/skaffold/README.md b/test/integration/testdata/skaffold/README.md new file mode 100644 index 0000000000..6dfeee1b3c --- /dev/null +++ b/test/integration/testdata/skaffold/README.md @@ -0,0 +1,3 @@ +This [example](https://github.com/GoogleContainerTools/skaffold/tree/master/integration/examples/microservices) is the microservices example and was copied from the skaffold repo. + + diff --git a/test/integration/testdata/skaffold/leeroy-app/Dockerfile b/test/integration/testdata/skaffold/leeroy-app/Dockerfile new file mode 100644 index 0000000000..940c5e989b --- /dev/null +++ b/test/integration/testdata/skaffold/leeroy-app/Dockerfile @@ -0,0 +1,10 @@ +FROM golang:1.12.9-alpine3.10 as builder +COPY app.go . +RUN go build -o /app . + +FROM alpine:3.10 +# Define GOTRACEBACK to mark this container as using the Go language runtime +# for `skaffold debug` (https://skaffold.dev/docs/workflows/debug/). +ENV GOTRACEBACK=single +CMD ["./app"] +COPY --from=builder /app . diff --git a/test/integration/testdata/skaffold/leeroy-app/app.go b/test/integration/testdata/skaffold/leeroy-app/app.go new file mode 100644 index 0000000000..40f9c08afa --- /dev/null +++ b/test/integration/testdata/skaffold/leeroy-app/app.go @@ -0,0 +1,17 @@ +package main + +import ( + "fmt" + "log" + "net/http" +) + +func handler(w http.ResponseWriter, r *http.Request) { + fmt.Fprintf(w, "leeroooooy app!!\n") +} + +func main() { + log.Print("leeroy app server ready") + http.HandleFunc("/", handler) + http.ListenAndServe(":50051", nil) +} diff --git a/test/integration/testdata/skaffold/leeroy-app/kubernetes/deployment.yaml b/test/integration/testdata/skaffold/leeroy-app/kubernetes/deployment.yaml new file mode 100644 index 0000000000..f416632e9a --- /dev/null +++ b/test/integration/testdata/skaffold/leeroy-app/kubernetes/deployment.yaml @@ -0,0 +1,35 @@ +apiVersion: v1 +kind: Service +metadata: + name: leeroy-app + labels: + app: leeroy-app +spec: + clusterIP: None + ports: + - port: 50051 + name: leeroy-app + selector: + app: leeroy-app +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: leeroy-app + labels: + app: leeroy-app +spec: + replicas: 1 + selector: + matchLabels: + app: leeroy-app + template: + metadata: + labels: + app: leeroy-app + spec: + containers: + - name: leeroy-app + image: leeroy-app + ports: + - containerPort: 50051 diff --git a/test/integration/testdata/skaffold/leeroy-web/Dockerfile b/test/integration/testdata/skaffold/leeroy-web/Dockerfile new file mode 100644 index 0000000000..ce5773cc31 --- /dev/null +++ b/test/integration/testdata/skaffold/leeroy-web/Dockerfile @@ -0,0 +1,10 @@ +FROM golang:1.12.9-alpine3.10 as builder +COPY web.go . +RUN go build -o /web . + +FROM alpine:3.10 +# Define GOTRACEBACK to mark this container as using the Go language runtime +# for `skaffold debug` (https://skaffold.dev/docs/workflows/debug/). +ENV GOTRACEBACK=single +CMD ["./web"] +COPY --from=builder /web . diff --git a/test/integration/testdata/skaffold/leeroy-web/kubernetes/deployment.yaml b/test/integration/testdata/skaffold/leeroy-web/kubernetes/deployment.yaml new file mode 100644 index 0000000000..1aa0c83fb8 --- /dev/null +++ b/test/integration/testdata/skaffold/leeroy-web/kubernetes/deployment.yaml @@ -0,0 +1,21 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: leeroy-web + labels: + app: leeroy-web +spec: + replicas: 1 + selector: + matchLabels: + app: leeroy-web + template: + metadata: + labels: + app: leeroy-web + spec: + containers: + - name: leeroy-web + image: leeroy-web + ports: + - containerPort: 8080 diff --git a/test/integration/testdata/skaffold/leeroy-web/web.go b/test/integration/testdata/skaffold/leeroy-web/web.go new file mode 100644 index 0000000000..69f9278565 --- /dev/null +++ b/test/integration/testdata/skaffold/leeroy-web/web.go @@ -0,0 +1,25 @@ +package main + +import ( + "io" + "net/http" + + "log" +) + +func handler(w http.ResponseWriter, r *http.Request) { + resp, err := http.Get("http://leeroy-app:50051") + if err != nil { + panic(err) + } + defer resp.Body.Close() + if _, err := io.Copy(w, resp.Body); err != nil { + panic(err) + } +} + +func main() { + log.Print("leeroy web server ready") + http.HandleFunc("/", handler) + http.ListenAndServe(":8080", nil) +} diff --git a/test/integration/testdata/skaffold/skaffold.yaml b/test/integration/testdata/skaffold/skaffold.yaml new file mode 100644 index 0000000000..7370643afc --- /dev/null +++ b/test/integration/testdata/skaffold/skaffold.yaml @@ -0,0 +1,18 @@ +apiVersion: skaffold/v2beta5 +kind: Config +build: + artifacts: + - image: leeroy-web + context: leeroy-web + - image: leeroy-app + context: leeroy-app +deploy: + kubectl: + manifests: + - leeroy-web/kubernetes/* + - leeroy-app/kubernetes/* +portForward: + - resourceType: deployment + resourceName: leeroy-web + port: 8080 + localPort: 9000