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
chaossql validate <spec.yaml>. The linter precompiles dynamic expressions and checks referential schema integrity to prevent runtime type errors.