Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

E2E test optimization for multi-distro support #319

Merged
merged 27 commits into from
Mar 5, 2022
Merged
Show file tree
Hide file tree
Changes from 26 commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
d3e65b2
Initial attempt at reworking e2e tests
YrrepNoj Feb 14, 2022
865e70f
adding the rest of the old e2e tests
YrrepNoj Feb 16, 2022
a439a6a
wip: cleaning up tests
YrrepNoj Feb 18, 2022
1c7e083
wip k3d, silly go mod
YrrepNoj Feb 18, 2022
fb82c4b
dear diary, did I do good?
jeff-mccoy Feb 18, 2022
d04a07b
change k3d version for testing to 5.2.1
YrrepNoj Feb 18, 2022
777dd64
cleanup e2e test for multi distro testing
YrrepNoj Feb 18, 2022
81df250
add unique github action for testing each e2e distro
YrrepNoj Feb 18, 2022
953d480
turns out its useful to build dependencies
YrrepNoj Feb 18, 2022
7390004
fix setup for k3s testing
YrrepNoj Feb 18, 2022
fc8f9e0
try to make k3s run as root during e2e pileine
YrrepNoj Feb 19, 2022
718a372
make sure we clean up kubeconfig after e2e test
YrrepNoj Feb 21, 2022
2083465
run k3s e2e test as root
YrrepNoj Feb 21, 2022
3bbde2d
wip, extend time and break apart build steps
YrrepNoj Feb 21, 2022
3ae1afe
doanlod dependencies early for k3s
YrrepNoj Feb 21, 2022
bf77ced
remove old e2e content
YrrepNoj Feb 22, 2022
107f10f
misc test code cleanup
YrrepNoj Feb 22, 2022
e604547
more test code cleanup
YrrepNoj Mar 1, 2022
e4874b7
add more docs to e2e README
YrrepNoj Mar 1, 2022
9a9e710
update key for registry1 e2e login
YrrepNoj Mar 1, 2022
d9b7a6c
Re-add cloud e2e test for the game example
YrrepNoj Mar 3, 2022
c13b70a
add k3s e2e workflow
YrrepNoj Mar 3, 2022
d077518
remove chat based e2e test
YrrepNoj Mar 4, 2022
e2bfd36
cleanup of e2e test code
YrrepNoj Mar 4, 2022
f6fc96c
Merge branch 'master' into 100-e2e-test-refresh
jeff-mccoy Mar 5, 2022
f915f8a
adr for e2e testing
YrrepNoj Mar 5, 2022
7aa6cd7
Merge branch 'master' into 100-e2e-test-refresh
jeff-mccoy Mar 5, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 0 additions & 15 deletions .github/workflows/slash-command-dispatch.yml

This file was deleted.

651 changes: 0 additions & 651 deletions .github/workflows/test-command.yml

This file was deleted.

20 changes: 20 additions & 0 deletions .github/workflows/test-k3d.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
name: e2e-k3d
on:
- pull_request

jobs:
build-and-test:
runs-on: ubuntu-latest
steps:
- name: Install GoLang
uses: actions/setup-go@v2
with:
go-version: 1.16.x
- name: Checkout Repo
uses: actions/checkout@v2
- name: Build CLI
run: make build-cli-linux
- name: Make Packages
run: make init-package package-example-game package-example-data-injection package-example-gitops-data
- name: Run Tests
run: TESTDISTRO=k3d make test-e2e
21 changes: 21 additions & 0 deletions .github/workflows/test-k3s.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
name: e2e-k3s
on:
- pull_request

jobs:
build-and-test:
runs-on: ubuntu-latest
steps:
- name: Install GoLang
uses: actions/setup-go@v2
with:
go-version: 1.16.x
- name: Checkout Repo
uses: actions/checkout@v2
- name: Build CLI
run: make build-cli-linux
- name: Make Packages
run: make init-package package-example-game package-example-data-injection package-example-gitops-data
- name: Run Tests
# NOTE: "PATH=$PATH" preserves the default user $PATH. This is needed to maintain the version of go installed in a previous step
run: sudo env "PATH=$PATH" TESTDISTRO=k3s make test-e2e
20 changes: 20 additions & 0 deletions .github/workflows/test-kind.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
name: e2e-kind
on:
- pull_request

jobs:
build-and-test:
runs-on: ubuntu-latest
steps:
- name: Install GoLang
uses: actions/setup-go@v2
with:
go-version: 1.16.x
- name: Checkout Repo
uses: actions/checkout@v2
- name: Build CLI
run: make build-cli-linux
- name: Make Packages
run: make init-package package-example-game package-example-data-injection package-example-gitops-data
- name: Run Tests
run: TESTDISTRO=kind make test-e2e
45 changes: 22 additions & 23 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ build-cli-linux: ## Build the Linux CLI
build-cli-mac: ## Build the Mac CLI
cd cli && $(MAKE) build-mac

build-cli: clean build-cli-linux build-cli-mac ## Build the CLI
build-cli: build-cli-linux build-cli-mac ## Build the CLI

init-package: ## Create the zarf init package, macos "brew install coreutils" first
$(ZARF_BIN) package create --confirm
Expand Down Expand Up @@ -78,25 +78,24 @@ package-example-gitops-data:
package-example-tiny-kafka:
cd examples/tiny-kafka && ../../$(ZARF_BIN) package create --confirm && mv zarf-package-* ../../build/

.PHONY: test-cloud-e2e-example-game
test-cloud-e2e-example-game: ## Runs the Doom game as an E2E test in the cloud. Requires access to an AWS account. Costs money. Make sure you ran the `build-cli`, `init-package`, and `package-example-game` targets first
cd test/e2e && go test ./... -run TestE2eExampleGame -v -timeout 1200s

.PHONY: test-cloud-e2e-gitea-and-grafana
test-cloud-e2e-gitea-and-grafana: ## E2E test of Gitea & Grafana. Requires access to an AWS account. Costs money. Make sure you ran the `build-cli` and `init-package` targets first
cd test/e2e && go test ./... -run TestGiteaAndGrafana -v -timeout 1200s

.PHONY: test-cloud-e2e-gitops
test-cloud-e2e-gitops: package-example-gitops-data ## E2E test of Gitops example. Requires access to an AWS account. Costs money. Make sure you ran the `build-cli` and `init-package` targets first
cd test/e2e && go test ./... -run TestGitopsExample -v -timeout 1200s

.PHONY: test-cloud-e2e-data-injection
test-cloud-e2e-data-injection: package-example-data-injection ## E2E test of the Data Injection example. Requires access to an AWS account. Costs money. Make sure you ran the `build-cli` and `init-package` targets first
cd test/e2e && go test ./... -run TestDataInjection -v -timeout 1200s

.PHONY: test-cloud-e2e-general-cli
test-cloud-e2e-general-cli: package-example-tiny-kafka ## Runs tests of the CLI that don't need a cluster
cd test/e2e && go test ./... -run TestGeneralCli -v -timeout 1200s

.PHONY: test-e2e
test-e2e: package-example-game test-cloud-e2e-example-game ## DEPRECATED - to be replaced by individual e2e test targets
# TODO: This can be cleaned up a little more when `zarf init` is able to provide the path to the `zarf-init.tar.zst`
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You actually don't have to do zarf init, when you run a package deploy or even zarf zarf-init.tar.zst, it should do the exact same thing now. Init is nothing more than a fixed shortcut right now to use the init package in the same directory.

.PHONY: test-new-e2e
test-e2e: ## Run e2e tests on a KiND cluster. All dependencies are assumed to be built and in the ./build directory
@ #Check to make sure all the packages we need exist
@if [ ! -f $(ZARF_BIN) ]; then\
$(MAKE) build-cli;\
fi
@if [ ! -f ./build/zarf-init.tar.zst ]; then\
$(MAKE) init-package;\
fi
@if [ ! -f ./build/zarf-package-appliance-demo-multi-games.tar.zst ]; then\
$(MAKE) package-example-game;\
fi
@if [ ! -f ./build/zarf-package-data-injection-demo.tar ]; then\
$(MAKE) package-example-data-injection;\
fi
@if [ ! -f ./build/zarf-package-gitops-service-data.tar.zst ]; then\
$(MAKE) package-example-gitops-data;\
fi

cd test/e2e && cp ../../build/zarf-init.tar.zst . && go test ./... -v -timeout 2400s && rm zarf-init.tar.zst
36 changes: 36 additions & 0 deletions docs/adr/0002-moving-e2e-tests-away-from-terratest.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# 2. Moving E2E Tests Away From Terratest

Date: 2022-03-04

## Status

Accepted

## Context

In previous releases of Zarf, the creation of the initialization package at the core of many of our E2E tests required repository secrets to login to registry1. Since this is an open-source project, anyone could submit a change to one of our GitHub workflows that could steal our secrets. In order to protect our secrets from any bad-actors we used [peter-evans/slash-command-dispatch@v2](https://github.com/peter-evans/slash-command-dispatch) so that only a maintainer would have the ability to run the E2E tests when a PR is submitted for review.

In the current version of Zarf (v0.15) images from registry1 are no longer needed to create the zarf-init.tar.zst. This means, given our current span of E2E tests, we no longer need to use repository secrets when running tests. This gives us the ability to reassess the way we do our E2E testing.

When considering how to handle the tests, some of the important additions we were considering were:
1. Ability to test against different kubernetes distributions
2. Ability to test against different linux distributions
3. Ability to run (at least some of) the E2E tests locally without relying on an ec2 instance - for quicker feedback loops when developing new features

## Decision

The previous E2E test code was not extensible enough to be reused to test Zarf against different kubernetes distributions. The test suite was refactored so that we could write a setup and teardown function for each kubernetes distribution we wanted to verify against and the test suite was then responsible for cycling through the different distributions. This gives us the ability to test multiple kubernetes distributions against the same exact test cases.

The individual test cases were also rewritten to not rely on terratest running a bash command over ssh. Instead, the test uses the locally built Zarf binary and example packages to validate expected behavior. This approach works both on local dev machines (linux/mac) and on the Ubuntu GitHub Runner that gets triggered when a pull request is created. This also has the positive side effect of not needing to wait several minutes for an ec2 instance to spin up for testing.

Since we no longer need repository secrets to run the E2E tests, we removed the requirement for a maintainer to use a `/test all` chatops command to dispatch the tests. Instead, there is a new test workflow defined for each kubernetes distribution we are verifying against and the tests get run automatically whenever a PR is created or updated.

When looking back at the list of 'important additions' we were considering above. All three are addressed with this approach. Testing against different kubernetes distributions is as simple as defining how to create and destroy the cluster. All of the test cases are runnable locally and then because of that testing on a linux distribution is possible by just switching over to another machine and running the same `make test-e2e` there. This also gives us the ability to test against cloud distributions like EKS! All you need is a valid kubeconfig and running `go test ./...` in the `./test/e2e` directory will run all of the test cases against the EKS cluster.

## Consequences

While it was not something we were doing before, testing directly on the GitHub Runner instead of using Terratest to test on an ec2 instance means that when we get around to adding automated testing of Zarf against different linux distrobutions we will want to have more discussions on if we want to use self-hosted runners of different OS's or if we want to go back to Terratest to stand up ec2 instances with different AMIs.

In the future, we will likely want to write E2E tests that use images that require repository secrets to access. When that happens we will want to bring back some form of 'maintainer action' to initiate the test workflow. Going back to [peter-evans/slash-command-dispatch@v2](https://github.com/peter-evans/slash-command-dispatch) might be the right answer for that but there will need to be more discussion to make sure the team agrees that's the best solution first.

As the amount of E2E tests we have grows, the longer it will take to get results back on each PR. Duhh! Paralyzing the tests on a single host will be difficult (but not impossible) because it means more logic will be needed in the test suite to make sure the host has enough resources to handle multiple clusters being run in parallel. The simpler solution would be to break out each of our tests into a new GitHub Workflow. This will easily mitigate the issue of tests taking long to run but also give us a lot more yaml to maintain. Either solution is valid but more team discussions will be needed as we get closer to needing it.
36 changes: 6 additions & 30 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,23 @@ go 1.16
require (
github.com/AlecAivazis/survey/v2 v2.3.2
github.com/alecthomas/jsonschema v0.0.0-20211228220459-151e3c21f49d
github.com/aws/aws-sdk-go v1.40.56 // indirect
github.com/derailed/k9s v0.25.18
github.com/distribution/distribution/v3 v3.0.0-20210804104954-38ab4c606ee3
github.com/docker/cli v20.10.12+incompatible
github.com/elazarl/goproxy v0.0.0-20190911111923-ecfe977594f1 // indirect
github.com/fatih/color v1.13.0
github.com/go-errors/errors v1.0.2-0.20180813162953-d98b870cc4e0 // indirect
github.com/go-git/go-git/v5 v5.4.2
github.com/go-logr/logr v1.2.2
github.com/goccy/go-yaml v1.9.5
github.com/google/go-containerregistry v0.8.0
github.com/gruntwork-io/terratest v0.38.2
github.com/mattn/go-colorable v0.1.12
github.com/mholt/archiver/v3 v3.5.1
github.com/mitchellh/go-wordwrap v1.0.1 // indirect
github.com/otiai10/copy v1.7.0
github.com/pterm/pterm v0.12.33
github.com/rancher/k3d/v5 v5.2.1
github.com/spf13/cobra v1.3.0
github.com/stretchr/testify v1.7.0
golang.org/x/crypto v0.0.0-20211215165025-cf75a172585e
Expand All @@ -26,36 +30,8 @@ require (
k8s.io/apimachinery v0.22.5
k8s.io/client-go v0.22.5
k8s.io/klog/v2 v2.40.1
sigs.k8s.io/kind v0.11.1
sigs.k8s.io/kustomize/api v0.8.11
sigs.k8s.io/kustomize/kyaml v0.11.0
sigs.k8s.io/yaml v1.3.0
)

replace (
// https://github.com/kubernetes/kubernetes/issues/79384#issuecomment-505627280
k8s.io/api => k8s.io/api v0.22.5
k8s.io/apiextensions-apiserver => k8s.io/apiextensions-apiserver v0.22.5 // indirect
k8s.io/apimachinery => k8s.io/apimachinery v0.22.5 // indirect
k8s.io/apiserver => k8s.io/apiserver v0.22.5
k8s.io/cli-runtime => k8s.io/cli-runtime v0.22.5
k8s.io/client-go => k8s.io/client-go v0.22.5
k8s.io/cloud-provider => k8s.io/cloud-provider v0.22.5
k8s.io/cluster-bootstrap => k8s.io/cluster-bootstrap v0.22.5
k8s.io/code-generator => k8s.io/code-generator v0.22.5
k8s.io/component-base => k8s.io/component-base v0.22.5
k8s.io/component-helpers => k8s.io/component-helpers v0.22.5
k8s.io/controller-manager => k8s.io/controller-manager v0.22.5
k8s.io/cri-api => k8s.io/cri-api v0.22.5
k8s.io/csi-translation-lib => k8s.io/csi-translation-lib v0.22.5
k8s.io/kube-aggregator => k8s.io/kube-aggregator v0.22.5
k8s.io/kube-controller-manager => k8s.io/kube-controller-manager v0.22.5
k8s.io/kube-proxy => k8s.io/kube-proxy v0.22.5
k8s.io/kube-scheduler => k8s.io/kube-scheduler v0.22.5
k8s.io/kubectl => k8s.io/kubectl v0.22.5
k8s.io/kubelet => k8s.io/kubelet v0.22.5
k8s.io/legacy-cloud-providers => k8s.io/legacy-cloud-providers v0.22.5
k8s.io/metrics => k8s.io/metrics v0.22.5
k8s.io/mount-utils => k8s.io/mount-utils v0.22.5
k8s.io/pod-security-admission => k8s.io/pod-security-admission v0.22.5
k8s.io/sample-apiserver => k8s.io/sample-apiserver v0.22.5
)
Loading