Conformance Fixtures

Status: DRAFT v0.1

Language-neutral test fixtures for the contracts in wire-contracts.md and the behaviors in core-concepts.md. Every Benzene implementation runs the same fixtures through its own runner; an implementation that passes them (plus the live-interop tests described in porting-guide.md §3) is conformant. API shape is explicitly not part of conformance.

The .NET runner lives at test/Benzene.Conformance.Test/ and is the reference for how a runner consumes these files.

Fixture files

File Verifies
status-vocabulary.json The status vocabulary strings and their success/failure classification (wire-contracts §3)
http-status-mapping.json Benzene→HTTP and HTTP→Benzene status tables (wire-contracts §4.1)
grpc-status-mapping.json Benzene→gRPC and gRPC→Benzene status tables (wire-contracts §4.2)
envelope-cases.json End-to-end message envelope handling: request in, pipeline + canonical handler, response envelope out (wire-contracts §1, core-concepts §4–6)
mesh-descriptor-cases.json ServiceDescriptor derivation from the canonical handlers, including payload schemas and descriptorHash properties (mesh §2) — required for ports that implement mesh
mesh-trace-cases.json TraceEvent behavior: traceparent join/reject rules and the invocation→semantic-status mapping (mesh §3) — required for ports that implement mesh
mesh-collector-cases.json Collector ingest, validation, derivation, and degradation behavior (mesh §4–6) — required for ports that implement a collector

Which fixtures a given conformance claim requires (cloud-service-profile.md §5):

Claim Required fixtures
Benzene Core status-vocabulary.json, the mapping tables for each protocol the port binds, envelope-cases.json
Cloud Service Profile support Core, plus mesh-descriptor-cases.json and mesh-trace-cases.json
Collector implementations additionally mesh-collector-cases.json (collector-only; not part of the profile)

At Core level the mesh fixtures apply only to ports that implement the optional mesh module (mesh.md §7); a port without mesh skips them and remains Core-conformant.

Canonical handlers

Envelope cases run against a fixed set of handlers that every runner MUST register natively, with exactly these topics and behaviors:

Topic Request body Behavior
conformance:greet { "name": string } Returns Ok with payload { "greeting": "Hello <name>" }
conformance:status { "status": string, "errors": string[]? } Returns the given status verbatim. For a success-class status, the payload is { "applied": "<status>" }; for a failure-class status, the result carries the given errors (and no payload).

No handler is registered for any other topic — cases targeting unregistered or empty topics verify the router's NotFound / ValidationError behavior.

Envelope case format

{
  "name": "unique-case-name",
  "request":  { "topic": "...", "headers": { }, "body": "..." },
  "expected": {
    "statusCode": "Ok",
    "body": { "greeting": "Hello world" },
    "headers": { "content-type": "application/json" }
  }
}

Mesh fixture formats

Subset matching is as for envelope cases, with one addition needed by these fixtures: arrays compare by exact length with per-element subset matching, and an expected empty array ([]) matches an actual array that is empty or absent (writers may omit empty collections).

Mapping table format

{
  "forward": [ { "from": "Ok", "to": "200" } ],
  "reverse": [ { "from": "200", "to": "Ok" } ]
}

Each row is asserted independently against the implementation's forward/reverse mapper. Rows with from of "<unknown>" assert the mapper's default for an unrecognized input.