# Linkerd2 Test Guide 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](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. ## Table of contents - [Unit tests](#unit-tests) - [Go](#go) - [JavaScript](#javascript) - [Shell](#shell) - [Integration tests](#integration-tests) - [Prerequisites](#prerequisites) - [Running tests](#running-tests) - [Writing tests](#writing-tests) ## Unit tests ### Go To run tests: ```bash go test -cover -race ./... ``` To investigate code coverage: ```bash cov=`mktemp` go test -coverprofile=$cov ./... go tool cover -html=$cov ``` #### Pretty-printed diffs for templated text When running `go test`, mismatched text is usually displayed as a compact diff. If you prefer to see the full text of the mismatch with colorized output, you can set the `LINKERD_TEST_PRETTY_DIFF` environment variable or run `go test ./cli/cmd/... --pretty-diff`. #### Updating templates When kubernetes templates change, several test fixtures usually need to be updated (in `cli/cmd/testdata/*.golden`). These golden files can be automatically regenerated with the command: ```sh go test ./cli/cmd/... --update ``` ### JavaScript JavaScript dependencies are managed via [yarn](https://yarnpkg.com/) and [webpack](https://webpack.js.org/). We use [jest](https://facebook.github.io/jest) as our test runner. To fetch dependencies and run tests, run: ```bash 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: ```bash bin/web test -o ``` Run tests that match a spec name (regex): ```bash bin/web test -t name-of-spec ``` Run watch mode: ```bash 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 ``` ### Shell ```bash bin/shellcheck -x bin/* ``` ## Integration tests The `test/integration` directory contains a test suite that can be run to validate Linkerd functionality via a series of end-to-end tests. ### Prerequisites #### Prerequisites for default behavior The integration tests will configure their own k3s clusters by default (using the k3d helper). There are no prerequisites for this test path. #### Prerequisites for existing cluster If integration tests should run on an existing Kubernetes cluster, then the `--skip-cluster-create` flag should be passed. This will disable the tests from creating their own clusters and instead use the current Kubernetes context. In this case, ensure the following: - The Linkerd docker images you're trying to test have been built and are accessible to the Kubernetes cluster to which you are deploying. If you're testing locally through a KinD or k3d cluster and don't want to push the images to a public registry, you can call `bin/image-load --kind|k3d` to load all the Linkerd images into those clusters. - The `kubectl` CLI has been configured to talk to that Kubernetes cluster ### Running tests You can use the `bin/tests` script to run one or all of the tests in the test suite. The `bin/tests` script requires an absolute path to a `linkerd` binary to test. Optional flags can be passed that change the testing behavior: - `--name`: Pass an argument with this flag to specify a specific test that should be run; all tests (except some special ones, see below) are run in the absence of this flag. Valid test names are included in the `bin/tests --help` output - `--skip-cluster-create`: Skip KinD cluster creation for each test and use an existing Kubernetes cluster - `--images`: (Primarily for CI) Loads images from the `image-archive/` directory into the KinD clusters created for each test View full help text: ```bash bin/tests --help ``` Run individual test: ```bash bin/tests --name upgrade /path/to/linkerd ``` #### Testing against the installed version of the CLI 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, run: ```bash bin/tests `which linkerd` ``` If using an existing cluster to run tests, the resources can be cleaned up manually with: ```bash bin/test-cleanup /path/to/linkerd ``` #### Testing against a locally-built version of the CLI You can also test a locally-built version of the `linkerd` CLI. First build all of the Linkerd images by running: ```bash 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: ```bash bin/tests $PWD/bin/linkerd ``` **Note**: As stated above, if running tests in an existing KinD cluster by passing `--skip-cluster-create`, `bin/kind-load` must be run so that the images are available to the cluster #### Special tests: cluster-domain, cni-calico-deep and multicluster When running `bin/tests` without specifying `--name` all tests except for `cluster-domain`, `cni-calico-deep` and `multicluster` are run, because these require creating the clusters with special configurations. To run any of these tests, invoke them explicitly with `--name` for the script to create the cluster (using k3d) and trigger the test: - `bin/tests --name cluster-domain`: This simply creates the cluster with a cluster domain setting different than the default `cluster.local`, then installs Linkerd and triggers some smoke tests. - `bin/tests --name cni-calico-deep`: This installs a cluster replacing the default CNI plugin (which for k3s is Flannel) with the Calico CNI plugin, then installs the Linkerd CNI plugin and the Linkerd control plane, and finally triggers the full suite of deep tests. - `bin/tests --name multicluster`: Two k3d clusters are installed each one with separate instances of Linkerd sharing the same trust root. Then the multicluster component is installed, both clusters are linked together and a test ensures exported services can be reached between the two clusters. #### Testing the dashboard If you're new to the repo, make sure you've installed web dependencies via [Yarn](https://yarnpkg.com): ```bash 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: ```bash # standalone bin/web run ``` OR ```bash # with webpack-dev-server bin/web dev ``` ## Writing tests 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: ```bash godoc github.com/linkerd/linkerd2/testutil | less ``` ## Scale tests The scale tests deploy a single Linkerd control-plane, and then scale up multiple sample apps across multiple replicas across multiple namespaces. Prerequisites: - a `linkerd` CLI binary - Linkerd Docker images associated with the `linkerd` CLI binary - a Kubernetes cluster with sufficient resources to run 100s of pods ## Run tests ```bash bin/test-scale usage: test-scale /path/to/linkerd [namespace] ``` For example, to test a newly built Linkerd CLI: ```bash bin/test-scale `pwd`/bin/linkerd ``` ## Cleanup ```bash bin/test-cleanup /path/to/linkerd ``` ## Test against multiple cloud providers The [`bin/test-clouds`](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: ```bash 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: ```bash bin/test-clouds `pwd`/bin/linkerd ``` To cleanup all integration tests: ```bash bin/test-clouds-cleanup ```