Test Composer Reference

This page describes the types of test commands available in Antithesis.

If you’re just trying to write a first test template to get up and running, we suggest using this section of Getting Started guide. If you’re not already familiar with the basic shape of a Test Composer test template, we suggest reading Test Composer basics before returning to this page.
Guidance on how to test each of these commands locally before deploying to Antithesis, is in Checking Test Templates Locally.

Test Commands

A test command can be any executable (binary or script with an appropriate shebang in the first line, e.g. #!/usr/bin/env bash)

It may have any or no extension, but must be marked executable by the container’s default user.

Driver Commands

Driver commands run after the first command (if provided) and during a period where Antithesis may be adding faults to the test environment. A test should have at least one driver command. The types of driver command vary in their approach to parallelism.

Test Composer Overview

Parallel driver command

<test_name>/parallel_driver_<command>

Parallel_driver commands are the core of a typical Antithesis test. The test composer may start a parallel_driver command while other parallel_driver commands (including earlier copies of the same one) are running.

Examples include:

  • A script in a “client” container that writes rows to a database, queries for those rows, and asserts that it finds the rows it wrote
  • A “low consistency” availability check that runs on a database node and asserts that it is possible to make a read without timing out
  • A “data source” that publishes to a queue

Singleton driver command

<test_name>/singleton_driver_<command>

A singleton_driver command will run as the only driver command in a particular branch of history. Non-driver commands like first and finally will still run.

Singleton_driver commands are the most straightforward way to port existing integration tests to Antithesis, or to use an existing Antithesis workload in the test composer, but they don’t take full advantage of the test composer.

Serial driver command

<test_name>/serial_driver_<command>

Serial_driver commands run at any point after the first command (if any) when there are no other driver commands running. This means that they may be run before or after parallel_driver commands or other serial_driver commands, but they will not be run alongside either. Non-driver commands like anytime will still run alongside.

Common examples of serial_driver fragments include:

  • “Do full failover”
  • A self-validating step that checks “when I’m done, exactly the rows I’ve tried to write got added”
  • Any other instruction that would be hindered by other things running in parallel

Serial_driver commands may be helpful in adapting singleton_driver commands to use the test composer.

Quiescent Commands

First command

<test_name>/first_<command>

First commands are optional commands used to leave the system in an appropriate state for the driver commands. If your test directory includes first commands, exactly one will be selected for a branch of history, and it will run after the Setup Complete lifecycle event but before any driver commands (see below).

First commands are often appropriate for setting up data or database schemas, or bootstrapping other components for later commands to depend on, but they are not required and may not be useful for every testing approach.

Eventually command

<test_name>/eventually_<command>

Eventually commands run after at least one driver command (see below) has started. Eventually commands create a new alternate branch of the multiverse in which all driver commands are killed and Antithesis no longer injects new faults.

Test Composer Eventually

Any ongoing faults will continue to run till their predetermined end. An Eventually command should therefore include retry loops and/or checks for service availability if you want to ensure that the system has time to recover.

Since Antithesis will not resume testing on this branch of history, Eventually commands may take destructive actions.

Eventually commands are ideal for testing “eventual” properties of a system, like availability or replica consistency.

Advanced Commands

The test command types above work well for most Antithesis users, but the test composer recognizes a few more in order to support specific situations.

Finally command

<test_name>/finally_<command>

Finally commands are quiescent commands that closely resemble eventually commands except that the test composer will only run a finally command in a branch where every driver command that was started has also completed successfully.

Finally commands may be useful for testing subtle invariants that are disrupted when drivers are killed partway through.

Common examples of finally commands include:

  • “Data is eventually consistent”
  • “The database contains $X lines”

Anytime command

<test_name>/anytime_<command>

Anytime commands will run at any time after the first command (if any), including during singleton or serial driver commands. They will not be started if a finally or eventually command is running, but if an anytime command is running when one of these commands starts, the anytime command will be allowed to continue.

Anytime commands enable you to run many of the same invariant checks that are typically expressed as parallel_driver commands alongside serial_driver and/or singleton_driver commands.

A common example of an anytime command is:

  • “A read always reflects the previous write” (causal consistency)
  • A “low consistency” availability check that runs on a database node and asserts that it is possible to make a read without timing out

Further reading

For a more detailed explanation of the concepts underpinning the test composer, see Principles of Test Composition.

For guidance on how to test each of these commands locally before deploying to Antithesis, see Checking Test Templates Locally.