Spec

A spec describes the behavior of a system via a simulation and an audit. The simulation models realistic usage of the system while the audit sets expectations for observed behavior.

There are two ways of representing a spec:

  1. via a Rust DSL
  2. as a JSON (or YAML) object

This reference will focus on the JSON / YAML representation. Here's an example:

key: my-service
seed: 41
start: now - years(5)
end: now + minutes(3)
channels:
  sqlite:
    type: stream
    command: sqlite3 db.sqlite
    format:
      type: sql
effects:
  user.create:
    channel: sqlite
    metadata:
      table: USER
    generator:
      type: object
      properties:
        id:
          type: number
          minimum: 1
          scale: 0
          step: 1
        name:
          type: string
          pattern: .{0,36}
signals:
  no-errors:
    type: sql
    query: >
      select count(*) from metadata
      where level = 'error';
    expect: result == 0

The signals parameter configures the audit, while the other parameters configure the simulation.

The rngo eval CLI command evaluates whether a spec hold for a given deployment of a system by running the simulation against the system, logging all data and then auditing the log.

Discriminated Unions

Several component types within a spec are represented as discriminated unions. This means that the component takes a type parameter, whose value is an enum that determines the schema of the other parameters..

The spec component types that are represented as discriminated unions are:

You can see in the example above that each of these component types have a type parameter. In fact, the effect has a generator of type object, which has nested generators of types number and string - each has a different parameter schema.

Parameters

keyrequired

A unique, meaningful identifier for the spec.

rngo init will set this to the name of the project's directory by default.

seedoptional

Makes the simulation's random number generator deterministic.

Must be a positive integer, and defaults to 1.

Changing seed lets you get a fresh set of data for an otherwise identical simulation.

startoptional

When the simulation starts.

May be any time past or future, but must come before end. Defaults to now - days(30).

May be expressed as either an ISO-8601 string, or a time expression.

endoptional

When the simulation ends.

May be any time past or future, but must come after start. Defaults to now.

May be expressed as either an ISO-8601 string, or a time expression.

channelsoptional

How to send inputs to and receive outputs from the system during the simulation

Must be an object of named channels. See the channel reference for how to define one.

effectsrequired

How to generate inputs during the simulation.

Must be an object of named effects. See the effect reference for how to define one.

signalsoptional

What patterns to look for in the log during the audit.

Must be an object of named signals. See the signal reference for how to define one.

generatorsoptional

Custom generator types that may be used within an effect.

Must be an object of named custom generator type. See the custom generator types reference for how to define one.