This document covers how to run all of the tests that are present in the Linkerd2 repo. Most of these tests are run in CI, but you can use the instructions here to run the tests from source. For more information about working in this repo, see the BUILD.md guide.
Note that all shell commands in this guide are expected to be run from the root
of this repo, unless otherwise indicated by a cd
command.
To run tests:
go test -cover -race ./...
To investigate code coverage:
cov=`mktemp`
go test -coverprofile=$cov ./...
go tool cover -html=$cov
To analyze and lint the Go code using golangci-lint, run:
bin/lint
Javascript dependencies are managed via yarn and webpack. We use jest as our test runner.
To fetch dependencies and run tests, run:
bin/web setup
bin/web test
# or alternatively:
cd web/app
yarn && NODE_ENV=test yarn webpack
yarn jest "$*"
For faster testing, run a subset of the tests by passing flags to jest.
Run tests on files that have changed since the last commit:
bin/web test -o
Run tests that match a spec name (regex):
bin/web test -t name-of-spec
Run watch mode:
bin/web test --watch # runs -o by default (tests only files changed since last commit)
bin/web test --watchAll # runs all tests after a change to a file
bin/shellcheck -x bin/*
The test/
directory contains a test suite that can be run to validate Linkerd
functionality via a series of end-to-end tests.
The integration test suite operates on your currently configured Kubernetes cluster. Prior to running the test suite, verify that:
- The Linkerd docker images you're trying to test have been built and are accessible to the Kubernetes cluster to which you are deploying
- The
kubectl
CLI has been configured to talk to that Kubernetes cluster - The namespace where the tests will install Linkerd does not already exist; by
default the namespace
l5d-integration
is used
You can use the bin/test-run
script to run the full suite of tests.
The bin/test-run
script requires an absolute path to a linkerd
binary to
test as the first argument. You can optionally pass the namespace where Linkerd
will be installed as the second argument.
$ bin/test-run
usage: test-run /path/to/linkerd [namespace]
It's also possible to run tests individually, using the go test
command. All
of the tests are located in the test/
directory, either at the root or in
subdirectories. The root test/install_test.go
test installs Linkerd, so that
must be run before any of the subdirectory tests (the bin/test-run
script does
this for you). The subdirectory tests are intended to be run independently of
each other, and in the future they may be run in parallel.
To run an individual test (e.g. the "get" test), first run the root test, and then run the subdirectory test. For instance:
go test -v ./test -integration-tests -linkerd /path/to/linkerd
go test -v ./test/get -integration-tests -linkerd /path/to/linkerd
You can run tests using your installed version of the linkerd
CLI. For
example, to run the full suite of tests using your installed CLI in the
"specialtest" namespace, run:
bin/test-run `which linkerd` specialtest
That will create multiple namespaces in your Kubernetes cluster:
$ kubectl get ns | grep specialtest
specialtest Active 4m
specialtest-egress-test Active 2m
specialtest-get-test Active 1m
...
To cleanup the namespaces after the test has finished, run:
bin/test-cleanup
You can also test a locally-built version of the linkerd
CLI. Note, however,
that this requires that you build the corresponding Linkerd docker images and
publish them to a docker registry that's accessible from the Kubernetes cluster
where you're running the tests. As a result, local testing mostly applies to
minikube, since you can build the
images directly into minikube's local docker registry, as described below.
To test your current branch on minikube, first build all of the Linkerd images in your minikube environment, by running:
DOCKER_TRACE=1 bin/mkube bin/docker-build
That command also copies the corresponding linkerd
binaries into the
target/cli
directory, and you can use the bin/linkerd
script to load those
binaries when running tests. To run tests using your local binary, run:
bin/test-run `pwd`/bin/linkerd
That will create multiple namespaces in your Kubernetes cluster:
$ kubectl get ns | grep l5d-integration
l5d-integration Active 4m
l5d-integration-egress-test Active 2m
l5d-integration-get-test Active 1m
...
To cleanup the namespaces after the test has finished, run:
bin/test-cleanup
We use WebdriverIO to test how the web dashboard looks and operates locally in Chrome. For cross-browser testing, we use SauceLabs, which runs simulataneous tests on different browsers in the cloud.
If you're new to the repo, make sure you've installed web dependencies via Yarn:
brew install yarn # if you don't already have yarn
bin/web setup
Then start up the dashboard at localhost:7777
. You can do that in one of two
ways:
# standalone
bin/web run
OR
# with webpack-dev-server
bin/web dev
To run a local WebdriverIO instance that will run the tests on a local instance of Chrome, run:
bin/web integration local
To run cross-browser tests via SauceLabs, you need to do a few things first:
-
Sign up for a (free) SauceLabs sub-account for the account 'buoyant'. If you are not a Buoyant staffer, the best way to get an account invite is to ask in the Linkerd Slack channel.
-
Once you have your username and key, set them as permanent environment variables. This keeps your credentials private, and means that everyone on the team can run the tests via their unique login without modifying the test files. Open your
~/.bash_profile
file and add:export SAUCE_USERNAME="your Sauce username" export SAUCE_ACCESS_KEY="your Sauce access key"
-
Now you'll download Sauce Connect, the proxy server that will open a secure tunnel between a SauceLabs VM and the Linkerd dashboard instance you're running on
localhost:7777
. You'll want to save it in a separate directory from the rest of your development files. After downloading it, navigate to that directory and start it up:SC=sc-4.5.3-osx # OSX example wget -O - https://saucelabs.com/downloads/$SC.zip | tar xfz - -C ~/ cd ~/$SC bin/sc -u $SAUCE_USERNAME -k $SAUCE_ACCESS_KEY
Wait until you see
Sauce Connect is up, you may start your tests
in your terminal. Open a separate terminal window and run:bin/web integration cloud
SauceLabs will start running the tests in the cloud. If any tests fail, you'll immediately get the URL in your terminal window with a video of the test and information about what happened. The test(s) will also appear in your SauceLabs archives a minute or so after they end. (Depending on time of day and server load, it may take longer for the tests to appear in the archives.)
-
When you're finished, close the tunnel by pressing
CTRL-C
in the Sauce Connect window. If you forget to do this, it will close on its own after a few minutes.
To add a new test, create a new subdirectory inside the test/
directory.
Configuration files, such as Kubernetes configs, should be placed inside a
testdata/
directory inside the test subdirectory that you created. Then create
a test file in the subdirectory that's suffixed with _test.go
. This test file
will be run automatically by the test runner script.
The tests rely heavily on the test helpers that are defined in the testutil/
directory. For a complete description of how to use the test helpers to write
your own tests, view the testutil
package's godoc, with:
godoc github.com/linkerd/linkerd2/testutil | less
The scale tests deploy a single Linkerd control-plane, and then scale up multiple sample apps across multiple replicas across multiple namespaces.
Prequisites:
- a
linkerd
CLI binary - Linkerd Docker images associated with the
linkerd
CLI binary - a Kubernetes cluster with sufficient resources to run 100s of pods
bin/test-scale
usage: test-scale /path/to/linkerd [namespace]
For example, to test a newly built Linkerd CLI:
bin/test-scale `pwd`/bin/linkerd
bin/test-cleanup
The bin/test-clouds
script runs the integration tests
against 4 cloud providers:
- Amazon (EKS)
- DigitalOcean (DO)
- Google (GKE)
- Microsoft (AKS)
This script assumes you have a working Kubernetes cluster set up on each Cloud provider, and that Kubernetes contexts are configured via environment variables.
For example:
export AKS=my-aks-cluster
export DO=do-nyc1-my-cluster
export EKS=arn:aws:eks:us-east-1:123456789012:cluster/my-cluster
export GKE=gke_my-project_us-east1-b_my-cluster
For more information on configuring access to multiple clusters, see: https://kubernetes.io/docs/tasks/access-application-cluster/configure-access-multiple-clusters/#define-clusters-users-and-contexts
bin/test-clouds `pwd`/bin/linkerd
To cleanup all integration tests:
bin/test-clouds-cleanup