Contributing to Lockstep

Copy Markdown View Source

Thanks for your interest. Lockstep is at v0.1.0 and looking for real-world feedback. Here's how to contribute.

  • Bug reports: open an issue with a minimal Lockstep test that demonstrates the problem and the strategy + seed it was found with.
  • Feature requests: open an issue describing the use case before writing code.
  • Pull requests: small + focused beats large + sweeping. Tests required.

Development setup

git clone https://github.com/b-erdem/lockstep
cd lockstep
mix deps.get
mix test

Core tests run on a fresh clone with no external setup. Some integration tests against external libraries (HyParView, DeltaCrdt, Phoenix.PubSub, Horde, GenStage, etc.) require those libraries to be cloned to specific paths — those tests skip cleanly if the paths don't exist. See test/erlang_pg_test.exs for an example of the skip pattern.

Filing a bug

Lockstep test that reproduces the issue is the gold standard:

defmodule MyBugTest do
  use Lockstep.Test

  ctest "minimal repro" do
    # ...
  end
end

Run it with:

mix test path/to/test.exs --seed 1

Include in your issue:

  • Full Lockstep version (mix deps)
  • Strategy + seed that triggers the bug
  • The trace file (in traces/) if Lockstep saved one
  • The Erlang/Elixir version

Adding a strategy

Lockstep's strategies live in lib/lockstep/strategy/. Each implements the Lockstep.Strategy behaviour. See lib/lockstep/strategy/random.ex as the simplest example. Tests go in test/strategy_*_test.exs.

Adding an OTP wrapper

If you find an OTP primitive that Lockstep doesn't intercept yet, the wrapper pattern is:

  1. Add a module under lib/lockstep/<primitive>.ex.
  2. Each public function calls Lockstep.Controller.nif_sync/3 (or the appropriate sync-point function) before doing the actual work.
  3. Add a clause to Lockstep.Rewriter so source code using the primitive is rewritten.
  4. Tests in test/<primitive>_*_test.exs.

Running the full test suite

Lockstep uses external libraries to validate its rewriter against real-world code. To run the full integration suite:

# Clone the libraries Lockstep tests against:
mkdir -p /tmp && cd /tmp
git clone https://github.com/derekkraan/delta_crdt_ex
git clone https://github.com/derekkraan/merkle_map
git clone https://github.com/derekkraan/horde horde_src
git clone https://github.com/bitwalker/libring
git clone https://github.com/keathley/groot
git clone https://github.com/sasa1977/con_cache concache_src
git clone https://github.com/phoenixframework/phoenix_pubsub phoenix_pubsub_src
git clone https://github.com/dashbitco/nimble_pool
git clone https://github.com/beam-telemetry/telemetry
git clone https://github.com/toniqsystems/hlclock

# Then back to the lockstep repo:
cd /path/to/lockstep
mix test

Tests skip cleanly when their target source isn't on disk, so you can run a partial set.

Code style

  • mix format before commit.
  • Clear module-level @moduledoc explaining what + why.
  • Function-level @doc for public API.
  • Tests describe the bug shape they're hunting for (see existing tests' moduledocs).

Hands-on engagement

If you want to apply Lockstep to a production BEAM system — concurrency audit, custom test scaffolding, multi-node race-hunting harness, or hardening on retainer — that's something I do directly. Reach out: baris@erdem.dev.

License

Apache 2.0. By contributing, you agree your contributions will be licensed under the same.