Looking to hire Laravel developers? Try LaraJobs

laravel maintained by raceproof

Description
Controlled and reproducible concurrency testing for Laravel applications.
Last update
2026/07/26 20:38 (dev-main)
License
Downloads
4

Comments
comments powered by Disqus

RaceProof for Laravel

Make race conditions arrive on cue - then keep the fix under test.

RaceProof coordinates independent Laravel processes against the same database, pauses them at explicit application checkpoints, releases them as one cohort, and gives you a single result for response and database assertions.

It is built for the failures that ordinary feature tests rarely reproduce: overselling the final unit, redeeming one coupon twice, losing wallet updates, accepting an expired quote, uniqueness races, deadlocks, and lock timeouts.

Release status: v1.0.0-beta.1 is available for both Composer packages. It is a signed prerelease with checksums, provenance, GitHub attestations, and a verified clean Packagist install; stable 1.0.0 remains gated by public beta evidence.

See the failure, then prove the fix

This animation summarizes the repository's executable three-process overselling fixture: the broken path creates three orders from stock 1 and ends at -2; the atomic claim creates one order, ends at 0, and returns two honest 409 responses. MySQL and PostgreSQL evidence exercise the same broken/fixed route pair.

The smallest useful test

Application code marks the critical point:

race_point('oversell-claim');

$created = DB::transaction(function () use ($product): bool {
    $claimed = Product::query()
        ->whereKey($product->getKey())
        ->where('stock', '>', 0)
        ->decrement('stock');

    if ($claimed === 0) {
        return false;
    }

    Order::query()->create(['product_id' => $product->getKey()]);

    return true;
});

abort_unless($created, 409);

The test starts real application processes, waits until all of them reach that point, and releases them together:

$result = race()
    ->participants(3)
    ->postJson('/api/checkout', ['product_id' => $product->getKey()])
    ->releaseWhenAllReach('oversell-claim')
    ->run();

$result
    ->assertAllFinished()
    ->assertNoWorkerFailures()
    ->assertStatusCount(201, 1)
    ->assertStatusCount(409, 2)
    ->assertNoServerErrors()
    ->assertInvariant(
        fn () => Order::query()->count() === 1
            && $product->fresh()->stock === 0,
        'Exactly one order may claim the final unit.',
    );

For a copy-ready broken-to-fixed walkthrough, use the five-minute guide.

Install

composer require raceproof/runtime:^1.0.0-beta.1@beta
composer require raceproof/laravel:^1.0.0-beta.1@beta --dev

php artisan raceproof:install
php artisan raceproof:doctor --self-test

Install raceproof/runtime only when application code contains race_point() calls. It is a framework-free production dependency whose checkpoint calls are no-ops unless a validated RaceProof worker activates an in-memory handler. It has no process runner, filesystem, network, command, or Laravel integration.

raceproof:install publishes configuration and prints a safe .env.testing checklist. It never edits an environment file. Doctor's --self-test mode boots a separate Laravel CLI process; --json emits a bounded schema-v1 result suitable for CI and support reports.

To contribute from source:

git clone https://github.com/zerodycoder/RaceProof.git
cd RaceProof
composer install
composer check

Maintainers can also run composer consumer:check to install and exercise RaceProof inside an isolated Laravel application. The consumer app verifies package discovery, participant/authentication modes, a real database race, CLI workflows, and Studio without relying on the package's Testbench bootstrap.

See runtime checkpoint deployment before adding instrumentation to production code.

How it works

  1. The parent test validates the environment, database, request, participant overrides, authentication specs, and checkpoint plan.
  2. RaceProof boots independent Laravel worker processes against the same configured database.
  3. A start barrier coordinates request entry; race_point() can rendezvous workers inside the application.
  4. The parent releases a checkpoint only after the complete cohort arrives.
  5. The result combines responses, worker failures, timeouts, redacted diagnostics, and a versioned event timeline for assertions and CI reports.

The operating system and database still decide execution order after release. RaceProof controls the important rendezvous; it does not claim exact schedule replay or formal proof that no other race exists.

Participant-specific requests and authentication

Each participant can override payload, headers, cookies, bearer tokens, session identity, Sanctum credentials, and trusted bootstrap data:

use RaceProof\Laravel\ParticipantBuilder;

$result = race()
    ->participants(2)
    ->postJson('/api/transfer', ['amount' => 100])
    ->actingAs($owner, 'web')
    ->forParticipant('p2', fn (ParticipantBuilder $participant) => $participant
        ->withPayload(['amount' => 75])
        ->withHeaders(['X-Tenant' => 'north'])
        ->withToken($sanctumToken)
        ->actingAs($reviewer)
        ->withBootstrap(TransferBootstrap::class, ['tenant' => 'north']))
    ->releaseWhenAllReach('balance-read')
    ->run();

All participant specs are validated before orchestration and cross the process boundary as JSON - never serialized closures. Read the request and authentication guide and bootstrap guide for merge rules and security boundaries.

Assertions and evidence

$result->assertAllFinished();
$result->assertNoWorkerFailures();
$result->assertNoServerErrors();
$result->assertNoTimeouts();
$result->assertStatusCount(201, 1);
$result->assertExactlySuccessful(1);
$result->assertStartSpreadBelow(10);
$result->assertInvariant(fn () => true, 'Invariant failed.');

$result->successful();
$result->failed();
$result->statuses();
$result->participant('p2');
$result->startSpreadMs();
$result->durationMs();
$result->failureReport();

Human, JSON, and JUnit reporters all use one versioned, bounded, redacted report model. See evidence reporters for CI examples and the JSON v1 contract.

RaceProof Studio

Studio is an optional, local evidence viewer. It visualizes retained runs, participant outcomes, timing, checkpoint lanes, warnings, and bounded response evidence without moving execution or assertions out of Pest/PHPUnit.

Enable it explicitly in a local or testing environment:

RACEPROOF_STUDIO_ENABLED=true
php artisan make:race-test InventoryOversell /api/checkout --participants=3
php artisan test --filter=InventoryOversellTest
php artisan raceproof:reports
php artisan raceproof:studio

Open /raceproof on the application's normal local development server. Studio is server-rendered and requires no Node/Vite setup. It never registers routes, reads archives, or writes reports in production, even if its flag is misconfigured. The dashboard is deliberately not an arbitrary endpoint runner: the committed test remains the reproducible source of truth.

Read the Studio guide for configuration, retention, CLI, and security details.

Safety model

RaceProof fails closed:

  • production is always refused;
  • tests must explicitly enable RaceProof;
  • non-testing environments need a separate explicit opt-in;
  • open parent database transactions and SQLite in-memory are rejected;
  • an exact database-name allowlist can be required in CI;
  • captured bodies and headers are bounded and sensitive data is redacted;
  • run, participant, and checkpoint identifiers are path-safe;
  • coordination uses JSON only, with no untrusted unserialize();
  • crash and timeout artifacts are retained for diagnosis.

Use a dedicated disposable database. Do not combine multi-process tests with transaction-based test traits: workers cannot see the parent's uncommitted records. The production safety guide and database guide contain the full operating contract.

Support matrix

Dimension Support
PHP 8.2+
Laravel 12 and 13
Databases MySQL 8.4 and PostgreSQL 17 continuously verified
Linux Full CI and database release-evidence platform
WSL2 Primary development target
macOS Best-effort; continuous independent-consumer smoke
Native Windows Experimental; continuous independent-consumer smoke
SQLite File-backed smoke tests only; not production lock evidence

The exact compatibility promise is maintained in the platform matrix.

Examples

All published examples are wired into executable tests; they are not standalone documentation snippets.

Documentation

Start with the documentation map, or jump directly to:

Project status

The code, API guard, deterministic archives, supply-chain checks, database evidence, and release automation are implemented. Public package publication and real beta-adoption evidence remain honest external gates; stable release is blocked until they are complete.

See the roadmap, pre-release audit, and beta evidence for the machine-checked status.

Contributing

Focused issues and pull requests are welcome. Before opening one, read CONTRIBUTING.md, the quality policy, and the code of conduct.

For security reports, follow SECURITY.md. Do not disclose a vulnerability in a public issue.

License

RaceProof is open source under the MIT License. You may use, modify, distribute, sublicense, and sell copies, including commercially. Copies or substantial portions must keep the copyright and permission notice. The software is provided without warranty. See the plain-language licensing guide for contribution and redistribution notes.