Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Crate and API Map

This chapter maps which crate owns which concept, what each one exports, and how they depend on each other.

The workspace splits into the app-agnostic core, portable resource contracts, the application-composition layer, deployment backends, and the cfgsync configuration pipeline. Example applications live under examples/ and depend on the framework, never the other way around.

graph BT
    art[cfgsync-artifacts]
    cc[cfgsync-core] --> art
    ca[cfgsync-adapter] --> cc
    ca --> art
    cr[cfgsync-runtime] --> ca
    core[testing-framework-core] --> ca
    container[testing-framework-container] --> core
    local[testing-framework-runner-local] --> core
    compose[testing-framework-runner-compose] --> core
    compose --> container
    k8s[testing-framework-runner-k8s] --> core
    k8s --> cc
    k8s --> art
    app[testing-framework-app] --> core
    app --> container
    app --> local

testing-framework-core

Path: testing-framework/core. The scenario engine and everything app-agnostic: builder, runtime, topology, observation, sources, capabilities. Every other framework crate depends on it.

ModuleContents
envThe Application trait (re-exported from scenario)
scenarioScenarioBuilder, Scenario, Workload, Expectation, RunContext, RunHandle, Runner, RuntimeExtensionFactory, DeploymentPolicy, cluster provisioning (ClusterRequest, ClusterSource, ClusterHandle, ClusterProvisioner, ClusterStartMode, ClusterControlRequest), control traits (NodeControlHandle, ClusterWaitHandle), sources (ExistingCluster, ExternalNodeSource), ObservabilityInputs, snapshots
topologyDeploymentDescriptor, DeploymentProvider, FixedDeploymentProvider, DeploymentSeed, DeploymentPlan, TopologyShapeBuilder, ClusterTopology, NodeCountTopology
observationObserver, SourceProvider, StaticSourceProvider, SourceProviderFactory, ObservationExtensionFactory, ObservationRuntime, ObservationHandle, ObservationConfig
runtimemanual (the ManualClusterHandle interface), process, retry
cfgsyncBridges deployments to the cfgsync pipeline (re-exports cfgsync-adapter, rendering output types)

Key builder entry points: ScenarioBuilder::with_deployment and ::new(provider). The shared fluent methods (with_workload, with_expectation, with_observer, policy setters, …) live on CoreBuilderExt.


testing-framework-container

Path: testing-framework/container. The portable contract for containerized workloads. It owns ContainerServiceSpec, ContainerStackRequest, ContainerStackProvisioner, resolved endpoints, cleanup ownership, and per-container lifecycle handles. It contains no application composition, Docker commands, Compose descriptors, Helm values, Kubernetes resources, or Local-process implementation.

The app crate consumes this contract when an AppDeployment provisions container resources. Compose implements it today; Kubernetes can implement the same contract without either backend depending on the app crate.


testing-framework-app

Path: testing-framework/app. The composition layer for heterogeneous stacks: singleton processes, extra clusters, container stacks, or several applications composed into one system. It consumes Local and container contracts without owning either backend model (see Backend Scope).

ExportRole
AppHost, AppHostEnv, AppHostTopology, AppHostScenarioBuilder, AppHostDeployerScenario entry point (AppHost::scenario().with_app(...)) and the backend-neutral deployer (AppHostDeployer.deploy(&scenario))
AppDeployment, AppHandleThe composition trait and its blanket handle bound
ClusterAppUniform cluster as an app: builds a managed ClusterRequest, exposes a ClusterHandle
ClusterRestartChaosRestart-chaos workload driving a ClusterHandle’s node control
DeployContextDeploy children, expose typed/named handles, provision clusters (deploy_cluster) and container stacks (deploy_container_stack), register cleanup (defer_cleanup)
AppDeploymentFactory, AppScenarioBuilderExt, AppRunContextExtBuilder registration (with_app, with_app_using) and workload-side handle lookup (app, require_app, …)
LocalProcessApp, LocalProcessHandleOne supervised local process as an app
AppRuntime, HandleRegistry, AppDeployErrorRuntime handle storage and errors; managed cleanup is kept separately

Deployment Backends

Each backend implements ClusterProvisioner<E> for its environment trait; the provisioner is passed per app through with_app_using (local is the with_app default).

testing-framework-runner-local (testing-framework/deployers/local) spawns nodes as local processes. Exports LocalClusterProvisioner, LocalCluster, ManualCluster, NodeManager, the LocalDeployerEnv / LocalBinaryApp environment traits with config/port helpers (LocalProcessSpec, LocalNodePorts, build_local_cluster_node_config, …), process primitives (LaunchSpec, NodeEndpoints, ProcessNode), and the whole binary module (BinaryProvider and its implementations). Honors TF_KEEP_LOGS for tempdir retention.

testing-framework-runner-compose (.../compose) renders Docker Compose stacks. Exports ComposeProvisioner (which implements both ClusterProvisioner and ContainerStackProvisioner), ComposeDeployEnv, descriptor builders (ComposeDescriptor, NodeDescriptor), compose lifecycle commands (compose_up, compose_down, dump_compose_logs), and the Docker config-server support used to serve cfgsync artifacts to containers. The cluster and container-stack roles are adapters over one internal managed-project runtime rather than independent Compose implementations.

testing-framework-runner-k8s (.../k8s) installs a Helm release. Exports K8sClusterProvisioner, K8sDeployEnv, ManualCluster (K8s variant), Helm/chart-value infrastructure (HelmInstallSpec, RunnerChartValues, render_binary_config_node_chart_assets, …), and wait/cleanup helpers. Depends directly on cfgsync-core and cfgsync-artifacts for artifact delivery.


cfgsync

cfgsync is the typed pipeline that turns app config into per-node files: app config → registration snapshot → per-node artifact sets → backend rendering. Consumed by the compose and k8s deployers (locally, configs are written straight to disk). See Static Artifacts and cfgsync.

CrateResponsibilityKey exports
cfgsync-artifactsApp-agnostic artifact modelArtifactFile, ArtifactSet
cfgsync-coreProtocol, client/server, template rendering, bundlesClient, serve_cfgsync, NodeRegistration, NodeArtifactsPayload, RenderedCfgsync, NodeArtifactsBundle, config sources
cfgsync-adapterMaterializing registration snapshots into artifactsRegistrationSnapshotMaterializer, CachedSnapshotMaterializer, PersistingSnapshotMaterializer, MaterializedArtifacts, RegistrationConfigSource
cfgsync-runtimeStandalone server/client binaries-facing runtimeserve_from_config, run_client_from_env, ServerConfig

Examples Workspace Layout

Every example app follows the same four-part shape under examples/<app>/:

examples/kvstore/
├── kvstore-node/            # the application binary under test
├── testing/
│   ├── integration/         # crate kvstore-runtime-ext: Application impl,
│   │                        #   local/compose/k8s env impls, observation
│   └── workloads/           # crate kvstore-runtime-workloads: Workloads + Expectations
└── examples/                # crate kvstore-examples: runnable bins

The naming is uniform: <app>-runtime-ext, <app>-runtime-workloads, <app>-examples. nats and redis_streams have no node crate because they run upstream binaries or images. multi_app uses an acceptance-suite layout instead: a job-worker/ binary crate, a fixture/ crate (multi-app-fixture: the stack deployment, handles, workload, and expectation), and an e2e/ crate (multi-app-e2e) whose integration tests drive the fixture. It demonstrates application composition.

Run any example bin with:

cargo run -p kvstore-examples --bin kvstore_basic_convergence

Note: the dependency arrows only ever point from examples toward the framework and from backends toward core. If you find yourself wanting an arrow in the other direction, read Framework vs Application Boundaries. The trait-level view of the same surface is in Public Extension Points.