Skip to content

Architecture overview

E2Engine is built around a small core model and a set of replaceable components for persistence, scheduling, execution, and runtime infrastructure.

At the center are the resources and execution models described throughout this documentation:

Environment
Test
TestSuite
│
▼
E2Engine Core
│
▼
TestExecution
TestSuiteExecution

The core coordinates these models without depending on a particular command-line interface, persistence implementation, or execution transport.

At a high level, E2Engine separates resource management, execution coordination, runtime execution, and external interfaces.

Interfaces
┌───────────────┐
│ CLI │
└───────┬───────┘
│
▼
┌─────────────────┐
│ E2Engine Core │
│ │
│ resources │
│ execution │
│ orchestration │
└───────┬─────────┘
│
┌──────────┴──────────┐
│ │
▼ ▼
┌─────────────┐ ┌─────────────┐
│ Repository │ │ Scheduler │
└─────────────┘ └──────┬──────┘
│
▼
┌─────────────┐
│ Runner │
└──────┬──────┘
│
▼
┌─────────────────────┐
│ Runtime Environment │
│ │
│ services │
│ routing │
│ call observation │
└─────────────────────┘

These boundaries allow the execution model to remain independent of how resources are stored or how execution work reaches a runner.

E2Engine Core owns the primary domain and execution model.

Its responsibilities include:

  • validating Environments, Tests, and TestSuites;
  • creating and retrieving resources;
  • resolving resource references;
  • resolving TestSuite selectors;
  • creating TestExecutions and TestSuiteExecutions;
  • coordinating execution;
  • maintaining structured execution results.

The core works with structured Go models rather than CLI-specific output or presentation types.

This keeps the execution model independent of the interface used to operate E2Engine.

Resources and execution state are accessed through repository abstractions.

E2Engine Core
│
▼
Repository API
│
▼
Repository implementation

The repository stores resources such as Environments, Tests, and TestSuites together with persistent TestExecution and TestSuiteExecution state.

The core depends on repository contracts rather than a particular storage implementation.

This allows repository implementations to vary without changing the resource or execution model.

Starting a test does not directly execute the test inside the core service.

Instead, the core creates the execution state and schedules resolved work for a runner.

Run request
│
▼
E2Engine Core
│
├── resolve resources
├── create execution
│
▼
Scheduler
│
▼
Runner
│
▼
Execute test

This separates execution coordination from execution infrastructure.

The scheduler defines how execution jobs are delivered, while the runner is responsible for performing those jobs and updating their execution state.

The default local execution infrastructure can run tests concurrently, but the core execution model does not depend on a particular scheduling or worker implementation.

The runner turns an Environment resource into an active runtime environment for test execution.

Environment resource
│
▼
Runtime Environment
│
├── services
├── routing
└── call observation

Each service in the Environment is mapped to a runtime implementation according to its protocol and mode.

Currently supported combinations are:

Protocol Mode
HTTP real
HTTP mocked
gRPC real
gRPC mocked

The runtime environment mounts these services and exposes the addresses declared by the Environment.

Its routing layer connects those addresses to the corresponding runtime services while observing interactions that pass through the modeled service boundaries.

These observations become part of the structured TestExecution result and can be evaluated against call expectations.

Within the runner, execution is divided into protocol-specific execution and evaluation.

TestJob
│
▼
Runtime Environment
│
▼
Protocol Executor
│
├── HTTP
└── gRPC
│
▼
Response Evaluation
│
▼
Call Evaluation
│
▼
TestExecutionResult

HTTP and gRPC have their own request executors and evaluators, while the surrounding execution lifecycle is shared.

The resulting TestExecutionResult is persisted as structured execution state.

For a TestSuite, multiple TestExecutions share the runtime Environment instance and are aggregated into a TestSuiteExecution.

See Running a test and Running a test suite for the execution lifecycle.

The core execution model is independent of how users or automation interact with E2Engine.

The CLI is currently the primary user-facing interface:

Developer
│
▼
CLI
│
▼
E2Engine Core

The CLI is responsible for command handling, configuration, and presentation. Domain resources and execution results remain structured core models.

This separation allows additional interfaces to operate the same model without moving interface-specific concerns into the core.

E2Engine components are configured independently from the domain resources they execute.

Configuration can be supplied through configuration files and, where supported, environment variables.

This distinction is intentional:

Resources
Environment / Test / TestSuite
│
│ describe what to execute
▼
Runtime configuration
repository / scheduler / runner / workers
│
│ controls how E2Engine operates
▼

An Environment therefore describes the distributed system involved in a test, while runtime configuration controls E2Engine itself.

E2Engine is split across several focused open-source repositories.

Repository Responsibility
core Domain models, APIs, resource management, execution coordination, and runtime execution
repository Repository implementations
runner-local Local execution infrastructure
cli Command-line interface
tests Integration and end-to-end tests
demo Executable demonstration system and E2Engine examples

The repositories follow the same architectural boundaries as the system itself rather than combining storage, execution infrastructure, and presentation into the core.

The complete flow can be summarized as:

Developer / automation
│
▼
Interface
│
▼
E2Engine Core
│
├──────▶ Repository
│
▼
Scheduler
│
▼
Runner
│
▼
Runtime Environment
│
├── real services
├── mocked services
└── observed calls
│
▼
Execution Result
│
▼
Repository

The architecture is designed so that the structured E2Engine model remains stable while infrastructure around it can be configured or replaced.

See Design principles for the principles behind these boundaries and Extending E2Engine for the available extension points.