From 7bd3551f024d3cc9afbbeb2f710cb3687e39f4fb Mon Sep 17 00:00:00 2001 From: Alfonso Acosta Date: Fri, 25 Oct 2019 20:45:45 +0200 Subject: [PATCH] Add linting and formatting checks for e2e tests --- Makefile | 36 +++++++++++++++++----- test/e2e/10_helm_chart.bats | 2 +- test/e2e/lib/defer.bash | 6 ++-- test/e2e/lib/install.bash | 60 ++++++++++++++++++------------------- test/e2e/lib/poll.bash | 4 +-- test/e2e/run.bash | 27 ++++++++++------- 6 files changed, 82 insertions(+), 53 deletions(-) diff --git a/Makefile b/Makefile index 16bb3b415..ff99fb17b 100644 --- a/Makefile +++ b/Makefile @@ -1,11 +1,13 @@ .DEFAULT: all -.PHONY: all release-bins clean realclean test integration-test generate-deploy check-generated +.PHONY: all release-bins clean realclean test integration-test generate-deploy check-generated lint-e2e SUDO := $(shell docker info > /dev/null 2> /dev/null || echo "sudo") TEST_FLAGS?= BATS_VERSION := 1.1.0 +SHELLCHECK_VERSION := 0.7.0 +SHFMT_VERSION := 2.6.4 include docker/kubectl.version include docker/kustomize.version @@ -17,7 +19,8 @@ include docker/helm.version ifeq ($(ARCH),) ARCH=amd64 endif -CURRENT_OS_ARCH=$(shell echo `go env GOOS`-`go env GOARCH`) +CURRENT_OS=$(shell go env GOOS) +CURRENT_OS_ARCH=$(shell echo $(CURRENT_OS)-`go env GOARCH`) GOBIN?=$(shell echo `go env GOPATH`/bin) godeps=$(shell go list -deps -f '{{if not .Standard}}{{ $$dep := . }}{{range .GoFiles}}{{$$dep.Dir}}/{{.}} {{end}}{{end}}' $(1) | sed "s%${PWD}/%%g") @@ -58,9 +61,17 @@ realclean: clean test: test/bin/helm test/bin/kubectl test/bin/kustomize $(GENERATED_TEMPLATES_FILE) PATH="${PWD}/bin:${PWD}/test/bin:${PATH}" go test ${TEST_FLAGS} $(shell go list ./... | grep -v "^github.com/fluxcd/flux/vendor" | sort -u) -e2e: test/bin/helm test/bin/kubectl test/e2e/bats build/.flux.done +e2e: lint-e2e test/bin/helm test/bin/kubectl test/e2e/bats build/.flux.done PATH="${PWD}/test/bin:${PATH}" CURRENT_OS_ARCH=$(CURRENT_OS_ARCH) test/e2e/run.bash +lint-e2e: test/bin/shfmt test/bin/shellcheck + @# shfmt is not compatible with .bats files, so we preprocess them to turn '@test's into functions + for I in test/e2e/*.bats; do \ + ( cat "$$I" | sed 's%@test.*%test() {%' | test/bin/shfmt -i 2 -sr -d ) || (echo "Please shfmt file $$I"; exit 1 )\ + done + test/bin/shfmt -i 2 -sr -l test/e2e/run.bash test/e2e/lib/* || ("Please run 'test/bin/shfmt -i 2 -sr -w' on e2e files"; exit 1) + test/bin/shellcheck test/e2e/run.bash test/e2e/lib/* test/e2e/*.bats + build/.%.done: docker/Dockerfile.% mkdir -p ./build/docker/$* cp $^ ./build/docker/$*/ @@ -82,8 +93,10 @@ build/helm: cache/linux-$(ARCH)/helm-$(HELM_VERSION) test/bin/helm: cache/$(CURRENT_OS_ARCH)/helm-$(HELM_VERSION) build/kustomize: cache/linux-amd64/kustomize-$(KUSTOMIZE_VERSION) test/bin/kustomize: cache/$(CURRENT_OS_ARCH)/kustomize-$(KUSTOMIZE_VERSION) +test/bin/shellcheck: cache/$(CURRENT_OS_ARCH)/shellcheck-$(SHELLCHECK_VERSION) +test/bin/shfmt: cache/$(CURRENT_OS_ARCH)/shfmt-$(SHFMT_VERSION) -build/kubectl test/bin/kubectl build/kustomize test/bin/kustomize build/helm test/bin/helm: +build/kubectl test/bin/kubectl build/kustomize test/bin/kustomize build/helm test/bin/helm test/bin/shellcheck test/bin/shfmt: mkdir -p build cp $< $@ if [ `basename $@` = "build" -a $(CURRENT_OS_ARCH) = "linux-$(ARCH)" ]; then strip $@; fi @@ -108,14 +121,23 @@ cache/%/helm-$(HELM_VERSION): docker/helm.version tar -m -C ./cache -xzf cache/$*/helm-$(HELM_VERSION).tar.gz $*/helm mv cache/$*/helm $@ -test/e2e/bats: cache/bats_v$(BATS_VERSION).tar.gz +cache/%/shellcheck-$(SHELLCHECK_VERSION): + mkdir -p cache/$* + curl --fail -L -o cache/$*/shellcheck-$(SHELLCHECK_VERSION).tar.xz "https://storage.googleapis.com/shellcheck/shellcheck-v$(SHELLCHECK_VERSION).$(CURRENT_OS).x86_64.tar.xz" + tar -C cache/$* --strip-components 1 -xvJf cache/$*/shellcheck-$(SHELLCHECK_VERSION).tar.xz shellcheck-v$(SHELLCHECK_VERSION)/shellcheck + mv cache/$*/shellcheck $@ + +cache/%/shfmt-$(SHFMT_VERSION): + mkdir -p cache/$* + curl --fail -L -o $@ "https://github.com/mvdan/sh/releases/download/v$(SHFMT_VERSION)/shfmt_v$(SHFMT_VERSION)_`echo $* | tr - _`" + +test/e2e/bats: cache/bats-v$(BATS_VERSION).tar.gz mkdir -p $@ tar -C $@ --strip-components 1 -xzf $< -cache/bats_v$(BATS_VERSION).tar.gz: +cache/bats-v$(BATS_VERSION).tar.gz: curl --fail -L -o $@ https://github.com/bats-core/bats-core/archive/v$(BATS_VERSION).tar.gz - $(GOBIN)/fluxctl: $(FLUXCTL_DEPS) $(GENERATED_TEMPLATES_FILE) go install ./cmd/fluxctl diff --git a/test/e2e/10_helm_chart.bats b/test/e2e/10_helm_chart.bats index b954d1920..75318578f 100644 --- a/test/e2e/10_helm_chart.bats +++ b/test/e2e/10_helm_chart.bats @@ -11,7 +11,7 @@ function setup() { @test "Helm chart installation smoke test" { # The gitconfig secret must exist and have the right value - poll_until_equals "gitconfig secret" "${GITCONFIG}" "kubectl get secrets -n "${FLUX_NAMESPACE}" gitconfig -ojsonpath={..data.gitconfig} | base64 --decode" + poll_until_equals "gitconfig secret" "${GITCONFIG}" "kubectl get secrets -n ${FLUX_NAMESPACE} gitconfig -ojsonpath={..data.gitconfig} | base64 --decode" # Test that the resources from https://github.com/fluxcd/flux-get-started are deployed poll_until_true 'namespace demo' 'kubectl describe ns/demo' diff --git a/test/e2e/lib/defer.bash b/test/e2e/lib/defer.bash index 7841eccca..278e98087 100644 --- a/test/e2e/lib/defer.bash +++ b/test/e2e/lib/defer.bash @@ -7,8 +7,8 @@ function on_exit() { echo -e '\nRunning deferred items, please do not interrupt until they are done:' fi for I in "${on_exit_items[@]}"; do - echo "deferred: ${I}" - eval "${I}" + echo "deferred: ${I}" + eval "${I}" done } @@ -16,4 +16,4 @@ trap on_exit EXIT function defer() { on_exit_items=("$*" "${on_exit_items[@]}") -} \ No newline at end of file +} diff --git a/test/e2e/lib/install.bash b/test/e2e/lib/install.bash index e7f1586d7..8aee6c2f4 100755 --- a/test/e2e/lib/install.bash +++ b/test/e2e/lib/install.bash @@ -15,30 +15,29 @@ function uninstall_tiller() { } function install_flux_with_helm() { - local create_crds='true' - if kubectl get crd fluxhelmreleases.helm.integrations.flux.weave.works helmreleases.flux.weave.works > /dev/null 2>&1; then - # CRDs existed, don't try to create them - echo 'CRDs existed, setting helmOperator.createCRD=false' - create_crds='false' - fi + local create_crds='true' + if kubectl get crd fluxhelmreleases.helm.integrations.flux.weave.works helmreleases.flux.weave.works > /dev/null 2>&1; then + # CRDs existed, don't try to create them + echo 'CRDs existed, setting helmOperator.createCRD=false' + create_crds='false' + fi helm install --name flux --wait \ ---namespace "${FLUX_NAMESPACE}" \ ---set image.repository=docker.io/fluxcd/flux \ ---set image.tag=latest \ ---set git.url=ssh://git@gitsrv/git-server/repos/cluster.git \ ---set git.secretName=flux-git-deploy \ ---set git.pollInterval=10s \ ---set git.config.secretName=gitconfig \ ---set git.config.enabled=true \ ---set-string git.config.data="${GITCONFIG}" \ ---set helmOperator.create=true `# just needed to add the HelmRelease CRD`\ ---set helmOperator.git.secretName=flux-git-deploy \ ---set helmOperator.createCRD="${create_crds}" \ ---set registry.excludeImage=* \ ---set-string ssh.known_hosts="${KNOWN_HOSTS}" \ -"${FLUX_ROOT_DIR}/chart/flux" - + --namespace "${FLUX_NAMESPACE}" \ + --set image.repository=docker.io/fluxcd/flux \ + --set image.tag=latest \ + --set git.url=ssh://git@gitsrv/git-server/repos/cluster.git \ + --set git.secretName=flux-git-deploy \ + --set git.pollInterval=10s \ + --set git.config.secretName=gitconfig \ + --set git.config.enabled=true \ + --set-string git.config.data="${GITCONFIG}" \ + --set helmOperator.create=true \ + --set helmOperator.git.secretName=flux-git-deploy \ + --set helmOperator.createCRD="${create_crds}" \ + --set registry.excludeImage=* \ + --set-string ssh.known_hosts="${KNOWN_HOSTS}" \ + "${FLUX_ROOT_DIR}/chart/flux" } function uninstall_flux_with_helm() { @@ -46,22 +45,23 @@ function uninstall_flux_with_helm() { kubectl delete crd helmreleases.flux.weave.works > /dev/null 2>&1 } -fluxctl_install_cmd="fluxctl install --namespace "${FLUX_NAMESPACE}" --git-url=ssh://git@gitsrv/git-server/repos/cluster.git --git-email=foo" +fluxctl_install_cmd="fluxctl install --namespace ${FLUX_NAMESPACE} --git-url=ssh://git@gitsrv/git-server/repos/cluster.git --git-email=foo" function install_flux_with_fluxctl() { local eol=$'\n' # Use the local Flux image instead of the latest release, use a poll interval of 10s # (to make tests quicker) and disable registry polling (to avoid overloading kind) - $fluxctl_install_cmd | \ - sed 's%docker\.io/fluxcd/flux:.*%fluxcd/flux:latest%' | \ - sed "s%--git-email=foo%--git-email=foo\\$eol - --git-poll-interval=10s%" | \ - sed "s%--git-email=foo%--git-email=foo\\$eol - --sync-interval=10s%" | \ - sed "s%--git-email=foo%--git-email=foo\\$eol - --registry-exclude-image=\*%" | \ + $fluxctl_install_cmd | + sed 's%docker\.io/fluxcd/flux:.*%fluxcd/flux:latest%' | + sed "s%--git-email=foo%--git-email=foo\\$eol - --git-poll-interval=10s%" | + sed "s%--git-email=foo%--git-email=foo\\$eol - --sync-interval=10s%" | + sed "s%--git-email=foo%--git-email=foo\\$eol - --registry-exclude-image=\*%" | kubectl apply -f - kubectl -n "${FLUX_NAMESPACE}" rollout status deployment/flux # Add the known hosts file manually (it's much easier than editing the manifests to add a volume) - local flux_podname=$(kubectl get pod -n flux-e2e -l name=flux -o jsonpath="{['items'][0].metadata.name}") - kubectl exec -n "${FLUX_NAMESPACE}" "${flux_podname}" -- sh -c "echo '$(cat ${FIXTURES_DIR}/known_hosts)' > /root/.ssh/known_hosts" + local flux_podname + flux_podname=$(kubectl get pod -n flux-e2e -l name=flux -o jsonpath="{['items'][0].metadata.name}") + kubectl exec -n "${FLUX_NAMESPACE}" "${flux_podname}" -- sh -c "echo '${KNOWN_HOSTS}' > /root/.ssh/known_hosts" } function uninstall_flux_with_fluxctl() { diff --git a/test/e2e/lib/poll.bash b/test/e2e/lib/poll.bash index fe21a110c..44f9dcf03 100644 --- a/test/e2e/lib/poll.bash +++ b/test/e2e/lib/poll.bash @@ -19,8 +19,8 @@ function poll_until_true() { count=0 until eval "$check_cmd"; do echo -n '.' >&3 - sleep $wait_period - count=$(($count + 1)) + sleep "$wait_period" + count=$((count + 1)) if [[ ${count} -eq ${retries} ]]; then echo ' No more retries left!' >&3 return 1 # fail diff --git a/test/e2e/run.bash b/test/e2e/run.bash index cd42ff0e4..c520eadb4 100755 --- a/test/e2e/run.bash +++ b/test/e2e/run.bash @@ -2,16 +2,19 @@ set -o errexit -# This script runs the bats tests, first ensuring there is a kubernetes cluster available, +# This script runs the bats tests, first ensuring there is a kubernetes cluster available, # with a flux namespace and a git secret ready to use # Global variables to be used in the libraries/tests export FLUX_NAMESPACE=flux-e2e -export FLUX_ROOT_DIR=$(git rev-parse --show-toplevel) +FLUX_ROOT_DIR=$(git rev-parse --show-toplevel) +export FLUX_ROOT_DIR export E2E_DIR="${FLUX_ROOT_DIR}/test/e2e" export FIXTURES_DIR="${E2E_DIR}/fixtures" -export KNOWN_HOSTS=$(cat "${FIXTURES_DIR}/known_hosts") -export GITCONFIG=$(cat "${FIXTURES_DIR}/gitconfig") +KNOWN_HOSTS=$(cat "${FIXTURES_DIR}/known_hosts") +export KNOWN_HOSTS +GITCONFIG=$(cat "${FIXTURES_DIR}/gitconfig") +export GITCONFIG export DEMO_NAMESPACE=demo KIND_VERSION="v0.5.1" @@ -20,11 +23,11 @@ KIND_CACHE_PATH="${CACHE_DIR}/kind-$KIND_VERSION" KIND_CLUSTER=flux-e2e USING_KIND=false - +# shellcheck disable=SC1090 source "${E2E_DIR}/lib/defer.bash" # Check if there is a kubernetes cluster running, otherwise use Kind -if ! kubectl version > /dev/null 2>&1 ; then +if ! kubectl version > /dev/null 2>&1; then if [ ! -f "${KIND_CACHE_PATH}" ]; then echo '>>> Downloading Kind' mkdir -p "${CACHE_DIR}" @@ -35,7 +38,8 @@ if ! kubectl version > /dev/null 2>&1 ; then chmod +x "${FLUX_ROOT_DIR}/test/bin/kind" kind create cluster --name "${KIND_CLUSTER}" --wait 5m defer kind --name "${KIND_CLUSTER}" delete cluster > /dev/null 2>&1 || true - export KUBECONFIG="$(kind --name="${KIND_CLUSTER}" get kubeconfig-path)" + KUBECONFIG="$(kind --name="${KIND_CLUSTER}" get kubeconfig-path)" + export KUBECONFIG USING_KIND=true kubectl get pods --all-namespaces fi @@ -49,10 +53,13 @@ defer rm -f "${FIXTURES_DIR}/id_rsa" "${FIXTURES_DIR}/id_rsa.pub" kubectl create secret generic flux-git-deploy --namespace="${FLUX_NAMESPACE}" --from-file="${FIXTURES_DIR}/known_hosts" --from-file="${FIXTURES_DIR}/id_rsa" --from-file=identity="${FIXTURES_DIR}/id_rsa" --from-file="${FIXTURES_DIR}/id_rsa.pub" if [ "${USING_KIND}" = 'true' ]; then - echo '>>> Loading images into the Kind cluster' - kind --name "${KIND_CLUSTER}" load docker-image 'docker.io/fluxcd/flux:latest' + echo '>>> Loading images into the Kind cluster' + kind --name "${KIND_CLUSTER}" load docker-image 'docker.io/fluxcd/flux:latest' fi # Run the tests echo '>>> Running the tests' -(cd "${E2E_DIR}"; "${E2E_DIR}/bats/bin/bats" -t .) +( + cd "${E2E_DIR}" + "${E2E_DIR}/bats/bin/bats" -t . +)