diff --git a/docs/INTEGRATION_TESTS.md b/docs/INTEGRATION_TESTS.md index ef76332951ca9..734d596aecab8 100644 --- a/docs/INTEGRATION_TESTS.md +++ b/docs/INTEGRATION_TESTS.md @@ -1,62 +1,79 @@ # Integration Tests -To run our current integration test suite: +## Running -Running the integration tests requires several docker containers to be -running. You can start the containers with: +To run all named integration tests: ```shell -docker-compose up +make test-integration ``` -To run only the integration tests use: +To run all tests, including unit and integration tests: ```shell -make test-integration +go test -count 1 -race ./... +``` + +## Developing + +To run integration tests against a service the project uses +[testcontainers][1]. The makes it very easy to create and cleanup +container-based tests. + +The `testutil/container.go` has a `Container` type that wraps this project to +easily create containers for testing in Telegraf. A typical test looks like +the following: + +```go +servicePort := "5432" + +container := testutil.Container{ + Image: "postgres:alpine", + ExposedPorts: []string{servicePort}, + Env: map[string]string{ + "POSTGRES_HOST_AUTH_METHOD": "trust", + }, + WaitingFor: wait.ForAll( + wait.ForLog("database system is ready to accept connections"), + wait.ForListeningPort(nat.Port(servicePort)), + ), +} + +err := container.Start() +require.NoError(t, err, "failed to start container") + +defer func() { + require.NoError(t, container.Terminate(), "terminating container failed") +}() ``` -Use `make docker-kill` to stop the containers. - -Contributing integration tests: - -- Add Integration to the end of the test name so it will be run with the above command. -- Writes tests where no library is being used in the plugin -- There is poor code coverage -- It has dynamic code that only gets run at runtime eg: SQL - -Current areas we have integration tests: - -| Area | What it does | -|------------------------------------|-------------------------------------------| -| Inputs: Aerospike | | -| Inputs: Disque | | -| Inputs: Dovecot | | -| Inputs: Mcrouter | | -| Inputs: Memcached | | -| Inputs: Mysql | | -| Inputs: Opcua | | -| Inputs: Openldap | | -| Inputs: Pgbouncer | | -| Inputs: Postgresql | | -| Inputs: Postgresql extensible | | -| Inputs: Procstat / Native windows | | -| Inputs: Prometheus | | -| Inputs: Redis | | -| Inputs: Sqlserver | | -| Inputs: Win perf counters | | -| Inputs: Win services | | -| Inputs: Zookeeper | | -| Outputs: Cratedb / Postgres | | -| Outputs: Elasticsearch | | -| Outputs: Kafka | | -| Outputs: MQTT | | -| Outputs: Nats | | -| Outputs: NSQ | | - -Areas we would benefit most from new integration tests: - -| Area | -|------------------------------------| -| SNMP | -| MYSQL | -| SQLSERVER | +The `servicePort` is the port the service is running on and Telegraf will +connect to. When the port is specified as a single value (e.g. `11211`) then +testcontainers will generate a random port for the service to start on. This +way multiple tests can be run and prevent ports from conflicting. + +The `test.Container` type requires at least the following three items: + +1. An image name from [DockerHub][2], which can include a specific tag or not +2. An array of port(s) to expose to the test to connect to +3. A wait stanza. This lays out what testcontainers will wait for to determine + that the container has started and is ready for use by the test. It is best + to provide not only a port, but also a log message. Ports can come up very + early in the container, and the service may not be ready. + +There are other optional parameters like `Env` to pass environmental variables +to the container or `BindMounts` to pass test data into the container as well. + +User's should start the container and then defer termination of the container. + +[1]: "testcontainers-go" +[2]: "DockerHub" + +## Contributing + +When adding integrations tests please do the following: + +- Add integration to the end of the test name +- Use testcontainers when an external service is required +- Use the testutil.Container to setup and configure testcontainers +- Ensure the testcontainer wait stanza is well-tested