Channel

Channels are proxies through which a simulation sends effects to and receives signals from the system-under-test. For example:

channels:
  db:
    format:
      type: sql
    target:
      type: stream
      command: psql -q $DATABASE_URL
  api:
    target:
      type: exec
      command: curl -sS -X {{method}} $API_BASE_URL{{path}}
  log:
    target:
      type: stream
      command: tail -F logs/app.log

Private Channels

All simulations will include channels that proxy to public interfaces - e.g., APIs, web apps, CLIs. But most will also include channels for private interfaces for a few different reasons.

DBs

When a simulation starts in the past, it will produce backdated effects, and usually public interfaces do not support backdating. So, you'll need to route these effects directly to a database.

SaaS

Many systems keep state in SaaS, which means that the simulation will either need to set up or query that state in order to reference it in other effects.

Observability

Simulations often incorporate logs, metrics, traces, etc. as read-only channels so that their signals can be the subject of invariants.

Target

A channel MUST specify a target, which defines how the channel sends data to and receives data from the system. Currently, there are two supported types: exec and stream.

Exec

An exec target runs the specified shell command whenever it receives an effect. The command may be a Handlebars template, to which the effect value is the input.

Any output from the command will be emitted as an interactive signal, i.e. one that includes the ID of the effect that triggered it.

Stream

The specified command for a stream target will be run by the CLI in a sub-shell prior to the start of simulation. Whenever the channel receives an effect, it pipes it into the stdin of the subshell.

Any data received from stdout or stderr will be emitted as an ambient signal, i.e. one without any explcit effect cause.

Relatedly, a stream target may be used to implement a read-only channel - i.e. one that no effect is routed to - since stdout and stderr will be proxied regardless of effect input.

Format

A channel MAY specify a format, which defines how the channel will transform effect data prior to sending it to the target. Currently, there are two support types: sql and json.

SQL

The sql format will transform an effect body into a SQL insert statement. E.g., the following effect event value:

{
  "id": 1,
  "name": "Alice",
  "admin": true
}

would become:

INSERT INTO `users` (id, name, admin) VALUES (1, 'Alice', true);

The table name is taken from the table field from the associated effect's metadata. If that's not specifed, it will fallback to the effect's name.

JSON

The json format is effectively a no-op currently - the channel will pass each effect event's value directly to the target unchanged.

Examples

cURL

You can use cURL as an exec target for an API channel. This example uses a template that expects the effect data to include method and path fields.

target:
  type: exec
  command: curl -sS -X {{method}} $API_BASE_URL{{path}}

PostgreSQL

Use a stream target and sql format to pipe SQL statements into psql's stdin. In most cases, this will be an example of a private channel.

format:
  type: sql
target:
  type: stream
  command: psql -q $DATABASE_URL

Log File

Use a stream target to receive signals from a log file. This is an example of a read-only channel, meaning no effects will be sent to it. Also, in most cases this will be private.

target:
  type: stream
  command: tail -F logs/app.log