From 53898b3ece1664a09eddf4681be6c247ae432a77 Mon Sep 17 00:00:00 2001 From: sqt <574914+sqt@users.noreply.github.com> Date: Sat, 29 Aug 2026 20:27:05 +0000 Subject: [PATCH] CI: per-test-binary DDS domains + a ReleaseSmall lane --- .github/workflows/release.yml | 10 +++ CHANGELOG.md | 25 ++++++++ build.zig | 59 ++++++++++++++++- docs/design/ci-platform-coverage-expansion.md | 35 +++++++---- docs/roadmap.md | 32 ++++++---- scripts/run_deterministic_matrix.py | 16 ++++- test/c_abi/bootstrap_test.zig | 13 ++-- test/c_abi/typesupport_test.zig | 3 +- test/dcps/api_test.zig | 33 +++++----- test/dcps/cft_test.zig | 5 +- test/dcps/entity_routing_test.zig | 5 +- test/dcps/factory_vtable_test.zig | 7 ++- test/dcps/get_field_refresh_test.zig | 3 +- test/dcps/ignore_test.zig | 23 +++---- test/dcps/instance_lifecycle_test.zig | 5 +- test/dcps/intraprocess_test.zig | 7 ++- test/dcps/listener_fallback_test.zig | 5 +- test/dcps/loopback_test.zig | 49 ++++++++------- test/dcps/matched_status_test.zig | 5 +- test/dcps/participant_vtable_test.zig | 15 ++--- test/dcps/pubsub_vtable_test.zig | 63 ++++++++++--------- test/dcps/qos_runtime_test.zig | 17 ++--- test/dcps/read_take_test.zig | 5 +- test/dcps/reader_vtable_test.zig | 7 ++- test/dcps/sample_rejected_test.zig | 5 +- test/dcps/topic_vtable_test.zig | 3 +- test/dcps/type_support_test.zig | 7 ++- test/dcps/wait_for_historical_test.zig | 17 ++--- test/dcps/waitset_lifecycle_test.zig | 5 +- test/dcps/wlp_loopback_test.zig | 13 ++-- test/dcps/writer_vtable_test.zig | 7 ++- test/support/domain.zig | 52 +++++++++++++++ test/transport/tcp_transport_test.zig | 37 ++++++----- 33 files changed, 398 insertions(+), 195 deletions(-) create mode 100644 test/support/domain.zig diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 061889d5..1507eeca 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -111,6 +111,16 @@ jobs: - name: Test (ReleaseFast) run: zig build test -Doptimize=ReleaseFast + # Linux x86_64 only: `test-release-small` forces the LLVM backend to work + # around a Zig 0.16 self-hosted-x86_64 bug that mis-aligns read-only + # globals at -OReleaseSmall (see the step's comment in build.zig). That + # workaround path has only been exercised on Linux; broaden this to the + # whole matrix -- as a plain `zig build test -Doptimize=ReleaseSmall` -- + # at the Zig 0.17 bump, when the underlying bug is gone. + - name: Test (ReleaseSmall, LLVM backend) + if: matrix.os == 'ubuntu-latest' + run: zig build test-release-small -Doptimize=ReleaseSmall + # Binding smoke tests, mirroring ci.yml's test-other job: the release # gate previously ran only `zig build test` (+ReleaseFast +TSan) and # never built a single binding, so a PR breaking the C/C++/Java diff --git a/CHANGELOG.md b/CHANGELOG.md index 0b013a28..5080eb2f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,31 @@ see [`docs/implementation_status.md`](docs/implementation_status.md); for planne Dated entries (no release tags past `v0.2.1-zig.0.16.0`; `build.zig.zon` is `0.2.1-zig.0.16.0-dev`). +## 2026-08-29 + +- **CI flake fix — unique DDS domain per test binary.** `zig build test` runs the ~29 + participant-creating test binaries as parallel Run steps; they all stood up participants + on domain 0 and contended for the same fixed RTPS ports (SPDP multicast 7400, metatraffic + unicast), so on slow runners (ARM64, DebugAllocator/TSan lanes) the loser hit + `error.BindFailed`, discovery stalled, and a loopback test timed out. `build.zig` now + gives each test binary's Run step a distinct `ZZDDS_TEST_DOMAIN_BASE` (per-lane counter, + see `addTestRun`); the new `test/support/domain.zig` reads it, and every DCPS/C-ABI test's + `create_participant` (plus `loopback_test` / `wlp_loopback_test`'s hand-wired + `UdpTransport.init` / `SpdpSedpDiscovery.init`) uses `test_domain.get()`. Distinct domains + map to disjoint port sets (250-port stride). `mock_loopback_test` is unchanged (it never + binds a real socket). +- **CI flake fix — `tcp_transport_test` reconnect race.** "connectionGeneration increments + on reconnect" replaced a fixed `sleepMs(100)` (a guess at how long the local TCP stack + takes to process a peer FIN) with a poll-until-observed loop: drive the reconnecting + `send()` until a new `TcpConnection` is seen, or a 5 s deadline. Same invariant asserted, + no magic constant. +- **`ReleaseSmall` CI lane.** New `zig build test-release-small` runs the unit suite at + `-OReleaseSmall`, wired into `run_deterministic_matrix.py` and `release.yml` (Linux + x86_64). It forces the LLVM backend to work around a Zig 0.16 self-hosted-x86_64 codegen + bug — read-only globals emitted without alignment at `-OReleaseSmall` — that is fixed on + Zig 0.17 master; switch back to the plain self-hosted backend at the 0.17 bump. See + `docs/design/ci-platform-coverage-expansion.md`. + ## 2026-08-26 - **`zzdds-examples` folded into `examples/`.** The standalone `zz-iot/zzdds-examples` repo diff --git a/build.zig b/build.zig index 26d07057..174c88b4 100644 --- a/build.zig +++ b/build.zig @@ -1,6 +1,21 @@ const std = @import("std"); const builtin = @import("builtin"); +/// Run a test binary, giving it a unique DDS domain via `ZZDDS_TEST_DOMAIN_BASE`. +/// +/// `zig build test` runs test binaries as parallel build-graph steps; the +/// participant-creating ones would otherwise all bind domain-0 RTPS ports +/// (SPDP multicast 7400, …) and race for them — a real CI flake, worst on the +/// slow ARM64 / DebugAllocator / TSan lanes. `next` is a per-lane counter +/// (each `zig build ` runs one lane's binaries at once); domains stay in +/// `1..232` (`7400 + 250*domain < 65536`). See `test/support/domain.zig`. +fn addTestRun(b: *std.Build, t: *std.Build.Step.Compile, next: *u32) *std.Build.Step.Run { + const r = b.addRunArtifact(t); + r.setEnvironmentVariable("ZZDDS_TEST_DOMAIN_BASE", b.fmt("{d}", .{next.*})); + next.* += 1; + return r; +} + /// Directories containing `jni.h`/`jni_md.h` for the JDK backing `java_path` /// (the `java` executable's own path, e.g. from `b.findProgram`). Resolves /// symlink chains (PATH/update-alternatives-style) back to a real @@ -1121,6 +1136,13 @@ pub fn build(b: *std.Build) void { // ── Unit tests ──────────────────────────────────────────────────────────── + // Shared by every DCPS test module (see `addTestRun` / test/support/domain.zig). + // link_libc: it reads its env var via std.c.getenv. + const test_domain_mod = b.createModule(.{ + .root_source_file = b.path("test/support/domain.zig"), + .link_libc = true, + }); + const test_step = b.step("test", "Run Zenzen DDS tests"); // emit-tests: compile all test binaries to zig-out/tests/ for kcov coverage analysis. @@ -1293,6 +1315,7 @@ pub fn build(b: *std.Build) void { "test/dcps/participant_vtable_test.zig", "test/dcps/writer_vtable_test.zig", }; + var dcps_test_domain: u32 = 1; for (dcps_test_files) |src| { const t = b.addTest(.{ .name = std.fs.path.stem(src), @@ -1303,11 +1326,12 @@ pub fn build(b: *std.Build) void { .{ .name = "zzdds", .module = zzdds_mod }, .{ .name = "zzdds_generated", .module = generated_dcps_mod }, .{ .name = "zidl_rt", .module = zidl_rt_mod }, + .{ .name = "test_domain", .module = test_domain_mod }, }, }), }); t.root_module.link_libc = true; - test_step.dependOn(&b.addRunArtifact(t).step); + test_step.dependOn(&addTestRun(b, t, &dcps_test_domain).step); emit_tests_step.dependOn(&b.addInstallArtifact(t, .{ .dest_dir = .{ .override = .{ .custom = "tests" } }, }).step); @@ -1398,6 +1422,27 @@ pub fn build(b: *std.Build) void { const emit_tests_llvm_step = b.step("emit-tests-llvm", "Build test binaries (LLVM backend, baseline CPU) for external DWARF-reading tools like Valgrind"); + // `zig build test-release-small -Doptimize=ReleaseSmall` — run the whole + // unit suite at ReleaseSmall. It reuses the LLVM-backend / baseline-CPU + // module graph above (the same `.use_llvm = true` artifacts emit-tests-llvm + // installs) rather than the normal self-hosted `test` step, purely to dodge + // an upstream Zig bug: Zig 0.16.0's self-hosted x86_64 backend, *only* at + // -OReleaseSmall, emits read-only global constants (vtable structs, + // `CAbiViews` values) with no alignment -- `&SomeImpl.views` lands at an odd + // address and `zidl_rt`'s `@alignCast(box.vtable)` traps it (`panic: + // incorrect alignment`), crashing ~37 C-ABI tests. The LLVM backend aligns + // rodata correctly in every mode; Debug/ReleaseSafe/ReleaseFast on the + // self-hosted backend are also fine -- ReleaseSmall is the only broken cell. + // The bug is fixed on Zig master (0.17.0-dev.1902+); it is not in any stable + // release (0.16.0, tagged 2026-04-13, is latest). Minimal repro + full trail: + // `zz-dev/releasesmall-misaligned-rodata-investigation.md`. + // + // AT THE ZIG 0.17 BUMP: delete this step and its run-artifact deps below, + // and add a plain `release-small` entry to scripts/run_deterministic_matrix.py + // and release.yml, mirroring `release-fast` (`zig build test + // -Doptimize=ReleaseSmall` on the normal self-hosted backend). + const test_release_small_step = b.step("test-release-small", "Run the unit suite at ReleaseSmall (LLVM backend -- see comment: works around a Zig 0.16 self-hosted-backend rodata-alignment bug)"); + const zzdds_tests_llvm = b.addTest(.{ .name = "zzdds_lib", .root_module = zzdds_mod_llvm_safe, @@ -1406,6 +1451,7 @@ pub fn build(b: *std.Build) void { emit_tests_llvm_step.dependOn(&b.addInstallArtifact(zzdds_tests_llvm, .{ .dest_dir = .{ .override = .{ .custom = "tests-llvm" } }, }).step); + test_release_small_step.dependOn(&b.addRunArtifact(zzdds_tests_llvm).step); for (fuzz_test_files) |src| { const t = b.addTest(.{ @@ -1423,6 +1469,7 @@ pub fn build(b: *std.Build) void { emit_tests_llvm_step.dependOn(&b.addInstallArtifact(t, .{ .dest_dir = .{ .override = .{ .custom = "tests-llvm" } }, }).step); + test_release_small_step.dependOn(&b.addRunArtifact(t).step); } for (transport_test_files) |src| { @@ -1441,6 +1488,7 @@ pub fn build(b: *std.Build) void { emit_tests_llvm_step.dependOn(&b.addInstallArtifact(t, .{ .dest_dir = .{ .override = .{ .custom = "tests-llvm" } }, }).step); + test_release_small_step.dependOn(&b.addRunArtifact(t).step); } for (discovery_test_files) |src| { @@ -1459,6 +1507,7 @@ pub fn build(b: *std.Build) void { emit_tests_llvm_step.dependOn(&b.addInstallArtifact(t, .{ .dest_dir = .{ .override = .{ .custom = "tests-llvm" } }, }).step); + test_release_small_step.dependOn(&b.addRunArtifact(t).step); } for (rtps_test_files) |src| { @@ -1477,8 +1526,10 @@ pub fn build(b: *std.Build) void { emit_tests_llvm_step.dependOn(&b.addInstallArtifact(t, .{ .dest_dir = .{ .override = .{ .custom = "tests-llvm" } }, }).step); + test_release_small_step.dependOn(&b.addRunArtifact(t).step); } + var rs_dcps_test_domain: u32 = 1; for (dcps_test_files) |src| { const t = b.addTest(.{ .name = std.fs.path.stem(src), @@ -1490,6 +1541,7 @@ pub fn build(b: *std.Build) void { .{ .name = "zzdds", .module = zzdds_mod_llvm_safe }, .{ .name = "zzdds_generated", .module = generated_dcps_mod_llvm_safe }, .{ .name = "zidl_rt", .module = zidl_rt_mod_llvm_safe }, + .{ .name = "test_domain", .module = test_domain_mod }, }, }), }); @@ -1497,6 +1549,7 @@ pub fn build(b: *std.Build) void { emit_tests_llvm_step.dependOn(&b.addInstallArtifact(t, .{ .dest_dir = .{ .override = .{ .custom = "tests-llvm" } }, }).step); + test_release_small_step.dependOn(&addTestRun(b, t, &rs_dcps_test_domain).step); } // ── TSan test step ──────────────────────────────────────────────────────── @@ -1582,6 +1635,7 @@ pub fn build(b: *std.Build) void { } // DCPS tests (TSan) — WaitSet thread test, loopback + var tsan_dcps_test_domain: u32 = 1; for (dcps_test_files) |src| { const t = b.addTest(.{ .root_module = b.createModule(.{ .root_source_file = b.path(src), @@ -1591,10 +1645,11 @@ pub fn build(b: *std.Build) void { .{ .name = "zzdds", .module = zzdds_mod_tsan }, .{ .name = "zzdds_generated", .module = generated_dcps_mod_tsan }, .{ .name = "zidl_rt", .module = zidl_rt_mod_tsan }, + .{ .name = "test_domain", .module = test_domain_mod }, }, }), .use_llvm = true }); t.root_module.link_libc = true; - tsan_step.dependOn(&b.addRunArtifact(t).step); + tsan_step.dependOn(&addTestRun(b, t, &tsan_dcps_test_domain).step); } // `zig build test-tsan-self-check` — regression guard proving TSan diff --git a/docs/design/ci-platform-coverage-expansion.md b/docs/design/ci-platform-coverage-expansion.md index 7eb66679..b9cab46c 100644 --- a/docs/design/ci-platform-coverage-expansion.md +++ b/docs/design/ci-platform-coverage-expansion.md @@ -220,18 +220,29 @@ discover it as a confusing CI failure. `Test (ReleaseFast)` step is in `release.yml`'s `test` job on all four platforms. No safety-panic-dependent tests were found; the suite passes clean. -**Outcome — `ReleaseSmall` NOT landed; root-caused to an upstream Zig bug (2026-08-29):** -`zig build test -Doptimize=ReleaseSmall` produces 37 `panic: incorrect alignment` crashes -(`bootstrap_test` / `typesupport_test`, via `zidl-rt`'s `entity_box.zig` `unboxAsView` -`@alignCast(box.vtable)`). Traced to **Zig 0.16.0's self-hosted x86_64 backend emitting -read-only global constants with no alignment, only at `-OReleaseSmall`**: `&SomeImpl.views` -(an `extern struct` with `@alignOf` 8) and every `*_vtable` global land at odd addresses, -byte-packed in `.rodata`; `unboxAsView`'s `@alignCast` correctly traps it. Not a zzdds/zidl -defect — reproduces in ~10 lines with a bare `const val: u32` (`-OReleaseSmall -fno-llvm --fno-lld` → 1-mod-4; `-OReleaseFast`, the LLVM backend, and Debug/ReleaseSafe all fine). -Full trail + minimal repro: `zz-dev/releasesmall-misaligned-rodata-investigation.md`. -Follow-ups: (1) file against `ziglang/zig`; (2) a ReleaseSmall lane, if wanted before the -fix lands, must force `.use_llvm = true` (as `emit-tests-llvm` already does for Valgrind). +**Outcome — `ReleaseSmall` landed 2026-08-29 via an LLVM-backend workaround (upstream bug +root-caused + confirmed fixed on Zig master).** First finding: `zig build test +-Doptimize=ReleaseSmall` produced 37 `panic: incorrect alignment` crashes (`bootstrap_test` +/ `typesupport_test`, via `zidl-rt`'s `entity_box.zig` `unboxAsView` `@alignCast(box.vtable)`). +Root cause: **Zig 0.16.0's self-hosted x86_64 backend emits read-only global constants with +no alignment, only at `-OReleaseSmall`** — `&SomeImpl.views` (an `extern struct` with +`@alignOf` 8) and every `*_vtable` global land at odd `.rodata` addresses; `@alignCast` +correctly traps it. Not a zzdds/zidl defect — reproduces in ~10 lines with a bare +`const val: u32` (`-OReleaseSmall -fno-llvm -fno-lld` → 1-mod-4; `-OReleaseFast`, the LLVM +backend, and Debug/ReleaseSafe all fine). **Fixed on `zig-0.17.0-dev.1902+896bd9e15`**; +still broken on 0.16.0 (the pinned toolchain and latest stable, tagged 2026-04-13; no +matching upstream issue, nothing to file). Full trail + repro: +`zz-dev/releasesmall-misaligned-rodata-investigation.md`. + +**What landed:** a new `zig build test-release-small` step (`build.zig`) that runs the whole +unit suite at `-OReleaseSmall` **on the LLVM backend** — it reuses the baseline-CPU / +`.use_llvm = true` module graph the `emit-tests-llvm` step already builds, and adds +`b.addRunArtifact` for each test binary. Wired into `run_deterministic_matrix.py` as the +`release-small` step (so `ci.yml`'s `test-linux` runs it) and into `release.yml`'s `test` +job as `Test (ReleaseSmall, LLVM backend)`, gated to `ubuntu-latest` (the workaround path is +Linux-exercised only). **At the Zig 0.17 bump:** delete `test-release-small` + its run-deps, +replace the matrix/release.yml entries with a plain `zig build test -Doptimize=ReleaseSmall` +on the normal self-hosted backend, and broaden the `release.yml` step to the whole matrix. ## Cross-cutting implementation notes diff --git a/docs/roadmap.md b/docs/roadmap.md index 0e1c3ed7..e80fe797 100644 --- a/docs/roadmap.md +++ b/docs/roadmap.md @@ -334,6 +334,15 @@ Audit of `build.zig` options, `scripts/run_deterministic_matrix.py`, `ci.yml`, a CMake package files) on each of the four release platforms, verifies completeness, and uploads a per-platform tarball that `publish` attaches to the GitHub release. Functional coverage of the bundled libraries is the `test` job's `test-bindings` step. +- **`ReleaseSmall` lane** (2026-08-29) — new `zig build test-release-small` step runs the + whole unit suite at `-OReleaseSmall`, wired into `run_deterministic_matrix.py` (so + `ci.yml`'s `test-linux` covers it) and `release.yml`'s `test` job (Linux x86_64 only). + The step **forces the LLVM backend** to sidestep a Zig 0.16 self-hosted-x86_64 codegen bug + (misaligned read-only globals at `-OReleaseSmall` — see the Deferred note below and the + step's `build.zig` comment). **At the Zig 0.17 bump: delete `test-release-small` and + replace it with a plain `zig build test -Doptimize=ReleaseSmall` step on the normal + self-hosted backend, broadened to the whole `release.yml` matrix** — the bug is fixed on + 0.17. ### Deferred (investigation trails exist) @@ -346,19 +355,16 @@ Audit of `build.zig` options, `scripts/run_deterministic_matrix.py`, `ci.yml`, a drift). Revisit when Zig bundles a newer LLVM. Trail: `zz-dev/macos-tsan-crash-investigation.md`. (TSan on Windows: Clang/LLVM has no supported target. Extending `examples-tsan` to macOS is a separate follow-up.) -- **`ReleaseSmall` gate — blocked on an upstream Zig codegen bug (root-caused 2026-08-29).** - `zig build test -Doptimize=ReleaseSmall` produces 37 `panic: incorrect alignment` crashes - (in `bootstrap_test` / `typesupport_test`, via `zidl-rt`'s `entity_box.zig` `unboxAsView` - `@alignCast(box.vtable)`). Root cause: **Zig 0.16.0's self-hosted x86_64 backend, only at - `-OReleaseSmall`, emits read-only global constants with no alignment** — `&SomeImpl.views` - (an `extern struct` `CAbiViews`, `@alignOf` 8) and every `*_vtable` global land at odd - addresses, packed byte-to-byte in `.rodata`. `unboxAsView`'s `@alignCast` correctly traps - it. Not a zzdds or zidl defect. Minimal repro (deterministic, ~10 lines): a bare - `const val: u32 = …` preceded by a 1-byte `const` lands 1-mod-4 under - `-OReleaseSmall -fno-llvm -fno-lld`; fine under `-OReleaseFast`, fine with the LLVM - backend, fine under Debug/ReleaseSafe. Full trail + repro in - `zz-dev/releasesmall-misaligned-rodata-investigation.md`. Next: file against `ziglang/zig`; - a ReleaseSmall CI lane would need `.use_llvm = true` (like `emit-tests-llvm`) until fixed. +- **Self-hosted `-OReleaseSmall` on Zig 0.16 — upstream codegen bug, worked around above.** + Zig 0.16.0's self-hosted x86_64 backend, *only* at `-OReleaseSmall`, emits read-only + global constants with no alignment: `&SomeImpl.views` (an `extern struct` `CAbiViews`, + `@alignOf` 8) and every `*_vtable` global land at odd `.rodata` addresses, and `zidl-rt`'s + `@alignCast(box.vtable)` traps it (`panic: incorrect alignment`, ~37 C-ABI tests). + `-OReleaseFast`, the LLVM backend, and Debug/ReleaseSafe are all fine. Not a zzdds/zidl + defect; **fixed on `zig-0.17.0-dev.1902`**, not in any stable release (0.16.0, tagged + 2026-04-13, is latest; no matching upstream issue found). The `ReleaseSmall` lane + (see *Landed*) sidesteps it by forcing the LLVM backend until the 0.17 bump. Minimal repro + + full trail: `zz-dev/releasesmall-misaligned-rodata-investigation.md`. ### Still open, ranked diff --git a/scripts/run_deterministic_matrix.py b/scripts/run_deterministic_matrix.py index 98a1f58d..ccdf1a9f 100755 --- a/scripts/run_deterministic_matrix.py +++ b/scripts/run_deterministic_matrix.py @@ -3,9 +3,14 @@ This is a convenience wrapper around the checks that are useful before pushing: formatting, sleep guardrails, Debug tests, feature-minimal tests, ReleaseSafe -tests, ReleaseFast tests, and fuzz harness compile-checks. ThreadSanitizer is -available as an opt-in because it is slower and can be noisy on some local -systems. +tests, ReleaseFast tests, ReleaseSmall tests, and fuzz harness compile-checks. +ThreadSanitizer is available as an opt-in because it is slower and can be noisy +on some local systems. + +The ReleaseSmall step runs via `zig build test-release-small`, which forces the +LLVM backend: Zig 0.16's self-hosted x86_64 backend mis-aligns read-only globals +at -OReleaseSmall (see that step's comment in build.zig). Drop back to a plain +`zig build test -Doptimize=ReleaseSmall` step at the Zig 0.17 bump. """ from __future__ import annotations @@ -49,6 +54,7 @@ def parse_args() -> argparse.Namespace: "feature-minimal", "release-safe", "release-fast", + "release-small", "fuzz", "tsan-self-check", "tsan", @@ -67,6 +73,10 @@ def steps(zig: str, include_tsan: bool) -> list[Step]: Step("feature-minimal", [zig, "build", "test", "-Dipv6=false", "-Dinterface-monitor=false"]), Step("release-safe", [zig, "build", "test", "-Doptimize=ReleaseSafe"]), Step("release-fast", [zig, "build", "test", "-Doptimize=ReleaseFast"]), + # LLVM backend forced by the `test-release-small` step itself -- see its + # build.zig comment. Switch to `["test", "-Doptimize=ReleaseSmall"]` at + # the Zig 0.17 bump. + Step("release-small", [zig, "build", "test-release-small", "-Doptimize=ReleaseSmall"]), Step("fuzz", [zig, "build", "test-fuzz"]), ] if include_tsan: diff --git a/test/c_abi/bootstrap_test.zig b/test/c_abi/bootstrap_test.zig index f3457a74..a9f67197 100644 --- a/test/c_abi/bootstrap_test.zig +++ b/test/c_abi/bootstrap_test.zig @@ -9,6 +9,7 @@ //! - topic_as_description: verified against the CFT TopicDescription vtable. const std = @import("std"); +const test_domain = @import("test_domain"); const testing = std.testing; const zzdds = @import("zzdds"); const DDS = @import("zzdds_generated").DDS; @@ -87,7 +88,7 @@ const Fixture = struct { errdefer d_w.deinit(); const factory_w = try DomainParticipantFactoryImpl.init(alloc, t_w.transport(), d_w.toDiscovery(), noop_security, .spec_random, .{}); errdefer factory_w.deinit(); - const dp_w = factory_w.toDDSFactory().create_participant(0, .{}, null, 0); + const dp_w = factory_w.toDDSFactory().create_participant(test_domain.get(), .{}, null, 0); const pub_w = dp_w.create_publisher(.{}, null, 0); const topic_w = dp_w.create_topic("BootTopic", "BootType", .{}, null, 0); @@ -97,7 +98,7 @@ const Fixture = struct { errdefer d_r.deinit(); const factory_r = try DomainParticipantFactoryImpl.init(alloc, t_r.transport(), d_r.toDiscovery(), noop_security, .spec_random, .{}); errdefer factory_r.deinit(); - const dp_r = factory_r.toDDSFactory().create_participant(0, .{}, null, 0); + const dp_r = factory_r.toDDSFactory().create_participant(test_domain.get(), .{}, null, 0); const sub_r = dp_r.create_subscriber(.{}, null, 0); const topic_r = dp_r.create_topic("BootTopic", "BootType", .{}, null, 0); @@ -173,7 +174,7 @@ test "support factory: generated create_participant and delete_participant" { const ext_factory = zidl_rt.unboxAsView(ZZDDS.DomainParticipantFactory, ext_factory_boxed); const factory = ext_factory.vtable.as_DomainParticipantFactory(ext_factory.ptr); - const dp = DDS_DomainParticipantFactory_create_participant_for_test(factory, 0, null); + const dp = DDS_DomainParticipantFactory_create_participant_for_test(factory, test_domain.get(), null); try testing.expect(dp.ptr != zzdds.dcps.NIL_PTR); try testing.expectEqual(DDS.RETCODE_OK, factory.delete_participant(dp)); } @@ -185,7 +186,7 @@ test "support factory: generated create_participant_ex uses config defaults" { const cfg = ZZDDS.DomainParticipantConfig.default(); const qos = DDS.DomainParticipantQos{}; - const dp = ext_factory.create_participant_ex(0, qos, null, 0, cfg); + const dp = ext_factory.create_participant_ex(test_domain.get(), qos, null, 0, cfg); try testing.expect(dp.ptr != zzdds.dcps.NIL_PTR); const factory = ext_factory.vtable.as_DomainParticipantFactory(ext_factory.ptr); @@ -267,7 +268,7 @@ test "support factory: zzdds_create_factory_with_allocator routes every allocati // allocator, not silently fall back to std.heap.c_allocator. const cfg = ZZDDS.DomainParticipantConfig.default(); const qos = DDS.DomainParticipantQos{}; - const dp = ext_factory.create_participant_ex(0, qos, null, 0, cfg); + const dp = ext_factory.create_participant_ex(test_domain.get(), qos, null, 0, cfg); try testing.expect(dp.ptr != zzdds.dcps.NIL_PTR); try testing.expect(track.alloc_calls.load(.monotonic) > calls_after_bootstrap); @@ -384,7 +385,7 @@ test "get_allocator: extensions-layer C-ABI vtables return the injected custom a const cfg = ZZDDS.DomainParticipantConfig.default(); const qos = DDS.DomainParticipantQos{}; - const dp = ext_factory.create_participant_ex(0, qos, null, 0, cfg); + const dp = ext_factory.create_participant_ex(test_domain.get(), qos, null, 0, cfg); defer _ = factory.delete_participant(dp); try testing.expectEqual(expected, dp.vtable.get_allocator(dp.ptr)); diff --git a/test/c_abi/typesupport_test.zig b/test/c_abi/typesupport_test.zig index 32e59590..a569ce90 100644 --- a/test/c_abi/typesupport_test.zig +++ b/test/c_abi/typesupport_test.zig @@ -4,6 +4,7 @@ //! compute_key_hash function pointer into the Zig TypeSupport infrastructure. const std = @import("std"); +const test_domain = @import("test_domain"); const testing = std.testing; const zzdds = @import("zzdds"); const DDS = @import("zzdds_generated").DDS; @@ -87,7 +88,7 @@ const Fixture = struct { .{}, ); errdefer factory.deinit(); - const dp = factory.toDDSFactory().create_participant(0, .{}, null, 0); + const dp = factory.toDDSFactory().create_participant(test_domain.get(), .{}, null, 0); const dp_boxed = try zidl_rt.boxEntity(alloc, dp.ptr, &DomainParticipantImpl.views); return .{ .delivery = delivery, .t = t, .d = d, .factory = factory, .dp = dp, .dp_boxed = dp_boxed, .alloc = alloc }; } diff --git a/test/dcps/api_test.zig b/test/dcps/api_test.zig index 869714f4..8a6547ce 100644 --- a/test/dcps/api_test.zig +++ b/test/dcps/api_test.zig @@ -8,6 +8,7 @@ //! threads are needed. const std = @import("std"); +const test_domain = @import("test_domain"); const zzdds = @import("zzdds"); const DDS = @import("zzdds_generated").DDS; @@ -110,7 +111,7 @@ test "DCPS: create_participant / delete_participant" { defer h.deinit(); const dpf = h.factory.toDDSFactory(); - const dp = dpf.create_participant(0, .{}, null, 0); + const dp = dpf.create_participant(test_domain.get(), .{}, null, 0); // ptr is *anyopaque; verify it's not the null address try testing.expect(@intFromPtr(dp.ptr) != 0); @@ -123,7 +124,7 @@ test "DCPS: delete_participant with outstanding children fails" { defer h.deinit(); const dpf = h.factory.toDDSFactory(); - const dp = dpf.create_participant(0, .{}, null, 0); + const dp = dpf.create_participant(test_domain.get(), .{}, null, 0); // Create a publisher without deleting it. _ = dp.create_publisher(.{}, null, 0); @@ -143,7 +144,7 @@ test "DCPS: create/delete Publisher and Subscriber" { defer h.deinit(); const dpf = h.factory.toDDSFactory(); - const dp = dpf.create_participant(0, .{}, null, 0); + const dp = dpf.create_participant(test_domain.get(), .{}, null, 0); defer _ = dpf.delete_participant(dp); const pub_ = dp.create_publisher(.{}, null, 0); @@ -161,7 +162,7 @@ test "DCPS: create/delete Topic" { defer h.deinit(); const dpf = h.factory.toDDSFactory(); - const dp = dpf.create_participant(0, .{}, null, 0); + const dp = dpf.create_participant(test_domain.get(), .{}, null, 0); defer _ = dpf.delete_participant(dp); const topic = dp.create_topic( @@ -184,7 +185,7 @@ test "DCPS: create/delete DataWriter and DataReader" { defer h.deinit(); const dpf = h.factory.toDDSFactory(); - const dp = dpf.create_participant(0, .{}, null, 0); + const dp = dpf.create_participant(test_domain.get(), .{}, null, 0); defer _ = dpf.delete_participant(dp); const pub_ = dp.create_publisher(.{}, null, 0); @@ -211,7 +212,7 @@ test "DCPS: delete_contained_entities removes all children" { defer h.deinit(); const dpf = h.factory.toDDSFactory(); - const dp = dpf.create_participant(0, .{}, null, 0); + const dp = dpf.create_participant(test_domain.get(), .{}, null, 0); const pub_ = dp.create_publisher(.{}, null, 0); const sub_ = dp.create_subscriber(.{}, null, 0); @@ -321,7 +322,7 @@ test "DCPS: get_statuscondition on participant returns bound condition" { defer h.deinit(); const dpf = h.factory.toDDSFactory(); - const dp = dpf.create_participant(0, .{}, null, 0); + const dp = dpf.create_participant(test_domain.get(), .{}, null, 0); defer _ = dpf.delete_participant(dp); const sc = dp.vtable.get_statuscondition(dp.ptr); @@ -335,7 +336,7 @@ test "DCPS: get_statuscondition on DataWriter returns non-null condition" { defer h.deinit(); const dpf = h.factory.toDDSFactory(); - const dp = dpf.create_participant(0, .{}, null, 0); + const dp = dpf.create_participant(test_domain.get(), .{}, null, 0); defer _ = dpf.delete_participant(dp); const pub_ = dp.create_publisher(.{}, null, 0); @@ -374,7 +375,7 @@ test "DCPS: DCPSTopic reader receives a sample when a topic is created" { const alloc = testing.allocator; const dpf = h.factory.toDDSFactory(); - const dp = dpf.create_participant(0, .{}, null, 0); + const dp = dpf.create_participant(test_domain.get(), .{}, null, 0); defer _ = dpf.delete_participant(dp); const bs_sub = dp.vtable.get_builtin_subscriber(dp.ptr); @@ -396,7 +397,7 @@ test "DCPS: DCPSPublication reports endpoint identity and disposal" { const alloc = testing.allocator; const dpf = h.factory.toDDSFactory(); - const dp = dpf.create_participant(0, .{}, null, 0); + const dp = dpf.create_participant(test_domain.get(), .{}, null, 0); defer _ = dpf.delete_participant(dp); const dp_impl: *DomainParticipantImpl = @ptrCast(@alignCast(dp.ptr)); @@ -428,7 +429,7 @@ test "DCPS: get_discovered_topics returns handle for a SEDP-discovered writer's const alloc = testing.allocator; const dpf = h.factory.toDDSFactory(); - const dp = dpf.create_participant(0, .{}, null, 0); + const dp = dpf.create_participant(test_domain.get(), .{}, null, 0); defer _ = dpf.delete_participant(dp); const dp_impl: *DomainParticipantImpl = @ptrCast(@alignCast(dp.ptr)); @@ -449,7 +450,7 @@ test "DCPS: get_discovered_topic_data returns name and type_name for discovered const alloc = testing.allocator; const dpf = h.factory.toDDSFactory(); - const dp = dpf.create_participant(0, .{}, null, 0); + const dp = dpf.create_participant(test_domain.get(), .{}, null, 0); defer _ = dpf.delete_participant(dp); const dp_impl: *DomainParticipantImpl = @ptrCast(@alignCast(dp.ptr)); @@ -478,7 +479,7 @@ test "DCPS: get_discovered_topics deduplicates same topic from multiple writers" const alloc = testing.allocator; const dpf = h.factory.toDDSFactory(); - const dp = dpf.create_participant(0, .{}, null, 0); + const dp = dpf.create_participant(test_domain.get(), .{}, null, 0); defer _ = dpf.delete_participant(dp); const dp_impl: *DomainParticipantImpl = @ptrCast(@alignCast(dp.ptr)); @@ -499,7 +500,7 @@ test "DCPS: contains_entity returns true for participant, topic, publisher, writ defer h.deinit(); const dpf = h.factory.toDDSFactory(); - const dp = dpf.create_participant(0, .{}, null, 0); + const dp = dpf.create_participant(test_domain.get(), .{}, null, 0); defer _ = dpf.delete_participant(dp); const dp_handle = dp.vtable.get_instance_handle(dp.ptr); @@ -529,7 +530,7 @@ test "DCPS: get_discovered_topics and get_discovered_topic_data work for locally const alloc = testing.allocator; const dpf = h.factory.toDDSFactory(); - const dp = dpf.create_participant(0, .{}, null, 0); + const dp = dpf.create_participant(test_domain.get(), .{}, null, 0); defer _ = dpf.delete_participant(dp); _ = dp.create_topic("LocalTopic", "LocalType", .{}, null, 0); @@ -555,7 +556,7 @@ test "DCPS: SEDP announcement for a locally-created topic does not produce a dup const alloc = testing.allocator; const dpf = h.factory.toDDSFactory(); - const dp = dpf.create_participant(0, .{}, null, 0); + const dp = dpf.create_participant(test_domain.get(), .{}, null, 0); defer _ = dpf.delete_participant(dp); _ = dp.create_topic("DupTopic", "DupType", .{}, null, 0); diff --git a/test/dcps/cft_test.zig b/test/dcps/cft_test.zig index 5db61e7b..3193dcf7 100644 --- a/test/dcps/cft_test.zig +++ b/test/dcps/cft_test.zig @@ -6,6 +6,7 @@ //! 3. Integration — CFT DataReader lifecycle and end-to-end sample filtering. const std = @import("std"); +const test_domain = @import("test_domain"); const zzdds = @import("zzdds"); const DDS = @import("zzdds_generated").DDS; @@ -373,7 +374,7 @@ const Fixture = struct { errdefer d_w.deinit(); const factory_w = try DomainParticipantFactoryImpl.init(alloc, t_w.transport(), d_w.toDiscovery(), noop_security, .spec_random, .{}); errdefer factory_w.deinit(); - const dp_w = factory_w.toDDSFactory().create_participant(0, .{}, null, 0); + const dp_w = factory_w.toDDSFactory().create_participant(test_domain.get(), .{}, null, 0); const pub_w = dp_w.create_publisher(.{}, null, 0); const topic_w = dp_w.create_topic("CftTopic", "CftType", .{}, null, 0); @@ -383,7 +384,7 @@ const Fixture = struct { errdefer d_r.deinit(); const factory_r = try DomainParticipantFactoryImpl.init(alloc, t_r.transport(), d_r.toDiscovery(), noop_security, .spec_random, .{}); errdefer factory_r.deinit(); - const dp_r = factory_r.toDDSFactory().create_participant(0, .{}, null, 0); + const dp_r = factory_r.toDDSFactory().create_participant(test_domain.get(), .{}, null, 0); const sub_r = dp_r.create_subscriber(.{}, null, 0); const topic_r = dp_r.create_topic("CftTopic", "CftType", .{}, null, 0); diff --git a/test/dcps/entity_routing_test.zig b/test/dcps/entity_routing_test.zig index cf31c125..ffe7642c 100644 --- a/test/dcps/entity_routing_test.zig +++ b/test/dcps/entity_routing_test.zig @@ -11,6 +11,7 @@ //! data port. MemoryTransport.send() is synchronous, so assertions are immediate. const std = @import("std"); +const test_domain = @import("test_domain"); const testing = std.testing; const zzdds = @import("zzdds"); const DDS = @import("zzdds_generated").DDS; @@ -287,7 +288,7 @@ const Fixture = struct { errdefer d_w.deinit(); const factory_w = try DomainParticipantFactoryImpl.init(alloc, t_w.transport(), d_w.toDiscovery(), noop_security, .spec_random, .{}); errdefer factory_w.deinit(); - const dp_w = factory_w.toDDSFactory().create_participant(0, .{}, null, 0); + const dp_w = factory_w.toDDSFactory().create_participant(test_domain.get(), .{}, null, 0); const dp_w_impl: *DomainParticipantImpl = @ptrCast(@alignCast(dp_w.ptr)); const t_r = try delivery.newTransport(); @@ -296,7 +297,7 @@ const Fixture = struct { errdefer d_r.deinit(); const factory_r = try DomainParticipantFactoryImpl.init(alloc, t_r.transport(), d_r.toDiscovery(), noop_security, .spec_random, .{}); errdefer factory_r.deinit(); - const dp_r = factory_r.toDDSFactory().create_participant(0, .{}, null, 0); + const dp_r = factory_r.toDDSFactory().create_participant(test_domain.get(), .{}, null, 0); const dp_r_impl: *DomainParticipantImpl = @ptrCast(@alignCast(dp_r.ptr)); const sub_r = dp_r.create_subscriber(.{}, null, 0); diff --git a/test/dcps/factory_vtable_test.zig b/test/dcps/factory_vtable_test.zig index e673a2b8..9e2f63b6 100644 --- a/test/dcps/factory_vtable_test.zig +++ b/test/dcps/factory_vtable_test.zig @@ -5,6 +5,7 @@ //! set/get_qos, deinit-via-vtable. const std = @import("std"); +const test_domain = @import("test_domain"); const zzdds = @import("zzdds"); const DDS = @import("zzdds_generated").DDS; @@ -93,10 +94,10 @@ test "lookup_participant: returns participant for matching domain_id" { var h = try Harness.init(1); defer h.deinit(); const f = h.factory.toDDSFactory(); - const dp = f.create_participant(7, .{}, null, 0); + const dp = f.create_participant(test_domain.get(), .{}, null, 0); defer _ = f.vtable.delete_participant(f.ptr, dp); - const found = f.vtable.lookup_participant(f.ptr, 7); + const found = f.vtable.lookup_participant(f.ptr, test_domain.get()); try testing.expect(found.ptr == dp.ptr); } @@ -104,7 +105,7 @@ test "lookup_participant: returns nil for unknown domain_id" { var h = try Harness.init(2); defer h.deinit(); const f = h.factory.toDDSFactory(); - const dp = f.create_participant(7, .{}, null, 0); + const dp = f.create_participant(test_domain.get(), .{}, null, 0); defer _ = f.vtable.delete_participant(f.ptr, dp); const found = f.vtable.lookup_participant(f.ptr, 99); diff --git a/test/dcps/get_field_refresh_test.zig b/test/dcps/get_field_refresh_test.zig index 7d6b9cb4..cc02cbc4 100644 --- a/test/dcps/get_field_refresh_test.zig +++ b/test/dcps/get_field_refresh_test.zig @@ -23,6 +23,7 @@ //! to reproduce with a single-threaded interleaving test. const std = @import("std"); +const test_domain = @import("test_domain"); const testing = std.testing; const zzdds = @import("zzdds"); const DDS = @import("zzdds_generated").DDS; @@ -66,7 +67,7 @@ const Fixture = struct { errdefer d_r.deinit(); const factory_r = try DomainParticipantFactoryImpl.init(alloc, t_r.transport(), d_r.toDiscovery(), noop_security, .spec_random, .{}); errdefer factory_r.deinit(); - const dp_r = factory_r.toDDSFactory().create_participant(0, .{}, null, 0); + const dp_r = factory_r.toDDSFactory().create_participant(test_domain.get(), .{}, null, 0); const sub_r = dp_r.create_subscriber(.{}, null, 0); const topic_r = dp_r.create_topic("GfrTopic", "GfrType", .{}, null, 0); diff --git a/test/dcps/ignore_test.zig b/test/dcps/ignore_test.zig index db501188..b379191d 100644 --- a/test/dcps/ignore_test.zig +++ b/test/dcps/ignore_test.zig @@ -4,6 +4,7 @@ //! sockets or background threads are needed. const std = @import("std"); +const test_domain = @import("test_domain"); const zzdds = @import("zzdds"); const DDS = @import("zzdds_generated").DDS; @@ -176,7 +177,7 @@ test "ignore_participant: removes from discovered cache" { defer h.deinit(); const dpf = h.factory.toDDSFactory(); - const dp = dpf.create_participant(0, .{}, null, 0); + const dp = dpf.create_participant(test_domain.get(), .{}, null, 0); defer _ = dpf.delete_participant(dp); const dp_impl: *DomainParticipantImpl = @ptrCast(@alignCast(dp.ptr)); @@ -212,7 +213,7 @@ test "ignore_participant: blocks future announcements from same prefix" { defer h.deinit(); const dpf = h.factory.toDDSFactory(); - const dp = dpf.create_participant(0, .{}, null, 0); + const dp = dpf.create_participant(test_domain.get(), .{}, null, 0); defer _ = dpf.delete_participant(dp); const dp_impl: *DomainParticipantImpl = @ptrCast(@alignCast(dp.ptr)); @@ -242,7 +243,7 @@ test "ignore_participant: bad handle returns RETCODE_BAD_PARAMETER" { defer h.deinit(); const dpf = h.factory.toDDSFactory(); - const dp = dpf.create_participant(0, .{}, null, 0); + const dp = dpf.create_participant(test_domain.get(), .{}, null, 0); defer _ = dpf.delete_participant(dp); const rc = dp.vtable.ignore_participant(dp.ptr, 0x7FFF_FFFF); @@ -254,7 +255,7 @@ test "ignore_participant: writer from ignored prefix not matched" { defer h.deinit(); const dpf = h.factory.toDDSFactory(); - const dp = dpf.create_participant(0, .{}, null, 0); + const dp = dpf.create_participant(test_domain.get(), .{}, null, 0); defer _ = dpf.delete_participant(dp); const dp_impl: *DomainParticipantImpl = @ptrCast(@alignCast(dp.ptr)); @@ -292,7 +293,7 @@ test "ignore_participant: reader from ignored prefix not matched to writer" { defer h.deinit(); const dpf = h.factory.toDDSFactory(); - const dp = dpf.create_participant(0, .{}, null, 0); + const dp = dpf.create_participant(test_domain.get(), .{}, null, 0); defer _ = dpf.delete_participant(dp); const dp_impl: *DomainParticipantImpl = @ptrCast(@alignCast(dp.ptr)); @@ -329,7 +330,7 @@ test "ignore_topic: bad handle returns BAD_PARAMETER" { defer h.deinit(); const dpf = h.factory.toDDSFactory(); - const dp = dpf.create_participant(0, .{}, null, 0); + const dp = dpf.create_participant(test_domain.get(), .{}, null, 0); defer _ = dpf.delete_participant(dp); try testing.expectEqual(DDS.RETCODE_BAD_PARAMETER, dp.vtable.ignore_topic(dp.ptr, 0x7FFF_FFFF)); @@ -340,7 +341,7 @@ test "ignore_topic: writer for ignored topic not matched to reader" { defer h.deinit(); const dpf = h.factory.toDDSFactory(); - const dp = dpf.create_participant(0, .{}, null, 0); + const dp = dpf.create_participant(test_domain.get(), .{}, null, 0); defer _ = dpf.delete_participant(dp); const dp_impl: *DomainParticipantImpl = @ptrCast(@alignCast(dp.ptr)); @@ -369,7 +370,7 @@ test "ignore_topic: reader for ignored topic not matched to writer" { defer h.deinit(); const dpf = h.factory.toDDSFactory(); - const dp = dpf.create_participant(0, .{}, null, 0); + const dp = dpf.create_participant(test_domain.get(), .{}, null, 0); defer _ = dpf.delete_participant(dp); const dp_impl: *DomainParticipantImpl = @ptrCast(@alignCast(dp.ptr)); @@ -393,7 +394,7 @@ test "ignore_publication: ignored writer not matched to reader" { defer h.deinit(); const dpf = h.factory.toDDSFactory(); - const dp = dpf.create_participant(0, .{}, null, 0); + const dp = dpf.create_participant(test_domain.get(), .{}, null, 0); defer _ = dpf.delete_participant(dp); const dp_impl: *DomainParticipantImpl = @ptrCast(@alignCast(dp.ptr)); @@ -429,7 +430,7 @@ test "ignore_subscription: ignored reader not matched to writer" { defer h.deinit(); const dpf = h.factory.toDDSFactory(); - const dp = dpf.create_participant(0, .{}, null, 0); + const dp = dpf.create_participant(test_domain.get(), .{}, null, 0); defer _ = dpf.delete_participant(dp); const dp_impl: *DomainParticipantImpl = @ptrCast(@alignCast(dp.ptr)); @@ -460,7 +461,7 @@ test "ignore_publication/subscription: duplicate call is idempotent" { defer h.deinit(); const dpf = h.factory.toDDSFactory(); - const dp = dpf.create_participant(0, .{}, null, 0); + const dp = dpf.create_participant(test_domain.get(), .{}, null, 0); defer _ = dpf.delete_participant(dp); try testing.expectEqual(DDS.RETCODE_OK, dp.vtable.ignore_publication(dp.ptr, 42)); diff --git a/test/dcps/instance_lifecycle_test.zig b/test/dcps/instance_lifecycle_test.zig index 5261dc54..8d0fd48b 100644 --- a/test/dcps/instance_lifecycle_test.zig +++ b/test/dcps/instance_lifecycle_test.zig @@ -4,6 +4,7 @@ //! Uses IntraProcessDelivery (synchronous, no pump) for deterministic delivery. const std = @import("std"); +const test_domain = @import("test_domain"); const zzdds = @import("zzdds"); const DDS = @import("zzdds_generated").DDS; @@ -64,7 +65,7 @@ const Fixture = struct { ); errdefer factory_w.deinit(); const dpf_w = factory_w.toDDSFactory(); - const dp_w = dpf_w.create_participant(0, .{}, null, 0); + const dp_w = dpf_w.create_participant(test_domain.get(), .{}, null, 0); const pub_w = dp_w.create_publisher(.{}, null, 0); const topic_w = dp_w.create_topic("ILTopic", "ILType", .{}, null, 0); @@ -82,7 +83,7 @@ const Fixture = struct { ); errdefer factory_r.deinit(); const dpf_r = factory_r.toDDSFactory(); - const dp_r = dpf_r.create_participant(0, .{}, null, 0); + const dp_r = dpf_r.create_participant(test_domain.get(), .{}, null, 0); const sub_r = dp_r.create_subscriber(.{}, null, 0); const topic_r = dp_r.create_topic("ILTopic", "ILType", .{}, null, 0); diff --git a/test/dcps/intraprocess_test.zig b/test/dcps/intraprocess_test.zig index 12b285ad..b675e302 100644 --- a/test/dcps/intraprocess_test.zig +++ b/test/dcps/intraprocess_test.zig @@ -18,6 +18,7 @@ //! MemoryTransport delivers RTPS DATA synchronously on write(). const std = @import("std"); +const test_domain = @import("test_domain"); const zzdds = @import("zzdds"); const DDS = @import("zzdds_generated").DDS; @@ -86,7 +87,7 @@ const Fixture = struct { ); errdefer factory_w.deinit(); const dpf_w = factory_w.toDDSFactory(); - const dp_w = dpf_w.create_participant(0, .{}, null, 0); + const dp_w = dpf_w.create_participant(test_domain.get(), .{}, null, 0); const pub_w = dp_w.create_publisher(.{}, null, 0); const topic_w = dp_w.create_topic( topic_name, @@ -111,7 +112,7 @@ const Fixture = struct { ); errdefer factory_r.deinit(); const dpf_r = factory_r.toDDSFactory(); - const dp_r = dpf_r.create_participant(0, .{}, null, 0); + const dp_r = dpf_r.create_participant(test_domain.get(), .{}, null, 0); const sub_r = dp_r.create_subscriber(.{}, null, 0); const topic_r = dp_r.create_topic( topic_name, @@ -413,7 +414,7 @@ test "intraprocess: same-participant writer and reader — no self-delivery" { ); defer factory.deinit(); const dpf = factory.toDDSFactory(); - const dp = dpf.create_participant(0, .{}, null, 0); + const dp = dpf.create_participant(test_domain.get(), .{}, null, 0); defer _ = dpf.delete_participant(dp); const publisher = dp.create_publisher(.{}, null, 0); diff --git a/test/dcps/listener_fallback_test.zig b/test/dcps/listener_fallback_test.zig index 13aff0ab..3a1b706f 100644 --- a/test/dcps/listener_fallback_test.zig +++ b/test/dcps/listener_fallback_test.zig @@ -8,6 +8,7 @@ //! vtable) two-participant entity trees. const std = @import("std"); +const test_domain = @import("test_domain"); const zzdds = @import("zzdds"); const DDS = @import("zzdds_generated").DDS; @@ -61,7 +62,7 @@ const Fixture = struct { errdefer d_w.deinit(); const factory_w = try DomainParticipantFactoryImpl.init(alloc, t_w.transport(), d_w.toDiscovery(), noop_security, .spec_random, .{}); errdefer factory_w.deinit(); - const dp_w = factory_w.toDDSFactory().create_participant(0, .{}, null, 0); + const dp_w = factory_w.toDDSFactory().create_participant(test_domain.get(), .{}, null, 0); const pub_w = dp_w.create_publisher(.{}, null, 0); const topic_w = dp_w.create_topic("FallbackTopic", "FallbackType", .{}, null, 0); @@ -71,7 +72,7 @@ const Fixture = struct { errdefer d_r.deinit(); const factory_r = try DomainParticipantFactoryImpl.init(alloc, t_r.transport(), d_r.toDiscovery(), noop_security, .spec_random, .{}); errdefer factory_r.deinit(); - const dp_r = factory_r.toDDSFactory().create_participant(0, .{}, null, 0); + const dp_r = factory_r.toDDSFactory().create_participant(test_domain.get(), .{}, null, 0); const sub_r = dp_r.create_subscriber(.{}, null, 0); const topic_r = dp_r.create_topic("FallbackTopic", "FallbackType", .{}, null, 0); diff --git a/test/dcps/loopback_test.zig b/test/dcps/loopback_test.zig index 26d7724a..d79b1b55 100644 --- a/test/dcps/loopback_test.zig +++ b/test/dcps/loopback_test.zig @@ -5,6 +5,7 @@ //! No external dependencies; runs under `zig build test`. const std = @import("std"); +const test_domain = @import("test_domain"); const zzdds = @import("zzdds"); const DDS = @import("zzdds_generated").DDS; @@ -72,9 +73,9 @@ fn runLoopback( // immediately releases it) and both claim pid=0, causing a unicast port clash. // Each test uses distinct pids so that sequential tests never re-bind ports // that were just released by the previous test (avoids Windows port-reuse races). - const udp_w = try UdpTransport.init(alloc, .{ .participant_id = w_pid }, 0, null); + const udp_w = try UdpTransport.init(alloc, .{ .participant_id = w_pid }, test_domain.get(), null); defer udp_w.deinit(); - const disc_w = try SpdpSedpDiscovery.init(alloc, udp_w.transport(), 0, 1_000); + const disc_w = try SpdpSedpDiscovery.init(alloc, udp_w.transport(), test_domain.get(), 1_000); var factory_w = try DomainParticipantFactoryImpl.init( alloc, udp_w.transport(), @@ -89,7 +90,7 @@ fn runLoopback( } const dpf_w = factory_w.toDDSFactory(); - const dp_w = dpf_w.create_participant(0, .{}, null, 0); + const dp_w = dpf_w.create_participant(test_domain.get(), .{}, null, 0); defer _ = dpf_w.delete_participant(dp_w); const pub_w = dp_w.create_publisher(.{}, null, 0); @@ -133,9 +134,9 @@ fn runLoopback( } // ── Reader participant ──────────────────────────────────────────────────── - const udp_r = try UdpTransport.init(alloc, .{ .participant_id = r_pid }, 0, null); + const udp_r = try UdpTransport.init(alloc, .{ .participant_id = r_pid }, test_domain.get(), null); defer udp_r.deinit(); - const disc_r = try SpdpSedpDiscovery.init(alloc, udp_r.transport(), 0, 1_000); + const disc_r = try SpdpSedpDiscovery.init(alloc, udp_r.transport(), test_domain.get(), 1_000); var factory_r = try DomainParticipantFactoryImpl.init( alloc, udp_r.transport(), @@ -150,7 +151,7 @@ fn runLoopback( } const dpf_r = factory_r.toDDSFactory(); - const dp_r = dpf_r.create_participant(0, .{}, null, 0); + const dp_r = dpf_r.create_participant(test_domain.get(), .{}, null, 0); defer _ = dpf_r.delete_participant(dp_r); const sub_r = dp_r.create_subscriber(.{}, null, 0); @@ -347,9 +348,9 @@ test "loopback: incompatible QoS — best_effort writer vs reliable reader" { dw_qos.reliability.kind = .BEST_EFFORT_RELIABILITY_QOS; dr_qos.reliability.kind = .RELIABLE_RELIABILITY_QOS; - const udp_w = try UdpTransport.init(alloc, .{ .participant_id = 8 }, 0, null); + const udp_w = try UdpTransport.init(alloc, .{ .participant_id = 8 }, test_domain.get(), null); defer udp_w.deinit(); - const disc_w = try SpdpSedpDiscovery.init(alloc, udp_w.transport(), 0, 1_000); + const disc_w = try SpdpSedpDiscovery.init(alloc, udp_w.transport(), test_domain.get(), 1_000); var factory_w = try DomainParticipantFactoryImpl.init( alloc, udp_w.transport(), @@ -364,7 +365,7 @@ test "loopback: incompatible QoS — best_effort writer vs reliable reader" { } const dpf_w = factory_w.toDDSFactory(); - const dp_w = dpf_w.create_participant(0, .{}, null, 0); + const dp_w = dpf_w.create_participant(test_domain.get(), .{}, null, 0); defer _ = dpf_w.delete_participant(dp_w); const pub_w = dp_w.create_publisher(.{}, null, 0); @@ -378,9 +379,9 @@ test "loopback: incompatible QoS — best_effort writer vs reliable reader" { const dw = pub_w.create_datawriter(topic_w, dw_qos, null, 0); const dw_impl: *DataWriterImpl = @ptrCast(@alignCast(dw.ptr)); - const udp_r = try UdpTransport.init(alloc, .{ .participant_id = 9 }, 0, null); + const udp_r = try UdpTransport.init(alloc, .{ .participant_id = 9 }, test_domain.get(), null); defer udp_r.deinit(); - const disc_r = try SpdpSedpDiscovery.init(alloc, udp_r.transport(), 0, 1_000); + const disc_r = try SpdpSedpDiscovery.init(alloc, udp_r.transport(), test_domain.get(), 1_000); var factory_r = try DomainParticipantFactoryImpl.init( alloc, udp_r.transport(), @@ -395,7 +396,7 @@ test "loopback: incompatible QoS — best_effort writer vs reliable reader" { } const dpf_r = factory_r.toDDSFactory(); - const dp_r = dpf_r.create_participant(0, .{}, null, 0); + const dp_r = dpf_r.create_participant(test_domain.get(), .{}, null, 0); defer _ = dpf_r.delete_participant(dp_r); const sub_r = dp_r.create_subscriber(.{}, null, 0); @@ -459,9 +460,9 @@ test "loopback: a single participant's own writer and reader on the same topic m // participant itself, reusing the exact same proxy-wiring path already // proven correct for remote participants (the other tests in this file). const alloc = std.testing.allocator; - const udp = try UdpTransport.init(alloc, .{ .participant_id = 12 }, 0, null); + const udp = try UdpTransport.init(alloc, .{ .participant_id = 12 }, test_domain.get(), null); defer udp.deinit(); - const disc = try SpdpSedpDiscovery.init(alloc, udp.transport(), 0, 1_000); + const disc = try SpdpSedpDiscovery.init(alloc, udp.transport(), test_domain.get(), 1_000); var factory = try DomainParticipantFactoryImpl.init( alloc, udp.transport(), @@ -476,7 +477,7 @@ test "loopback: a single participant's own writer and reader on the same topic m } const dpf = factory.toDDSFactory(); - const dp = dpf.create_participant(0, .{}, null, 0); + const dp = dpf.create_participant(test_domain.get(), .{}, null, 0); defer _ = dpf.delete_participant(dp); var dw_qos = DDS.DataWriterQos{}; @@ -560,9 +561,9 @@ fn waitForRawOpTake(dr: DDS.DataReader, payloads_seq: *DDS.OctetSeqSeq, hashes_s test "loopback: DDS.DataWriter.write_raw / DDS.DataReader.take_raw generic ops, loan mode" { const alloc = std.testing.allocator; - const udp = try UdpTransport.init(alloc, .{ .participant_id = 13 }, 0, null); + const udp = try UdpTransport.init(alloc, .{ .participant_id = 13 }, test_domain.get(), null); defer udp.deinit(); - const disc = try SpdpSedpDiscovery.init(alloc, udp.transport(), 0, 1_000); + const disc = try SpdpSedpDiscovery.init(alloc, udp.transport(), test_domain.get(), 1_000); var factory = try DomainParticipantFactoryImpl.init( alloc, udp.transport(), @@ -577,7 +578,7 @@ test "loopback: DDS.DataWriter.write_raw / DDS.DataReader.take_raw generic ops, } const dpf = factory.toDDSFactory(); - const dp = dpf.create_participant(0, .{}, null, 0); + const dp = dpf.create_participant(test_domain.get(), .{}, null, 0); defer _ = dpf.delete_participant(dp); var dw_qos = DDS.DataWriterQos{}; @@ -642,16 +643,16 @@ test "loopback: DDS.DataWriter.write_raw / DDS.DataReader.take_raw generic ops, test "loopback: DDS.DataWriter.write_raw / DDS.DataReader.take_raw generic ops, two participants" { const alloc = std.testing.allocator; - const udp_w = try UdpTransport.init(alloc, .{ .participant_id = 21 }, 0, null); + const udp_w = try UdpTransport.init(alloc, .{ .participant_id = 21 }, test_domain.get(), null); defer udp_w.deinit(); - const disc_w = try SpdpSedpDiscovery.init(alloc, udp_w.transport(), 0, 1_000); + const disc_w = try SpdpSedpDiscovery.init(alloc, udp_w.transport(), test_domain.get(), 1_000); var factory_w = try DomainParticipantFactoryImpl.init(alloc, udp_w.transport(), disc_w.toDiscovery(), noop_security, .spec_random, .{}); defer { factory_w.deinit(); disc_w.deinit(); } const dpf_w = factory_w.toDDSFactory(); - const dp_w = dpf_w.create_participant(0, .{}, null, 0); + const dp_w = dpf_w.create_participant(test_domain.get(), .{}, null, 0); defer _ = dpf_w.delete_participant(dp_w); var dw_qos = DDS.DataWriterQos{}; @@ -661,16 +662,16 @@ test "loopback: DDS.DataWriter.write_raw / DDS.DataReader.take_raw generic ops, const dw = pub_w.create_datawriter(topic_w, dw_qos, null, 0); const dw_impl: *DataWriterImpl = @ptrCast(@alignCast(dw.ptr)); - const udp_r = try UdpTransport.init(alloc, .{ .participant_id = 22 }, 0, null); + const udp_r = try UdpTransport.init(alloc, .{ .participant_id = 22 }, test_domain.get(), null); defer udp_r.deinit(); - const disc_r = try SpdpSedpDiscovery.init(alloc, udp_r.transport(), 0, 1_000); + const disc_r = try SpdpSedpDiscovery.init(alloc, udp_r.transport(), test_domain.get(), 1_000); var factory_r = try DomainParticipantFactoryImpl.init(alloc, udp_r.transport(), disc_r.toDiscovery(), noop_security, .spec_random, .{}); defer { factory_r.deinit(); disc_r.deinit(); } const dpf_r = factory_r.toDDSFactory(); - const dp_r = dpf_r.create_participant(0, .{}, null, 0); + const dp_r = dpf_r.create_participant(test_domain.get(), .{}, null, 0); defer _ = dpf_r.delete_participant(dp_r); var dr_qos = DDS.DataReaderQos{}; diff --git a/test/dcps/matched_status_test.zig b/test/dcps/matched_status_test.zig index 3f931f6c..b7a03bab 100644 --- a/test/dcps/matched_status_test.zig +++ b/test/dcps/matched_status_test.zig @@ -6,6 +6,7 @@ //! synchronously so every assertion is deterministic. const std = @import("std"); +const test_domain = @import("test_domain"); const zzdds = @import("zzdds"); const DDS = @import("zzdds_generated").DDS; @@ -53,7 +54,7 @@ const Fixture = struct { errdefer d_w.deinit(); const factory_w = try DomainParticipantFactoryImpl.init(alloc, t_w.transport(), d_w.toDiscovery(), noop_security, .spec_random, .{}); errdefer factory_w.deinit(); - const dp_w = factory_w.toDDSFactory().create_participant(0, .{}, null, 0); + const dp_w = factory_w.toDDSFactory().create_participant(test_domain.get(), .{}, null, 0); const pub_w = dp_w.create_publisher(.{}, null, 0); const topic_w = dp_w.create_topic("MatchTopic", "MatchType", .{}, null, 0); @@ -63,7 +64,7 @@ const Fixture = struct { errdefer d_r.deinit(); const factory_r = try DomainParticipantFactoryImpl.init(alloc, t_r.transport(), d_r.toDiscovery(), noop_security, .spec_random, .{}); errdefer factory_r.deinit(); - const dp_r = factory_r.toDDSFactory().create_participant(0, .{}, null, 0); + const dp_r = factory_r.toDDSFactory().create_participant(test_domain.get(), .{}, null, 0); const sub_r = dp_r.create_subscriber(.{}, null, 0); const topic_r = dp_r.create_topic("MatchTopic", "MatchType", .{}, null, 0); diff --git a/test/dcps/participant_vtable_test.zig b/test/dcps/participant_vtable_test.zig index 8d20474d..f937a65d 100644 --- a/test/dcps/participant_vtable_test.zig +++ b/test/dcps/participant_vtable_test.zig @@ -5,6 +5,7 @@ //! partition-name ownership lifecycle through DataWriter/DataReader creation. const std = @import("std"); +const test_domain = @import("test_domain"); const zzdds = @import("zzdds"); const DDS = @import("zzdds_generated").DDS; @@ -83,7 +84,7 @@ const Fixture = struct { .{}, ); errdefer factory.deinit(); - const dp = factory.toDDSFactory().create_participant(0, .{}, null, 0); + const dp = factory.toDDSFactory().create_participant(test_domain.get(), .{}, null, 0); return .{ .net = net, .transport = t, .factory = factory, .dp = dp }; } @@ -230,7 +231,7 @@ test "registerTypeSupport: deinit on participant teardown calls entry deinit" { ); defer factory.deinit(); - const dp = factory.toDDSFactory().create_participant(0, .{}, null, 0); + const dp = factory.toDDSFactory().create_participant(test_domain.get(), .{}, null, 0); const dp_impl: *DomainParticipantImpl = @ptrCast(@alignCast(dp.ptr)); var deinit_called = false; @@ -761,7 +762,7 @@ test "createParticipantWithConfig: TCP enabled with empty bind_address fails cle // concrete address configured for the TCP data transport to advertise. const qos = DDS.DomainParticipantQos{}; - const dp = factory.createParticipantWithConfig(0, &qos, null, 0, config); + const dp = factory.createParticipantWithConfig(test_domain.get(), &qos, null, 0, config); defer { if (dp.ptr != nil.NIL_PTR) _ = factory.toDDSFactory().delete_participant(dp); } @@ -793,7 +794,7 @@ test "createParticipantWithConfig: TCP enabled with a concrete bind_address succ config.transport.tcp.bind_address = "127.0.0.1"; const qos = DDS.DomainParticipantQos{}; - const dp = factory.createParticipantWithConfig(0, &qos, null, 0, config); + const dp = factory.createParticipantWithConfig(test_domain.get(), &qos, null, 0, config); defer { if (dp.ptr != nil.NIL_PTR) _ = factory.toDDSFactory().delete_participant(dp); } @@ -841,7 +842,7 @@ test "createParticipantWithConfig: config.qos seeds default_topic_qos" { }; const qos = DDS.DomainParticipantQos{}; - const dp = factory.createParticipantWithConfig(0, &qos, null, 0, config); + const dp = factory.createParticipantWithConfig(test_domain.get(), &qos, null, 0, config); defer { if (dp.ptr != nil.NIL_PTR) _ = factory.toDDSFactory().delete_participant(dp); } @@ -880,7 +881,7 @@ test "createParticipantWithConfig: config.qos seeds Publisher's default_datawrit }; const qos = DDS.DomainParticipantQos{}; - const dp = factory.createParticipantWithConfig(0, &qos, null, 0, config); + const dp = factory.createParticipantWithConfig(test_domain.get(), &qos, null, 0, config); defer { if (dp.ptr != nil.NIL_PTR) _ = factory.toDDSFactory().delete_participant(dp); } @@ -971,7 +972,7 @@ test "deinit: reentrant delete_participant from a timer-driven listener does not ); defer factory.deinit(); const dpf = factory.toDDSFactory(); - const dp = dpf.create_participant(0, .{}, null, 0); + const dp = dpf.create_participant(test_domain.get(), .{}, null, 0); try testing.expect(dp.ptr != nil.NIL_PTR); const pub_ = dp.create_publisher(.{}, null, 0); diff --git a/test/dcps/pubsub_vtable_test.zig b/test/dcps/pubsub_vtable_test.zig index 83fceb75..c16f0b2a 100644 --- a/test/dcps/pubsub_vtable_test.zig +++ b/test/dcps/pubsub_vtable_test.zig @@ -7,6 +7,7 @@ //! get_participant, set/get_default_*_qos, copy_from_topic_qos, deinit. const std = @import("std"); +const test_domain = @import("test_domain"); const zzdds = @import("zzdds"); const DDS = @import("zzdds_generated").DDS; @@ -94,7 +95,7 @@ const Harness = struct { test "Publisher: enable returns RETCODE_OK" { var h = try Harness.init(0x20); defer h.deinit(); - const dp = h.factory.toDDSFactory().create_participant(0, .{}, null, 0); + const dp = h.factory.toDDSFactory().create_participant(test_domain.get(), .{}, null, 0); defer _ = h.factory.toDDSFactory().delete_participant(dp); const pub_ = dp.create_publisher(.{}, null, 0); @@ -104,7 +105,7 @@ test "Publisher: enable returns RETCODE_OK" { test "Publisher: get_statuscondition and get_status_changes" { var h = try Harness.init(0x21); defer h.deinit(); - const dp = h.factory.toDDSFactory().create_participant(0, .{}, null, 0); + const dp = h.factory.toDDSFactory().create_participant(test_domain.get(), .{}, null, 0); defer _ = h.factory.toDDSFactory().delete_participant(dp); const pub_ = dp.create_publisher(.{}, null, 0); @@ -124,7 +125,7 @@ test "Publisher: lookup_datawriter found and not-found" { var h = try Harness.init(0x22); defer h.deinit(); const dpf = h.factory.toDDSFactory(); - const dp = dpf.create_participant(0, .{}, null, 0); + const dp = dpf.create_participant(test_domain.get(), .{}, null, 0); defer _ = dpf.delete_participant(dp); const pub_ = dp.create_publisher(.{}, null, 0); @@ -146,7 +147,7 @@ test "Publisher: delete_contained_entities clears all writers" { var h = try Harness.init(0x23); defer h.deinit(); const dpf = h.factory.toDDSFactory(); - const dp = dpf.create_participant(0, .{}, null, 0); + const dp = dpf.create_participant(test_domain.get(), .{}, null, 0); defer _ = dpf.delete_participant(dp); const pub_ = dp.create_publisher(.{}, null, 0); @@ -161,7 +162,7 @@ test "Publisher: delete_datawriter returns BAD_PARAMETER for unknown writer" { var h = try Harness.init(0x24); defer h.deinit(); const dpf = h.factory.toDDSFactory(); - const dp = dpf.create_participant(0, .{}, null, 0); + const dp = dpf.create_participant(test_domain.get(), .{}, null, 0); defer _ = dpf.delete_participant(dp); const pub_ = dp.create_publisher(.{}, null, 0); @@ -172,7 +173,7 @@ test "Publisher: delete_datawriter returns BAD_PARAMETER for unknown writer" { test "Publisher: set_qos / get_qos round-trip" { var h = try Harness.init(0x25); defer h.deinit(); - const dp = h.factory.toDDSFactory().create_participant(0, .{}, null, 0); + const dp = h.factory.toDDSFactory().create_participant(test_domain.get(), .{}, null, 0); defer _ = h.factory.toDDSFactory().delete_participant(dp); const pub_ = dp.create_publisher(.{}, null, 0); @@ -192,7 +193,7 @@ test "Publisher: set_qos / get_qos round-trip" { test "Publisher: set_listener / get_listener round-trip" { var h = try Harness.init(0x26); defer h.deinit(); - const dp = h.factory.toDDSFactory().create_participant(0, .{}, null, 0); + const dp = h.factory.toDDSFactory().create_participant(test_domain.get(), .{}, null, 0); defer _ = h.factory.toDDSFactory().delete_participant(dp); const pub_ = dp.create_publisher(.{}, null, 0); @@ -205,7 +206,7 @@ test "Publisher: set_listener / get_listener round-trip" { test "Publisher: suspend/resume/begin/end return OK" { var h = try Harness.init(0x27); defer h.deinit(); - const dp = h.factory.toDDSFactory().create_participant(0, .{}, null, 0); + const dp = h.factory.toDDSFactory().create_participant(test_domain.get(), .{}, null, 0); defer _ = h.factory.toDDSFactory().delete_participant(dp); const pub_ = dp.create_publisher(.{}, null, 0); @@ -221,7 +222,7 @@ test "Publisher: wait_for_acknowledgments with BEST_EFFORT writer returns OK" { var h = try Harness.init(0x28); defer h.deinit(); const dpf = h.factory.toDDSFactory(); - const dp = dpf.create_participant(0, .{}, null, 0); + const dp = dpf.create_participant(test_domain.get(), .{}, null, 0); defer _ = dpf.delete_participant(dp); const pub_ = dp.create_publisher(.{}, null, 0); @@ -240,7 +241,7 @@ test "Publisher: wait_for_acknowledgments with infinite timeout and no writers" var h = try Harness.init(0x29); defer h.deinit(); const dpf = h.factory.toDDSFactory(); - const dp = dpf.create_participant(0, .{}, null, 0); + const dp = dpf.create_participant(test_domain.get(), .{}, null, 0); defer _ = dpf.delete_participant(dp); const pub_ = dp.create_publisher(.{}, null, 0); @@ -255,7 +256,7 @@ test "Publisher: wait_for_acknowledgments with infinite timeout and no writers" test "Publisher: get_participant returns the owning DomainParticipant" { var h = try Harness.init(0x2A); defer h.deinit(); - const dp = h.factory.toDDSFactory().create_participant(0, .{}, null, 0); + const dp = h.factory.toDDSFactory().create_participant(test_domain.get(), .{}, null, 0); defer _ = h.factory.toDDSFactory().delete_participant(dp); const pub_ = dp.create_publisher(.{}, null, 0); @@ -268,7 +269,7 @@ test "Publisher: get_participant returns the owning DomainParticipant" { test "Publisher: set/get_default_datawriter_qos round-trip" { var h = try Harness.init(0x2B); defer h.deinit(); - const dp = h.factory.toDDSFactory().create_participant(0, .{}, null, 0); + const dp = h.factory.toDDSFactory().create_participant(test_domain.get(), .{}, null, 0); defer _ = h.factory.toDDSFactory().delete_participant(dp); const pub_ = dp.create_publisher(.{}, null, 0); @@ -286,7 +287,7 @@ test "Publisher: set/get_default_datawriter_qos round-trip" { test "Publisher: copy_from_topic_qos copies relevant fields" { var h = try Harness.init(0x2C); defer h.deinit(); - const dp = h.factory.toDDSFactory().create_participant(0, .{}, null, 0); + const dp = h.factory.toDDSFactory().create_participant(test_domain.get(), .{}, null, 0); defer _ = h.factory.toDDSFactory().delete_participant(dp); const pub_ = dp.create_publisher(.{}, null, 0); @@ -305,7 +306,7 @@ test "Publisher: copy_from_topic_qos copies relevant fields" { test "Subscriber: enable, get_statuscondition, get_status_changes, get_instance_handle" { var h = try Harness.init(0x30); defer h.deinit(); - const dp = h.factory.toDDSFactory().create_participant(0, .{}, null, 0); + const dp = h.factory.toDDSFactory().create_participant(test_domain.get(), .{}, null, 0); defer _ = h.factory.toDDSFactory().delete_participant(dp); const sub = dp.create_subscriber(.{}, null, 0); @@ -328,7 +329,7 @@ test "Subscriber: lookup_datareader found and not-found" { var h = try Harness.init(0x31); defer h.deinit(); const dpf = h.factory.toDDSFactory(); - const dp = dpf.create_participant(0, .{}, null, 0); + const dp = dpf.create_participant(test_domain.get(), .{}, null, 0); defer _ = dpf.delete_participant(dp); const sub = dp.create_subscriber(.{}, null, 0); @@ -349,7 +350,7 @@ test "Subscriber: delete_contained_entities" { var h = try Harness.init(0x32); defer h.deinit(); const dpf = h.factory.toDDSFactory(); - const dp = dpf.create_participant(0, .{}, null, 0); + const dp = dpf.create_participant(test_domain.get(), .{}, null, 0); defer _ = dpf.delete_participant(dp); const sub = dp.create_subscriber(.{}, null, 0); @@ -363,7 +364,7 @@ test "Subscriber: delete_contained_entities" { test "Subscriber: delete_datareader returns BAD_PARAMETER for unknown reader" { var h = try Harness.init(0x33); defer h.deinit(); - const dp = h.factory.toDDSFactory().create_participant(0, .{}, null, 0); + const dp = h.factory.toDDSFactory().create_participant(test_domain.get(), .{}, null, 0); defer _ = h.factory.toDDSFactory().delete_participant(dp); const sub = dp.create_subscriber(.{}, null, 0); @@ -374,7 +375,7 @@ test "Subscriber: delete_datareader returns BAD_PARAMETER for unknown reader" { test "Subscriber: get_datareaders with empty subscriber returns empty list" { var h = try Harness.init(0x34); defer h.deinit(); - const dp = h.factory.toDDSFactory().create_participant(0, .{}, null, 0); + const dp = h.factory.toDDSFactory().create_participant(test_domain.get(), .{}, null, 0); defer _ = h.factory.toDDSFactory().delete_participant(dp); const sub = dp.create_subscriber(.{}, null, 0); @@ -393,7 +394,7 @@ test "Subscriber: notify_datareaders fires listener for readers with DATA_AVAILA var h = try Harness.init(0x35); defer h.deinit(); const dpf = h.factory.toDDSFactory(); - const dp = dpf.create_participant(0, .{}, null, 0); + const dp = dpf.create_participant(test_domain.get(), .{}, null, 0); defer _ = dpf.delete_participant(dp); const sub = dp.create_subscriber(.{}, null, 0); @@ -410,7 +411,7 @@ test "Subscriber: notify_datareaders fires listener for readers with DATA_AVAILA test "Subscriber: notify_datareaders with no readers returns OK" { var h = try Harness.init(0x36); defer h.deinit(); - const dp = h.factory.toDDSFactory().create_participant(0, .{}, null, 0); + const dp = h.factory.toDDSFactory().create_participant(test_domain.get(), .{}, null, 0); defer _ = h.factory.toDDSFactory().delete_participant(dp); const sub = dp.create_subscriber(.{}, null, 0); @@ -422,7 +423,7 @@ test "Subscriber: notify_datareaders with no readers returns OK" { test "Subscriber: set_qos / get_qos round-trip" { var h = try Harness.init(0x37); defer h.deinit(); - const dp = h.factory.toDDSFactory().create_participant(0, .{}, null, 0); + const dp = h.factory.toDDSFactory().create_participant(test_domain.get(), .{}, null, 0); defer _ = h.factory.toDDSFactory().delete_participant(dp); const sub = dp.create_subscriber(.{}, null, 0); @@ -439,7 +440,7 @@ test "Subscriber: set_qos / get_qos round-trip" { test "Subscriber: set_listener / get_listener round-trip" { var h = try Harness.init(0x38); defer h.deinit(); - const dp = h.factory.toDDSFactory().create_participant(0, .{}, null, 0); + const dp = h.factory.toDDSFactory().create_participant(test_domain.get(), .{}, null, 0); defer _ = h.factory.toDDSFactory().delete_participant(dp); const sub = dp.create_subscriber(.{}, null, 0); @@ -452,7 +453,7 @@ test "Subscriber: set_listener / get_listener round-trip" { test "Subscriber: begin_access / end_access return RETCODE_OK" { var h = try Harness.init(0x39); defer h.deinit(); - const dp = h.factory.toDDSFactory().create_participant(0, .{}, null, 0); + const dp = h.factory.toDDSFactory().create_participant(test_domain.get(), .{}, null, 0); defer _ = h.factory.toDDSFactory().delete_participant(dp); const sub = dp.create_subscriber(.{}, null, 0); @@ -465,7 +466,7 @@ test "Subscriber: begin_access / end_access return RETCODE_OK" { test "Subscriber: get_participant returns the owning DomainParticipant" { var h = try Harness.init(0x3A); defer h.deinit(); - const dp = h.factory.toDDSFactory().create_participant(0, .{}, null, 0); + const dp = h.factory.toDDSFactory().create_participant(test_domain.get(), .{}, null, 0); defer _ = h.factory.toDDSFactory().delete_participant(dp); const sub = dp.create_subscriber(.{}, null, 0); @@ -478,7 +479,7 @@ test "Subscriber: get_participant returns the owning DomainParticipant" { test "Subscriber: set/get_default_datareader_qos round-trip" { var h = try Harness.init(0x3B); defer h.deinit(); - const dp = h.factory.toDDSFactory().create_participant(0, .{}, null, 0); + const dp = h.factory.toDDSFactory().create_participant(test_domain.get(), .{}, null, 0); defer _ = h.factory.toDDSFactory().delete_participant(dp); const sub = dp.create_subscriber(.{}, null, 0); @@ -495,7 +496,7 @@ test "Subscriber: set/get_default_datareader_qos round-trip" { test "Subscriber: copy_from_topic_qos copies relevant fields" { var h = try Harness.init(0x3C); defer h.deinit(); - const dp = h.factory.toDDSFactory().create_participant(0, .{}, null, 0); + const dp = h.factory.toDDSFactory().create_participant(test_domain.get(), .{}, null, 0); defer _ = h.factory.toDDSFactory().delete_participant(dp); const sub = dp.create_subscriber(.{}, null, 0); @@ -514,7 +515,7 @@ test "Subscriber: copy_from_topic_qos copies relevant fields" { test "Publisher: set_qos with partition names — clone survives replacement" { var h = try Harness.init(0xB0); defer h.deinit(); - const dp = h.factory.toDDSFactory().create_participant(0, .{}, null, 0); + const dp = h.factory.toDDSFactory().create_participant(test_domain.get(), .{}, null, 0); defer _ = h.factory.toDDSFactory().delete_participant(dp); const pub_ = dp.create_publisher(.{}, null, 0); defer _ = dp.vtable.delete_contained_entities(dp.ptr); @@ -538,7 +539,7 @@ test "Publisher: set_qos with partition names — clone survives replacement" { test "Publisher: get_qos returns independent clone — replacement does not dangle" { var h = try Harness.init(0xB1); defer h.deinit(); - const dp = h.factory.toDDSFactory().create_participant(0, .{}, null, 0); + const dp = h.factory.toDDSFactory().create_participant(test_domain.get(), .{}, null, 0); defer _ = h.factory.toDDSFactory().delete_participant(dp); const pub_ = dp.create_publisher(.{}, null, 0); defer _ = dp.vtable.delete_contained_entities(dp.ptr); @@ -561,7 +562,7 @@ test "Publisher: get_qos returns independent clone — replacement does not dang test "Publisher: set_default_datawriter_qos with user_data — clone survives replacement" { var h = try Harness.init(0xB2); defer h.deinit(); - const dp = h.factory.toDDSFactory().create_participant(0, .{}, null, 0); + const dp = h.factory.toDDSFactory().create_participant(test_domain.get(), .{}, null, 0); defer _ = h.factory.toDDSFactory().delete_participant(dp); const pub_ = dp.create_publisher(.{}, null, 0); defer _ = dp.vtable.delete_contained_entities(dp.ptr); @@ -585,7 +586,7 @@ test "Publisher: set_default_datawriter_qos with user_data — clone survives re test "Subscriber: set_qos with partition names — clone survives replacement" { var h = try Harness.init(0xB3); defer h.deinit(); - const dp = h.factory.toDDSFactory().create_participant(0, .{}, null, 0); + const dp = h.factory.toDDSFactory().create_participant(test_domain.get(), .{}, null, 0); defer _ = h.factory.toDDSFactory().delete_participant(dp); const sub = dp.create_subscriber(.{}, null, 0); defer _ = dp.vtable.delete_contained_entities(dp.ptr); @@ -609,7 +610,7 @@ test "Subscriber: set_qos with partition names — clone survives replacement" { test "Subscriber: set_default_datareader_qos with user_data — clone survives replacement" { var h = try Harness.init(0xB4); defer h.deinit(); - const dp = h.factory.toDDSFactory().create_participant(0, .{}, null, 0); + const dp = h.factory.toDDSFactory().create_participant(test_domain.get(), .{}, null, 0); defer _ = h.factory.toDDSFactory().delete_participant(dp); const sub = dp.create_subscriber(.{}, null, 0); defer _ = dp.vtable.delete_contained_entities(dp.ptr); diff --git a/test/dcps/qos_runtime_test.zig b/test/dcps/qos_runtime_test.zig index 5d9803ba..3cf780ef 100644 --- a/test/dcps/qos_runtime_test.zig +++ b/test/dcps/qos_runtime_test.zig @@ -6,6 +6,7 @@ //! for fully deterministic timer control. const std = @import("std"); +const test_domain = @import("test_domain"); const zzdds = @import("zzdds"); const DDS = @import("zzdds_generated").DDS; @@ -96,7 +97,7 @@ const Fixture = struct { ); errdefer factory_w.deinit(); const dpf_w = factory_w.toDDSFactory(); - const dp_w = dpf_w.create_participant(0, .{}, null, 0); + const dp_w = dpf_w.create_participant(test_domain.get(), .{}, null, 0); const pub_w = dp_w.create_publisher(.{}, null, 0); const topic_w = dp_w.create_topic("QosTopic", "QosType", .{}, null, 0); @@ -114,7 +115,7 @@ const Fixture = struct { ); errdefer factory_r.deinit(); const dpf_r = factory_r.toDDSFactory(); - const dp_r = dpf_r.create_participant(0, .{}, null, 0); + const dp_r = dpf_r.create_participant(test_domain.get(), .{}, null, 0); const sub_r = dp_r.create_subscriber(.{}, null, 0); const topic_r = dp_r.create_topic("QosTopic", "QosType", .{}, null, 0); @@ -328,7 +329,7 @@ const OwnershipFixture = struct { .{}, ); errdefer factory_a.deinit(); - const dp_a = factory_a.toDDSFactory().create_participant(0, .{}, null, 0); + const dp_a = factory_a.toDDSFactory().create_participant(test_domain.get(), .{}, null, 0); const pub_a = dp_a.create_publisher(.{}, null, 0); const topic_a = dp_a.create_topic("OwnTopic", "OwnType", .{}, null, 0); @@ -345,7 +346,7 @@ const OwnershipFixture = struct { .{}, ); errdefer factory_b.deinit(); - const dp_b = factory_b.toDDSFactory().create_participant(0, .{}, null, 0); + const dp_b = factory_b.toDDSFactory().create_participant(test_domain.get(), .{}, null, 0); const pub_b = dp_b.create_publisher(.{}, null, 0); const topic_b = dp_b.create_topic("OwnTopic", "OwnType", .{}, null, 0); @@ -362,7 +363,7 @@ const OwnershipFixture = struct { .{}, ); errdefer factory_r.deinit(); - const dp_r = factory_r.toDDSFactory().create_participant(0, .{}, null, 0); + const dp_r = factory_r.toDDSFactory().create_participant(test_domain.get(), .{}, null, 0); const sub_r = dp_r.create_subscriber(.{}, null, 0); const topic_r = dp_r.create_topic("OwnTopic", "OwnType", .{}, null, 0); @@ -881,7 +882,7 @@ const TimerFixture = struct { errdefer factory.deinit(); try factory.clock_registry.register("manual", clock); const dpf = factory.toDDSFactory(); - const dp = dpf.create_participant(0, .{}, null, 0); + const dp = dpf.create_participant(test_domain.get(), .{}, null, 0); const dp_impl: *DomainParticipantImpl = @ptrCast(@alignCast(dp.ptr)); const pub_ = dp.create_publisher(.{}, null, 0); const sub_ = dp.create_subscriber(.{}, null, 0); @@ -1424,7 +1425,7 @@ const TwoPartyTimerFixture = struct { const factory_w = try DomainParticipantFactoryImpl.init(alloc, t_w.transport(), d_w.toDiscovery(), noop_security, .spec_random, config); errdefer factory_w.deinit(); try factory_w.clock_registry.register("manual", clock); - const dp_w = factory_w.toDDSFactory().create_participant(0, .{}, null, 0); + const dp_w = factory_w.toDDSFactory().create_participant(test_domain.get(), .{}, null, 0); const pub_ = dp_w.create_publisher(.{}, null, 0); const topic_w = dp_w.create_topic("LiveTopic", "LiveType", .{}, null, 0); @@ -1435,7 +1436,7 @@ const TwoPartyTimerFixture = struct { const factory_r = try DomainParticipantFactoryImpl.init(alloc, t_r.transport(), d_r.toDiscovery(), noop_security, .spec_random, config); errdefer factory_r.deinit(); try factory_r.clock_registry.register("manual", clock); - const dp_r = factory_r.toDDSFactory().create_participant(0, .{}, null, 0); + const dp_r = factory_r.toDDSFactory().create_participant(test_domain.get(), .{}, null, 0); const dp_r_impl: *DomainParticipantImpl = @ptrCast(@alignCast(dp_r.ptr)); const sub_ = dp_r.create_subscriber(.{}, null, 0); const topic_r = dp_r.create_topic("LiveTopic", "LiveType", .{}, null, 0); diff --git a/test/dcps/read_take_test.zig b/test/dcps/read_take_test.zig index 2fdcb740..31e5b45b 100644 --- a/test/dcps/read_take_test.zig +++ b/test/dcps/read_take_test.zig @@ -3,6 +3,7 @@ //! Uses IntraProcessDelivery (synchronous, no pump) for deterministic delivery. const std = @import("std"); +const test_domain = @import("test_domain"); const zzdds = @import("zzdds"); const DDS = @import("zzdds_generated").DDS; @@ -61,7 +62,7 @@ const Fixture = struct { ); errdefer factory_w.deinit(); const dpf_w = factory_w.toDDSFactory(); - const dp_w = dpf_w.create_participant(0, .{}, null, 0); + const dp_w = dpf_w.create_participant(test_domain.get(), .{}, null, 0); const pub_w = dp_w.create_publisher(.{}, null, 0); const topic_w = dp_w.create_topic("RTTopic", "RTType", .{}, null, 0); @@ -79,7 +80,7 @@ const Fixture = struct { ); errdefer factory_r.deinit(); const dpf_r = factory_r.toDDSFactory(); - const dp_r = dpf_r.create_participant(0, .{}, null, 0); + const dp_r = dpf_r.create_participant(test_domain.get(), .{}, null, 0); const sub_r = dp_r.create_subscriber(.{}, null, 0); const topic_r = dp_r.create_topic("RTTopic", "RTType", .{}, null, 0); diff --git a/test/dcps/reader_vtable_test.zig b/test/dcps/reader_vtable_test.zig index c7b84f4d..dc99a4f9 100644 --- a/test/dcps/reader_vtable_test.zig +++ b/test/dcps/reader_vtable_test.zig @@ -6,6 +6,7 @@ //! matchedWriterCount, and matched-publication queries. const std = @import("std"); +const test_domain = @import("test_domain"); const zzdds = @import("zzdds"); const DDS = @import("zzdds_generated").DDS; @@ -73,7 +74,7 @@ const SingleFixture = struct { errdefer d.deinit(); const factory = try DomainParticipantFactoryImpl.init(alloc, t.transport(), d.toDiscovery(), noop_security, .spec_random, .{}); errdefer factory.deinit(); - const dp = factory.toDDSFactory().create_participant(0, .{}, null, 0); + const dp = factory.toDDSFactory().create_participant(test_domain.get(), .{}, null, 0); const sub = dp.create_subscriber(.{}, null, 0); const topic = dp.create_topic("RdrVtTopic", "RdrVtType", .{}, null, 0); return .{ .alloc = alloc, .delivery = delivery, .t = t, .d = d, .factory = factory, .dp = dp, .sub = sub, .topic = topic }; @@ -127,7 +128,7 @@ const TwoPartyFixture = struct { errdefer d_w.deinit(); const factory_w = try DomainParticipantFactoryImpl.init(alloc, t_w.transport(), d_w.toDiscovery(), noop_security, .spec_random, .{}); errdefer factory_w.deinit(); - const dp_w = factory_w.toDDSFactory().create_participant(0, .{}, null, 0); + const dp_w = factory_w.toDDSFactory().create_participant(test_domain.get(), .{}, null, 0); const pub_w = dp_w.create_publisher(.{}, null, 0); const topic_w = dp_w.create_topic("RdrPubTopic", "RdrPubType", .{}, null, 0); @@ -137,7 +138,7 @@ const TwoPartyFixture = struct { errdefer d_r.deinit(); const factory_r = try DomainParticipantFactoryImpl.init(alloc, t_r.transport(), d_r.toDiscovery(), noop_security, .spec_random, .{}); errdefer factory_r.deinit(); - const dp_r = factory_r.toDDSFactory().create_participant(0, .{}, null, 0); + const dp_r = factory_r.toDDSFactory().create_participant(test_domain.get(), .{}, null, 0); const sub_r = dp_r.create_subscriber(.{}, null, 0); const topic_r = dp_r.create_topic("RdrPubTopic", "RdrPubType", .{}, null, 0); return .{ diff --git a/test/dcps/sample_rejected_test.zig b/test/dcps/sample_rejected_test.zig index e285f31c..b8b4aac9 100644 --- a/test/dcps/sample_rejected_test.zig +++ b/test/dcps/sample_rejected_test.zig @@ -4,6 +4,7 @@ //! and all assertions are deterministic. const std = @import("std"); +const test_domain = @import("test_domain"); const zzdds = @import("zzdds"); const DDS = @import("zzdds_generated").DDS; @@ -57,7 +58,7 @@ const Fixture = struct { errdefer d_w.deinit(); const factory_w = try DomainParticipantFactoryImpl.init(alloc, t_w.transport(), d_w.toDiscovery(), noop_security, .spec_random, .{}); errdefer factory_w.deinit(); - const dp_w = factory_w.toDDSFactory().create_participant(0, .{}, null, 0); + const dp_w = factory_w.toDDSFactory().create_participant(test_domain.get(), .{}, null, 0); const pub_w = dp_w.create_publisher(.{}, null, 0); const topic_w = dp_w.create_topic("RejTopic", "RejType", .{}, null, 0); const t_r = try delivery.newTransport(); @@ -66,7 +67,7 @@ const Fixture = struct { errdefer d_r.deinit(); const factory_r = try DomainParticipantFactoryImpl.init(alloc, t_r.transport(), d_r.toDiscovery(), noop_security, .spec_random, .{}); errdefer factory_r.deinit(); - const dp_r = factory_r.toDDSFactory().create_participant(0, .{}, null, 0); + const dp_r = factory_r.toDDSFactory().create_participant(test_domain.get(), .{}, null, 0); const sub_r = dp_r.create_subscriber(.{}, null, 0); const topic_r = dp_r.create_topic("RejTopic", "RejType", .{}, null, 0); return .{ diff --git a/test/dcps/topic_vtable_test.zig b/test/dcps/topic_vtable_test.zig index 6cc29aed..f1707f2b 100644 --- a/test/dcps/topic_vtable_test.zig +++ b/test/dcps/topic_vtable_test.zig @@ -1,6 +1,7 @@ //! Tests for TopicImpl and ContentFilteredTopicImpl vtable methods. const std = @import("std"); +const test_domain = @import("test_domain"); const zzdds = @import("zzdds"); const DDS = @import("zzdds_generated").DDS; @@ -30,7 +31,7 @@ const Fixture = struct { errdefer d.deinit(); const factory = try DomainParticipantFactoryImpl.init(alloc, t.transport(), d.toDiscovery(), noop_security, .spec_random, .{}); errdefer factory.deinit(); - const dp = factory.toDDSFactory().create_participant(0, .{}, null, 0); + const dp = factory.toDDSFactory().create_participant(test_domain.get(), .{}, null, 0); return .{ .alloc = alloc, .delivery = delivery, .t = t, .d = d, .factory = factory, .dp = dp }; } diff --git a/test/dcps/type_support_test.zig b/test/dcps/type_support_test.zig index 6632eb5a..50d8c742 100644 --- a/test/dcps/type_support_test.zig +++ b/test/dcps/type_support_test.zig @@ -8,6 +8,7 @@ //! the CDR payloads and correctly applies ownership per-instance. const std = @import("std"); +const test_domain = @import("test_domain"); const testing = std.testing; const zzdds = @import("zzdds"); const DDS = @import("zzdds_generated").DDS; @@ -103,7 +104,7 @@ const Fixture = struct { .{}, ); errdefer factory_a.deinit(); - const dp_a = factory_a.toDDSFactory().create_participant(0, .{}, null, 0); + const dp_a = factory_a.toDDSFactory().create_participant(test_domain.get(), .{}, null, 0); const pub_a = dp_a.create_publisher(.{}, null, 0); const topic_a = dp_a.create_topic("TSTopic", "TSType", .{}, null, 0); @@ -120,7 +121,7 @@ const Fixture = struct { .{}, ); errdefer factory_b.deinit(); - const dp_b = factory_b.toDDSFactory().create_participant(0, .{}, null, 0); + const dp_b = factory_b.toDDSFactory().create_participant(test_domain.get(), .{}, null, 0); const pub_b = dp_b.create_publisher(.{}, null, 0); const topic_b = dp_b.create_topic("TSTopic", "TSType", .{}, null, 0); @@ -137,7 +138,7 @@ const Fixture = struct { .{}, ); errdefer factory_r.deinit(); - const dp_r = factory_r.toDDSFactory().create_participant(0, .{}, null, 0); + const dp_r = factory_r.toDDSFactory().create_participant(test_domain.get(), .{}, null, 0); const sub_r = dp_r.create_subscriber(.{}, null, 0); const topic_r = dp_r.create_topic("TSTopic", "TSType", .{}, null, 0); diff --git a/test/dcps/wait_for_historical_test.zig b/test/dcps/wait_for_historical_test.zig index 0e940bd8..fdc048d9 100644 --- a/test/dcps/wait_for_historical_test.zig +++ b/test/dcps/wait_for_historical_test.zig @@ -5,6 +5,7 @@ //! background threads are needed. const std = @import("std"); +const test_domain = @import("test_domain"); const zzdds = @import("zzdds"); const DDS = @import("zzdds_generated").DDS; @@ -147,7 +148,7 @@ test "wait_for_historical_data: VOLATILE returns OK immediately" { const alloc = testing.allocator; const dpf = h.factory.toDDSFactory(); - const dp = dpf.create_participant(0, .{}, null, 0); + const dp = dpf.create_participant(test_domain.get(), .{}, null, 0); defer _ = dpf.delete_participant(dp); const topic = dp.create_topic("TestTopic", "TestType", .{}, null, 0); @@ -170,7 +171,7 @@ test "wait_for_historical_data: TRANSIENT_LOCAL with no matched writers returns defer h.deinit(); const dpf = h.factory.toDDSFactory(); - const dp = dpf.create_participant(0, .{}, null, 0); + const dp = dpf.create_participant(test_domain.get(), .{}, null, 0); defer _ = dpf.delete_participant(dp); const topic = dp.create_topic("TestTopic", "TestType", .{}, null, 0); @@ -207,7 +208,7 @@ test "wait_for_historical_data: non-zero max_wait with no matched writer times o defer h.deinit(); const dpf = h.factory.toDDSFactory(); - const dp = dpf.create_participant(0, .{}, null, 0); + const dp = dpf.create_participant(test_domain.get(), .{}, null, 0); defer _ = dpf.delete_participant(dp); const topic = dp.create_topic("TestTopic", "TestType", .{}, null, 0); @@ -241,7 +242,7 @@ test "wait_for_historical_data: matches and delivers *during* the wait, not befo defer h.deinit(); const dpf = h.factory.toDDSFactory(); - const dp = dpf.create_participant(0, .{}, null, 0); + const dp = dpf.create_participant(test_domain.get(), .{}, null, 0); defer _ = dpf.delete_participant(dp); const dp_impl: *DomainParticipantImpl = @ptrCast(@alignCast(dp.ptr)); @@ -298,7 +299,7 @@ test "wait_for_historical_data: times out before first HEARTBEAT from transient- defer h.deinit(); const dpf = h.factory.toDDSFactory(); - const dp = dpf.create_participant(0, .{}, null, 0); + const dp = dpf.create_participant(test_domain.get(), .{}, null, 0); defer _ = dpf.delete_participant(dp); const dp_impl: *DomainParticipantImpl = @ptrCast(@alignCast(dp.ptr)); @@ -329,7 +330,7 @@ test "wait_for_historical_data: returns OK after first HB with empty history (la defer h.deinit(); const dpf = h.factory.toDDSFactory(); - const dp = dpf.create_participant(0, .{}, null, 0); + const dp = dpf.create_participant(test_domain.get(), .{}, null, 0); defer _ = dpf.delete_participant(dp); const dp_impl: *DomainParticipantImpl = @ptrCast(@alignCast(dp.ptr)); @@ -363,7 +364,7 @@ test "wait_for_historical_data: returns OK after history fully delivered (data b defer h.deinit(); const dpf = h.factory.toDDSFactory(); - const dp = dpf.create_participant(0, .{}, null, 0); + const dp = dpf.create_participant(test_domain.get(), .{}, null, 0); defer _ = dpf.delete_participant(dp); const dp_impl: *DomainParticipantImpl = @ptrCast(@alignCast(dp.ptr)); @@ -410,7 +411,7 @@ test "wait_for_historical_data: returns OK once pending data fills history floor defer h.deinit(); const dpf = h.factory.toDDSFactory(); - const dp = dpf.create_participant(0, .{}, null, 0); + const dp = dpf.create_participant(test_domain.get(), .{}, null, 0); defer _ = dpf.delete_participant(dp); const dp_impl: *DomainParticipantImpl = @ptrCast(@alignCast(dp.ptr)); diff --git a/test/dcps/waitset_lifecycle_test.zig b/test/dcps/waitset_lifecycle_test.zig index f95bd614..e2d1ffab 100644 --- a/test/dcps/waitset_lifecycle_test.zig +++ b/test/dcps/waitset_lifecycle_test.zig @@ -12,6 +12,7 @@ //! covered by waitset_test.zig. const std = @import("std"); +const test_domain = @import("test_domain"); const zzdds = @import("zzdds"); const DDS = @import("zzdds_generated").DDS; @@ -66,7 +67,7 @@ const Fixture = struct { ); errdefer factory_w.deinit(); const dpf_w = factory_w.toDDSFactory(); - const dp_w = dpf_w.create_participant(0, .{}, null, 0); + const dp_w = dpf_w.create_participant(test_domain.get(), .{}, null, 0); const pub_w = dp_w.create_publisher(.{}, null, 0); const topic_w = dp_w.create_topic(topic_name, type_name, .{}, null, 0); @@ -84,7 +85,7 @@ const Fixture = struct { ); errdefer factory_r.deinit(); const dpf_r = factory_r.toDDSFactory(); - const dp_r = dpf_r.create_participant(0, .{}, null, 0); + const dp_r = dpf_r.create_participant(test_domain.get(), .{}, null, 0); const sub_r = dp_r.create_subscriber(.{}, null, 0); const topic_r = dp_r.create_topic(topic_name, type_name, .{}, null, 0); diff --git a/test/dcps/wlp_loopback_test.zig b/test/dcps/wlp_loopback_test.zig index 3a3678da..de8817b8 100644 --- a/test/dcps/wlp_loopback_test.zig +++ b/test/dcps/wlp_loopback_test.zig @@ -13,6 +13,7 @@ //! lenient (e.g. an accidentally-infinite lease). const std = @import("std"); +const test_domain = @import("test_domain"); const zzdds = @import("zzdds"); const DDS = @import("zzdds_generated").DDS; @@ -71,14 +72,14 @@ fn setupMatchedPairEx( liveliness: DDS.LivelinessQosPolicy, reader_reliability: DDS.ReliabilityQosPolicyKind, ) !Pair { - const udp_w = try UdpTransport.init(alloc, .{ .participant_id = w_pid }, 0, null); + const udp_w = try UdpTransport.init(alloc, .{ .participant_id = w_pid }, test_domain.get(), null); errdefer udp_w.deinit(); - const disc_w = try SpdpSedpDiscovery.init(alloc, udp_w.transport(), 0, 1_000); + const disc_w = try SpdpSedpDiscovery.init(alloc, udp_w.transport(), test_domain.get(), 1_000); errdefer disc_w.deinit(); const factory_w = try DomainParticipantFactoryImpl.init(alloc, udp_w.transport(), disc_w.toDiscovery(), noop_security, .spec_random, .{}); errdefer factory_w.deinit(); const dpf_w = factory_w.toDDSFactory(); - const dp_w = dpf_w.create_participant(0, .{}, null, 0); + const dp_w = dpf_w.create_participant(test_domain.get(), .{}, null, 0); errdefer _ = dpf_w.delete_participant(dp_w); const pub_w = dp_w.create_publisher(.{}, null, 0); @@ -88,14 +89,14 @@ fn setupMatchedPairEx( dw_qos.liveliness = liveliness; const dw = pub_w.create_datawriter(topic_w, dw_qos, null, 0); - const udp_r = try UdpTransport.init(alloc, .{ .participant_id = r_pid }, 0, null); + const udp_r = try UdpTransport.init(alloc, .{ .participant_id = r_pid }, test_domain.get(), null); errdefer udp_r.deinit(); - const disc_r = try SpdpSedpDiscovery.init(alloc, udp_r.transport(), 0, 1_000); + const disc_r = try SpdpSedpDiscovery.init(alloc, udp_r.transport(), test_domain.get(), 1_000); errdefer disc_r.deinit(); const factory_r = try DomainParticipantFactoryImpl.init(alloc, udp_r.transport(), disc_r.toDiscovery(), noop_security, .spec_random, .{}); errdefer factory_r.deinit(); const dpf_r = factory_r.toDDSFactory(); - const dp_r = dpf_r.create_participant(0, .{}, null, 0); + const dp_r = dpf_r.create_participant(test_domain.get(), .{}, null, 0); errdefer _ = dpf_r.delete_participant(dp_r); const sub_r = dp_r.create_subscriber(.{}, null, 0); diff --git a/test/dcps/writer_vtable_test.zig b/test/dcps/writer_vtable_test.zig index 3bc3e45c..32102816 100644 --- a/test/dcps/writer_vtable_test.zig +++ b/test/dcps/writer_vtable_test.zig @@ -9,6 +9,7 @@ //! and all four notification fire paths. const std = @import("std"); +const test_domain = @import("test_domain"); const zzdds = @import("zzdds"); const DDS = @import("zzdds_generated").DDS; @@ -87,7 +88,7 @@ const SingleFixture = struct { .{}, ); errdefer factory.deinit(); - const dp = factory.toDDSFactory().create_participant(0, .{}, null, 0); + const dp = factory.toDDSFactory().create_participant(test_domain.get(), .{}, null, 0); const pub_ = dp.create_publisher(.{}, null, 0); const topic = dp.create_topic("WriterTopic", "WriterType", .{}, null, 0); return .{ @@ -151,7 +152,7 @@ const TwoPartyFixture = struct { .{}, ); errdefer factory_w.deinit(); - const dp_w = factory_w.toDDSFactory().create_participant(0, .{}, null, 0); + const dp_w = factory_w.toDDSFactory().create_participant(test_domain.get(), .{}, null, 0); const pub_ = dp_w.create_publisher(.{}, null, 0); const topic_w = dp_w.create_topic("WVTopic", "WVType", .{}, null, 0); @@ -168,7 +169,7 @@ const TwoPartyFixture = struct { .{}, ); errdefer factory_r.deinit(); - const dp_r = factory_r.toDDSFactory().create_participant(0, .{}, null, 0); + const dp_r = factory_r.toDDSFactory().create_participant(test_domain.get(), .{}, null, 0); const sub_ = dp_r.create_subscriber(.{}, null, 0); const topic_r = dp_r.create_topic("WVTopic", "WVType", .{}, null, 0); diff --git a/test/support/domain.zig b/test/support/domain.zig new file mode 100644 index 00000000..30f3a6d5 --- /dev/null +++ b/test/support/domain.zig @@ -0,0 +1,52 @@ +//! Per-test-binary DDS domain id. +//! +//! `zig build test` runs the participant-creating test binaries as parallel +//! build-graph Run steps. If they all stand up `DomainParticipant`s on +//! domain 0 they contend for the same fixed RTPS ports — SPDP multicast +//! 7400, metatraffic unicast `7400 + 2*participant_id + 10` — and the loser +//! gets `error.BindFailed`, discovery never completes, and a loopback test +//! times out. It is a real CI flake, worst on slow runners (ARM64, and the +//! DebugAllocator / TSan lanes). +//! +//! `build.zig` gives each test binary's Run step a distinct +//! `ZZDDS_TEST_DOMAIN_BASE` (see `addTestRun`); this reads it. Distinct +//! domains map to disjoint port sets (`port_base + domain_gain*domain`, a +//! 250-port stride), so two test binaries never share a socket. +//! +//! A bare `zig test test/dcps/foo.zig` (no env var) falls back to a fixed +//! non-zero domain — still clear of domain 0, which examples, the dds-rtps +//! interop harness, and manual runs use. + +const std = @import("std"); + +/// Fallback for invocations with no `ZZDDS_TEST_DOMAIN_BASE` (a direct +/// `zig test ` rather than `zig build test`). +pub const FALLBACK: u32 = 199; + +/// Upper bound: `7400 + 250*domain` must stay below 65536, so `domain < 233`. +const MAX_DOMAIN: u32 = 232; + +var cached: ?u32 = null; + +/// The DDS domain id this test binary should use. Stable for the process +/// lifetime; every `create_participant` in a test should pass it. Tests in +/// the same binary run serially and share this domain — that is fine for +/// DDS (each participant is torn down before the next is created), and a +/// leak that broke it would be a real bug worth surfacing, not something to +/// paper over with more domains. +pub fn get() u32 { + if (cached) |d| return d; + const d = resolve(); + cached = d; + return d; +} + +fn resolve() u32 { + // std.c.getenv (not std.process.*): matches examples/zig/shape and needs + // no allocator; every test binary links libc, and so does this module + // (see build.zig's test_domain_mod). + const raw = std.c.getenv("ZZDDS_TEST_DOMAIN_BASE") orelse return FALLBACK; + const s = std.mem.trim(u8, std.mem.span(raw), &std.ascii.whitespace); + const n = std.fmt.parseInt(u32, s, 10) catch return FALLBACK; + return if (n >= 1 and n <= MAX_DOMAIN) n else FALLBACK; +} diff --git a/test/transport/tcp_transport_test.zig b/test/transport/tcp_transport_test.zig index 27e7f19a..78bd387e 100644 --- a/test/transport/tcp_transport_test.zig +++ b/test/transport/tcp_transport_test.zig @@ -766,21 +766,30 @@ test "tcp transport: connectionGeneration increments on reconnect, not on ordina for (server.all_connections.items) |co| _ = std.c.shutdown(co.fd, 2); // SHUT_RDWR server.conn_mu.unlock(); } - // Give the kernel a moment to actually process and propagate the - // shutdown before testing behavior that depends on it having happened. - // This is the well-known TCP characteristic where the first send() after - // a remote RST can still succeed locally (the RST hasn't been processed - // by the local stack yet) — the failure only surfaces on a later send or - // read. CI showed this isn't just a theoretical race: it reproduced on - // both Windows and (previously-passing) macOS once the send followed the - // shutdown closely enough, so this is a real cross-platform TCP settling - // delay to account for, not a platform-specific quirk. - sleepMs(100); - - // Reconnect: generation becomes 2. - try ct.send(&dest, "second"); - latch.waitFor(3); + // The transport detects a dead connection lazily, on the next write + // failure — there's no disconnect event for a send-only connection. After + // shutdown() the local stack may not have processed the peer's FIN yet, + // and the first post-shutdown send() can still succeed on the doomed + // socket (the well-known "first send after a remote RST succeeds locally" + // characteristic — CI has hit this on Windows and macOS). A fixed sleep + // here is a guess at that settling time; under a slow/loaded runner + // (ARM64 + DebugAllocator) it loses the race and generation stays 1. + // Instead, drive the reconnect until the new TcpConnection is observed: + // the first send() that lands after the FIN is processed triggers the + // redial, earlier ones are harmless no-ops on the still-"live" socket. + { + const deadline = time_mod.nanoTimestamp() + 5 * std.time.ns_per_s; + while (time_mod.nanoTimestamp() < deadline) { + ct.send(&dest, "second") catch {}; + if (ct.connectionGeneration(&dest) == 2) break; + sleepMs(20); + } else return error.ReconnectNeverObserved; + } + + // Reconnect happened: generation is 2, and the byte reached the server + // over the new connection. try testing.expectEqual(@as(u32, 2), ct.connectionGeneration(&dest)); + latch.waitFor(3); } // ── IPv6 loopback send + receive ──────────────────────────────────────────────