ChaosSQL

Specification

Declarative Language Specification

Exhaustive syntax reference for chaos.yaml: transaction definitions, dynamic expressions, variable bindings, and invariant assertions.

Overview of the Declarative Language (DSL)

ChaosSQL employs a declarative YAML-based Domain-Specific Language (chaos.yaml) to specify concurrency fuzzing scenarios entirely decoupled from application source code. The specification formally models target database configurations, worker concurrency scheduling, transactional sequences, inductive invariants, and stochastic fault injection rules.

Complete Root Properties Taxonomy

Field Type Required Technical Description
version string Yes DSL specification schema version (supports "1.0" and "1.1").
name string Yes Unique scenario identifier (e.g., banking_lost_update).
description string No Textual documentation detailing concurrency hypothesis and business rules.
database (or setup) object Yes Target engine driver configuration, DDL schema, and DML seed scripts.
engine (or workload) object Yes Execution parameters: worker count, PRNG seed, and stochastic jitter ranges.
operations (or transactions) array Yes Atomic transactional workloads scheduled across concurrent workers.
invariants array Yes Post-execution and continuous global data consistency assertions.
faults (or fault_injection) object No Controlled stochastic fault injection (transient aborts, connection drops).

The database (or setup) Block

Specifies the target database driver, connection details, and initialization lifecycle scripts:

database:
  driver: "sqlite"             # Supported drivers: "sqlite", "postgres", "mysql"
  schema: "schema.sql"         # Relative path to DDL schema script or inline SQL string
  seed: "seed.sql"             # Relative path to DML initial seed data script
  dsn: "file:memdb?mode=memory&cache=shared" # Optional DSN (required for Postgres/MySQL)

The engine (or workload) Block

Configures concurrent thread scheduling and deterministic randomization:

engine:
  workers: 8                   # Number of concurrent worker goroutines
  iterations: 50               # Total number of transactions to schedule (mutually exclusive with duration)
  duration: 10s                # Optional: time-bounded execution duration
  seed: 1337                   # Deterministic 64-bit PCG64 PRNG seed
  jitter_ms: [1, 10]           # Stochastic delay interval [min, max] between SQL steps
  isolation: "READ COMMITTED"  # Optional: transaction isolation level override

Operations, Variable Capture, and Dynamic Expressions

Each entry in the operations (or transactions) array models an atomic transactional workload. Steps within an operation execute sequentially inside the transaction assigned to an individual worker.

Lexical Capture Syntax (-> var_name or => var_name)

Extracts column values from a SELECT query result and binds them to lexical variables in the transaction context for subsequent statement interpolation:

operations:
  - name: "transfer_funds"
    steps:
      # Capture column 'balance' into variable 'current_bal'
      - "SELECT balance FROM accounts WHERE id = 1 -> current_bal"
      - "UPDATE accounts SET balance = {current_bal - 100} WHERE id = 1"

Dynamic Expression Interpolation ({expr})

ChaosSQL embeds the high-performance expr-lang compilation engine, supporting arithmetic, logical conditions, and inline expressions evaluated at runtime:

  • Arithmetic Operations: {current_bal - 100}, {price * quantity * 0.9}
  • Ternary Conditionals: {avail > 0 ? avail - 1 : 0}
  • Dynamic Variable Substitution: UPDATE products SET stock = {avail - 1} WHERE id = {target_product}

Conditional Guard Predicates in SQL

Dynamic expressions can be embedded inside WHERE clauses to model atomic compare-and-swap or guarded update logic:

operations:
  - name: "conditional_checkout"
    steps:
      - "SELECT stock FROM products WHERE id = 1 -> avail"
      - "UPDATE products SET stock = {avail - 1} WHERE id = 1 AND {avail > 0}"

Dynamic Parameters (params)

Version 1.1 of the DSL introduces randomized per-transaction parameter generators:

operations:
  - name: "dynamic_transfer"
    params:
      sender_id: "rand_int(1, 10)"
      receiver_id: "rand_int(11, 20)"
      amount: "rand_int(50, 200)"
    steps:
      - "UPDATE accounts SET balance = balance - {amount} WHERE id = {sender_id}"
      - "UPDATE accounts SET balance = balance + {amount} WHERE id = {receiver_id}"

Global Invariant Assertions (invariants)

Invariants represent system conservation laws and inductive safety properties that must hold true regardless of thread interleavings.

Field Type Description
name string Descriptive identifier for the invariant rule (e.g., conservation_of_money).
query string Aggregated verification SQL query executed post-fuzzing to retrieve final state.
assert string Boolean expression evaluated over the query result columns and engine metrics.

Supported Assertion Comparison Operators

Invariant assertions support all standard relational comparison operators evaluated over query columns:

  • == : Strict equality (e.g., total == 2000).
  • != : Non-equality (e.g., drift != 0).
  • < : Less than (e.g., overdraft_count < 1).
  • <= : Less than or equal to (e.g., active_claims <= max_capacity).
  • > : Greater than (e.g., on_duty > 0).
  • >= : Greater than or equal to (e.g., balance >= 0).

Special Variables Injected into Assertion Context

  • col_name: Values returned by any column in the invariant verification query (e.g., total, balance, on_duty).
  • total_completed: Total number of transactions successfully committed (EventCommit).
  • total_aborted: Total number of transactions rolled back due to serialization conflicts or deadlocks.
  • total_operations: Absolute count of scheduled transactions.
invariants:
  # 1. Fundamental conservation of capital (strict equality: ==)
  - name: "conservation_of_money"
    query: "SELECT sum(balance) AS total FROM accounts;"
    assert: "total == 2000"

  # 2. Strict linear relationship between successful commits and balance
  - name: "balance_audit"
    query: "SELECT balance FROM accounts WHERE id = 1;"
    assert: "balance == 1000 - (total_completed * 100)"

  # 3. Non-negativity constraint (greater than or equal to: >=)
  - name: "stock_non_negative"
    query: "SELECT stock FROM products WHERE id = 1;"
    assert: "stock >= 0"

  # 4. Hospital on-call safety quorum
  - name: "at_least_one_doctor_on_call"
    query: "SELECT count(*) AS on_duty FROM doctors WHERE on_call = true;"
    assert: "on_duty >= 1"

  # 5. Non-zero drift guard (inequality: !=)
  - name: "no_audit_drift"
    query: "SELECT abs(sum(debit) - sum(credit)) AS drift FROM general_ledger;"
    assert: "drift == 0"

Controlled Fault Injection (faults / fault_injection)

Allows engineers to stress isolation mechanisms under simulated network partitions, unhandled client disconnects, and ungraceful aborts:

faults:
  transient_abort_rate: 0.15  # 15% probability of abrupt mid-transaction ROLLBACK (tests G1a dirty read)
  connection_drop_rate: 0.05  # 5% probability of sudden connection termination
  latency_spikes:
    probability: 0.10
    delay_ms: 100             # Injects 100ms asynchronous pause to widen race vulnerability window
Mandatory Static Linter: Always validate complex specifications prior to execution using chaossql validate <spec.yaml>. The linter precompiles dynamic expressions and checks referential schema integrity to prevent runtime type errors.