Skip to content

Latest commit

 

History

History
217 lines (150 loc) · 7.16 KB

README.md

File metadata and controls

217 lines (150 loc) · 7.16 KB

Testing

This document explains the E2E and other test coverage for local-csi-driver.

Unit Tests

To run the unit tests, run:

make test

This will run all the unit tests in the project. Unit tests are throughout the code base. All libraries (e.g. internal/pkg/*) should be covered completely. Elsewhere, functions should be covered as appropriate, depending on their complexity.

It is expected that all logic outside the controller reconcilers will be covered by unit tests. Within the controller reconcilers, complex logic should be extracted into functions that are covered by unit tests.

We also have some unit tests that cover controller behavior and run against a fake k8s api server. They do not require compiling and deploying images into a real cluster, making them quick to run. All controller code paths should be tested here.

Within the code, look for suite_test.go as the starting points for integration tests and *_test.go files for the test cases for each controller.

Ginkgo is used for the integration tests. See controller tests for a guide.

E2E Tests

Setup

These tests are designed to run on a running cluster, and they verify behavior triggering externally on that cluster (e.g. by creating PVCs).

For local E2E development, create a three-node Kind cluster with a loop-backed LVM volume group on each node:

make kind-e2e-bootstrap

make clean will remove the Kind cluster.

If CREATE_CLUSTER is unset or set to false, the test suite uses the current kubectl context. Set CREATE_CLUSTER=true to let the test setup create and remove a Kind cluster.

SKIP_UNINSTALL set to true will leave the cluster running for debugging or to speed up successive runs.

SKIP_INSTALL_PROMETHEUS set to true will skip installing Prometheus, which is installed by default so that metrics can be verified.

SKIP_METRICS set to true skips the metrics endpoint tests.

To further optimize dev cycles, only specific tests can be run by setting FOCUS. For example, FOCUS="should delete pv" make e2e will run only the PV delete test.

LABEL_FILTER can be used to run tests with specific labels. For example, LABEL_FILTER="lvm" make e2e will run only tests with the lvm label.

E2E Integration Tests

These tests are run in a Kubernetes cluster. To run the E2E tests, you need to set up a Kubernetes cluster and install the project in it. You can do this the following command to do all of these steps in one go:

REGISTRY=<registry>.azurecr.io make docker-build helm-build helm-push test-e2e

Those tests that are part of the E2E suite are run in the cluster. The tests are written in Go and use the Ginkgo testing framework. The tests are located in the test/e2e directory. By default, the test-e2e target will include tests that can run in a kind cluster.

You can also run the E2E tests in a local Kubernetes cluster using kind. Create the cluster and local volume groups with:

make kind-e2e-bootstrap

Tests labeled for AKS-specific behavior are skipped in this mode.

If you have a real AKS cluster, you can run the tests with:

REGISTRY=<registry>.azurecr.io make docker-build helm-build helm-push test-e2e-aks

For more information on how to set up the AKS cluster, see the deployment instructions in the deployment README.

External E2E Tests

To run the external E2E tests, you need to set up a Kubernetes cluster and install the project in it. You can do this with:

REGISTRY=<registry>.azurecr.io make docker-build helm-build helm-push test-external-e2e

This runs the non-disruptive external E2E suite against the current cluster. The tests are written in Go and use the Ginkgo testing framework. There are two test configurations, lvm and lvm-annotation.

The lvm tests only run the generic ephemeral volume tests, which is the only kind of volume permitted by default by the driver.

The lvm-annotation tests run all the tests specified by the external tests. It uses kyverno to add the localdisk.csi.acstor.io/accept-ephemeral-storage: "true" annotation to the persistent volume claim. This allows the tests to test the "accept-ephemeral-storage" mode of the driver. The tests are located in the test/external directory.

Sanity Tests

To run the sanity tests, run:

REGISTRY=<registry>.azurecr.io make docker-build helm-build helm-push test-sanity

The sanity tests are conformance tests that check whether the driver adheres to the CSI specification. The tests are written in Go and use the Ginkgo testing framework. The implementation can be found in the kubernetes-csi/csi-test repo. The tests are located in the test/sanity directory and run against the current Kubernetes cluster. If a change breaks the tests, refer to the container-storage-interface/spec repo to review the spec to make any necessary changes to the driver.

Scale and AKS Integration Tests

Scale Tests

To run scale tests, which verify the driver's behavior under high load:

SCALE=150 make test-scale

This will create 150 volumes and run a set of tests against them. The number of volumes can be adjusted by changing the SCALE variable.

Upgrade Tests

To test the driver's functionality after upgrading the Kubernetes cluster:

LABEL_FILTER=lvm make test-upgrade
LABEL_FILTER=lvm-annotation make test-upgrade

These tests ensure that the driver remains functional after a cluster upgrade.

Restart and Scaledown Tests

Restart Tests

To test the driver's behavior after restarting the cluster:

make test-restart

Scaledown Tests

To test the driver's behavior when scaling down the cluster:

make test-scaledown

These tests ensure that the driver handles node removal gracefully.

Container Structure

make test-container-structure verifies that the Docker images produced are valid and pass tests. For example, it tests that the correct files and their permissions are correct, and that when run, they produce the expected output.

See /test/container-structure/README.md for details.

Unit

make test runs the unit tests.

Unit tests are throughout the code base. All libraries (e.g. internal/pkg/*) should be covered completely. Elsewhere, functions should be covered as appropriate, depending on their complexity.

It is expected that all logic outside the controller reconcilers will be covered by unit tests. Within the controller reconcilers, complex logic should be extracted into functions that are covered by unit tests.