Supertester.ConcurrentHarness (Supertester v0.6.0)

Copy Markdown View Source

Scenario-based concurrency harness for OTP processes.

This module coordinates multi-threaded test scenarios against a target process (typically a GenServer) while keeping isolation, cleanup, chaos injection, performance validation, telemetry, and invariant checks in one place.

High level usage:

scenario =
  Supertester.ConcurrentHarness.simple_genserver_scenario(
    MyServer,
    [:increment, :decrement],
    5,
    chaos: Supertester.ConcurrentHarness.chaos_inject_crash(),
    performance_expectations: [max_time_ms: 100],
    invariant: fn server, _ctx ->
      assert {:ok, state} = Supertester.GenServerHelpers.get_server_state_safely(server)
      assert state.count >= 0
    end
  )

assert {:ok, report} = Supertester.ConcurrentHarness.run(scenario)

The returned report contains thread events, chaos + mailbox + performance diagnostics, and emits telemetry for start/stop/chaos/mailbox/perf events.

Summary

Functions

Chaos hook helper that injects a crash into the primary subject.

Chaos hook helper that kills supervisor children while the scenario runs.

Default invariant that simply returns :ok.

Converts a property helper configuration into a runnable scenario.

Runs a concurrent scenario and returns a diagnostic report.

Runs a scenario while enforcing additional performance bounds externally.

Builds a scenario for a GenServer module with repeated operation scripts.

Types

chaos_fun()

@type chaos_fun() :: (pid(), map() -> any())

operation()

@type operation() :: {:call, term()} | {:cast, term()} | {:custom, (pid() -> any())}

scenario()

@type scenario() :: Supertester.ConcurrentHarness.Scenario.t() | map() | keyword()

thread_script()

@type thread_script() :: [operation()]

Functions

chaos_inject_crash(spec \\ :immediate, opts \\ [])

@spec chaos_inject_crash(
  Supertester.ChaosHelpers.crash_spec(),
  keyword()
) :: chaos_fun()

Chaos hook helper that injects a crash into the primary subject.

chaos_kill_children(opts \\ [])

@spec chaos_kill_children(keyword()) :: chaos_fun()

Chaos hook helper that kills supervisor children while the scenario runs.

default_invariant(pid, ctx)

@spec default_invariant(pid(), map()) :: :ok

Default invariant that simply returns :ok.

from_property_config(module, config, opts \\ [])

@spec from_property_config(module(), map(), keyword()) ::
  Supertester.ConcurrentHarness.Scenario.t()

Converts a property helper configuration into a runnable scenario.

run(scenario)

@spec run(scenario()) :: {:ok, map()} | {:error, term()}

Runs a concurrent scenario and returns a diagnostic report.

run_with_performance(scenario, expectations)

@spec run_with_performance(
  scenario(),
  keyword()
) :: {:ok, map()} | {:error, term()}

Runs a scenario while enforcing additional performance bounds externally.

simple_genserver_scenario(module, operations, thread_count, opts \\ [])

@spec simple_genserver_scenario(
  module(),
  [term() | operation()],
  pos_integer(),
  keyword()
) ::
  Supertester.ConcurrentHarness.Scenario.t()

Builds a scenario for a GenServer module with repeated operation scripts.

Options

  • :server_opts - options passed to start_link/1
  • :default_operation - :call or :cast for bare terms (default: :call)
  • :call_timeout_ms - timeout for GenServer.call/3 (default: 1_000)
  • :timeout_ms - overall scenario timeout (default: 5_000)
  • :invariant - function of fn pid, ctx -> term end
  • :cleanup - custom cleanup callback
  • :metadata - map merged into report metadata
  • :mailbox - keyword list passed to mailbox monitoring
  • :chaos - function (pid, ctx) -> any injected while threads execute
  • :performance_expectations - keyword list forwarded to assert_expectations/2