...
1# Linkerd2 Test Guide
2
3This document covers how to run all of the tests that are present in the
4Linkerd2 repo. Most of these tests are run in CI, but you can use the
5instructions here to run the tests from source. For more information about
6working in this repo, see the [BUILD.md](BUILD.md) guide.
7
8Note that all shell commands in this guide are expected to be run from the root
9of this repo, unless otherwise indicated by a `cd` command.
10
11## Table of contents
12
13- [Unit tests](#unit-tests)
14 - [Go](#go)
15 - [JavaScript](#javascript)
16 - [Shell](#shell)
17- [Integration tests](#integration-tests)
18 - [Prerequisites](#prerequisites)
19 - [Running tests](#running-tests)
20 - [Writing tests](#writing-tests)
21
22## Unit tests
23
24### Go
25
26To run tests:
27
28```bash
29go test -cover -race ./...
30```
31
32To investigate code coverage:
33
34```bash
35cov=`mktemp`
36go test -coverprofile=$cov ./...
37go tool cover -html=$cov
38```
39
40#### Pretty-printed diffs for templated text
41
42When running `go test`, mismatched text is usually displayed as a compact diff.
43If you prefer to see the full text of the mismatch with colorized output, you
44can set the `LINKERD_TEST_PRETTY_DIFF` environment variable or run `go test
45./cli/cmd/... --pretty-diff`.
46
47#### Updating templates
48
49When kubernetes templates change, several test fixtures usually need to be
50updated (in `cli/cmd/testdata/*.golden`). These golden files can be
51automatically regenerated with the command:
52
53```sh
54go test ./cli/cmd/... --update
55```
56
57### JavaScript
58
59JavaScript dependencies are managed via [yarn](https://yarnpkg.com/) and
60[webpack](https://webpack.js.org/). We use
61[jest](https://facebook.github.io/jest) as our test runner.
62
63To fetch dependencies and run tests, run:
64
65```bash
66bin/web setup
67bin/web test
68
69# or alternatively:
70
71cd web/app
72yarn && NODE_ENV=test yarn webpack
73yarn jest "$*"
74```
75
76For faster testing, run a subset of the tests by passing flags to jest.
77
78Run tests on files that have changed since the last commit:
79
80```bash
81bin/web test -o
82```
83
84Run tests that match a spec name (regex):
85
86```bash
87bin/web test -t name-of-spec
88```
89
90Run watch mode:
91
92```bash
93bin/web test --watch # runs -o by default (tests only files changed since last commit)
94bin/web test --watchAll # runs all tests after a change to a file
95```
96
97### Shell
98
99```bash
100bin/shellcheck -x bin/*
101```
102
103## Integration tests
104
105The `test/integration` directory contains a test suite that can be run to
106validate Linkerd functionality via a series of end-to-end tests.
107
108### Prerequisites
109
110#### Prerequisites for default behavior
111
112The integration tests will configure their own k3s clusters by default (using
113the k3d helper). There are no prerequisites for this test path.
114
115#### Prerequisites for existing cluster
116
117If integration tests should run on an existing Kubernetes cluster, then the
118`--skip-cluster-create` flag should be passed. This will disable the tests from
119creating their own clusters and instead use the current Kubernetes context.
120
121In this case, ensure the following:
122
123- The Linkerd docker images you're trying to test have been built and are
124 accessible to the Kubernetes cluster to which you are deploying.
125 If you're testing locally through a KinD or k3d cluster and don't want to push
126 the images to a public registry, you can call `bin/image-load --kind|k3d` to
127 load all the Linkerd images into those clusters.
128- The `kubectl` CLI has been configured to talk to that Kubernetes cluster
129
130### Running tests
131
132You can use the `bin/tests` script to run one or all of the tests in the test
133suite.
134
135The `bin/tests` script requires an absolute path to a `linkerd` binary to test.
136
137Optional flags can be passed that change the testing behavior:
138
139- `--name`: Pass an argument with this flag to specify a specific test that
140 should be run; all tests (except some special ones, see below) are run in the
141 absence of this flag. Valid test names are included in the `bin/tests --help`
142 output
143- `--skip-cluster-create`: Skip KinD cluster creation for each test and use an
144 existing Kubernetes cluster
145- `--images`: (Primarily for CI) Loads images from the `image-archive/`
146 directory into the KinD clusters created for each test
147
148View full help text:
149
150```bash
151bin/tests --help
152```
153
154Run individual test:
155
156```bash
157bin/tests --name upgrade /path/to/linkerd
158```
159
160#### Testing against the installed version of the CLI
161
162You can run tests using your installed version of the `linkerd` CLI. For
163example, to run the full suite of tests using your installed CLI, run:
164
165```bash
166bin/tests `which linkerd`
167```
168
169If using an existing cluster to run tests, the resources can be cleaned up
170manually with:
171
172```bash
173bin/test-cleanup /path/to/linkerd
174```
175
176#### Testing against a locally-built version of the CLI
177
178You can also test a locally-built version of the `linkerd` CLI.
179
180First build all of the Linkerd images by running:
181
182```bash
183bin/docker-build
184```
185
186That command also copies the corresponding `linkerd` binaries into the
187`target/cli` directory, and you can use the `bin/linkerd` script to load those
188binaries when running tests. To run tests using your local binary, run:
189
190```bash
191bin/tests $PWD/bin/linkerd
192```
193
194**Note**: As stated above, if running tests in an existing KinD cluster by
195passing `--skip-cluster-create`, `bin/kind-load` must be run so that the images are
196available to the cluster
197
198#### Special tests: cluster-domain, cni-calico-deep and multicluster
199
200When running `bin/tests` without specifying `--name` all tests except for
201`cluster-domain`, `cni-calico-deep` and `multicluster` are run, because these require
202creating the clusters with special configurations. To run any of these tests,
203invoke them explicitly with `--name` for the script to create the cluster (using
204k3d) and trigger the test:
205
206- `bin/tests --name cluster-domain`: This simply creates the cluster with a
207 cluster domain setting different than the default `cluster.local`, then
208 installs Linkerd and triggers some smoke tests.
209- `bin/tests --name cni-calico-deep`: This installs a cluster replacing the
210 default CNI plugin (which for k3s is Flannel) with the Calico CNI plugin, then
211 installs the Linkerd CNI plugin and the Linkerd control plane, and finally
212 triggers the full suite of deep tests.
213- `bin/tests --name multicluster`: Two k3d clusters are installed each one with
214 separate instances of Linkerd sharing the same trust root. Then the
215 multicluster component is installed, both clusters are linked together and a
216 test ensures exported services can be reached between the two clusters.
217
218#### Testing the dashboard
219
220If you're new to the repo, make sure you've installed web dependencies via
221[Yarn](https://yarnpkg.com):
222
223```bash
224brew install yarn # if you don't already have yarn
225bin/web setup
226```
227
228Then start up the dashboard at `localhost:7777`. You can do that in one of two
229ways:
230
231```bash
232# standalone
233bin/web run
234```
235
236OR
237
238```bash
239# with webpack-dev-server
240bin/web dev
241```
242
243## Writing tests
244
245To add a new test, create a new subdirectory inside the `test/` directory.
246Configuration files, such as Kubernetes configs, should be placed inside a
247`testdata/` directory inside the test subdirectory that you created. Then create
248a test file in the subdirectory that's suffixed with `_test.go`. This test file
249will be run automatically by the test runner script.
250
251The tests rely heavily on the test helpers that are defined in the `testutil/`
252directory. For a complete description of how to use the test helpers to write
253your own tests, view the `testutil` package's godoc, with:
254
255```bash
256godoc github.com/linkerd/linkerd2/testutil | less
257```
258
259## Scale tests
260
261The scale tests deploy a single Linkerd control-plane, and then scale up
262multiple sample apps across multiple replicas across multiple namespaces.
263
264Prerequisites:
265
266- a `linkerd` CLI binary
267- Linkerd Docker images associated with the `linkerd` CLI binary
268- a Kubernetes cluster with sufficient resources to run 100s of pods
269
270## Run tests
271
272```bash
273bin/test-scale
274usage: test-scale /path/to/linkerd [namespace]
275```
276
277For example, to test a newly built Linkerd CLI:
278
279```bash
280bin/test-scale `pwd`/bin/linkerd
281```
282
283## Cleanup
284
285```bash
286bin/test-cleanup /path/to/linkerd
287```
288
289## Test against multiple cloud providers
290
291The [`bin/test-clouds`](bin/test-clouds) script runs the integration tests
292against 4 cloud providers:
293
294- Amazon (EKS)
295- DigitalOcean (DO)
296- Google (GKE)
297- Microsoft (AKS)
298
299This script assumes you have a working Kubernetes cluster set up on each Cloud
300provider, and that Kubernetes contexts are configured via environment variables.
301
302For example:
303
304```bash
305export AKS=my-aks-cluster
306export DO=do-nyc1-my-cluster
307export EKS=arn:aws:eks:us-east-1:123456789012:cluster/my-cluster
308export GKE=gke_my-project_us-east1-b_my-cluster
309```
310
311For more information on configuring access to multiple clusters, see:
312<https://kubernetes.io/docs/tasks/access-application-cluster/configure-access-multiple-clusters/#define-clusters-users-and-contexts>
313
314```bash
315bin/test-clouds `pwd`/bin/linkerd
316```
317
318To cleanup all integration tests:
319
320```bash
321bin/test-clouds-cleanup
322```
View as plain text