Environments
An Environment describes the service boundaries that participate in an E2Engine test.
It defines:
- which services E2Engine exposes;
- whether each service is real or mocked;
- where requests to real services are forwarded;
- how mocked services respond;
- HTTP request defaults;
- and, for gRPC services, the protobuf contract E2Engine uses.
A test executes against an environment by sending traffic through the service addresses defined by that environment.
The environment model
Section titled “The environment model”At a high level, an environment is a collection of services:
Environment │ ├── Service │ ├── HTTP or gRPC │ └── real or mocked │ ├── Service │ ├── HTTP or gRPC │ └── real or mocked │ └── ...For example, the E2Engine payment demo defines:
payment-demo │ ├── fraud │ HTTP │ mocked │ ├── account │ gRPC │ real │ └── notification gRPC mockedThis topology is represented explicitly in the environment specification rather than being embedded in test orchestration code.
Environment resource
Section titled “Environment resource”An environment is a versioned E2Engine resource:
kind: Environmentversion: 1.0.0name: payment-demodescription: dependencies for the E2Engine payment demo
spec: services: # ...Resource fields
Section titled “Resource fields”| Field | Type | Required | Description |
|---|---|---|---|
kind |
string | yes | Resource kind. Must be Environment. |
id |
string | no | E2Engine resource ID. Assigned when the resource is created. |
name |
string | yes | Environment name. Between 3 and 200 characters. |
version |
string | yes | Environment specification version. Must be a semantic version. |
description |
string | no | Human-readable description. Between 3 and 2000 characters when specified. |
spec |
object | yes | Environment-specific configuration. |
created_at |
timestamp | no | Creation timestamp assigned to the stored resource. |
updated_at |
timestamp | no | Last-update timestamp assigned to the stored resource. |
When defining an environment in a file, you normally provide kind, name, version, description, and spec.
Fields such as id, created_at, and updated_at belong to the stored resource and are managed by E2Engine.
Services
Section titled “Services”spec.services defines the service boundaries available inside the environment.
spec: services: - id: account kind: grpc mode: real address: 127.0.0.1:8082 grpc_target: 127.0.0.1:50051 # ...An environment must contain at least one service.
Service IDs must be unique within the environment.
Service addresses must also be unique within the environment.
Service fields
Section titled “Service fields”| Field | Type | Required | Description |
|---|---|---|---|
id |
string | yes | Service identifier. Between 3 and 200 characters and unique within the environment. |
kind |
string | yes | Service protocol: http or grpc. |
mode |
string | yes | Service behavior: real or mocked. |
address |
string | yes | Stable logical network address exposed inside the environment. |
http_target |
string | conditional | Destination of a real HTTP service. |
grpc_target |
string | conditional | Destination of a real gRPC service. |
request_defaults |
object | no | Default request properties applied by the service. |
fixtures |
array | conditional | Responses provided by a mocked service. |
proto |
object | conditional | Protobuf definition for a gRPC service. |
The combination of kind and mode determines which additional fields are valid.
Service addresses and targets
Section titled “Service addresses and targets”Every service has an address.
For a real service, it also has a target.
For example:
- id: direct-real-http kind: http mode: real address: 127.0.0.1:8083 http_target: http://127.0.0.1:9000These two addresses have different roles.
Application / Test │ │ http://127.0.0.1:8083 ▼ E2Engine │ │ forwards to ▼http://127.0.0.1:9000 │ ▼ Real serviceaddress is the stable logical address through which the service participates in the environment.
http_target or grpc_target is the actual destination to which E2Engine forwards traffic for a real service.
Routing traffic through the environment allows E2Engine to observe service interactions during a test execution.
Service kinds
Section titled “Service kinds”E2Engine currently supports two service kinds:
| Kind | Value | Description |
|---|---|---|
| HTTP | http |
HTTP service boundary. |
| gRPC | grpc |
gRPC service boundary. |
Each service must specify exactly one kind.
Service modes
Section titled “Service modes”A service can operate in one of two modes:
| Mode | Value | Description |
|---|---|---|
| Real | real |
Traffic is forwarded to an actual service. |
| Mocked | mocked |
E2Engine handles the service and returns configured fixture responses. |
This allows one environment to combine real and controlled dependencies.
For example:
services: - id: fraud kind: http mode: mocked # ...
- id: account kind: grpc mode: real # ...
- id: notification kind: grpc mode: mocked # ...Real HTTP services
Section titled “Real HTTP services”A real HTTP service requires an http_target.
- id: direct-real-http kind: http mode: real address: 127.0.0.1:8083 http_target: http://127.0.0.1:9000http_target must be a valid HTTP URL.
A real HTTP service:
- must define
http_target; - must not define
grpc_target; - must not define
fixtures; - must not define
proto.
Requests received on address are forwarded to http_target.
Mocked HTTP services
Section titled “Mocked HTTP services”A mocked HTTP service is implemented by E2Engine using fixtures.
- id: fraud kind: http mode: mocked address: 127.0.0.1:8081
fixtures: - when: http: method: POST path: /check body: '{"accountId":"acc-001","amount":12500,"currency":"EUR"}'
then: http: status: 200 headers: Content-Type: - application/json body: '{"approved":true}'A mocked service must define at least one fixture and must not define a target.
For HTTP services, every fixture must contain both:
when: http: # request matching
then: http: # responsegRPC fixture definitions are not allowed on an HTTP service.
HTTP fixture matching
Section titled “HTTP fixture matching”when.http describes an HTTP request that a fixture can match.
when: http: method: POST path: /check headers: Content-Type: - application/json body: '{"accountId":"acc-001"}'HTTP fixture request fields
Section titled “HTTP fixture request fields”| Field | Type | Required | Description |
|---|---|---|---|
method |
string | yes | HTTP method to match. |
path |
string | yes | Request path. Must be a valid path beginning with /. |
headers |
map | no | Expected request headers. Each header can contain multiple values. |
body |
string | no | Expected JSON request body. |
Supported HTTP methods are:
GETPOSTPUTDELETEPATCHOPTIONSHEADWhen body is specified, it must contain valid JSON.
HTTP fixture responses
Section titled “HTTP fixture responses”then.http defines the response returned by a mocked HTTP service.
then: http: status: 200 headers: Content-Type: - application/json body: '{"approved":true}'HTTP fixture response fields
Section titled “HTTP fixture response fields”| Field | Type | Required | Description |
|---|---|---|---|
status |
integer | yes | HTTP status code from 100 through 599. |
headers |
map | no | Response headers. Each header can contain multiple values. |
body |
string | no | JSON response body. |
When body is specified, it must contain valid JSON.
Real gRPC services
Section titled “Real gRPC services”A real gRPC service requires:
- a
grpc_target; - an external protobuf definition.
For example:
- id: account kind: grpc mode: real address: 127.0.0.1:8082 grpc_target: 127.0.0.1:50051
proto: external: file: ./proto/account.proto service: account.v1.AccountServiceA real gRPC service:
- must define
grpc_target; - must not define
http_target; - must not define
fixtures; - must use an external protobuf definition.
An internal protobuf definition cannot be used for a real gRPC service.
gRPC protobuf definitions
Section titled “gRPC protobuf definitions”Every gRPC service requires a proto definition.
Exactly one of the following must be configured:
proto: external:or:
proto: internal:They cannot be specified together.
External protobuf definitions
Section titled “External protobuf definitions”An external definition refers to an existing protobuf contract.
A local .proto file can be used:
proto: external: file: ./proto/account.proto service: account.v1.AccountServiceAlternatively, a Buf module can be referenced:
proto: external: buf_module: example/module service: example.v1.ExampleServiceAn external protobuf definition contains:
| Field | Type | Required | Description |
|---|---|---|---|
file |
string | conditional | Path to a protobuf file. |
buf_module |
string | conditional | Buf module containing the protobuf definition. |
service |
string | yes | Fully qualified protobuf service name. |
Exactly one of file or buf_module must be provided.
Internal protobuf definitions
Section titled “Internal protobuf definitions”For mocked gRPC services, a small protobuf contract can be defined directly in the environment.
proto: internal: package: notification.v1 service: NotificationService
methods: - name: Send request: fields: - name: account_id type: string
- name: payment_id type: string
- name: amount type: int64
- name: currency type: string
response: fields: []An internal protobuf definition contains:
| Field | Type | Required | Description |
|---|---|---|---|
package |
string | yes | Protobuf package name. |
service |
string | yes | Service name. |
methods |
array | yes | Methods exposed by the service. At least one method is required. |
Each method contains a request and response message definition.
gRPC methods
Section titled “gRPC methods”methods: - name: Send
request: fields: - name: account_id type: string
response: fields: []| Field | Type | Required | Description |
|---|---|---|---|
name |
string | yes | Method name. |
request |
object | yes | Request message definition. |
response |
object | yes | Response message definition. |
gRPC message fields
Section titled “gRPC message fields”A request or response message contains zero or more fields:
fields: - name: account_id type: string
- name: amount type: int64
- name: tags type: string repeated: trueEach field supports:
| Field | Type | Required | Description |
|---|---|---|---|
name |
string | yes | Field name. |
type |
string | yes | Scalar protobuf field type. |
repeated |
boolean | no | Whether the field is repeated. Defaults to false. |
Supported field types are:
stringboolint32int64uint32uint64floatdoublebytesInternal protobuf definitions intentionally represent a focused subset of protobuf sufficient for defining lightweight mocked services.
Mocked gRPC services
Section titled “Mocked gRPC services”A mocked gRPC service combines an external or internal protobuf definition with fixtures.
For example:
- id: notification kind: grpc mode: mocked address: 127.0.0.1:8083
proto: internal: package: notification.v1 service: NotificationService
methods: - name: Send request: fields: - name: account_id type: string response: fields: []
fixtures: - when: grpc: method: Send message: account_id: acc-001
then: grpc: status: OK message: {}For gRPC services, every fixture must contain both:
when: grpc:and:
then: grpc:HTTP fixtures are not allowed on a gRPC service.
gRPC fixture matching
Section titled “gRPC fixture matching”when.grpc describes the request to match.
when: grpc: method: Send message: account_id: acc-001 payment_id: payment-1| Field | Type | Required | Description |
|---|---|---|---|
method |
string | yes | gRPC method name. |
message |
object | no | Request message fields to match. |
gRPC fixture responses
Section titled “gRPC fixture responses”then.grpc describes the response returned by the mocked service.
then: grpc: status: OK message: {}| Field | Type | Required | Description |
|---|---|---|---|
status |
string | no | gRPC status. |
message |
object | no | Response message fields. |
Supported status values are:
OKCanceledUnknownInvalidArgumentDeadlineExceededNotFoundAlreadyExistsPermissionDeniedResourceExhaustedFailedPreconditionAbortedOutOfRangeUnimplementedInternalUnavailableDataLossUnauthenticatedIf status is omitted, E2Engine uses the default successful gRPC behavior.
Request defaults
Section titled “Request defaults”A service can define request defaults:
request_defaults: headers: Authorization: - Bearer example-tokenCurrently, request defaults support HTTP-style headers:
| Field | Type | Required | Description |
|---|---|---|---|
headers |
map | no | Default request headers, with one or more values per header. |
Request defaults are useful when multiple requests to a service require the same request metadata.
Complete example
Section titled “Complete example”The payment demo combines all of the main environment concepts:
kind: Environmentversion: 1.0.0name: payment-demodescription: dependencies for the E2Engine payment demo
spec: services: - id: fraud kind: http mode: mocked address: 127.0.0.1:8081
fixtures: - when: http: method: POST path: /check body: '{"accountId":"acc-001","amount":12500,"currency":"EUR"}'
then: http: status: 200 headers: Content-Type: - application/json body: '{"approved":true}'
- id: account kind: grpc mode: real address: 127.0.0.1:8082 grpc_target: 127.0.0.1:50051
proto: external: file: ./proto/account.proto service: account.v1.AccountService
- id: notification kind: grpc mode: mocked address: 127.0.0.1:8083
proto: internal: package: notification.v1 service: NotificationService methods: - name: Send request: fields: - name: account_id type: string - name: payment_id type: string - name: amount type: int64 - name: currency type: string response: fields: []
fixtures: - when: grpc: method: Send message: account_id: acc-001 payment_id: payment-1 amount: 12500 currency: EUR
then: grpc: status: OK message: {}The resulting environment can be viewed as:
payment-demo │ ┌────────────┼────────────┐ │ │ │ ▼ ▼ ▼ fraud account notification HTTP gRPC gRPC mocked real mocked │ │ │ fixture :50051 fixtureValidation rules
Section titled “Validation rules”E2Engine validates environment specifications before they are used.
The main environment-level rules are:
kindmust beEnvironment;namemust contain between 3 and 200 characters;versionmust be a semantic version;description, when present, must contain between 3 and 2000 characters;- an environment must contain at least one service;
- service IDs must be unique;
- service addresses must be unique.
For every service:
idmust contain between 3 and 200 characters;kindmust behttporgrpc;modemust berealormocked;addressmust be a valid network address.
For real services:
- a target is required;
- HTTP services require
http_target; - gRPC services require
grpc_target; - the target must match the service kind;
- fixtures are not allowed.
For mocked services:
- at least one fixture is required;
http_targetandgrpc_targetare not allowed.
For HTTP services:
- protobuf definitions are not allowed;
- fixtures must contain HTTP
whenandthendefinitions; - gRPC fixture definitions are not allowed;
- fixture paths must be valid paths beginning with
/.
For gRPC services:
- a protobuf definition is required;
- exactly one of
externalorinternalmust be specified; - real gRPC services cannot use an internal protobuf definition;
- an internal definition must contain at least one method;
- an external definition must specify exactly one of
fileorbuf_module; - fixtures must contain gRPC
whenandthendefinitions; - HTTP fixture definitions are not allowed.
Environments and tests
Section titled “Environments and tests”An environment answers:
What services participate in this test environment, and how should E2Engine handle them?
A Test answers a different question:
What behavior should be executed and verified inside that environment?
Keeping these concepts separate allows the same environment to be reused by multiple tests.
For example:
payment-demo │ ├── successful-payment ├── fraud-rejection └── account-rejectionAll three tests can execute against the same service topology while expressing different expected behavior.

