Skip to content

Commit

Permalink
e2e tests, rebase of 606 (#658)
Browse files Browse the repository at this point in the history
* Easy e2e tests

This patch updates documentation, the Makefile, and creates some new
programs under the `hack` directory in order to make e2e testing as easy
as possible, both locally and as a invocation point for Prow jobs.

* Makefile: Remove commented out deps

Signed-off-by: Naadir Jeewa <[email protected]>
  • Loading branch information
randomvariable authored and k8s-ci-robot committed Mar 14, 2019
1 parent 78f45a1 commit 92bda1a
Show file tree
Hide file tree
Showing 12 changed files with 304 additions and 22 deletions.
13 changes: 13 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,19 @@ help: ## Display this help
test: generate verify ## Run tests
bazel test --nosandbox_debug //pkg/... //cmd/... $(BAZEL_ARGS)

.PHONY: integration
integration: generate verify ## Run integraion tests
bazel test --define='gotags=integration' --test_output all //test/integration/...

JANITOR_ENABLED ?= 0
.PHONY: e2e
e2e: generate verify ## Run e2e tests
JANITOR_ENABLED=$(JANITOR_ENABLED) ./hack/e2e.sh

.PHONY: e2e-janitor
e2e-janitor:
./hack/e2e-aws-janitor.sh

## --------------------------------------
## Docker
## --------------------------------------
Expand Down
59 changes: 59 additions & 0 deletions docs/development.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@
- [Building and pushing dev images to GCR](#building-and-pushing-dev-images-to-gcr)
- [Building and pushing dev images to custom (non GCR) container registry](#building-and-pushing-dev-images-to-custom-non-gcr-container-registry)
- [Running clusterctl](#running-clusterctl)
- [Executing unit tests](#executing-unit-tests)
- [Executing integration tests](#executing-integration-tests)
- [Executing e2e tests](#executing-e2e-tests)
- [Executing e2e tests with Boskos](#executing-e2e-tests-with-boskos)
- [Automated Testing](#automated-testing)
- [Mocks](#mocks)
- [Troubleshooting](#troubleshooting)
Expand Down Expand Up @@ -130,6 +134,61 @@ manifests creating a target cluster in AWS. After this is finished you will have
a kubeconfig copied locally. You can debug most issues by SSHing into the
instances that have been created and reading `/var/log/cloud-init-output.log`.

#### Executing unit tests

`make test` executes the project's unit tests. These tests do not stand up a
Kubernetes cluster, nor do they have external dependencies.

#### Executing integration tests
`make integration` executes the project's integration tests. These tests stand
up a local Kubernetes cluster using Kind in order to deploy the project's CRDs.
The tested controller is **not** used to deploy Kubernetes to AWS.

These tests depend on the following binaries in the system path:
* `kind`

#### Executing e2e tests
`make e2e` executes the project's end-to-end tests with AWS account
information parsed from the environment.

These tests stand up a local Kubernetes cluster using Kind. The project's CRDs
and controllers are deployed to the Kind cluster and are used to deploy
Kubernetes to AWS.

The AWS janitor is disabled by default. `JANITOR_ENABLED=1 make e2e` executes
janitor immediately after running the e2e tests.

Please keep in mind that the janitor is highly destructive and should not
be executed against shared AWS accounts or preferrably AWS accounts not
dedicated to testing this project.

These tests depend on the following binaries in the system path:
* `kind`
* `aws-janitor`

#### Executing e2e tests with Boskos
`BOSKOS_HOST=http://boskos make e2e` executes the project's end-to-end tests
with AWS account information acquired from a Boskos host.

These tests stand up a local Kubernetes cluster using Kind. The project's CRDs
and controllers are deployed to the Kind cluster and are used to deploy
Kubernetes to AWS.

The AWS janitor is disabled by default.
`BOSKOS_HOST=http://boskos JANITOR_ENABLED=1 make e2e` executes
the janitor immediately after running the e2e tests.

Please keep in mind that the janitor is highly destructive and should not
be executed against shared AWS accounts or preferrably AWS accounts not
dedicated to testing this project.

`BOSKOS_HOST=http://boskos make e2e` executes the project's
end-to-end tests with the janitor disabled.

These tests depend on the following binaries in the system path:
* `kind`
* `aws-janitor`

### Automated Testing

#### Mocks
Expand Down
6 changes: 3 additions & 3 deletions hack/checkout_account.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@

body = json.load(resp)
conn.close()
print 'export BOSKOS_RESOURCE_NAME="%s"' % body['name']
print 'export AWS_ACCESS_KEY_ID="%s"' % body['userdata']['access-key-id']
print 'export AWS_SECRET_ACCESS_KEY="%s"' % body['userdata']['secret-access-key']
print 'export BOSKOS_RESOURCE_NAME="%s";' % body['name']
print 'export AWS_ACCESS_KEY_ID="%s";' % body['userdata']['access-key-id']
print 'export AWS_SECRET_ACCESS_KEY="%s";' % body['userdata']['secret-access-key']

9 changes: 9 additions & 0 deletions hack/e2e-aws-disallowed.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# This file is a line-delimited list of MD5 checksums of AWS keys that should
# not be used with the CAPA e2e tests or any janitorial work that occurs after
# the test execution.
#
# To add a new key to the file, execute:
#
# $ echo "${AWS_ACCESS_KEY_ID}" | { md5sum 2>/dev/null || md5; } | awk '{print $1}' >> hack/e2e-aws-disallowed.txt

afbf8e5c5622470940b050594f82c47e
45 changes: 45 additions & 0 deletions hack/e2e-aws-janitor.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
#!/bin/bash

# Copyright 2019 The Kubernetes Authors.
#
# 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.

################################################################################
# usage: e2e-aws-janitor.sh [FLAGS]
# This program is a wrapper for running the aws-janitor command with a check
# that prevents disallowed AWS keys from being used.
#
# FLAGS
# To see a full list of flags supported by this program, run "aws-janitor -h"
################################################################################

set -o errexit
set -o nounset
set -o pipefail

REPO_ROOT=$(dirname "${BASH_SOURCE[0]}")/..
cd "${REPO_ROOT}" || exit 1

# Require the aws-janitor command.
command -v aws-janitor >/dev/null 2>&1 || \
{ echo "aws-janitor not found" 1>&2; exit 1; }

# Prevent a disallowed AWS key from being used.
if grep -iqF "$(echo "${AWS_ACCESS_KEY_ID-}" | \
{ md5sum 2>/dev/null || md5; } | \
awk '{print $1}')" hack/e2e-aws-disallowed.txt; then
echo "The provided AWS key is not allowed" 1>&2
exit 1
fi

exec aws-janitor -all "${@-}"
46 changes: 46 additions & 0 deletions hack/e2e-aws-resources-list.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
#!/bin/bash

# Copyright 2019 The Kubernetes Authors.
#
# 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.

set -o errexit
set -o nounset
set -o pipefail

################################################################################
# usage: e2e-aws-resources-list.sh [FLAGS]
# This program is a wrapper for running the aws-resources-list command with
# a check that prevents disallowed AWS keys from being used.
#
# FLAGS
# To see a full list of flags supported by this program, run
# "aws-resources-list -h"
################################################################################

REPO_ROOT=$(dirname "${BASH_SOURCE[0]}")/..
cd "${REPO_ROOT}" || exit 1

# Require the aws-resources-list command.
command -v aws-resources-list >/dev/null 2>&1 || \
{ echo "aws-resources-list not found" 1>&2; exit 1; }

# Prevent a disallowed AWS key from being used.
if grep -iqF "$(echo "${AWS_ACCESS_KEY_ID-}" | \
{ md5sum 2>/dev/null || md5; } | \
awk '{print $1}')" hack/e2e-aws-disallowed.txt; then
echo "The provided AWS key is not allowed" 1>&2
exit 1
fi

exec aws-resources-list "${@-}"
88 changes: 88 additions & 0 deletions hack/e2e.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
#!/bin/bash

# Copyright 2019 The Kubernetes Authors.
#
# 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.

################################################################################
# usage: e2e.sh
# This program runs the e2e tests.
#
# ENVIRONMENT VARIABLES
# JANITOR_ENABLED
# Set to 1 to run the aws-janitor command after running the e2e tests.
################################################################################

set -o nounset
set -o pipefail

REPO_ROOT=$(dirname "${BASH_SOURCE[0]}")/..
cd "${REPO_ROOT}" || exit 1

# If BOSKOS_HOST is set then acquire an AWS account from Boskos.
if [ -n "${BOSKOS_HOST:-}" ]; then
# Check out the account from Boskos and store the produced environment
# variables in a temporary file.
account_env_var_file="$(mktemp)"
python hack/checkout_account.py 1>"${account_env_var_file}"
checkout_account_status="${?}"

# If the checkout process was a success then load the account's
# environment variables into this process.
# shellcheck disable=SC1090
[ "${checkout_account_status}" = "0" ] && . "${account_env_var_file}"

# Always remove the account environment variable file. It contains
# sensitive information.
rm -f "${account_env_var_file}"

if [ ! "${checkout_account_status}" = "0" ]; then
echo "error getting account from boskos" 1>&2
exit "${checkout_account_status}"
fi
fi

# Prevent a disallowed AWS key from being used.
if grep -iqF "$(echo "${AWS_ACCESS_KEY_ID-}" | \
{ md5sum 2>/dev/null || md5; } | \
awk '{print $1}')" hack/e2e-aws-disallowed.txt; then
echo "The provided AWS key is not allowed" 1>&2
exit 1
fi

bazel test --define='gotags=e2e' --test_output all //test/e2e/...
bazel_status="${?}"

# If the artifacts environment variable is set then coalesce the test results.
[ -z "${ARTIFACTS:-}" ] || python hack/coalesce.py

# If Boskos is being used then release the AWS account back to Boskos.
[ -z "${BOSKOS_HOST:-}" ] || hack/checkin_account.py

# The janitor is typically not run as part of the e2e process, but rather
# in a parallel process via a service on the same cluster that runs Prow and
# Boskos.
#
# However, setting JANITOR_ENABLED=1 tells this program to run the janitor
# after the e2e test is executed.
if [ "${JANITOR_ENABLED:-0}" = "1" ]; then
if ! command -v aws-janitor >/dev/null 2>&1; then
echo "skipping janitor; aws-janitor not found" 1>&2
else
aws-janitor -all -v 2
fi
else
echo "skipping janitor; JANITOR_ENABLED=${JANITOR_ENABLED}" 1>&2
fi

exit "${bazel_status}"
9 changes: 5 additions & 4 deletions hack/print-workspace-status.sh
Original file line number Diff line number Diff line change
Expand Up @@ -79,8 +79,9 @@ GIT_VERSION ${GIT_VERSION-}
GIT_BRANCH ${GIT_BRANCH-}
GIT_RELEASE_TAG ${GIT_RELEASE_TAG-}
GIT_RELEASE_COMMIT ${GIT_RELEASE_COMMIT-}
AWS_ACCESS_KEY_ID ${AWS_ACCESS_KEY_ID-}
AWS_SECRET_ACCESS_KEY ${AWS_SECRET_ACCESS_KEY-}
AWS_SESSION_TOKEN ${AWS_SESSION_TOKEN-}
AWS_REGION ${AWS_REGION:-us-east-1}
STABLE_AWS_ACCESS_KEY_ID ${AWS_ACCESS_KEY_ID-}
STABLE_AWS_SECRET_ACCESS_KEY ${AWS_SECRET_ACCESS_KEY-}
STABLE_AWS_DEFAULT_REGION ${AWS_DEFAULT_REGION-}
STABLE_AWS_REGION ${AWS_REGION:-${AWS_DEFAULT_REGION-}}
STABLE_AWS_SESSION_TOKEN ${AWS_SESSION_TOKEN-}
EOF
2 changes: 1 addition & 1 deletion scripts/ci-bazel-integration.sh
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ set -o nounset
set -o pipefail

REPO_ROOT=$(dirname "${BASH_SOURCE[0]}")/..

cd "${REPO_ROOT}" || exit 1

bazel test --define='gotags=integration' --test_output all //test/integration/...
bazel_status="${?}"
python hack/coalesce.py
Expand Down
30 changes: 23 additions & 7 deletions test/e2e/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -38,13 +38,15 @@ go_test(
"-credFile=$(location manifests/provider-credentials.profile)",
"-clusterYAML=$(location manifests/cluster.yaml)",
"-machineYAML=$(location manifests/machines.yaml)",
"-regionFile=$(location region.txt)",
],
data = [
"manifests/addons.yaml",
"manifests/cluster.yaml",
"manifests/machines.yaml",
"manifests/provider-credentials.profile",
"provider-components-e2e.yaml",
"region.txt",
"//cmd/manager:manager-amd64.tar",
"@io_k8s_kubernetes//cmd/kubectl:kubectl",
"@io_k8s_sigs_kind//:kind",
Expand Down Expand Up @@ -119,9 +121,9 @@ genrule(
outs = ["manifests/provider-credentials.profile"],
cmd = " && ".join([
"touch $@",
"export AWS_ACCESS_KEY_ID=$$(grep ^AWS_ACCESS_KEY_ID bazel-out/volatile-status.txt | cut -f2 -d\" \")",
"export AWS_SECRET_ACCESS_KEY=$$(grep ^AWS_SECRET_ACCESS_KEY bazel-out/volatile-status.txt | cut -f2 -d\" \")",
"export AWS_SESSION_TOKEN=$$(grep ^AWS_SESSION_TOKEN bazel-out/volatile-status.txt | cut -f2 -d\" \")",
"export AWS_ACCESS_KEY_ID=$$(grep ^STABLE_AWS_ACCESS_KEY_ID bazel-out/stable-status.txt | cut -f2 -d\" \")",
"export AWS_SECRET_ACCESS_KEY=$$(grep ^STABLE_AWS_SECRET_ACCESS_KEY bazel-out/stable-status.txt | cut -f2 -d\" \")",
"export AWS_SESSION_TOKEN=$$(grep ^STABLE_AWS_SESSION_TOKEN bazel-out/stable-status.txt | cut -f2 -d\" \")",
"echo '[default]' >> $@",
"echo aws_access_key_id = $$AWS_ACCESS_KEY_ID >> $@",
"echo aws_secret_access_key = $$AWS_SECRET_ACCESS_KEY >> $@",
Expand All @@ -136,13 +138,15 @@ genrule(
outs = ["manifests/provider-credentials.sh"],
cmd = " && ".join([
"touch $@",
"export AWS_ACCESS_KEY_ID=$$(grep ^AWS_ACCESS_KEY_ID bazel-out/volatile-status.txt | cut -f2 -d\" \")",
"export AWS_SECRET_ACCESS_KEY=$$(grep ^AWS_SECRET_ACCESS_KEY bazel-out/volatile-status.txt | cut -f2 -d\" \")",
"export AWS_SESSION_TOKEN=$$(grep ^AWS_SESSION_TOKEN bazel-out/volatile-status.txt | cut -f2 -d\" \")",
"export AWS_REGION=$$(grep ^AWS_REGION bazel-out/volatile-status.txt | cut -f2 -d\" \")",
"export AWS_ACCESS_KEY_ID=$$(grep ^STABLE_AWS_ACCESS_KEY_ID bazel-out/stable-status.txt | cut -f2 -d\" \")",
"export AWS_SECRET_ACCESS_KEY=$$(grep ^STABLE_AWS_SECRET_ACCESS_KEY bazel-out/stable-status.txt | cut -f2 -d\" \")",
"export AWS_SESSION_TOKEN=$$(grep ^STABLE_AWS_SESSION_TOKEN bazel-out/stable-status.txt | cut -f2 -d\" \")",
"export AWS_DEFAULT_REGION=$$(grep ^STABLE_AWS_DEFAULT_REGION bazel-out/stable-status.txt | cut -f2 -d\" \")",
"export AWS_REGION=$$(grep ^STABLE_AWS_REGION bazel-out/stable-status.txt | cut -f2 -d\" \")",
"echo export AWS_ACCESS_KEY_ID=$$AWS_ACCESS_KEY_ID >> $@",
"echo export AWS_SECRET_ACCESS_KEY=$$AWS_SECRET_ACCESS_KEY >> $@",
"echo export AWS_SESSION_TOKEN=$$AWS_SESSION_TOKEN >> $@",
"echo export AWS_DEFAULT_REGION=$$AWS_DEFAULT_REGION >> $@",
"echo export AWS_REGION=$$AWS_REGION >> $@",
]),
stamp = 1,
Expand All @@ -164,3 +168,15 @@ genrule(
tools = ["@io_k8s_sigs_kustomize//:kustomize"],
visibility = ["//visibility:public"],
)

genrule(
name = "e2e-region",
outs = ["region.txt"],
cmd = " && ".join([
"touch $@",
"export AWS_DEFAULT_REGION=$$(grep ^STABLE_AWS_DEFAULT_REGION bazel-out/stable-status.txt | cut -f2 -d\" \")",
"echo $$AWS_DEFAULT_REGION >> $@",
]),
stamp = 1,
visibility = ["//visibility:private"],
)
Loading

0 comments on commit 92bda1a

Please sign in to comment.