Skip to content

GazaliAhmad/causal-order-test

Repository files navigation

@causal-order/testing

Systems-testing and runtime-validation tooling for the causal-order stack.

Current npm release: @causal-order/testing@0.2.6.

Install

Baseline stack:

npm install @causal-order/testing @causal-order/transport @causal-order/dedupe causal-order

Monitor-aware stack:

npm install @causal-order/testing @causal-order/transport @causal-order/monitor better-sqlite3 @causal-order/dedupe causal-order

Baseline pipeline:

@causal-order/transport -> @causal-order/dedupe -> causal-order

Monitor-enabled pipeline:

@causal-order/transport -> @causal-order/monitor -> @causal-order/dedupe -> causal-order

Quick Start

Run the built-in simulation against the installed stack:

causal-order-testing-runtime --duration 5m --time-scale 60 --profile expected-production-3way-mesh

Run the same harness against the published transport adapter:

causal-order-testing-adapter-runtime --adapter @causal-order/transport/testing --duration 20m --time-scale 60 --profile expected-production-3way-mesh

Run a monitor-aware scenario:

causal-order-testing-adapter-runtime --adapter @causal-order/transport/testing --monitor --duration 20m --time-scale 60 --profile monitor-healthy-rolling-4h --run-name monitor-healthy

Inspect the latest run:

causal-order-testing-latest
causal-order-testing-summary artifacts/runs/<run-folder>
causal-order-testing-compare artifacts/runs/<older-run> artifacts/runs/<newer-run>

What This Package Is

@causal-order/testing is the deployment-style harness for the causal-order ecosystem.

It is meant to exercise:

  • causal-order: the ordering core
  • @causal-order/dedupe: the duplicate-filtering layer
  • @causal-order/transport: transport implementations driven through the adapter runtime
  • @causal-order/monitor: health-aware buffering and replay between transport ingestion and downstream delivery

It is not another pipeline stage. It is the simulation, fault-injection, runtime-validation, and reporting layer around the installed stack.

Stack Shape

simulated nodes -> @causal-order/transport -> @causal-order/monitor -> @causal-order/dedupe -> causal-order
                   |<-------------------------- @causal-order/testing ----------------------------------->|
                   |             workload, faults, adapter runtime, summaries, and validation             |

Transport Quickstart

Use the published @causal-order/transport/testing entrypoint when you want the harness to drive the real transport implementation directly.

npm install @causal-order/testing @causal-order/transport @causal-order/dedupe causal-order
causal-order-testing-adapter-runtime --adapter @causal-order/transport/testing --duration 20m --time-scale 60 --profile expected-production-3way-mesh

Then inspect the latest run:

causal-order-testing-latest
causal-order-testing-summary artifacts/runs/<run-folder>

This is the npm-facing path for validating the published WebSocket + JSON transport implementation without writing custom harness glue.

The published reporting layer includes:

  • dedupe-aware adapter-run verdicts based on accepted, dropped, and ordered counters
  • wall-clock transport artifacts produced by @causal-order/transport under artifacts/transport-runs/
  • monitor-aware outage artifacts from @causal-order/monitor, including replay posture, recovery transitions, and side-by-side outage comparison signals
  • failed replay sessions and retry-backoff visibility through the dedicated monitor replay retry scenario

The same CLI can read both:

  • /testing adapter-runtime artifacts under artifacts/runs/
  • /transport wall-clock artifacts under artifacts/transport-runs/

If you want a cleaner transport sanity run before moving to the more realistic stress profiles, use transport-sanity-mesh:

causal-order-testing-adapter-runtime --adapter @causal-order/transport/testing --duration 10m --time-scale 60 --node-ids edge-a,edge-b,edge-c,edge-d,edge-e,edge-f,edge-g,edge-h --profile transport-sanity-mesh --run-name transport-sanity-8node-10m

Monitor Quickstart

@causal-order/monitor can be exercised through the same adapter runtime by enabling monitor mode.

npm install @causal-order/testing @causal-order/transport @causal-order/monitor better-sqlite3 @causal-order/dedupe causal-order

Run a monitor-aware transport scenario against the published transport adapter entrypoint:

causal-order-testing-adapter-runtime --adapter @causal-order/transport/testing --monitor --duration 20m --time-scale 60 --profile monitor-healthy-rolling-4h --run-name monitor-healthy

For outage and recovery passes, use one of the monitor profiles:

causal-order-testing-adapter-runtime --adapter @causal-order/transport/testing --monitor --duration 20m --time-scale 60 --profile monitor-transport-outage-burst --run-name monitor-transport-outage
causal-order-testing-adapter-runtime --adapter @causal-order/transport/testing --monitor --duration 20m --time-scale 60 --profile monitor-replay-retry-backoff --run-name monitor-replay-retry

Then inspect the latest run with the same reporting commands:

causal-order-testing-latest
causal-order-testing-summary artifacts/runs/<run-folder>
causal-order-testing-compare artifacts/runs/<older-run> artifacts/runs/<newer-run>

Monitor-enabled runs can emit monitor-specific artifacts such as monitor-heartbeats.ndjson, monitor-health.ndjson, monitor-replay.ndjson, and monitor-summary.json.

What It Does

This package gives you a deployment-style harness for stressing the causal-order stack under realistic conditions such as:

  • workload profiles
  • topology expansion through --node-ids
  • dark-node and jitter-node fault injection
  • adapter-driven transport simulation through a pluggable harness contract
  • rejoin-aware recovery pacing
  • run artifact generation and summary tooling

If you want to use your own transport implementation instead of @causal-order/transport/testing, point the adapter runtime at your module:

causal-order-testing-adapter-runtime --adapter ./dist/my-harness-adapter.js --duration 5m --time-scale 60 --profile expected-production-3way-mesh

The package writes run artifacts under artifacts/runs/ in the caller's working directory by default.

If you are inspecting a wall-clock transport run under artifacts/transport-runs/, point the same summary and compare commands at that run folder:

causal-order-testing-summary artifacts/transport-runs/<run-folder>
causal-order-testing-compare artifacts/transport-runs/<older-run> artifacts/transport-runs/<newer-run>

For adapter-driven runs, interpret the summaries in this order:

  • transport lifecycle and error counts
  • dedupe accepted versus dropped counters
  • final ordered count
  • anomaly totals and types

That keeps the report aligned with the actual pipeline semantics:

delivered -> dedupe accepted/dropped -> ordered

CLI

Baseline runtime:

causal-order-testing-runtime --duration 20m --time-scale 60 --profile expected-production-3way-mesh

Rejoin-aware runtime:

causal-order-testing-runtime-rejoin --duration 20m --time-scale 60 --profile expected-production-mesh-dark-jitter --dark-nodes edge-b --jitter-nodes edge-c

Adapter runtime:

causal-order-testing-adapter-runtime --adapter ./dist/my-harness-adapter.js --duration 20m --time-scale 60 --profile expected-production-3way-mesh

Summaries:

causal-order-testing-latest
causal-order-testing-summary artifacts/runs/<run-folder>
causal-order-testing-compare artifacts/runs/<older-run> artifacts/runs/<newer-run>
causal-order-testing-duplicates artifacts/runs/<run-folder>

Library API

The package also exposes the reusable config and harness helpers:

import {
  type HarnessAdapter,
  type HarnessAdapterFactory,
  type HarnessAdapterOptions,
  type HarnessError,
  type HarnessEventContext,
  type HarnessPeerState,
  buildConfig,
  buildRejoinHarnessConfig,
  parseDurationToMs,
  formatDuration,
  createSimulationClock,
} from "@causal-order/testing";

This is the intended public API for composition. The CLI runtime files remain package bins rather than import-first modules.

Focused Subpaths

If you only want a narrower surface area for one part of the stack, the package also exposes focused subpaths:

  • @causal-order/testing/transport
  • @causal-order/testing/dedupe
  • @causal-order/testing/order
  • @causal-order/testing/providers/default

Use the top-level package when you want the full harness surface. Use the focused subpaths when you want clearer imports for transport adapters, dedupe-oriented provider work, or ordering-oriented provider work.

Adapter Contract

Custom transport integrations are expected to export either createHarnessAdapter or a default factory that matches HarnessAdapterFactory.

import type {
  HarnessAdapterFactory,
  SimulationEvent,
} from "@causal-order/testing";

export const createHarnessAdapter: HarnessAdapterFactory = async ({
  nodeIds,
  runDir,
  log,
}) => {
  const eventHandlers = new Set<
    (event: SimulationEvent, context: { peerId?: string; connectionId?: string }) => void
  >();

  return {
    async start() {
      log?.(`starting adapter for ${nodeIds.length} nodes in ${runDir}`);
    },
    async stop() {},
    async send(event) {
      for (const handler of eventHandlers) {
        handler(event, {
          peerId: event.nodeId,
          connectionId: `${event.nodeId}-example`,
        });
      }
    },
    onEvent(handler) {
      eventHandlers.add(handler);
      return () => eventHandlers.delete(handler);
    },
    onPeerState() {
      return () => {};
    },
    onError() {
      return () => {};
    },
  };
};

The adapter runtime accepts package specifiers, subpath exports, local file paths, and file:// URLs through --adapter.

What the Adapter Does

The adapter runtime keeps ownership of:

  • workload generation
  • event timing, duplication, and chaos shaping
  • pipeline-provider orchestration for the dedupe and ordering stages
  • artifact generation and summary reporting

Your adapter is responsible for:

  • starting the transport under test
  • accepting synthetic SimulationEvent values from the harness through send()
  • delivering those events through the real transport path
  • calling onEvent() with the events that come back out of the transport implementation
  • surfacing transport lifecycle and errors through onPeerState() and onError()

That means an adapter should be thin glue around a transport implementation, not a second copy of the harness.

Testing @causal-order/transport

@causal-order/transport publishes a ready-made adapter entrypoint at @causal-order/transport/testing.

Use it when you want the /testing suite to drive the real transport implementation directly instead of writing a custom adapter. See the transport quickstart above for the install and runtime command.

Notes

  • Built-in workload profiles now resolve relative to the installed package instead of the caller's working directory.
  • The harness now loads the dedupe and ordering path through a pipeline-provider boundary, with the published causal-order and @causal-order/dedupe packages used by the default provider.
  • Default run artifacts still land under artifacts/runs/ in the caller's working directory.
  • The published summary and compare commands are dedupe-aware for adapter runs and also read /transport wall-clock artifacts under artifacts/transport-runs/.
  • Monitor-enabled adapter runs expose replay phases, recovery transitions, failed replay sessions, and retry-horizon evidence without manual NDJSON inspection.

For repository development details, see CONTRIBUTING.md.

About

No description, website, or topics provided.

Resources

License

Contributing

Stars

0 stars

Watchers

0 watching

Forks

Packages

 
 
 

Contributors