iceoryx2 v0.10.0: targeted validation on Jetson AGX Orin
I performed a one-off, targeted validation of iceoryx2 v0.10.0 on a Jetson AGX Orin and wanted to share the results as community feedback.
The sample covered event notifications, per-subscriber history, request delivery failure recovery and dynamic payload allocation. Two additional scenarios checked basic communication between separate processes.
This report describes the test conditions and observed results. An appendix lists the selected upstream tests and commands for rerunning them. The custom probe implementation is not included; its configurations, inputs and assertions are documented below, but those descriptions do not provide an exact executable reproduction.
1. Summary
The final runs completed successfully:
- 17 selected upstream IPC conformance tests.
- Four additional feature and regression scenarios.
- Two separate-process IPC communication baselines.
No runtime test failures or timeouts occurred in these final runs. The iceoryx2 product source was not modified.
These results apply to the specific version, environment and scenarios described here. They do not establish full release correctness or performance characteristics.
2. Environment and build configuration
| Item | Tested configuration |
|---|---|
| Hardware | NVIDIA Jetson AGX Orin Developer Kit |
| Operating system | Ubuntu 22.04.4 LTS |
| Architecture | aarch64 |
| Kernel | Linux 5.15.148-rt-tegra |
| Rust | rustc 1.97.0 |
| Cargo | 1.97.0 |
| iceoryx2 | v0.10.0 |
| Commit | 135d09dd8b29f321f1725920d434864c4e512378 |
| Test date | 2026-09-21 |
The upstream conformance tests used the release workspace lockfile and enabled the std feature.
The standalone probes used local path dependencies on iceoryx2 and iceoryx2-cal from the same pinned source. Both dependencies had default features disabled and std enabled. These probes used a separate locked dependency resolution, rather than the release workspace lockfile.
Both final test builds completed offline on the device with two build jobs.
Each selected upstream test had an external 30-second timeout. Each additional scenario also had a 30-second external deadline; for a separate-process baseline, this deadline covered both participating processes together.
3. Selected upstream tests
The upstream sample contained 17 tests using the IPC service variant:
| Area | Tests executed | Result |
|---|---|---|
| Event notifications | 5 | Passed |
| Subscriber history | 4 | Passed |
| Failed request delivery | 3 | Passed |
| Dynamic payload allocation | 5 | Passed |
Each test was selected by its exact name and executed individually. Its output was checked to confirm that one test actually ran and passed, rather than accepting an invocation that selected zero tests.
The additional scenarios below supplemented these existing regressions with explicit message sequences, boundary conditions and recovery checks.
4. Event notifications — #925 and #1813
This scenario checked broadcast delivery, targeted delivery and accumulated event counts.
The service had two listeners and one notifier. Event ID 7 was used for the main checks. The target listener was identified using a listener key obtained from that same notifier.
The following phases ran sequentially, draining events between phases:
| Notifications sent | Expected count at other listener | Expected count at target listener | Observed |
|---|---|---|---|
| 17 broadcasts | 17 | 17 | Matched |
| 23 targeted notifications | 0 | 23 | Matched |
| 5 broadcasts and 7 targeted notifications | 5 | 12 | Matched |
Counts were calculated by summing EventActivation.count, rather than counting callback invocations.
Each broadcast reported two recipients. After draining each phase, neither listener had an additional activation remaining.
An event-ID boundary check was also included:
- The configured maximum event ID was 32.
- Broadcasting event ID 32 succeeded, and both listeners received it.
- Broadcasting event ID 33 returned
EventIdOutOfBounds. - Targeting event ID 33 at the selected listener also returned
EventIdOutOfBounds. - The rejected operations did not produce additional activations.
Result: broadcast and targeted notifications reached the expected listeners, repeated notifications produced the expected accumulated counts, and the tested invalid IDs were rejected.
5. Per-subscriber history — #1185
This scenario checked that subscribers could request different amounts of history from the same publisher and subsequently receive live messages.
The service was configured with:
- History size: 8.
- One publisher and four subscribers.
- Subscriber buffer size: 12.
- Safe overflow disabled.
The sequence was:
- Publish values
0through8before creating any subscriber. - Create subscribers requesting history sizes of 0, 2 and 4, plus one subscriber using the default.
- Update the publisher connections.
- Publish three live values:
9,10and11. - Drain each subscriber and compare its complete sequence.
| History request | Expected sequence | Observed |
|---|---|---|
| 0 | [9, 10, 11] |
Exact match |
| 2 | [7, 8, 9, 10, 11] |
Exact match |
| 4 | [5, 6, 7, 8, 9, 10, 11] |
Exact match |
| Default, resolving to 8 here | [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11] |
Exact match |
No additional samples remained after these sequences were consumed.
The selected upstream tests also covered rejection when an explicit history request exceeded the service history size or the subscriber buffer size.
Result: each subscriber received the requested historical suffix, followed by the live messages in the expected order.
6. Request delivery failure recovery — #1969
This scenario deliberately exercised failed delivery and then checked whether the client could continue making successful requests.
The main checks used active-request capacities of 1 and 4, with four rounds for each capacity.
Safe overflow for requests was disabled, fire-and-forget requests were enabled, and the client backpressure handler returned DiscardDataAndFail.
Each round performed the following steps:
- Fill the server request queue with numbered requests.
- Drop their pending responses, leaving the queued fire-and-forget requests without retaining client active-request capacity.
- Attempt additional sends while the server queue remained full.
- Require those sends to fail with:
RequestSendError::SendError(SendError::UnableToDeliver). - Drain and verify the original queued requests.
- Send a fresh request and verify its response content.
For capacity 1, each round required two failed sends. For capacity 4, each round required five failed sends.
Across the eight rounds:
- All 28 deliberately rejected sends returned the expected delivery error.
- Backpressure callback counts matched the failed-send counts.
- All eight subsequent request/response exchanges succeeded with the expected values.
An ExceedsMaxActiveRequests error would not have counted as successful coverage of this delivery-failure path.
Partial delivery to multiple servers
A second check used two servers: one with a full queue and one able to receive. It ran with fire-and-forget both disabled and enabled.
After the partially delivered request failed:
- With fire-and-forget disabled, the healthy server did not expose the canceled request.
- With fire-and-forget enabled, the healthy server received it, but
is_connected()returned false. - After draining the blocked server, a fresh request succeeded and responses from both servers were received.
This checked response-channel state through the public API; it was not a measurement of OS-resource teardown.
The selected upstream regressions additionally checked that a failed send preserved other pending responses.
Result: the tested delivery failures did not prevent subsequent requests from succeeding, and the partially delivered request channels behaved as expected.
7. Dynamic payload allocation — #1920
This scenario checked payload integrity during growth and behavior at the allocation limit.
Both BestFit and PowerOfTwo were tested with:
- One publisher and one subscriber.
- History disabled.
- One buffered sample.
- One borrowed sample.
- One loaned sample.
- Initial maximum slice-length hint of 1.
- Safe overflow disabled.
Every successful message was checked byte-for-byte against a pattern depending on both its byte index and message sequence.
BestFit
The payload sizes were:
1 + 32 × n, for n = 0..254.
Each size was sent and received three times.
This covered 255 size levels, from 1 to 8129 bytes. All 765 send/receive checks succeeded with exact payload contents.
After these successful allocations:
- Two attempts to allocate an 8161-byte payload returned
LoanError::OutOfMemory. - A subsequent one-byte message was still sent and received successfully.
This behavior is consistent with the segment limit in v0.10.0. The interpretation of an initial segment followed by 254 growths comes from the implementation and test sequence; the probe did not directly count segment creations or simultaneously active segments.
The 8161-byte failure point belongs to this particular sequence of reallocations. It is not a general maximum payload size for iceoryx2.
PowerOfTwo
The tested sizes included:
- 0 and 1 byte.
2^k - 1,2^kand2^k + 1, fork = 5..18.
This produced 44 size points, each checked three times. The largest payload was 262145 bytes.
All 132 send/receive checks passed with exact payload contents.
Result: the tested growth boundaries preserved data, the BestFit sequence reached the expected allocation failure, and that failure did not prevent subsequent reuse for a smaller payload.
8. Separate-process IPC baselines
The four feature scenarios above used multiple ipc::Service objects within a single process.
Two additional scenarios checked communication between distinct processes.
Publish/subscribe
A receiver process and a sender process exchanged the exact sequence:
[1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008]
History was disabled. Each send reported one recipient, and the receiver verified the complete sequence without additional samples.
Request/response
A server process and a client process exchanged four requests with an active-request limit of 1:
| Request | Expected response | Observed |
|---|---|---|
| 2001 | 6003 | Matched |
| 2002 | 6006 | Matched |
| 2003 | 6009 | Matched |
| 2004 | 6012 | Matched |
Readiness was coordinated before sending. Control files were used only for process synchronization; message payloads traveled through iceoryx2 IPC.
All four baseline processes exited successfully.
9. Evidence and coverage limits
The results were checked against the recorded process exits and scenario observations. The tested source and dependency lockfiles remained unchanged during execution.
All eight standalone probe processes exited successfully without timeouts.
This validation did not include:
- Other operating systems, architectures or language bindings.
- Long-running stress or endurance tests.
- Process-crash recovery.
- Sanitizers or race-detection tools.
- Throughput, latency or real-time jitter measurements.
- Minimum-supported-Rust-version testing.
- Comparisons against versions before the fixes.
The two separate-process baselines do not establish that every feature scenario was tested across process boundaries.
The checks establish the observed behavior of this v0.10.0 sample. Without pre-fix comparisons, they do not independently establish the causal effect of each individual fix.
10. Community feedback
No failures were observed within this selected v0.10.0 sample on the Jetson environment described above.
I hope this provides a useful additional data point from a Linux ARM64 device. Feedback on the test assumptions, expected behavior or coverage would be welcome.
Appendix: rerunning the selected upstream tests
The following applies to the existing upstream tests, not the custom scenarios described above.
Use a checkout at:
135d09dd8b29f321f1725920d434864c4e512378
From the repository root, build the conformance test executable:
cargo test --locked --offline -j2 \
-p iceoryx2-conformance-tests \
--features std \
--test iceoryx2-conformance-tests-tests \
--no-run
This command assumes the locked dependencies are already cached.
Cargo prints the path of the generated test executable. Set sampling_test_binary below to that exact path; the filename hash depends on the build.
The following Bash snippet runs the same 17 selected tests individually, with a 30-second timeout per test. It uses GNU timeout, as available on the tested Linux environment.
set -e
# Replace <hash> with the executable hash printed by Cargo.
sampling_test_binary="target/debug/deps/iceoryx2_conformance_tests_tests-<hash>"
while IFS= read -r sampling_case; do
timeout 30 "$sampling_test_binary" "$sampling_case" \
--exact --nocapture --test-threads=1
done <<'TEST_CASES'
service_event_tests::ipc::service_event::notifying_single_specific_listener_works
service_event_tests::ipc::service_event::notifying_single_specific_listener_with_custom_event_id_works
service_event_tests::ipc::service_event::notifying_with_listener_key_repeatedly_works
service_event_tests::ipc::service_event::notifying_single_specific_listener_with_invalid_event_id_results_in_error
service_event_tests::ipc::service_event::communication_with_max_notifiers_and_listeners_multi_notification
service_publish_subscribe_tests::ipc::service_publish_subscribe::subscriber_history_request_cannot_exceed_history_size
service_publish_subscribe_tests::ipc::service_publish_subscribe::subscriber_history_request_cannot_exceed_buffer_size
service_publish_subscribe_tests::ipc::service_publish_subscribe::subscriber_receives_history_request_amount_of_samples
service_publish_subscribe_tests::ipc::service_publish_subscribe::subscriber_with_different_history_request_receive_samples
service_publish_subscribe_tests::ipc::service_publish_subscribe::send_and_receives_increasing_samples_works_for_best_fit_allocation_strategy
service_publish_subscribe_tests::ipc::service_publish_subscribe::send_and_receives_increasing_samples_works_for_power_of_two_allocation_strategy
service_publish_subscribe_tests::ipc::service_publish_subscribe::send_and_receives_increasing_samples_with_overflow_for_best_fit_allocation_strategy
service_publish_subscribe_tests::ipc::service_publish_subscribe::send_and_receives_increasing_samples_with_overflow_for_power_of_two_allocation_strategy
service_publish_subscribe_tests::ipc::service_publish_subscribe::send_increasing_samples_with_best_fit_finally_leads_to_out_of_memory_error
client_tests::ipc::client::failed_request_send_does_not_consume_active_request_capacity
client_tests::ipc::client::failed_request_send_closes_partially_delivered_response_channels
client_tests::ipc::client::failed_request_send_preserves_other_pending_responses
TEST_CASES
For each invocation, check that the output reports one executed test and 1 passed; 0 failed. A zero exit code with zero selected tests should not be counted as a successful validation.