Cross-cutting tests

Unit tests

Per-crate, no IPC, parallel-safe.

Test Case: ExponentialBackoff invariants TEST_0100
status: open
verifies: REQ_0233

Property test (proptest) on ExponentialBackoff confirming: delays are monotonically non-decreasing until the cap is reached, delays never exceed the configured maximum, reset() returns the policy to the initial delay, and jitter stays within the configured ratio. Lives under taktora-connector-core/tests/.

Test Case: ConnectorHealth state-machine transitions TEST_0101
status: open
verifies: REQ_0230, REQ_0234

Unit test asserting that every valid transition between ConnectorHealth variants (per Health and reconnect lifecycle (ARCH_0012)) emits exactly one HealthEvent on the connector’s health channel, and that illegal transitions panic in debug builds.

Test Case: MqttRouting wildcard demux predicate TEST_0102
status: open
verifies: REQ_0254

Unit-level coverage of the topic-match predicate independent of any broker or iceoryx2 service: every (subscription pattern, incoming topic) pair is asserted against the MQTT 3.1.1 wildcard semantics (single-level +, multi-level #).

Test Case: ChannelDescriptor validation TEST_0103
status: open
verifies: REQ_0201, REQ_0221
links incoming: REQ_0221

Asserts that constructing a ChannelDescriptor with an empty name fails, and that the const-generic N propagates correctly through create_writer / create_reader (compile-fail tests ensure mismatched N values do not type-check).


Workspace end-to-end tests

Full stack exercised via taktora-connector-host examples or assert_cmd-driven binary smoke tests.

Test Case: In-process gateway smoke TEST_0150
status: open
verifies: REQ_0241, ARCH_0020

Single-binary integration: ConnectorHost launches the plugin executor and an in-process tokio task hosting MqttGateway against a rumqttd fixture. End-to-end pub/sub round-trip succeeds; process exits cleanly on programmatic stop.

Test Case: Separate-process gateway smoke TEST_0151
status: open
verifies: REQ_0242, ARCH_0021

Two binaries: a plugin process running ConnectorHost and a gateway process running ConnectorGateway against rumqttd. SHM transport carries envelopes between them. A round-trip succeeds; both processes exit cleanly.

Test Case: SIGINT clean exit within 5-second budget TEST_0152
status: open
verifies: REQ_0243, ARCH_0013

While the connector is mid-traffic, send SIGINT; the host returns from run() within 5 seconds; tokio runtime drains; all iceoryx2 services release; exit code is 0.

Test Case: No control-plane envelopes flow TEST_0153
status: open
verifies: REQ_0244, REQ_0291

With one channel configured, observe the iceoryx2 service for the duration of a normal session: the only envelopes that flow are user-payload envelopes (no “ping”, “version”, or “shutdown handshake”). Asserts the framework’s no-control-plane invariant.


Loom concurrency tests

Run with cargo test --features loom under cfg(loom).

Test Case: Bridge handoff under arbitrary interleaving TEST_0160
status: open
verifies: REQ_0259, BB_0022

Loom model of OutboundGatewayItem.execute racing with the tokio task draining the bridge: every produced frame is observed exactly once by the consumer; no deadlock.

Test Case: Health state-machine under concurrent updates TEST_0161
status: open
verifies: REQ_0230, REQ_0234

Loom model with multiple threads attempting transitions simultaneously (e.g. the tokio task reporting Down while the reconnect timer fires Connecting): the state machine never enters an invalid state and no event is dropped.


Cross-cutting traceability

Used filter: types(test)

ID

Title

Status

Verifies

TEST_0100

ExponentialBackoff invariants

open

REQ_0233

TEST_0101

ConnectorHealth state-machine transitions

open

REQ_0230; REQ_0234

TEST_0102

MqttRouting wildcard demux predicate

open

REQ_0254

TEST_0103

ChannelDescriptor validation

open

REQ_0201; REQ_0221

TEST_0104

Interval trigger fires the configured number of times

implemented

REQ_0001

TEST_0105

Interval cardinality matches run_n on the threaded pool

implemented

REQ_0002

TEST_0106

ExecutionMonitor brackets every dispatch

implemented

REQ_0003

TEST_0107

Subscriber-triggered ingestion wakes the item

implemented

REQ_0010

TEST_0108

Publisher API send paths deliver to attached subscribers

implemented

REQ_0011

TEST_0109

Publisher::loan round-trips without serialisation

implemented

REQ_0012

TEST_0110

JsonCodec round-trip property test

open

REQ_0210; REQ_0212

TEST_0111

Codec encode error on undersized buffer

open

REQ_0213

TEST_0112

Codec decode error propagation

open

REQ_0214

TEST_0113

NotifyOutcome surfaces listeners-notified count

implemented

REQ_0013

TEST_0114

Chain runs its items in declared order

implemented

REQ_0020

TEST_0115

Diamond DAG runs every vertex exactly once

implemented

REQ_0021

TEST_0116

StopChain and Err propagate to downstream items

implemented

REQ_0022

TEST_0117

wrap_with_condition gates execution on the predicate

implemented

REQ_0023

TEST_0118

TriggerDeclarer::deadline stores the (listener, deadline) pair

implemented

REQ_0030

TEST_0119

ExecutionMonitor::post_execute reports per-execute duration

implemented

REQ_0031

TEST_0120

ChannelWriter → ChannelReader round-trip

open

REQ_0205; REQ_0223

TEST_0121

Sequence-number monotonicity

open

REQ_0202

TEST_0122

Timestamp populated at send

open

REQ_0203

TEST_0123

Correlation ID round-trip

open

REQ_0204

TEST_0124

Per-channel size — 4 KB, 64 KB, 1 MB

open

REQ_0201; BB_0010

TEST_0125

Payload-overflow rejection

open

REQ_0201

TEST_0126

Service naming derived from descriptor

open

REQ_0206; BB_0011

TEST_0127

ThreadAttributes affinity_mask compiles and runs

implemented

REQ_0040

TEST_0128

ThreadAttributes priority setter compiles into the worker thread body

implemented

REQ_0041

TEST_0129

Stoppable::stop wakes an idle WaitSet from another thread

implemented

REQ_0051

TEST_0130

QoS 0 round-trip

open

REQ_0252

TEST_0131

QoS 1 round-trip

open

REQ_0252

TEST_0132

Retained-message publish + subscribe

open

REQ_0253

TEST_0133

Wildcard subscription with `+`

open

REQ_0254

TEST_0134

Wildcard subscription with `#`

open

REQ_0254

TEST_0135

Username/password authentication

open

REQ_0255

TEST_0136

TLS connection (developer-machine only)

open

REQ_0256

TEST_0137

Reconnect after broker bounce

open

REQ_0232; REQ_0233

TEST_0138

HealthEvent emitted on every transition

open

REQ_0234

TEST_0139

Outbound bridge saturation → BackPressure

open

REQ_0260

TEST_0140

Inbound bridge saturation → DroppedInbound

open

REQ_0261

TEST_0141

Per-iteration error slot is pre-allocated, not Arc-Mutex-allocated per cycle

implemented

REQ_0062

TEST_0150

In-process gateway smoke

open

REQ_0241; ARCH_0020

TEST_0151

Separate-process gateway smoke

open

REQ_0242; ARCH_0021

TEST_0152

SIGINT clean exit within 5-second budget

open

REQ_0243; ARCH_0013

TEST_0153

No control-plane envelopes flow

open

REQ_0244; REQ_0291

TEST_0160

Bridge handoff under arbitrary interleaving

open

REQ_0259; BB_0022

TEST_0161

Health state-machine under concurrent updates

open

REQ_0230; REQ_0234

TEST_0170

Zero allocations in steady-state dispatch

open

REQ_0060

TEST_0180

Cap exhaustion and oversize alloc both fail-closed

open

REQ_0300; REQ_0301

TEST_0181

Steady-state cap behaviour under burst

open

REQ_0300

TEST_0182

lock() then alloc panics

open

REQ_0302

TEST_0183

Counter accuracy

open

REQ_0303

TEST_0184

Concurrent alloc/dealloc safety smoke

open

REQ_0304

TEST_0190

Histogram percentile accuracy

implemented

REQ_0100

TEST_0191

Per-task max jitter under synthetic period violation

implemented

REQ_0101

TEST_0192

Overrun counter increments exactly per overrun cycle

implemented

REQ_0102

TEST_0193

Push and pull stat paths agree

implemented

REQ_0103

TEST_0194

Allocation-free telemetry update

implemented

REQ_0104

TEST_0200

EthercatConnector trait surface

open

REQ_0310

TEST_0201

EthercatRouting field round-trip

open

REQ_0311

TEST_0202

Single MainDevice per gateway instance

open

REQ_0312

TEST_0203

Bus reaches OP before traffic accepted

open

REQ_0313

TEST_0204

Static PDO map accepted from options

open

REQ_0314

TEST_0205

PDO mapping applied during PRE-OP to SAFE-OP

open

REQ_0315

TEST_0206

Cycle time configurable

open

REQ_0316

TEST_0207

Missed ticks are skipped not queued

open

REQ_0317

TEST_0208

Distributed Clocks bring-up is opt-in

open

REQ_0318

TEST_0209

Up requires OP and matching working counter

open

REQ_0319

TEST_0210

Working-counter mismatch transitions to Degraded

open

REQ_0320

TEST_0211

Tokio sidecar contained inside connector crate

open

REQ_0321

TEST_0212

Bridge channels are bounded with configurable capacity

open

REQ_0322

TEST_0213

Outbound bridge saturation surfaces as BackPressure

open

REQ_0323

TEST_0214

Inbound bridge saturation surfaces as DroppedInbound

open

REQ_0324

TEST_0215

Gateway opens raw socket on Linux with CAP_NET_RAW

open

REQ_0325

TEST_0216

PDI bit-slice byte-aligned round-trip

open

REQ_0326; REQ_0327

TEST_0217

PDI bit-slice unaligned round-trip

open

REQ_0326; REQ_0327

TEST_0218

Adjacent PDI bit slices do not interfere

open

REQ_0326

TEST_0219

Per-channel routing registry has stable iteration order

open

REQ_0328

TEST_0220

Outbound end-to-end (plugin send → PDI slice via mock)

open

REQ_0326; REQ_0328

TEST_0221

Inbound end-to-end (PDI slice via mock → plugin recv)

open

REQ_0327; REQ_0328

TEST_0222

Loopback round-trip (plugin → mock → plugin)

open

REQ_0326; REQ_0327

TEST_0223

Asymmetric expected_wkc summing

open

REQ_0329

TEST_0224

DC cycle path branches on options.distributed_clocks

open

REQ_0330

TEST_0225

Recovery state machine drives BusDriver::recover per policy

open

REQ_0331; REQ_0332

TEST_0226

Health transitions during recovery

open

REQ_0333

TEST_0227

Hardware drill — endurance + unplug/replug

open

REQ_0331

TEST_0240

Harness builds and runs on Linux non-RT

open

REQ_0111

TEST_0241

NDJSON schema validation

open

REQ_0111

TEST_0242

Harness telemetry agrees with stats_snapshot

open

REQ_0113

TEST_0300

ZenohRouting field validation

open

REQ_0401

TEST_0301

ZenohConnector implements Connector with ZenohRouting

open

REQ_0400

TEST_0302

Pub/sub end-to-end against MockZenohSession

open

REQ_0402; REQ_0407; REQ_0408; REQ_0445

TEST_0303

Query round-trip against MockZenohSession

open

REQ_0420; REQ_0421; REQ_0422; REQ_0423; REQ_0424; REQ_0426; REQ_0427

TEST_0304

Codec failure paths for queries

open

REQ_0427

TEST_0305

Outbound bridge saturation surfaces as BackPressure

open

REQ_0404; REQ_0405

TEST_0306

Inbound bridge saturation surfaces as DroppedInbound

open

REQ_0406; REQ_0428

TEST_0307

Query timeout emits 0x03 terminator

open

REQ_0425

TEST_0308

Health state machine on MockZenohSession lifecycle

implemented

REQ_0440; REQ_0442

TEST_0309

REQ_0441 anti-req — no ReconnectPolicy on session loss

implemented

REQ_0441

TEST_0310

zenoh-integration feature gates the real zenoh dep

implemented

REQ_0444; REQ_0445

TEST_0311

Cross-platform support

implemented

REQ_0446

TEST_0312

Two-peer real session pub/sub

draft

REQ_0440; REQ_0443

TEST_0313

Client-mode router smoke

draft

REQ_0440; REQ_0443

TEST_0314

Tokio sidecar contained inside taktora-connector-zenoh

implemented

REQ_0403

TEST_0400

parse() accepts a representative Beckhoff EL3001 ESI

open

REQ_0500; REQ_0504

TEST_0401

Parser compiles under no_std + alloc

rejected

REQ_0501

TEST_0402

Parser is independent of ethercrab

open

REQ_0503

TEST_0403

Vendor-specific elements survive as RawXml

open

REQ_0505

TEST_0404

Parse errors carry line and column

open

REQ_0506

TEST_0410

Name sanitisation handles ESI naming edge cases

open

REQ_0511

TEST_0411

Revision collision produces distinct idents

open

REQ_0512

TEST_0412

PDO entry dedup collapses structurally identical layouts

open

REQ_0513

TEST_0413

TokenStream emission, not string formatting

open

REQ_0514

TEST_0420

EL3001 backend output snapshot

open

REQ_0521; REQ_0522

TEST_0421

Generated registry covers every emitted device

open

REQ_0525

TEST_0422

Generated module compiles under no_std + alloc

open

REQ_0526

TEST_0423

Backend is the sole ethercrab consumer in the toolchain

open

REQ_0520

TEST_0424

Object-dictionary emission gated by feature flag

open

REQ_0533

TEST_0430

EsiDevice trait shape compiles for a hand-written device

open

REQ_0530

TEST_0431

EsiConfigurable async trait shape compiles

open

REQ_0531

TEST_0432

ethercat-esi-rt is the trait home, not taktora-internal

open

REQ_0532

TEST_0440

Builder writes a parseable Rust file to OUT_DIR

open

REQ_0540; REQ_0541

TEST_0441

cargo rerun-if-changed emitted per ESI input

open

REQ_0542

TEST_0442

Output passes prettyplease formatting

open

REQ_0543

TEST_0450

cargo esi expand emits a single device's code

open

REQ_0550

TEST_0451

cargo esi list enumerates devices

open

REQ_0551

TEST_0452

CLI output matches build helper output byte-for-byte

open

REQ_0552

TEST_0460

Verifier passes on matching ESI + SII pair

open

REQ_0560

TEST_0461

Verifier reports the differing field

open

REQ_0561

TEST_0462

Verifier reuses ethercat-esi parser

open

REQ_0562

TEST_0463

Verifier exit codes follow the documented matrix

open

REQ_0563

TEST_0470

Repeated codegen runs produce byte-identical output

open

QG_0010; REQ_0543

TEST_0471

Input-file ordering does not affect output

open

QG_0010; REQ_0512; REQ_0513

TEST_0472

Layering integrity check (Cargo.toml audit)

open

QG_0011; REQ_0503; REQ_0520