Expand description

dockertest is a testing and automation abstraction for Docker.

The primary utility for this crate is to easily employ docker in test infrastructure, with the following key features:

  • Optionally enable connection to a Docker daemon via TLS on top of TCP or connect locally via unix socket (named pipe on Windows)
  • Ensure that the docker container is running prior to test code.
  • Support multiple containers per test.
  • Support multiple containers from same image, with different configurations.
  • Retrieve Image from remote source according to PullPolicy.
  • Support custom registries, which can be individually assigned to Image.
  • Dictate how each RunningContainer is created and operated from an Image through a Composition.
  • This allows us to have muliple containers with the same Image, but with different start conditions.
  • Control each Composition condition for when it is deemed running through WaitFor.
  • There exists multiple convenient WaitFor implementations, however, user-supplied implementations through the trait can be provided.
  • Control the StartPolicy of each Composition. For inter-dependant containers, a Strict policy can be sat, and they will be started in succession until their WaitFor condition is met, according to the order they where added to DockerTest.

Once the DockerTest test is run, the provided closure will be ran once all predicates for each supplied Composition has successfully been fulfilled. The closure is provided with one DockerOperations parameter, allowing the test body to interact with DockerTest and each individual RunningContainer. The reference to each RunningContainer is queried through a handle, which is the user-provided container name, specified in Composition through Composition::with_container_name. See the Handle section.

Handle - referencing the same container throughout your test

dockertest assigns a handle to each Composition, which carries over to a RunningContainer. When writing a test, one will reference the intended object through its handle.

By default, the handle is auto-assigned to be the repository name of the Composition.

The user may change the handle by changing the container name (as seen from the user - the final container name will be disambiguated for each dockertest) through the Composition::with_container_name builder method on Composition.

If the test includes multiple Compositions with the same handle, attempting to reference one that has multiple occurrences will fail the test at runtime.

WaitFor - Control how to determine when the container is ready

Each Composition require a trait object of WaitFor whose method WaitFor::wait_for_ready must resolve until the container can become a RunningContainer. This trait may be implemented and supplied to Composition through Composition::with_wait_for.

The batteries included implementations are:

  • RunningWait - wait for the container to report running status.
  • ExitedWait - wait for the container to report exited status.
  • NoWait - don’t wait for anything
  • MessageWait - wait for the following message to appear in the log stream.

Prune policy

By default, dockertest will stop and remove all containers and created volumes regardless of execution result. You can control this policy by setting the environment variable DOCKERTEST_PRUNE:

  • “always”: default remove everything
  • “never”: leave all containers running
  • “stop_on_failure”: stop containers on execution failure
  • “running_on_failure”: leave containers running on execution failure

Viewing logs of test execution

dockertest utilizes the tracing log infrastructure. To enable this log output, you must perform enable a subscriber to handle the events. This can easily be done by for instance the wrapper crate test-env-log, that provides a new impl of the #[test] attribute.

Cargo.toml

[dev-dependencies]
tracing = "0.1.13"
tracing-subscriber = "0.2"
test-log = { version = "0.2", default-features = false, features = ["trace"] }

Top of test file

use test_log::test;

Example

use dockertest::{Composition, DockerTest};
use std::sync::{Arc, Mutex};

#[test]
fn hello_world_test() {
    // Define our test instance
    let mut test = DockerTest::new();

    // Construct the Composition to be added to the test.
    // A Composition is an Image configured with environment, arguments, StartPolicy, etc.,
    // seen as an instance of the Image prior to constructing the Container.
    let hello = Composition::with_repository("hello-world");

    // Populate the test instance.
    // The order of compositions added reflect the execution order (depending on StartPolicy).
    test.add_composition(hello);

    let has_ran: Arc<Mutex<bool>> = Arc::new(Mutex::new(false));
    let has_ran_test = has_ran.clone();
    test.run(|ops| async move {
        // A handle to operate on the Container.
        let _container = ops.handle("hello-world");

        // The container is in a running state at this point.
        // Depending on the Image, it may exit on its own (like this hello-world image)
        let mut ran = has_ran_test.lock().unwrap();
        *ran = true;
    });

    let ran = has_ran.lock().unwrap();
    assert!(*ran);
}

Modules

Contains WaitFor trait used to determine when a PendingContainer has started and all the default implementations of it.

Structs

Represents an instance of an Image.

The test body parameter provided in the DockerTest::run argument closure.

The internal configuration object of a DockerTest instance.

Represents a docker Image.

Specifies how Composition should handle container logging.

Represent a docker container object in a pending phase between it being created on the daemon, but may not be running.

Represents credentials to a custom remote Docker Registry.

Represent a docker container in running state and available to the test body.

Enums

Public library error conditions.

Specifies how should a Composition handle logs.

Specifies when LogAction is applicable.

Specifies which log sources we want to read from containers.

The policy for pulling from remote locations.

Represents the Source of an Image.

Specifies the starting policy of a Composition.

Specifies who is responsible for managing a static container.