rosotacom-dev 2.5.dev77__tar.gz → 2.5.dev79__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/PKG-INFO +1 -1
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom/cli.py +186 -15
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom/cli_benchmark.py +27 -21
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom_dev.egg-info/PKG-INFO +1 -1
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom_dev.egg-info/SOURCES.txt +1 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom_dev.egg-info/scm_file_list.json +1 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom_dev.egg-info/scm_version.json +2 -2
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/tests/unit/test_cli_benchmark.py +9 -1
- rosotacom_dev-2.5.dev79/tests/unit/test_ota_benchmark_peer_exec.py +134 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/.devcontainer/devcontainer.json.template +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/.devcontainer/re_generate_devcontainer_json.py +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/.github/CODEOWNERS +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/.github/ISSUE_TEMPLATE/documentation-audit.md +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/.github/ISSUE_TEMPLATE/implementation-cleanup.md +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/.github/ISSUE_TEMPLATE/quality-workflow.md +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/.github/ISSUE_TEMPLATE/redesign.md +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/.github/ISSUE_TEMPLATE/release-process.md +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/.github/ISSUE_TEMPLATE/repository-diagnosis.md +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/.github/ISSUE_TEMPLATE/test-ci-audit.md +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/.github/ISSUE_TEMPLATE/work-item.md +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/.github/actions/setup-just/action.yml +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/.github/dependabot.yml +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/.github/workflows/benchmark-calibrate.yml +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/.github/workflows/benchmark-gate.yml +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/.github/workflows/dev-release.yml +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/.github/workflows/image-scan.yml +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/.github/workflows/nightly-e2e.yml +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/.github/workflows/pr-lightweight.yml +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/.github/workflows/pr-merge-gate.yml +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/.github/workflows/release.yml +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/.pre-commit-config.yaml +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/AGENTS.md +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/CONCURRENCY.md +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/CONTRIBUTING.md +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/DEVELOPMENT_PRINCIPLES.md +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/LICENSE.txt +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/MANIFEST.in +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/README.md +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/budgets.jsonl +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/calibration/README.md +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/calibration/capacity-size-tight-cyclone.json +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/calibration/probe-loss-gop-tight-cyclone.json +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/calibration/probe-loss-nominal-cyclone.json +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/calibration/probe-loss-tight-cyclone.json +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/calibration/probe-loss-tight-fastdds.json +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/calibration/probe-loss-tight-zenoh.json +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/codecov.yml +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/deployment-configuration.md +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/docs/benchmark-ab.md +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/docs/benchmark-bag-as-load.md +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/docs/ci.md +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/docs/ffmpeg-keyframes.md +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/docs/findings/README.md +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/docs/findings/a-fitted-delay-table-never-reached-the-shaper.md +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/docs/findings/a-shorter-group-does-not-lose-fewer-key-frames.md +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/docs/findings/a-transport-element-doubles-every-fastdds-sample.md +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/docs/findings/cyclone-fragment-equal-to-max-drops-fragmented-samples.md +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/docs/findings/cyclone-spdp-discovery-bursts.md +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/docs/findings/delay-alone-no-loss.md +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/docs/findings/fastdds-datagram-cap-drops-large-samples.md +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/docs/findings/graph-derived-types-block-a-non-graph-transport.md +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/docs/findings/head-of-line-irregularity.md +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/docs/findings/jitter-loss-bandwidth-latency.md +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/docs/findings/keyframe-loss-kills-the-next-deltas.md +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/docs/findings/lifespan-is-enforced-by-one-reader-and-not-the-other.md +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/docs/findings/lighter-message-loss.md +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/docs/findings/neither-a-queue-nor-a-burst-tilts-the-size-law.md +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/docs/findings/one-domain-two-cyclone-configs-stop-interoperating.md +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/docs/findings/oversubscription-queues-not-losses.md +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/docs/findings/reorder-becomes-reader-loss.md +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/docs/findings/repro/decode_chain_repro.py +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/docs/findings/repro/reorder_drop_repro.py +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/docs/findings/sender-rows-make-a-dead-link-look-loss-free.md +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/docs/findings/the-size-law-belongs-to-the-transport-not-the-link.md +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/docs/findings/zero-loss-boundaries-18kb-20hz.md +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/docs/forensics-report.md +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/docs/geo-link-map.md +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/docs/github-repository-settings.md +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/docs/link-bandwidth.md +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/docs/link-trace.md +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/docs/ota-pcap.md +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/docs/owner-runbook.md +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/docs/performance-bands.md +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/docs/playbooks/README.md +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/docs/quality-model.md +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/docs/release-notes/TEMPLATE.md +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/docs/release-notes/v2.1.md +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/docs/release-notes/v2.2.md +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/docs/release-notes/v2.3.md +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/docs/release-notes/v2.4.md +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/docs/release.md +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/docs/rfcs/0001-expectation-driven-test-suite.md +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/docs/rfcs/0002-expectation-concepts.md +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/docs/rfcs/0003-metric-backbone.md +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/docs/rfcs/0004-network-profiles.md +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/docs/rfcs/0005-benchmark-genres-and-ci.md +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/docs/rfcs/0006-dynamic-qos.md +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/docs/rfcs/0007-regression-gate.md +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/docs/rfcs/README.md +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/docs/testing.md +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/docs/work-items.md +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/install.sh +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/justfile +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/media/control_center.png +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/media/echo_test.png +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/media/forensics-report-example.png +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/media/host.png +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/media/vehicle.png +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/pyproject.toml +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/requirements.txt +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/rosotacom.yaml +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/session-configuration.md +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/setup.cfg +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom/__init__.py +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom/__main__.py +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom/anonymize.py +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom/bag_ground_truth.py +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom/benched_set.py +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom/benchmark.py +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom/benchmark_delta.py +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom/bundle_check.py +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom/deployment.py +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom/ffmpeg_packet.py +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom/forensics.py +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom/geomap.py +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom/image_cache.py +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom/netem_dist.py +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom/network_preflight.py +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom/network_profiles.py +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom/network_shaper.py +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom/plots.py +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom/py.typed +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom/resources/benched-set.yaml +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom/resources/examples/.gitignore +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom/resources/examples/README.md +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom/resources/examples/__init__.py +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom/resources/examples/bags/8_drop_reference/metadata.yaml +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom/resources/examples/deployment.example.yaml +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom/resources/examples/dist/field-20260817.dist +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom/resources/examples/profiles.yaml +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom/resources/examples/ros2docker.json +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom/resources/examples/ros2docker.lyrical.json +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom/resources/examples/rosotacom.yaml +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom/resources/examples/scenarios/2_native_chatter/scenario-definition.yaml +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom/resources/examples/scripts/1_heartbeat/run_machine_a.sh +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom/resources/examples/scripts/1_heartbeat/run_machine_b.sh +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom/resources/examples/scripts/2_native_chatter/machine_a/external.lyrical.ros2docker.json +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom/resources/examples/scripts/2_native_chatter/machine_a/external.ros2docker.json +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom/resources/examples/scripts/2_native_chatter/machine_a/run_communication.sh +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom/resources/examples/scripts/2_native_chatter/machine_a/run_external.py +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom/resources/examples/scripts/2_native_chatter/machine_a/wait_for_echo_topic.sh +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom/resources/examples/scripts/2_native_chatter/machine_b/external.lyrical.ros2docker.json +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom/resources/examples/scripts/2_native_chatter/machine_b/external.ros2docker.json +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom/resources/examples/scripts/2_native_chatter/machine_b/run_communication.sh +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom/resources/examples/scripts/2_native_chatter/machine_b/run_external.py +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom/resources/examples/scripts/3_comp_occ_grid/machine_a/external.ros2docker.json +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom/resources/examples/scripts/3_comp_occ_grid/machine_a/external_session.yaml +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom/resources/examples/scripts/3_comp_occ_grid/machine_a/foxglove.json +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom/resources/examples/scripts/3_comp_occ_grid/machine_a/run_communication.sh +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom/resources/examples/scripts/3_comp_occ_grid/machine_a/run_external.py +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom/resources/examples/scripts/3_comp_occ_grid/machine_b/costmap_1second/costmap_1second_0.mcap +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom/resources/examples/scripts/3_comp_occ_grid/machine_b/costmap_1second/metadata.yaml +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom/resources/examples/scripts/3_comp_occ_grid/machine_b/external.ros2docker.json +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom/resources/examples/scripts/3_comp_occ_grid/machine_b/run_communication.sh +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom/resources/examples/scripts/3_comp_occ_grid/machine_b/run_external.py +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom/resources/examples/scripts/4_comp_occ_grid_zen/machine_a/external.ros2docker.json +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom/resources/examples/scripts/4_comp_occ_grid_zen/machine_a/external_session.yaml +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom/resources/examples/scripts/4_comp_occ_grid_zen/machine_a/foxglove.json +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom/resources/examples/scripts/4_comp_occ_grid_zen/machine_a/run_communication.sh +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom/resources/examples/scripts/4_comp_occ_grid_zen/machine_a/run_external.py +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom/resources/examples/scripts/4_comp_occ_grid_zen/machine_b/costmap_1second/costmap_1second_0.mcap +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom/resources/examples/scripts/4_comp_occ_grid_zen/machine_b/costmap_1second/metadata.yaml +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom/resources/examples/scripts/4_comp_occ_grid_zen/machine_b/external.ros2docker.json +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom/resources/examples/scripts/4_comp_occ_grid_zen/machine_b/run_communication.sh +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom/resources/examples/scripts/4_comp_occ_grid_zen/machine_b/run_external.py +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom/resources/examples/scripts/5_sized_payload/machine_a/external.ros2docker.json +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom/resources/examples/scripts/5_sized_payload/machine_a/external_session.yaml +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom/resources/examples/scripts/5_sized_payload/machine_a/run_communication.sh +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom/resources/examples/scripts/5_sized_payload/machine_a/run_external.py +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom/resources/examples/scripts/5_sized_payload/machine_b/external.ros2docker.json +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom/resources/examples/scripts/5_sized_payload/machine_b/external_session.yaml +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom/resources/examples/scripts/5_sized_payload/machine_b/run_communication.sh +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom/resources/examples/scripts/5_sized_payload/machine_b/run_external.py +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom/resources/examples/scripts/6_sized_payload_zen/machine_a/external.ros2docker.json +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom/resources/examples/scripts/6_sized_payload_zen/machine_a/external_session.yaml +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom/resources/examples/scripts/6_sized_payload_zen/machine_a/run_communication.sh +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom/resources/examples/scripts/6_sized_payload_zen/machine_a/run_external.py +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom/resources/examples/scripts/6_sized_payload_zen/machine_b/external.ros2docker.json +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom/resources/examples/scripts/6_sized_payload_zen/machine_b/external_session.yaml +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom/resources/examples/scripts/6_sized_payload_zen/machine_b/run_communication.sh +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom/resources/examples/scripts/6_sized_payload_zen/machine_b/run_external.py +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom/resources/examples/sessions/10_restamp/session-definition.yaml +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom/resources/examples/sessions/11_trickle/session-definition.yaml +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom/resources/examples/sessions/12_content_integrity/session-definition.yaml +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom/resources/examples/sessions/13_link_latency/session-definition.yaml +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom/resources/examples/sessions/14_remote_assist_anonymized/session-definition.yaml +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom/resources/examples/sessions/15_remote_assist_anonymized_costmap/session-definition.yaml +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom/resources/examples/sessions/16_remote_assist_anonymized_camera/session-definition.yaml +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom/resources/examples/sessions/17_synthetic_camera_quality/session-definition.yaml +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom/resources/examples/sessions/1_heartbeat/session-definition.yaml +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom/resources/examples/sessions/1_heartbeat_status/session-definition.yaml +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom/resources/examples/sessions/2_native_chatter/session-definition.yaml +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom/resources/examples/sessions/3_comp_occ_grid/session-definition.yaml +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom/resources/examples/sessions/4_comp_occ_grid_zen/session-definition.yaml +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom/resources/examples/sessions/5_sized_payload/session-definition.yaml +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom/resources/examples/sessions/6_sized_payload_zen/session-definition.yaml +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom/resources/examples/sessions/7_latched_static/session-definition.yaml +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom/resources/examples/sessions/8_drop/session-definition.yaml +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom/resources/examples/sessions/9_throttle/session-definition.yaml +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom/resources/examples/sessions/bench_1_1_capacity/session-definition.yaml +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom/resources/examples/sessions/bench_1_2_load_sweep/session-definition.yaml +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom/resources/examples/sessions/bench_1_3_ramp/session-definition.yaml +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom/resources/examples/sessions/bench_1_4_recovery/session-definition.yaml +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom/resources/examples/sessions/bench_1_5_camera/session-definition.yaml +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom/resources/ros2docker.json.example +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom/resources/ros2docker.lyrical.json.example +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom/resources/ws/.vscode/c_cpp_properties.json +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom/resources/ws/.vscode/settings.json +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom/resources/ws/ota_configs/archive/fastdds_easy_mode.xml.template +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom/resources/ws/ota_configs/archive/fastdds_initial_peer_list.xml.template +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom/resources/ws/ota_configs/archive/fastdds_v2.xml.template +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom/resources/ws/ota_configs/archive/fastdds_v3.xml.template +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom/resources/ws/ota_configs/archive/fastdds_v4.xml.template +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom/resources/ws/ota_configs/archive/fastdds_v5.xml.template +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom/resources/ws/ota_configs/create_zenoh_json5.py +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom/resources/ws/ota_configs/cyclonedds_local_participants.xml.template +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom/resources/ws/ota_configs/cyclonedds_minimal.xml.template +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom/resources/ws/ota_configs/cyclonedds_scoped.xml.template +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom/resources/ws/ota_configs/cyclonedds_tuned.xml.template +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom/resources/ws/ota_configs/fastdds_easy_mode.xml.template +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom/resources/ws/ota_configs/fastdds_local.xml.template +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom/resources/ws/ota_configs/fastdds_tuned.xml.template +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom/resources/ws/ota_configs/fastdds_unicast.xml.template +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom/resources/ws/ota_configs/get_ota_xml.py +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom/resources/ws/ota_configs/utils.py +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom/resources/ws/ota_configs/zenoh.json5.template +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom/resources/ws/ros2src/.gitkeep +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom/resources/ws/ros2src/com_cpp/CMakeLists.txt +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom/resources/ws/ros2src/com_cpp/COLCON_IGNORE +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom/resources/ws/ros2src/com_cpp/LICENSE.txt +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom/resources/ws/ros2src/com_cpp/package.xml +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom/resources/ws/ros2src/com_cpp/src/hz_monitor.cpp +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom/resources/ws/ros2src/com_cpp/src/universal_compressor.cpp +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom/resources/ws/ros2src/com_cpp/src/universal_decompressor.cpp +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom/resources/ws/ros2src/com_msgs/CMakeLists.txt +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom/resources/ws/ros2src/com_msgs/LICENSE.txt +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom/resources/ws/ros2src/com_msgs/msg/CompressedData.msg +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom/resources/ws/ros2src/com_msgs/msg/EchoHeartbeat.msg +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom/resources/ws/ros2src/com_msgs/msg/OtaStamped.msg +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom/resources/ws/ros2src/com_msgs/msg/SizedPayload.msg +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom/resources/ws/ros2src/com_msgs/package.xml +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom/resources/ws/ros2src/com_py/LICENSE.txt +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom/resources/ws/ros2src/com_py/com_py/__init__.py +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom/resources/ws/ros2src/com_py/com_py/base_bridge_relay.py +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom/resources/ws/ros2src/com_py/com_py/bridge_in.py +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom/resources/ws/ros2src/com_py/com_py/bridge_out.py +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom/resources/ws/ros2src/com_py/com_py/ffmpeg_flags.py +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom/resources/ws/ros2src/com_py/com_py/heartbeat_echo.py +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom/resources/ws/ros2src/com_py/com_py/hz_monitor.py +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom/resources/ws/ros2src/com_py/com_py/image_bandwidth_reducer.py +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom/resources/ws/ros2src/com_py/com_py/image_pixel_capper.py +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom/resources/ws/ros2src/com_py/com_py/lanelet_saver.py +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom/resources/ws/ros2src/com_py/com_py/latch_relay.py +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom/resources/ws/ros2src/com_py/com_py/legacy/costmap_remapper.py +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom/resources/ws/ros2src/com_py/com_py/legacy/marker_remapper.py +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom/resources/ws/ros2src/com_py/com_py/legacy/speed_test.py +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom/resources/ws/ros2src/com_py/com_py/legacy/tf_remapper.py +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom/resources/ws/ros2src/com_py/com_py/legacy/traffic_monitor.py +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom/resources/ws/ros2src/com_py/com_py/legacy/wifi_network_analysis_1.py +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom/resources/ws/ros2src/com_py/com_py/link_bytes.py +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom/resources/ws/ros2src/com_py/com_py/link_trace.py +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom/resources/ws/ros2src/com_py/com_py/local_global_frame_bridge.py +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom/resources/ws/ros2src/com_py/com_py/localization_map_split_reduce_saver.py +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom/resources/ws/ros2src/com_py/com_py/msg_transform.py +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom/resources/ws/ros2src/com_py/com_py/ota_pcap.py +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom/resources/ws/ros2src/com_py/com_py/pair_management.py +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom/resources/ws/ros2src/com_py/com_py/playout_pacer.py +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom/resources/ws/ros2src/com_py/com_py/playout_pacer_core.py +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom/resources/ws/ros2src/com_py/com_py/pub_sub_pair.py +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom/resources/ws/ros2src/com_py/com_py/qos.py +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom/resources/ws/ros2src/com_py/com_py/relay_in.py +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom/resources/ws/ros2src/com_py/com_py/relay_out.py +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom/resources/ws/ros2src/com_py/com_py/restamp.py +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom/resources/ws/ros2src/com_py/com_py/sized_publisher.py +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom/resources/ws/ros2src/com_py/com_py/stage_latency.py +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom/resources/ws/ros2src/com_py/com_py/stage_latency_core.py +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom/resources/ws/ros2src/com_py/com_py/status_overview.py +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom/resources/ws/ros2src/com_py/com_py/status_overview_core.py +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom/resources/ws/ros2src/com_py/com_py/tf_map_to_cart_saver.py +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom/resources/ws/ros2src/com_py/com_py/topic_monitor.py +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom/resources/ws/ros2src/com_py/com_py/topic_resolution.py +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom/resources/ws/ros2src/com_py/com_py/trickle.py +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom/resources/ws/ros2src/com_py/com_py/universal_compressor.py +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom/resources/ws/ros2src/com_py/com_py/universal_decompressor.py +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom/resources/ws/ros2src/com_py/com_py/universal_ota_unwrapper.py +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom/resources/ws/ros2src/com_py/com_py/universal_ota_wrapper.py +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom/resources/ws/ros2src/com_py/package.xml +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom/resources/ws/ros2src/com_py/resource/com_py +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom/resources/ws/ros2src/com_py/setup.cfg +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom/resources/ws/ros2src/com_py/setup.py +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom/resources/ws/ros2src/com_py/test/test_copyright.py +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom/resources/ws/ros2src/com_py/test/test_flake8.py +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom/resources/ws/ros2src/com_py/test/test_pep257.py +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom/resources/ws/session/content/base/session_plugin_base.yaml +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom/resources/ws/session/content/network/up_connectivity.py +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom/resources/ws/session/content/network/wifi_network_analysis_2.py +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom/resources/ws/session/creation/anonymize_bag.py +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom/resources/ws/session/creation/catmux_log_setup.sh +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom/resources/ws/session/creation/create_session_yaml.py +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom/resources/ws/session/creation/generate_session_files.py +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom/resources/ws/session/creation/run_session.py +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom/resources/ws/session/creation/run_session_in_external_terminal.py +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom/resources/ws/session/creation/strip_ansi.py +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom/status_eval.py +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom/stream_stats.py +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom/trace_profiles.py +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom/transit.py +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom/video_quality.py +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom_dev.egg-info/dependency_links.txt +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom_dev.egg-info/entry_points.txt +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom_dev.egg-info/requires.txt +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom_dev.egg-info/top_level.txt +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/terminology.md +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/tests/contract/test_benched_set_registry.py +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/tests/contract/test_findings.py +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/tests/contract/test_generated_topics_have_a_producer.py +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/tests/contract/test_lyrical_runtime_compat.py +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/tests/contract/test_markdown_links.py +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/tests/contract/test_ota_source_bundle.py +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/tests/contract/test_package_metadata.py +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/tests/contract/test_packaged_resources.py +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/tests/contract/test_profile_covers_generated_commands.py +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/tests/contract/test_pytest_policy.py +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/tests/contract/test_readme_examples.py +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/tests/contract/test_security_maintenance_config.py +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/tests/contract/test_session_configuration_doc.py +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/tests/contract/test_session_template_substitution.py +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/tests/contract/test_workflow_contracts.py +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/tests/e2e/conftest.py +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/tests/e2e/test_anonymize_e2e.py +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/tests/e2e/test_benchmark_ab.py +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/tests/e2e/test_benchmark_capacity.py +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/tests/e2e/test_benchmark_replay.py +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/tests/e2e/test_parallel_smoke.py +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/tests/e2e/test_smoke.py +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/tests/e2e/test_timeline_stepping.py +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/tests/e2e/test_video_quality_e2e.py +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/tests/sessions/generate_rmw_matrix.py +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/tests/sessions/rmw_matrix/1_heartbeat_cyclone-local_zenoh-ros2dds-ota/session-definition.yaml +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/tests/sessions/rmw_matrix/1_heartbeat_cyclone-ota/session-definition.yaml +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/tests/sessions/rmw_matrix/1_heartbeat_cyclone-ota-tuned/session-definition.yaml +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/tests/sessions/rmw_matrix/1_heartbeat_fastdds/session-definition.yaml +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/tests/sessions/rmw_matrix/1_heartbeat_fastdds-default/session-definition.yaml +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/tests/sessions/rmw_matrix/1_heartbeat_zen-endpoints/session-definition.yaml +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/tests/unit/test_anonymize.py +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/tests/unit/test_bag_ground_truth.py +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/tests/unit/test_benched_set.py +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/tests/unit/test_benchmark.py +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/tests/unit/test_benchmark_delta.py +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/tests/unit/test_bundle_check.py +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/tests/unit/test_catmux_pane_logging.py +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/tests/unit/test_cli.py +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/tests/unit/test_concurrency.py +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/tests/unit/test_container_shaping.py +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/tests/unit/test_deployment.py +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/tests/unit/test_ffmpeg_flags.py +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/tests/unit/test_ffmpeg_packet.py +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/tests/unit/test_field_profiles.py +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/tests/unit/test_forensics.py +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/tests/unit/test_geomap.py +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/tests/unit/test_image_cache.py +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/tests/unit/test_link_bytes.py +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/tests/unit/test_link_trace.py +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/tests/unit/test_netem_dist.py +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/tests/unit/test_network_preflight.py +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/tests/unit/test_network_profiles.py +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/tests/unit/test_network_shaper.py +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/tests/unit/test_ota_link_configs.py +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/tests/unit/test_ota_pcap.py +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/tests/unit/test_ota_unwrapper.py +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/tests/unit/test_ota_wrapper.py +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/tests/unit/test_ota_xml.py +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/tests/unit/test_playout_pacer.py +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/tests/unit/test_plots.py +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/tests/unit/test_pub_sub_pair_types.py +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/tests/unit/test_qos_fallback_logging.py +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/tests/unit/test_relay_optional_parameters.py +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/tests/unit/test_ros_node_entity_ownership.py +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/tests/unit/test_session_pipeline.py +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/tests/unit/test_stage_latency.py +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/tests/unit/test_status_eval.py +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/tests/unit/test_status_overview.py +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/tests/unit/test_status_overview_observer.py +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/tests/unit/test_stream_stats.py +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/tests/unit/test_terminology_stage_ownership.py +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/tests/unit/test_trace_profiles.py +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/tests/unit/test_transit.py +0 -0
- {rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/tests/unit/test_video_quality.py +0 -0
|
@@ -293,6 +293,12 @@ class OtaSmokePlan:
|
|
|
293
293
|
peers: dict[str, OtaSmokePeer]
|
|
294
294
|
install_mode: str = "source"
|
|
295
295
|
install_pin: str | None = None
|
|
296
|
+
#: Where the peers write session instances, relative to the project file's
|
|
297
|
+
#: own directory. `session-instances` is the default a project that says
|
|
298
|
+
#: nothing gets; a project that sets `session_instances_dir` to anything
|
|
299
|
+
#: else -- `../instances`, say -- used to have its artifacts looked for in a
|
|
300
|
+
#: directory nothing writes to, and the miss was silent.
|
|
301
|
+
instances_rel: str = "session-instances"
|
|
296
302
|
|
|
297
303
|
|
|
298
304
|
@dataclass(frozen=True)
|
|
@@ -1835,6 +1841,26 @@ def _ota_checkout_project_path(project_config: Path) -> tuple[Path, str]:
|
|
|
1835
1841
|
)
|
|
1836
1842
|
|
|
1837
1843
|
|
|
1844
|
+
def _ota_instances_rel(runtime: RuntimeConfig) -> str:
|
|
1845
|
+
"""Where this project writes session instances, relative to its own file.
|
|
1846
|
+
|
|
1847
|
+
The peers resolve the project from their own checkout, so the *relative*
|
|
1848
|
+
answer is the one that travels; an absolute path is the orchestrator's and
|
|
1849
|
+
means nothing on the far side. A project that says nothing gets
|
|
1850
|
+
`session-instances`, which is what the collection used to assume for every
|
|
1851
|
+
project -- and a project that says `../instances` had its artifacts looked
|
|
1852
|
+
for in a directory nothing writes to.
|
|
1853
|
+
"""
|
|
1854
|
+
default = "session-instances"
|
|
1855
|
+
if not runtime.rosotacom_config:
|
|
1856
|
+
return default
|
|
1857
|
+
raw = _load_yaml_file(runtime.rosotacom_config)
|
|
1858
|
+
value = raw.get("session_instances_dir")
|
|
1859
|
+
if not value:
|
|
1860
|
+
return default
|
|
1861
|
+
return str(value)
|
|
1862
|
+
|
|
1863
|
+
|
|
1838
1864
|
def _ota_plan_from_bindings(
|
|
1839
1865
|
bindings: dict[str, PeerBinding],
|
|
1840
1866
|
*,
|
|
@@ -1845,6 +1871,7 @@ def _ota_plan_from_bindings(
|
|
|
1845
1871
|
project: str | None = None,
|
|
1846
1872
|
exec_commands: Mapping[str, str] | None = None,
|
|
1847
1873
|
cpusets: Mapping[str, str] | None = None,
|
|
1874
|
+
instances_rel: str = "session-instances",
|
|
1848
1875
|
) -> OtaSmokePlan:
|
|
1849
1876
|
_ota_validate_install_mode(install_mode)
|
|
1850
1877
|
if cpusets:
|
|
@@ -1923,6 +1950,7 @@ def _ota_plan_from_bindings(
|
|
|
1923
1950
|
peers=peers,
|
|
1924
1951
|
install_mode=install_mode,
|
|
1925
1952
|
install_pin=install_pin,
|
|
1953
|
+
instances_rel=instances_rel,
|
|
1926
1954
|
)
|
|
1927
1955
|
|
|
1928
1956
|
|
|
@@ -1935,6 +1963,7 @@ def _ota_write_state(instance: SessionInstance, plan: OtaSmokePlan) -> OtaSmokeP
|
|
|
1935
1963
|
"project": plan.project,
|
|
1936
1964
|
"install_mode": plan.install_mode,
|
|
1937
1965
|
"install_pin": plan.install_pin,
|
|
1966
|
+
"instances_rel": plan.instances_rel,
|
|
1938
1967
|
"peers": {
|
|
1939
1968
|
name: {
|
|
1940
1969
|
"address": peer.address,
|
|
@@ -1979,6 +2008,7 @@ def _ota_load_state(path_arg: str) -> OtaSmokePlan:
|
|
|
1979
2008
|
peers=peers,
|
|
1980
2009
|
install_mode=_ota_validate_install_mode(str(raw["install_mode"])),
|
|
1981
2010
|
install_pin=str(install_pin) if install_pin else None,
|
|
2011
|
+
instances_rel=str(raw.get("instances_rel") or "session-instances"),
|
|
1982
2012
|
)
|
|
1983
2013
|
|
|
1984
2014
|
|
|
@@ -2404,12 +2434,26 @@ def _ota_stop_parts(
|
|
|
2404
2434
|
return parts
|
|
2405
2435
|
|
|
2406
2436
|
|
|
2437
|
+
#: How a benchmark's load maps onto `publish-test-topics` flags. The keys are
|
|
2438
|
+
#: `_sized_publisher_param_args`'s own, so a load dict travels from the
|
|
2439
|
+
#: benchmark to the peer's publisher without being rewritten on the way.
|
|
2440
|
+
_OTA_LOAD_FLAGS: tuple[tuple[str, str], ...] = (
|
|
2441
|
+
("size", "--load-size"),
|
|
2442
|
+
("pattern", "--load-size-pattern"),
|
|
2443
|
+
("rate", "--load-rate-hz"),
|
|
2444
|
+
("streams", "--load-streams"),
|
|
2445
|
+
("interval_jitter_ms", "--load-interval-jitter-ms"),
|
|
2446
|
+
("interval_jitter_seed", "--load-interval-jitter-seed"),
|
|
2447
|
+
)
|
|
2448
|
+
|
|
2449
|
+
|
|
2407
2450
|
def _ota_publish_parts(
|
|
2408
2451
|
target: InteractiveSmokeTarget,
|
|
2409
2452
|
identity: str,
|
|
2410
2453
|
peer_args: list[str],
|
|
2411
2454
|
*,
|
|
2412
2455
|
stop: bool = False,
|
|
2456
|
+
load: Mapping[str, Any] | None = None,
|
|
2413
2457
|
) -> list[str]:
|
|
2414
2458
|
parts = [
|
|
2415
2459
|
"publish-test-topics",
|
|
@@ -2421,6 +2465,13 @@ def _ota_publish_parts(
|
|
|
2421
2465
|
]
|
|
2422
2466
|
if stop:
|
|
2423
2467
|
parts.append("--stop")
|
|
2468
|
+
else:
|
|
2469
|
+
merged = dict(load or {})
|
|
2470
|
+
if "size" not in merged and merged.get("size_a") is not None:
|
|
2471
|
+
merged["size"] = merged["size_a"]
|
|
2472
|
+
for key, flag in _OTA_LOAD_FLAGS:
|
|
2473
|
+
if merged.get(key) is not None:
|
|
2474
|
+
parts.extend([flag, str(merged[key])])
|
|
2424
2475
|
for override in peer_args:
|
|
2425
2476
|
parts.extend(["--peer-address", override])
|
|
2426
2477
|
return parts
|
|
@@ -2769,6 +2820,7 @@ def _resolve_ota_smoke_context(
|
|
|
2769
2820
|
project=project,
|
|
2770
2821
|
exec_commands=exec_commands,
|
|
2771
2822
|
cpusets=_parse_peer_cpuset_overrides(getattr(args, "peer_cpuset", None)),
|
|
2823
|
+
instances_rel=_ota_instances_rel(runtime),
|
|
2772
2824
|
)
|
|
2773
2825
|
plan_peers = set(plan.peers)
|
|
2774
2826
|
target_peers = set(_peer_keys_from_cfg(target.cfg))
|
|
@@ -3732,14 +3784,41 @@ def _resolve_ota_profile(
|
|
|
3732
3784
|
return name, profile
|
|
3733
3785
|
|
|
3734
3786
|
|
|
3735
|
-
def
|
|
3787
|
+
def _loaded_peer(cfg: dict[str, Any]) -> str | None:
|
|
3788
|
+
"""Which peer's egress carries this session's dominant direction.
|
|
3789
|
+
|
|
3790
|
+
A profile's ``uplink`` leg is the impaired one in almost every profile this
|
|
3791
|
+
project ships, so which peer it lands on decides what the run measures. The
|
|
3792
|
+
session already says: `topics.a_to_b` and `topics.b_to_a` are its two
|
|
3793
|
+
directions, and the one with more topics is the one the load runs over.
|
|
3794
|
+
Reading it here is what keeps a one-host and a two-host run of the *same*
|
|
3795
|
+
session under the *same* profile from shaping opposite directions -- which
|
|
3796
|
+
they did, silently, until 2026-08-31.
|
|
3797
|
+
"""
|
|
3798
|
+
topics = cfg.get("topics")
|
|
3799
|
+
if not isinstance(topics, dict):
|
|
3800
|
+
return None
|
|
3801
|
+
a_to_b = len(topics.get("a_to_b") or ())
|
|
3802
|
+
b_to_a = len(topics.get("b_to_a") or ())
|
|
3803
|
+
if a_to_b == b_to_a:
|
|
3804
|
+
return None
|
|
3805
|
+
return "a" if a_to_b > b_to_a else "b"
|
|
3806
|
+
|
|
3807
|
+
|
|
3808
|
+
def _profile_directions_for(peers: list[str], cfg: dict[str, Any]) -> dict[str, str]:
|
|
3736
3809
|
"""Map each peer to the profile direction its egress carries (RFC 0004).
|
|
3737
3810
|
|
|
3738
|
-
|
|
3739
|
-
``downlink
|
|
3740
|
-
|
|
3741
|
-
|
|
3742
|
-
|
|
3811
|
+
The sender of the session's dominant direction shapes ``uplink``; the other
|
|
3812
|
+
peer shapes ``downlink``. Where the two directions carry the same number of
|
|
3813
|
+
topics the session does not say, and the a/b convention decides: the first
|
|
3814
|
+
peer is the centre and receives, the second is the vehicle and sends.
|
|
3815
|
+
``shared.profile_directions: { a: …, b: … }`` overrides either.
|
|
3816
|
+
"""
|
|
3817
|
+
directions: dict[str, str] = {}
|
|
3818
|
+
if len(peers) == 2:
|
|
3819
|
+
sender = _loaded_peer(cfg) or peers[1]
|
|
3820
|
+
other = next(name for name in peers if name != sender)
|
|
3821
|
+
directions = {sender: "uplink", other: "downlink"}
|
|
3743
3822
|
shared = cfg.get("shared")
|
|
3744
3823
|
override = shared.get("profile_directions") if isinstance(shared, dict) else None
|
|
3745
3824
|
if isinstance(override, dict):
|
|
@@ -3751,6 +3830,11 @@ def _profile_directions(plan: OtaSmokePlan, cfg: dict[str, Any]) -> dict[str, st
|
|
|
3751
3830
|
return directions
|
|
3752
3831
|
|
|
3753
3832
|
|
|
3833
|
+
def _profile_directions(plan: OtaSmokePlan, cfg: dict[str, Any]) -> dict[str, str]:
|
|
3834
|
+
"""`_profile_directions_for` against a plan's peers."""
|
|
3835
|
+
return _profile_directions_for(sorted(plan.peers), cfg)
|
|
3836
|
+
|
|
3837
|
+
|
|
3754
3838
|
def _ota_resolve_interfaces(peer: OtaSmokePeer, peer_addr: str, *, dry_run: bool) -> tuple[str, str | None]:
|
|
3755
3839
|
"""Discover ``(OTA egress, control)`` interfaces on ``peer`` from the kernel, not
|
|
3756
3840
|
guesses: the OTA interface is the route to the other peer's data address; the
|
|
@@ -3935,6 +4019,7 @@ def _ota_start_session_publishers(
|
|
|
3935
4019
|
plan: OtaSmokePlan,
|
|
3936
4020
|
*,
|
|
3937
4021
|
dry_run: bool,
|
|
4022
|
+
load: Mapping[str, Any] | None = None,
|
|
3938
4023
|
) -> None:
|
|
3939
4024
|
if target.target_type != "session":
|
|
3940
4025
|
print("OTA smoke: target is a scenario; using its application publishers.")
|
|
@@ -3942,7 +4027,7 @@ def _ota_start_session_publishers(
|
|
|
3942
4027
|
peer_args = _ota_peer_address_args(plan)
|
|
3943
4028
|
for peer_name in sorted(plan.peers):
|
|
3944
4029
|
peer = plan.peers[peer_name]
|
|
3945
|
-
command = _ota_rosotacom_command(plan, _ota_publish_parts(target, peer_name, peer_args), peer)
|
|
4030
|
+
command = _ota_rosotacom_command(plan, _ota_publish_parts(target, peer_name, peer_args, load=load), peer)
|
|
3946
4031
|
result = _ota_run(peer, command, label=f"{peer_name}: start synthetic publishers", dry_run=dry_run, check=False)
|
|
3947
4032
|
_print_completed_output(result)
|
|
3948
4033
|
if result.returncode != 0:
|
|
@@ -4068,21 +4153,44 @@ def _ota_collect_logs(
|
|
|
4068
4153
|
dry_run: bool,
|
|
4069
4154
|
) -> None:
|
|
4070
4155
|
project = shlex.quote(plan.project)
|
|
4156
|
+
instances_rel = shlex.quote(plan.instances_rel)
|
|
4071
4157
|
instance_suffix = shlex.quote(f"*_{instance.instance_id}")
|
|
4158
|
+
collected = 0
|
|
4072
4159
|
for peer in plan.peers.values():
|
|
4073
4160
|
script = (
|
|
4074
4161
|
f"cd {shlex.quote(_ota_peer_workdir(plan, peer))} && "
|
|
4075
4162
|
f"project_dir=$(dirname {project}) && "
|
|
4076
|
-
f'
|
|
4163
|
+
f'instances_root=$(cd "$project_dir" && cd "$(dirname {instances_rel})" 2>/dev/null '
|
|
4164
|
+
f'&& printf %s "$PWD/$(basename {instances_rel})") && '
|
|
4165
|
+
f'instance_dir=$(find "$instances_root" -mindepth 2 -maxdepth 2 '
|
|
4077
4166
|
f"-type d -name {instance_suffix} -print -quit 2>/dev/null) && "
|
|
4078
4167
|
'if [ -n "$instance_dir" ]; then '
|
|
4079
|
-
'
|
|
4080
|
-
'
|
|
4168
|
+
'root=$(dirname "$(dirname "$instance_dir")"); '
|
|
4169
|
+
'relative=${instance_dir#"$root"/}; '
|
|
4170
|
+
'tar cz -C "$root" "$relative" 2>/dev/null | base64; fi'
|
|
4081
4171
|
)
|
|
4082
4172
|
result = _ota_run(peer, script, label=f"{peer.name}: collect session-instances", dry_run=dry_run, check=False)
|
|
4083
|
-
if dry_run
|
|
4173
|
+
if dry_run:
|
|
4174
|
+
continue
|
|
4175
|
+
if not result.stdout.strip():
|
|
4176
|
+
# Silence here used to end as "no status/events.jsonl files found"
|
|
4177
|
+
# after the run was already over, which describes the symptom and
|
|
4178
|
+
# not the cause. Say which peer, and where it was looked for.
|
|
4179
|
+
print(
|
|
4180
|
+
f"OTA smoke: peer {peer.name} returned no session instance matching "
|
|
4181
|
+
f"*_{instance.instance_id} under its {plan.instances_rel!r} "
|
|
4182
|
+
f"(relative to {plan.project!r}).",
|
|
4183
|
+
file=sys.stderr,
|
|
4184
|
+
)
|
|
4084
4185
|
continue
|
|
4085
4186
|
_ota_extract_peer_artifacts(instance, peer, result.stdout)
|
|
4187
|
+
collected += 1
|
|
4188
|
+
if not dry_run and not collected:
|
|
4189
|
+
print(
|
|
4190
|
+
"OTA smoke: nothing was collected from any peer -- the run produced no local records. "
|
|
4191
|
+
"Check that the project's session_instances_dir is the one the peers write to.",
|
|
4192
|
+
file=sys.stderr,
|
|
4193
|
+
)
|
|
4086
4194
|
|
|
4087
4195
|
|
|
4088
4196
|
def _ota_extract_peer_artifacts(instance: SessionInstance, peer: OtaSmokePeer, encoded: str) -> None:
|
|
@@ -7372,9 +7480,30 @@ def _smoke_topic_pub_qos_args(qos: dict[str, Any] | None) -> str:
|
|
|
7372
7480
|
return " ".join(shlex.quote(arg) for arg in args) + (" " if args else "")
|
|
7373
7481
|
|
|
7374
7482
|
|
|
7375
|
-
def _smoke_publisher_command(
|
|
7483
|
+
def _smoke_publisher_command(
|
|
7484
|
+
spec: SmokeTopicSpec,
|
|
7485
|
+
ros_setup: str,
|
|
7486
|
+
duration: float,
|
|
7487
|
+
load: Mapping[str, Any] | None = None,
|
|
7488
|
+
) -> str:
|
|
7489
|
+
"""The publisher command for one crossed topic.
|
|
7490
|
+
|
|
7491
|
+
`load` overrides what the session's own `expect` says, and only for a
|
|
7492
|
+
`SizedPayload` stream: a benchmark chooses its load, and a session that also
|
|
7493
|
+
declares one is describing what it expects to see rather than what a
|
|
7494
|
+
measurement should offer. Without this the benchmark's `--size` and
|
|
7495
|
+
`--rate-hz` reached the local runner and stopped there, so a two-host run
|
|
7496
|
+
measured the session's defaults while reporting the load that was asked for.
|
|
7497
|
+
"""
|
|
7376
7498
|
assert spec.publish_topic is not None and spec.publish_type is not None
|
|
7377
7499
|
if spec.publish_type == "com_msgs/msg/SizedPayload":
|
|
7500
|
+
from .cli_benchmark import _sized_publisher_param_args
|
|
7501
|
+
|
|
7502
|
+
if load:
|
|
7503
|
+
args = " ".join(
|
|
7504
|
+
shlex.quote(str(part)) for part in _sized_publisher_param_args(spec.publish_topic, dict(load))
|
|
7505
|
+
)
|
|
7506
|
+
return f"{ros_setup} && timeout {duration} ros2 run com_py sized_publisher --ros-args {args}"
|
|
7378
7507
|
size = spec.expected_size or SMOKE_SIZED_PAYLOAD_BYTES
|
|
7379
7508
|
return (
|
|
7380
7509
|
f"{ros_setup} && timeout {duration} ros2 run com_py sized_publisher --ros-args "
|
|
@@ -7427,16 +7556,23 @@ def _start_smoke_topic_publishers(
|
|
|
7427
7556
|
log_line: Callable[[str], None] = print,
|
|
7428
7557
|
duration: float = 180.0,
|
|
7429
7558
|
source_peer_key: str | None = None,
|
|
7559
|
+
load: Mapping[str, Any] | None = None,
|
|
7430
7560
|
) -> list[SmokeTopicSpec]:
|
|
7431
7561
|
started: list[SmokeTopicSpec] = []
|
|
7432
7562
|
for spec in _smoke_publish_specs(cfg, source_peer_key=source_peer_key):
|
|
7433
7563
|
assert spec.publish_topic is not None and spec.publish_type is not None
|
|
7434
7564
|
container = containers[spec.source_peer_key]
|
|
7435
7565
|
ros_setup = ros_setups[spec.source_peer_key]
|
|
7436
|
-
cmd = _smoke_publisher_command(spec, ros_setup, duration)
|
|
7566
|
+
cmd = _smoke_publisher_command(spec, ros_setup, duration, load)
|
|
7567
|
+
# The rate the publisher was actually given, not the one the session
|
|
7568
|
+
# expects: they differ exactly when a benchmark chose the load, and a
|
|
7569
|
+
# log that reports the session's number there is how a run that measured
|
|
7570
|
+
# the wrong load reads as one that measured the right one.
|
|
7571
|
+
rate = (load or {}).get("rate", spec.publish_rate)
|
|
7572
|
+
offered = f" at {rate:g} Hz" + (" (benchmark load)" if load else "")
|
|
7437
7573
|
log_line(
|
|
7438
7574
|
f"Starting smoke publisher {spec.source_peer_key}->{spec.receiver_peer_key} "
|
|
7439
|
-
f"{spec.publish_topic} ({spec.publish_type}) in {container}"
|
|
7575
|
+
f"{spec.publish_topic} ({spec.publish_type}) in {container}{offered}"
|
|
7440
7576
|
)
|
|
7441
7577
|
subprocess.run(
|
|
7442
7578
|
["docker", "exec", "-d", container, "bash", "-c", cmd],
|
|
@@ -7449,7 +7585,7 @@ def _start_smoke_topic_publishers(
|
|
|
7449
7585
|
log_line(
|
|
7450
7586
|
f"OK: smoke publisher {spec.source_peer_key}->{spec.receiver_peer_key} "
|
|
7451
7587
|
f"{spec.publish_topic} ({spec.publish_type}) is advertising in {container} "
|
|
7452
|
-
f"at {
|
|
7588
|
+
f"at {rate:g} Hz"
|
|
7453
7589
|
)
|
|
7454
7590
|
started.append(spec)
|
|
7455
7591
|
break
|
|
@@ -7801,6 +7937,30 @@ def probe_content_command(args: argparse.Namespace) -> int:
|
|
|
7801
7937
|
return 0 if ok else 1
|
|
7802
7938
|
|
|
7803
7939
|
|
|
7940
|
+
def _publish_load_override(args: argparse.Namespace) -> dict[str, Any] | None:
|
|
7941
|
+
"""The benchmark's load as `_sized_publisher_param_args` wants it, or None.
|
|
7942
|
+
|
|
7943
|
+
None means "use what the session expects", which is what an ordinary smoke
|
|
7944
|
+
run wants. A benchmark always passes something, because choosing the load is
|
|
7945
|
+
the whole point of it.
|
|
7946
|
+
"""
|
|
7947
|
+
load: dict[str, Any] = {}
|
|
7948
|
+
if getattr(args, "load_size", None) is not None:
|
|
7949
|
+
load["size"] = int(args.load_size)
|
|
7950
|
+
load["size_a"] = int(args.load_size)
|
|
7951
|
+
if getattr(args, "load_size_pattern", None):
|
|
7952
|
+
load["pattern"] = args.load_size_pattern
|
|
7953
|
+
if getattr(args, "load_rate_hz", None) is not None:
|
|
7954
|
+
load["rate"] = float(args.load_rate_hz)
|
|
7955
|
+
if getattr(args, "load_streams", None) is not None:
|
|
7956
|
+
load["streams"] = int(args.load_streams)
|
|
7957
|
+
if getattr(args, "load_interval_jitter_ms", None) is not None:
|
|
7958
|
+
load["interval_jitter_ms"] = float(args.load_interval_jitter_ms)
|
|
7959
|
+
if getattr(args, "load_interval_jitter_seed", None) is not None:
|
|
7960
|
+
load["interval_jitter_seed"] = int(args.load_interval_jitter_seed)
|
|
7961
|
+
return load or None
|
|
7962
|
+
|
|
7963
|
+
|
|
7804
7964
|
def publish_test_topics_command(args: argparse.Namespace) -> int:
|
|
7805
7965
|
"""Start or stop synthetic local app publishers for the peer's crossed topics.
|
|
7806
7966
|
|
|
@@ -7826,6 +7986,7 @@ def publish_test_topics_command(args: argparse.Namespace) -> int:
|
|
|
7826
7986
|
cfg,
|
|
7827
7987
|
duration=args.duration,
|
|
7828
7988
|
source_peer_key=args.identity,
|
|
7989
|
+
load=_publish_load_override(args),
|
|
7829
7990
|
)
|
|
7830
7991
|
except RuntimeError as exc:
|
|
7831
7992
|
print(f"ERROR: {exc}", file=sys.stderr)
|
|
@@ -10357,6 +10518,16 @@ def main(argv: list[str] | None = None) -> int:
|
|
|
10357
10518
|
publish_test_topics_parser.add_argument(
|
|
10358
10519
|
"--stop", action="store_true", help="Stop running synthetic test topic publishers."
|
|
10359
10520
|
)
|
|
10521
|
+
# The benchmark's load, for the peer that publishes it. Without these a
|
|
10522
|
+
# two-host benchmark offered the session's own expected load and reported
|
|
10523
|
+
# the one that was asked for -- a run that reads as a success and measures
|
|
10524
|
+
# something else.
|
|
10525
|
+
publish_test_topics_parser.add_argument("--load-size", type=int, help=argparse.SUPPRESS)
|
|
10526
|
+
publish_test_topics_parser.add_argument("--load-size-pattern", help=argparse.SUPPRESS)
|
|
10527
|
+
publish_test_topics_parser.add_argument("--load-rate-hz", type=float, help=argparse.SUPPRESS)
|
|
10528
|
+
publish_test_topics_parser.add_argument("--load-streams", type=int, help=argparse.SUPPRESS)
|
|
10529
|
+
publish_test_topics_parser.add_argument("--load-interval-jitter-ms", type=float, help=argparse.SUPPRESS)
|
|
10530
|
+
publish_test_topics_parser.add_argument("--load-interval-jitter-seed", type=int, help=argparse.SUPPRESS)
|
|
10360
10531
|
publish_test_topics_parser.set_defaults(func=publish_test_topics_command)
|
|
10361
10532
|
|
|
10362
10533
|
list_parser = subparsers.add_parser("list-sessions", help="List configured sessions.")
|
|
@@ -5163,6 +5163,7 @@ def _make_live_run_point(args: argparse.Namespace, session_name: str) -> RunPoin
|
|
|
5163
5163
|
_peer_command_runner,
|
|
5164
5164
|
_peer_watchdog_launcher,
|
|
5165
5165
|
_profile_directions,
|
|
5166
|
+
_profile_directions_for,
|
|
5166
5167
|
_remove_smoke_network,
|
|
5167
5168
|
_resolve_ota_profile,
|
|
5168
5169
|
_resolve_ota_smoke_context,
|
|
@@ -5327,7 +5328,10 @@ def _make_live_run_point(args: argparse.Namespace, session_name: str) -> RunPoin
|
|
|
5327
5328
|
_ota_start_peers(target, plan, instance.instance_id, dry_run=dry_run)
|
|
5328
5329
|
if not dry_run:
|
|
5329
5330
|
time.sleep(12)
|
|
5330
|
-
|
|
5331
|
+
# The load is the benchmark's, not the session's expectation:
|
|
5332
|
+
# without this the peer published what its own `expect` declares
|
|
5333
|
+
# and the run reported the load that was asked for.
|
|
5334
|
+
_ota_start_session_publishers(target, plan, dry_run=dry_run, load=load)
|
|
5331
5335
|
|
|
5332
5336
|
if not dry_run:
|
|
5333
5337
|
if profile_obj is not None and profile_obj.is_timeline:
|
|
@@ -5651,34 +5655,36 @@ def _make_live_run_point(args: argparse.Namespace, session_name: str) -> RunPoin
|
|
|
5651
5655
|
print(
|
|
5652
5656
|
f" netem distribution {table_name!r} installed in {dist_container}: {dist_target}"
|
|
5653
5657
|
)
|
|
5658
|
+
# Which peer's egress carries `uplink` is the session's
|
|
5659
|
+
# answer, not the runner's: the same session under the same
|
|
5660
|
+
# profile must be shaped identically here and across two
|
|
5661
|
+
# machines, and hard-coding a=uplink here while the OTA path
|
|
5662
|
+
# hard-coded b=uplink meant it was not.
|
|
5663
|
+
lab_directions = _profile_directions_for(["a", "b"], cfg)
|
|
5664
|
+
lab_containers = {"a": a_container, "b": b_container}
|
|
5654
5665
|
if profile_obj.is_timeline:
|
|
5655
|
-
|
|
5656
|
-
|
|
5657
|
-
|
|
5658
|
-
|
|
5659
|
-
|
|
5660
|
-
|
|
5661
|
-
# Peer B shapes downlink (egress to A)
|
|
5662
|
-
shaper_b = ProfileShaper("eth0", make_container_runner(b_container))
|
|
5663
|
-
lab_shapers.append(shaper_b)
|
|
5664
|
-
steps_b = expand_timeline(profile_obj, "eth0", direction="downlink")
|
|
5665
|
-
lab_peer_steps["b"] = (shaper_b, steps_b)
|
|
5666
|
+
for peer_name in ("a", "b"):
|
|
5667
|
+
shaper = ProfileShaper("eth0", make_container_runner(lab_containers[peer_name]))
|
|
5668
|
+
lab_shapers.append(shaper)
|
|
5669
|
+
steps = expand_timeline(profile_obj, "eth0", direction=lab_directions[peer_name])
|
|
5670
|
+
lab_peer_steps[peer_name] = (shaper, steps)
|
|
5666
5671
|
|
|
5667
5672
|
for shaper in lab_shapers:
|
|
5668
5673
|
shaper.arm([])
|
|
5669
5674
|
else:
|
|
5670
|
-
|
|
5671
|
-
|
|
5672
|
-
|
|
5673
|
-
|
|
5674
|
-
|
|
5675
|
-
|
|
5676
|
-
|
|
5677
|
-
shaper_b.arm(shaping_commands("eth0", profile_obj.downlink))
|
|
5675
|
+
for peer_name in ("a", "b"):
|
|
5676
|
+
leg = profile_obj.uplink if lab_directions[peer_name] == "uplink" else profile_obj.downlink
|
|
5677
|
+
if leg is None or leg.is_empty:
|
|
5678
|
+
continue
|
|
5679
|
+
shaper = ProfileShaper("eth0", make_container_runner(lab_containers[peer_name]))
|
|
5680
|
+
lab_shapers.append(shaper)
|
|
5681
|
+
shaper.arm(shaping_commands("eth0", leg))
|
|
5678
5682
|
|
|
5679
5683
|
# 4. Verify shaping was applied (diagnostic)
|
|
5680
5684
|
if profile_obj is not None and not getattr(args, "dry_run", False):
|
|
5681
|
-
for
|
|
5685
|
+
for peer_name in ("a", "b"):
|
|
5686
|
+
label = f"{peer_name.upper()} ({lab_directions[peer_name]})"
|
|
5687
|
+
container = lab_containers[peer_name]
|
|
5682
5688
|
tc_binary = container_tc_overrides.get(container, "tc")
|
|
5683
5689
|
res = subprocess.run(
|
|
5684
5690
|
["docker", "exec", "-u", "root", container, tc_binary, "qdisc", "show", "dev", "eth0"],
|
|
@@ -373,6 +373,7 @@ tests/unit/test_netem_dist.py
|
|
|
373
373
|
tests/unit/test_network_preflight.py
|
|
374
374
|
tests/unit/test_network_profiles.py
|
|
375
375
|
tests/unit/test_network_shaper.py
|
|
376
|
+
tests/unit/test_ota_benchmark_peer_exec.py
|
|
376
377
|
tests/unit/test_ota_link_configs.py
|
|
377
378
|
tests/unit/test_ota_pcap.py
|
|
378
379
|
tests/unit/test_ota_unwrapper.py
|
{rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/src/rosotacom_dev.egg-info/scm_file_list.json
RENAMED
|
@@ -368,6 +368,7 @@
|
|
|
368
368
|
"tests/unit/test_network_preflight.py",
|
|
369
369
|
"tests/unit/test_network_profiles.py",
|
|
370
370
|
"tests/unit/test_network_shaper.py",
|
|
371
|
+
"tests/unit/test_ota_benchmark_peer_exec.py",
|
|
371
372
|
"tests/unit/test_ota_link_configs.py",
|
|
372
373
|
"tests/unit/test_ota_pcap.py",
|
|
373
374
|
"tests/unit/test_ota_unwrapper.py",
|
|
@@ -2309,7 +2309,15 @@ def test_live_lab_run_point_uses_instance_scoped_smoke_network(
|
|
|
2309
2309
|
monkeypatch.setattr(cli, "_load_runtime_config", lambda args: runtime)
|
|
2310
2310
|
monkeypatch.setattr(cli, "_resolve_session", lambda session_name, runtime: session)
|
|
2311
2311
|
monkeypatch.setattr(cli, "_resolve_session_instance", lambda runtime, session, instance_id=None: instance)
|
|
2312
|
-
|
|
2312
|
+
# One a->b topic, as every benchmark session has: which container meets the
|
|
2313
|
+
# profile's `uplink` leg follows the session's own loaded direction, so a
|
|
2314
|
+
# fixture with no topics would be asserting an arbitrary default rather than
|
|
2315
|
+
# the rule.
|
|
2316
|
+
monkeypatch.setattr(
|
|
2317
|
+
cli,
|
|
2318
|
+
"_effective_session_config",
|
|
2319
|
+
lambda *args, **kwargs: {"topics": {"a_to_b": [{"topic": "/bench_capacity"}], "b_to_a": []}},
|
|
2320
|
+
)
|
|
2313
2321
|
monkeypatch.setattr(cli, "_list_docker_containers", lambda all_states=False: [])
|
|
2314
2322
|
monkeypatch.setattr(
|
|
2315
2323
|
cli, "_ensure_smoke_network", lambda name, subnet, labels=None: networks_created.append((name, subnet))
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
"""What a two-host benchmark must carry to its peers, and where it looks after.
|
|
2
|
+
|
|
3
|
+
Three defects this pins, all found by running one: the same session under the
|
|
4
|
+
same profile was shaped in opposite directions on one host and on two; the
|
|
5
|
+
benchmark's load never left the orchestrator; and the collection looked for the
|
|
6
|
+
peer's artifacts in a directory the project does not use, then reported the
|
|
7
|
+
symptom rather than the cause.
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
from __future__ import annotations
|
|
11
|
+
|
|
12
|
+
import argparse
|
|
13
|
+
|
|
14
|
+
from rosotacom.cli import (
|
|
15
|
+
_ota_instances_rel,
|
|
16
|
+
_ota_publish_parts,
|
|
17
|
+
_profile_directions_for,
|
|
18
|
+
_publish_load_override,
|
|
19
|
+
)
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class _Target:
|
|
23
|
+
target_type = "session"
|
|
24
|
+
name = "bench_1_1_capacity"
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def _cfg(a_to_b: int, b_to_a: int, **shared) -> dict:
|
|
28
|
+
return {
|
|
29
|
+
"topics": {
|
|
30
|
+
"a_to_b": [{"topic": f"/a{i}"} for i in range(a_to_b)],
|
|
31
|
+
"b_to_a": [{"topic": f"/b{i}"} for i in range(b_to_a)],
|
|
32
|
+
},
|
|
33
|
+
"shared": shared,
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
# ------------------------------------------------- which peer meets `uplink`
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
def test_the_sender_of_the_loaded_direction_shapes_uplink():
|
|
41
|
+
"""A profile's impaired leg must land on the egress that carries the load.
|
|
42
|
+
|
|
43
|
+
`bench_1_1_capacity` sends a->b. The OTA runner used to hand `uplink` to b
|
|
44
|
+
on the a=centre/b=vehicle convention, so a run under a loss profile shaped
|
|
45
|
+
the idle direction and delivered every message -- a green run measuring
|
|
46
|
+
nothing.
|
|
47
|
+
"""
|
|
48
|
+
assert _profile_directions_for(["a", "b"], _cfg(1, 0)) == {"a": "uplink", "b": "downlink"}
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
def test_a_vehicle_to_centre_session_still_shapes_the_vehicle():
|
|
52
|
+
assert _profile_directions_for(["a", "b"], _cfg(0, 1)) == {"b": "uplink", "a": "downlink"}
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
def test_a_symmetric_session_falls_back_to_the_a_b_convention():
|
|
56
|
+
"""Neither direction dominates, so the session does not say; b sends."""
|
|
57
|
+
assert _profile_directions_for(["a", "b"], _cfg(2, 2)) == {"b": "uplink", "a": "downlink"}
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
def test_an_explicit_declaration_wins_over_both():
|
|
61
|
+
cfg = _cfg(1, 0, profile_directions={"a": "downlink", "b": "uplink"})
|
|
62
|
+
assert _profile_directions_for(["a", "b"], cfg) == {"a": "downlink", "b": "uplink"}
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
# ------------------------------------------------------- the load must travel
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
def test_the_benchmark_load_reaches_the_peer_command():
|
|
69
|
+
parts = _ota_publish_parts(_Target(), "a", [], load={"size": 12000, "rate": 10.0, "streams": 2})
|
|
70
|
+
assert "--load-size" in parts and parts[parts.index("--load-size") + 1] == "12000"
|
|
71
|
+
assert "--load-rate-hz" in parts and parts[parts.index("--load-rate-hz") + 1] == "10.0"
|
|
72
|
+
assert "--load-streams" in parts and parts[parts.index("--load-streams") + 1] == "2"
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
def test_a_size_pattern_travels_as_itself():
|
|
76
|
+
parts = _ota_publish_parts(_Target(), "a", [], load={"pattern": "a*4,b*1", "size_a": 5000})
|
|
77
|
+
assert parts[parts.index("--load-size-pattern") + 1] == "a*4,b*1"
|
|
78
|
+
# `size_a` is the pattern's own base size and must reach the peer as --load-size.
|
|
79
|
+
assert parts[parts.index("--load-size") + 1] == "5000"
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
def test_no_load_leaves_the_session_to_say_what_it_expects():
|
|
83
|
+
parts = _ota_publish_parts(_Target(), "a", [])
|
|
84
|
+
assert not [p for p in parts if p.startswith("--load-")]
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
def test_stopping_carries_no_load():
|
|
88
|
+
parts = _ota_publish_parts(_Target(), "a", [], stop=True, load={"size": 1})
|
|
89
|
+
assert "--stop" in parts
|
|
90
|
+
assert not [p for p in parts if p.startswith("--load-")]
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
def test_the_peer_turns_the_flags_back_into_a_load():
|
|
94
|
+
args = argparse.Namespace(
|
|
95
|
+
load_size=12000,
|
|
96
|
+
load_size_pattern=None,
|
|
97
|
+
load_rate_hz=10.0,
|
|
98
|
+
load_streams=None,
|
|
99
|
+
load_interval_jitter_ms=None,
|
|
100
|
+
load_interval_jitter_seed=None,
|
|
101
|
+
)
|
|
102
|
+
assert _publish_load_override(args) == {"size": 12000, "size_a": 12000, "rate": 10.0}
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
def test_an_empty_namespace_means_use_the_session():
|
|
106
|
+
args = argparse.Namespace(
|
|
107
|
+
load_size=None,
|
|
108
|
+
load_size_pattern=None,
|
|
109
|
+
load_rate_hz=None,
|
|
110
|
+
load_streams=None,
|
|
111
|
+
load_interval_jitter_ms=None,
|
|
112
|
+
load_interval_jitter_seed=None,
|
|
113
|
+
)
|
|
114
|
+
assert _publish_load_override(args) is None
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
# --------------------------------------------- where the artifacts are looked for
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
class _Runtime:
|
|
121
|
+
def __init__(self, path):
|
|
122
|
+
self.rosotacom_config = path
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
def test_the_collection_follows_the_project_not_a_convention(tmp_path):
|
|
126
|
+
project = tmp_path / "rosotacom.yaml"
|
|
127
|
+
project.write_text("session_instances_dir: ../instances\n", encoding="utf-8")
|
|
128
|
+
assert _ota_instances_rel(_Runtime(project)) == "../instances"
|
|
129
|
+
|
|
130
|
+
|
|
131
|
+
def test_a_project_that_says_nothing_gets_the_default(tmp_path):
|
|
132
|
+
project = tmp_path / "rosotacom.yaml"
|
|
133
|
+
project.write_text("session_configs_dir:\n - sessions\n", encoding="utf-8")
|
|
134
|
+
assert _ota_instances_rel(_Runtime(project)) == "session-instances"
|
{rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/.devcontainer/devcontainer.json.template
RENAMED
|
File without changes
|
{rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/.devcontainer/re_generate_devcontainer_json.py
RENAMED
|
File without changes
|
|
File without changes
|
{rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/.github/ISSUE_TEMPLATE/documentation-audit.md
RENAMED
|
File without changes
|
{rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/.github/ISSUE_TEMPLATE/implementation-cleanup.md
RENAMED
|
File without changes
|
{rosotacom_dev-2.5.dev77 → rosotacom_dev-2.5.dev79}/.github/ISSUE_TEMPLATE/quality-workflow.md
RENAMED
|
File without changes
|
|
File without changes
|