Go SDK overview

Antithesis Go SDK

The Antithesis Go SDK enables you to integrate your Go applications with Antithesis and is available on Github here.

Functionality

Like our other SDKs, the Go SDK offers three main types of functionality:

  • The assert functions define test properties about your software or test template.
  • The random functions request structured and unstructured randomness from the Antithesis Platform.
  • The lifecycle functions inform the Antithesis Environment that particular test phases or milestones have been reached.
  • The SDK includes 2 other packages that you should never directly use in your code: the instrumentation package, and the internal package. These are used by the SDK itself.

The SDK also includes Go instrumentor, a command-line tool which transforms your source code to enable full SDK functionality when running in the Antithesis environment, by providing assertion cataloging and coverage instrumentation.

We strongly recommend instrumenting your code this way as it provides significant benefits when testing in Antithesis, such as more intelligent exploration and more detailed debugging artifacts. Read on for more about different approaches to instrumentation.

Using the Go SDK

The basic workflow for using the Go SDK is:

  1. Include the Go SDK in your manifest. 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. Install and run the Go instrumentor following the instructions here. The instrumentor can be used for: a. 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. b. 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. For production builds, you might disable assertions by providing the tag no_antithesis_sdk. This minimizes runtime cost to a level that’s unnoticeable for most applications, but doesn’t entirely eliminate it.

  5. Deploy your build: either to Antithesis to test, 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.

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.

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