The ABQ native runner protocol defines how native test frameworks must communicate with ABQ.

The best way to test an implementation of the protocol with a test framework is via the ABQ tester harness.

Environment Variables

ABQ_SOCKET: The socket address to use for communicating with the ABQ worker parent process, e.g. localhost:10000. If ABQ_SOCKET is not present then the test runner should treat ABQ as disabled regardless of what other environment variables are present.

ABQ_GENERATE_MANIFEST: When present, this indicates that the test runner should send a manifest over the protocol and then exit.

Communication Protocols

Talking over a network

All payloads sent over a network are JSON-encoded data.

Payloads are sent as UTF-8 encoded messages with the following scheme:

For example, to send {foo: "bar"}, you first send the length “12” as a big-endian 32 bit int, then the UTF-8 encoded JSON object.

Spawn Message

When an abq native runner starts with ABQ_SOCKET present, it must send a AbqNativeRunnerSpawned message to the ABQ_SOCKET as soon as it is viable to do so. Generally, a native runner should do this on process startup.

The native runner invoker, which provided ABQ_SOCKET, is permitted to treat the lack of receipt of such a message within a certain timeframe as an indication that the invoked runner process either does not speak the ABQ protocol, or has errored.

The timeout within which a native runner must send a AbqNativeRunnerSpawned message is determined by the ABQ worker and is opaque to the native runner. Only one AbqNativeRunnerSpawned message should be sent to ABQ_SOCKET, and it must be exactly the first of any messages sent when a native runner starts.

If the receiver of the AbqNativeRunnerSpawned message cannot interoperate with the ABQ protocol as specified by the ABQ protocol version number of the version field, the invoker of the native process is free to terminate or kill the native process.

type AbqNativeRunnerSpawnedMessage = {
  type: "abq_native_runner_spawned";
  protocol_version: AbqProtocolVersion;
  runner_specification: AbqNativeRunnerSpecification;
}

// Indicates the compatible ABQ protocol version.
type AbqProtocolVersion = {
  type: "abq_protocol_version";
  major: number; // unsigned 64-bit integer
  minor: number; // unsigned 64-bit integer
}

// Reflects information about the ABQ native test runner integration under execution.
// This data should reflect the name and version information of the ABQ-specific integration,
// if that differs from a the test framework the ABQ integration is wrapping.
type AbqNativeRunnerSpecification = {
  type: "abq_native_runner_specification";
  name: string; // The canonical name of the ABQ native test runner integration
  version: string; // The canonical version of the ABQ native test runner integration
  test_framework: string; // The testing framework the ABQ native test runner integration is for
  test_framework_version: string;
  language: string; // The standard programming language the testing framework targets
  language_version: string;
  host: string; // The platform the native runner is running on. Should include OS/arch if possible.
}

Manifest Generation

When a manifest has been generated and is ready to be sent to the parent process, a ManifestMessage should be encoded and sent over the socket: