Files
tendermint/test/e2e
William Banfield 5ba0d131c4 e2e: setup testing for multi-version (#9819)
This pull requests sets up the e2e tests to be able to support multiple versions within the same test network. This is achieved through a few simple changes:

* Each node takes a `version` parameter in the testnet manifest. This dictates which version of the testapp to use. If not set, the locally available version is used.
* Adds a `testapp-docker.yml` workflow that publishes the testapp to docker hub so that tagged versions may be available for use in a multi-version test network.

This change does not actually add a testnetwork that does multi-version testing. Since no previous versions of the testapp have been published to dockerhub, there are not old versions available to test against. We'll either need to configure this after the next minor release which will trigger a testapp to be pushed to dockerhub, or push an image from the previous version of Tendermint so that the multiversion test has an old version to pull.

#### PR checklist

- [ ] Tests written/updated, or no tests needed
- [ ] `CHANGELOG_PENDING.md` updated, or no changelog entry needed
- [ ] Updated relevant documentation (`docs/`) and code comments, or no
      documentation updates needed
2022-12-02 18:37:33 +00:00
..
2022-08-01 17:15:03 +02:00

End-to-End Tests

Spins up and tests Tendermint networks in Docker Compose based on a testnet manifest. To run the CI testnet:

make
./build/runner -f networks/ci.toml

This creates and runs a testnet named ci under networks/ci/ (determined by the manifest filename).

Testnet Manifests

Testnets are specified as TOML manifests. For an example see networks/ci.toml, and for documentation see pkg/manifest.go.

Random Testnet Generation

Random (but deterministic) combinations of testnets can be generated with generator:

./build/generator -d networks/generated/

# Split networks into 8 groups (by filename)
./build/generator -g 8 -d networks/generated/

Multiple testnets can be run with the run-multiple.sh script:

./run-multiple.sh networks/generated/gen-group3-*.toml

Test Stages

The test runner has the following stages, which can also be executed explicitly by running ./build/runner -f <manifest> <stage>:

  • setup: generates configuration files.

  • start: starts Docker containers.

  • load: generates a transaction load against the testnet nodes.

  • perturb: runs any requested perturbations (e.g. node restarts or network disconnects).

  • wait: waits for a few blocks to be produced, and for all nodes to catch up to it.

  • test: runs test cases in tests/ against all nodes in a running testnet.

  • stop: stops Docker containers.

  • cleanup: removes configuration files and Docker containers/networks.

Auxiliary commands:

  • logs: outputs all node logs.

  • tail: tails (follows) node logs until canceled.

Tests

Test cases are written as normal Go tests in tests/. They use a testNode() helper which executes each test as a parallel subtest for each node in the network.

Running Manual Tests

To run tests manually, set the E2E_MANIFEST environment variable to the path of the testnet manifest (e.g. networks/ci.toml) and run them as normal, e.g.:

./build/runner -f networks/ci.toml start
E2E_MANIFEST=networks/ci.toml go test -v ./tests/...

Optionally, E2E_NODE specifies the name of a single testnet node to test.

These environment variables can also be specified in tests/e2e_test.go to run tests from an editor or IDE:

func init() {
	// This can be used to manually specify a testnet manifest and/or node to
	// run tests against. The testnet must have been started by the runner first.
	os.Setenv("E2E_MANIFEST", "networks/ci.toml")
	os.Setenv("E2E_NODE", "validator01")
}

Debugging Failures

If a command or test fails, the runner simply exits with an error message and non-zero status code. The testnet is left running with data in the testnet directory, and can be inspected with e.g. docker ps, docker logs, or ./build/runner -f <manifest> logs or tail. To shut down and remove the testnet, run ./build/runner -f <manifest> cleanup.

If the standard log_level is not detailed enough (e.g. you want "debug" level logging for certain modules), you can change it in the manifest file.

Each node exposes a pprof server. To find out the local port, run docker port <NODENAME> 6060 | awk -F: '{print $2}'. Then you may perform any queries supported by the pprof tool. Julia Evans has a great post on this subject.

export PORT=$(docker port full01 6060 | awk -F: '{print $2}')

go tool pprof http://localhost:$PORT/debug/pprof/goroutine
go tool pprof http://localhost:$PORT/debug/pprof/heap
go tool pprof http://localhost:$PORT/debug/pprof/threadcreate
go tool pprof http://localhost:$PORT/debug/pprof/block
go tool pprof http://localhost:$PORT/debug/pprof/mutex

Enabling IPv6

Docker does not enable IPv6 by default. To do so, enter the following in daemon.json (or in the Docker for Mac UI under Preferences → Docker Engine):

{
  "ipv6": true,
  "fixed-cidr-v6": "2001:db8:1::/64"
}

Benchmarking Testnets

It is also possible to run a simple benchmark on a testnet. This is done through the benchmark command. This manages the entire process: setting up the environment, starting the test net, waiting for a considerable amount of blocks to be used (currently 100), and then returning the following metrics from the sample of the blockchain:

  • Average time to produce a block
  • Standard deviation of producing a block
  • Minimum and maximum time to produce a block

Running Individual Nodes

The E2E test harness is designed to run several nodes of varying configurations within docker. It is also possible to run a single node in the case of running larger, geographically-dispersed testnets. To run a single node you can either run:

Built-in

make node
tendermint init validator
TMHOME=$HOME/.tendermint ./build/node ./node/built-in.toml

To make things simpler the e2e application can also be run in the tendermint binary by running

tendermint start --proxy-app e2e

However this won't offer the same level of configurability of the application.

Socket

make node
tendermint init validator
tendermint start
./build/node ./node.socket.toml

Check node/config.go to see how the settings of the test application can be tweaked.