Internal Crate Reference

High-level roles of the crates that make up the framework:

  • Configs (testing-framework/configs/): Prepares reusable configuration primitives for nodes, networking, tracing, data availability, and wallets, shared by all scenarios and runners. Includes topology generation and circuit asset resolution.

  • Core scenario orchestration (testing-framework/core/): Houses the topology and scenario model, runtime coordination, node clients, and readiness/health probes. Defines Deployer and Runner traits, ScenarioBuilder, and RunContext.

  • Workflows (testing-framework/workflows/): Packages workloads (transaction, DA, chaos) and expectations (consensus liveness) into reusable building blocks. Offers fluent DSL extensions (ScenarioBuilderExt, ChaosBuilderExt).

  • Runners (testing-framework/runners/{local,compose,k8s}/): Implements deployment backends (local host, Docker Compose, Kubernetes) that all consume the same scenario plan. Each provides a Deployer implementation (LocalDeployer, ComposeDeployer, K8sDeployer).

  • Runner Examples (examples/runner-examples): Runnable binaries demonstrating framework usage and serving as living documentation. These are the primary entry point for running scenarios (local_runner.rs, compose_runner.rs, k8s_runner.rs).

Where to Add New Capabilities

What You're AddingWhere It GoesExamples
Node config parametertesting-framework/configs/src/topology/configs/Slot duration, log levels, DA params
Topology featuretesting-framework/core/src/topology/New network layouts, node roles
Scenario capabilitytesting-framework/core/src/scenario/New capabilities, context methods
Workloadtesting-framework/workflows/src/workloads/New traffic generators
Expectationtesting-framework/workflows/src/expectations/New success criteria
Builder APItesting-framework/workflows/src/builder/DSL extensions, fluent methods
Deployertesting-framework/runners/New deployment backends
Example scenarioexamples/src/bin/Demonstration binaries

Extension Workflow

Adding a New Workload

  1. Define the workload in testing-framework/workflows/src/workloads/your_workload.rs:

    #![allow(unused)]
    fn main() {
    use async_trait::async_trait;
    use testing_framework_core::scenario::{Workload, RunContext, DynError};
    
    pub struct YourWorkload {
        // config fields
    }
    
    #[async_trait]
    impl Workload for YourWorkload {
        fn name(&self) -> &'static str { "your_workload" }
        async fn start(&self, ctx: &RunContext) -> Result<(), DynError> {
            // implementation
            Ok(())
        }
    }
    }
  2. Add builder extension in testing-framework/workflows/src/builder/mod.rs:

    #![allow(unused)]
    fn main() {
    pub trait ScenarioBuilderExt {
        fn your_workload(self) -> YourWorkloadBuilder;
    }
    }
  3. Use in examples in examples/src/bin/your_scenario.rs:

    #![allow(unused)]
    fn main() {
    let mut plan = ScenarioBuilder::topology_with(|t| {
            t.network_star()
                .validators(3)
                .executors(0)
        })
        .your_workload_with(|w| {  // Your new DSL method with closure
            w.some_config()
        })
        .build();
    }

Adding a New Expectation

  1. Define the expectation in testing-framework/workflows/src/expectations/your_expectation.rs:

    #![allow(unused)]
    fn main() {
    use async_trait::async_trait;
    use testing_framework_core::scenario::{Expectation, RunContext, DynError};
    
    pub struct YourExpectation {
        // config fields
    }
    
    #[async_trait]
    impl Expectation for YourExpectation {
        fn name(&self) -> &str { "your_expectation" }
        async fn evaluate(&mut self, ctx: &RunContext) -> Result<(), DynError> {
            // implementation
            Ok(())
        }
    }
    }
  2. Add builder extension in testing-framework/workflows/src/builder/mod.rs:

    #![allow(unused)]
    fn main() {
    pub trait ScenarioBuilderExt {
        fn expect_your_condition(self) -> Self;
    }
    }

Adding a New Deployer

  1. Implement Deployer trait in testing-framework/runners/your_runner/src/deployer.rs:

    #![allow(unused)]
    fn main() {
    use async_trait::async_trait;
    use testing_framework_core::scenario::{Deployer, Runner, Scenario};
    
    pub struct YourDeployer;
    
    #[async_trait]
    impl Deployer for YourDeployer {
        type Error = YourError;
        
        async fn deploy(&self, scenario: &Scenario) -> Result<Runner, Self::Error> {
            // Provision infrastructure
            // Wait for readiness
            // Return Runner
        }
    }
    }
  2. Provide cleanup and handle node control if supported.

  3. Add example in examples/src/bin/your_runner.rs.

For detailed examples, see Extending the Framework and Custom Workload Example.