Go SDK#

The Antithesis Go SDK offers packages and tools for placing your Go code under test and using Antithesis functionality. It is available on Github here.

See also a tutorial of how to use the SDK.

Packages#

  • The assert package is used to define test properties about your software or workload.

  • The random package provides methods for requesting both structured and unstructured randomness from the Antithesis platform.

  • The lifecycle package contains functions which inform the Antithesis environment that particular test phases or milestones have been reached.

  • Additionally, the instrumentation package provides runtime support for the Go instrumentor tool. You should never directly use this package in your code.

Tools#

  • The Go instrumentor is a command-line tool which transforms your source code to enable full SDK functionality when running in the Antithesis environment. The instrumentor provides assertion cataloging and coverage instrumentation.

    • Assertion cataloging: The instrumentor modifies your program so that at runtime it emits a catalog entry for every assertion you define (like Always(), Sometimes(), Unreachable(), etc.) Assertion cataloging is necessary for certain assertions to work.

    • Coverage instrumentation: The instrumentor adds coverage callbacks at every basic block in the program’s control flow and writes the transformed source files to a separate directory. These callbacks enable the Antithesis platform to test your program more effectively.

Using the Go SDK#

The basic workflow for using the Go SDK is:

  1. Include the Go SDK in your dependencies. Use the command

    go get github.com/antithesishq/antithesis-sdk-go@latest.

  2. Call SDK functions from your code. For example create a test property with an assertion such as assert.Always(some condition).

  3. Run the Go instrumentor. The instrumentor can be used for:
    1. Assertion cataloging only, by running

      $GOPATH/bin/antithesis-go-instrumentor -assert_only <input_dir>

      This option has low runtime overhead and is suitable for running code locally or in production. See “SDK runtime behavior” below for details.

    2. Both assertion cataloging and coverage instrumentation, by running

      $GOPATH/bin/antithesis-go-instrumentor <input_dir> <output_dir>

      The instrumentation is necessary to enable full analysis in the Antithesis environment, but you incur a performance hit when running instrumented code outside Antithesis.

  4. Build your Go project. For example, run go build --tags=antithesis_sdk. For production builds, you probably will disable assertions by not providing the antithesis_sdk tag.

  5. Deploy your build: either to Antithesis or into production.

SDK runtime behavior#

When your code is run outside Antithesis, our SDK has sensible fallback behavior with minimal performance overhead. This enables you to have a single build of your software that runs both inside and outside Antithesis. One benefit of this is that Sometimes Assertions continue to function outside Antithesis, and can be quite useful for discovering what states of your program are encountered during real-world use.

Functions in the assert and lifecycle packages have three modes for local execution:

  1. Default, where assert and lifecycle use local implementations of Antithesis functionality. However, the results will not be logged anywhere because no logfile has been specified.

    This mode is the default behavior.

    E.g. run go build -o myapp myapp.go. You must have first used the Go instrumentor to generate a catalog for myapp.go. You will get misleading and unexpected results without a catalog. You must run the Go instrumentor every time you add new assertions so that they will be cataloged.

  2. Default with logging, which is the same as the above but logs output locally in a structured JSON format.

    This mode is selected at runtime by setting the environment variable ANTITHESIS_SDK_LOCAL_OUTPUT at program startup. This variable must be set to a filepath: a logfile will be created at this location. The file must be located inside an already-existing directory. You may supply either a relative or absolute path.

    E.g. set ANTITHESIS_SDK_LOCAL_OUTPUT=assertions_20240520.json at startup in the example above.

  3. No-op, which disables lifecycle and assert calls and skips over them at low cost. In particular, the arguments to these functions are evaluated, but the functions are stubbed-out.

    This mode is selected at build-time with the build tag no_antithesis_sdk.

    E.g. go build -tags no_antithesis_sdk -o myapp myapp.go.

Functions in the random package always fall back upon the crypto/rand package for entropy when run outside of Antithesis.

Warning

Coverage instrumentation has a higher performance overhead than the SDK. We do not recommend running binaries with coverage instrumentation in production.