rosotacom-dev 2.5.dev10__tar.gz → 2.5.dev13__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.dev10 → rosotacom_dev-2.5.dev13}/PKG-INFO +6 -2
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/README.md +5 -1
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/src/rosotacom/cli.py +133 -14
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/src/rosotacom_dev.egg-info/PKG-INFO +6 -2
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/src/rosotacom_dev.egg-info/scm_version.json +2 -2
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/tests/unit/test_cli.py +199 -5
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/.devcontainer/devcontainer.json.template +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/.devcontainer/re_generate_devcontainer_json.py +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/.github/CODEOWNERS +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/.github/ISSUE_TEMPLATE/documentation-audit.md +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/.github/ISSUE_TEMPLATE/implementation-cleanup.md +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/.github/ISSUE_TEMPLATE/quality-workflow.md +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/.github/ISSUE_TEMPLATE/redesign.md +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/.github/ISSUE_TEMPLATE/release-process.md +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/.github/ISSUE_TEMPLATE/repository-diagnosis.md +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/.github/ISSUE_TEMPLATE/test-ci-audit.md +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/.github/ISSUE_TEMPLATE/work-item.md +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/.github/dependabot.yml +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/.github/workflows/benchmark-calibrate.yml +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/.github/workflows/benchmark-gate.yml +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/.github/workflows/dev-release.yml +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/.github/workflows/image-scan.yml +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/.github/workflows/nightly-e2e.yml +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/.github/workflows/pr-lightweight.yml +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/.github/workflows/pr-merge-gate.yml +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/.github/workflows/release.yml +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/.pre-commit-config.yaml +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/AGENTS.md +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/CONCURRENCY.md +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/CONTRIBUTING.md +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/DEVELOPMENT_PRINCIPLES.md +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/LICENSE.txt +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/MANIFEST.in +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/budgets.jsonl +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/calibration/README.md +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/calibration/capacity-size-tight-cyclone.json +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/calibration/probe-loss-gop-tight-cyclone.json +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/calibration/probe-loss-nominal-cyclone.json +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/calibration/probe-loss-tight-cyclone.json +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/calibration/probe-loss-tight-fastdds.json +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/calibration/probe-loss-tight-zenoh.json +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/codecov.yml +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/deployment-configuration.md +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/docs/benchmark-ab.md +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/docs/benchmark-bag-as-load.md +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/docs/ci.md +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/docs/ffmpeg-keyframes.md +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/docs/findings/README.md +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/docs/findings/cyclone-spdp-discovery-bursts.md +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/docs/findings/delay-alone-no-loss.md +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/docs/findings/head-of-line-irregularity.md +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/docs/findings/jitter-loss-bandwidth-latency.md +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/docs/findings/lighter-message-loss.md +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/docs/findings/zero-loss-boundaries-18kb-20hz.md +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/docs/forensics-report.md +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/docs/geo-link-map.md +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/docs/github-repository-settings.md +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/docs/link-trace.md +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/docs/owner-runbook.md +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/docs/performance-bands.md +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/docs/playbooks/README.md +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/docs/quality-model.md +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/docs/release-notes/TEMPLATE.md +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/docs/release-notes/v2.1.md +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/docs/release-notes/v2.2.md +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/docs/release-notes/v2.3.md +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/docs/release-notes/v2.4.md +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/docs/release.md +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/docs/rfcs/0001-expectation-driven-test-suite.md +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/docs/rfcs/0002-expectation-concepts.md +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/docs/rfcs/0003-metric-backbone.md +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/docs/rfcs/0004-network-profiles.md +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/docs/rfcs/0005-benchmark-genres-and-ci.md +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/docs/rfcs/0006-dynamic-qos.md +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/docs/rfcs/0007-regression-gate.md +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/docs/rfcs/README.md +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/docs/testing.md +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/docs/work-items.md +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/install.sh +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/justfile +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/media/control_center.png +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/media/echo_test.png +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/media/forensics-report-example.png +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/media/host.png +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/media/vehicle.png +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/pyproject.toml +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/requirements.txt +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/rosotacom.yaml +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/run_session_in_container.py +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/session-configuration.md +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/setup.cfg +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/src/rosotacom/__init__.py +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/src/rosotacom/__main__.py +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/src/rosotacom/anonymize.py +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/src/rosotacom/bag_ground_truth.py +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/src/rosotacom/benched_set.py +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/src/rosotacom/benchmark.py +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/src/rosotacom/bundle_check.py +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/src/rosotacom/cli_benchmark.py +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/src/rosotacom/deployment.py +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/src/rosotacom/ffmpeg_packet.py +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/src/rosotacom/forensics.py +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/src/rosotacom/geomap.py +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/src/rosotacom/network_profiles.py +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/src/rosotacom/network_shaper.py +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/src/rosotacom/plots.py +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/src/rosotacom/py.typed +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/src/rosotacom/resources/benched-set.yaml +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/src/rosotacom/resources/examples/.gitignore +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/src/rosotacom/resources/examples/README.md +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/src/rosotacom/resources/examples/__init__.py +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/src/rosotacom/resources/examples/bags/8_drop_reference/metadata.yaml +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/src/rosotacom/resources/examples/deployment.example.yaml +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/src/rosotacom/resources/examples/profiles.yaml +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/src/rosotacom/resources/examples/ros2docker.json +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/src/rosotacom/resources/examples/rosotacom.yaml +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/src/rosotacom/resources/examples/scenarios/2_native_chatter/scenario-definition.yaml +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/src/rosotacom/resources/examples/scripts/1_heartbeat/run_machine_a.sh +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/src/rosotacom/resources/examples/scripts/1_heartbeat/run_machine_b.sh +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/src/rosotacom/resources/examples/scripts/2_native_chatter/machine_a/external.ros2docker.json +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/src/rosotacom/resources/examples/scripts/2_native_chatter/machine_a/run_communication.sh +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/src/rosotacom/resources/examples/scripts/2_native_chatter/machine_a/run_external.py +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/src/rosotacom/resources/examples/scripts/2_native_chatter/machine_a/wait_for_echo_topic.sh +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/src/rosotacom/resources/examples/scripts/2_native_chatter/machine_b/external.ros2docker.json +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/src/rosotacom/resources/examples/scripts/2_native_chatter/machine_b/run_communication.sh +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/src/rosotacom/resources/examples/scripts/2_native_chatter/machine_b/run_external.py +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/src/rosotacom/resources/examples/scripts/3_comp_occ_grid/machine_a/external.ros2docker.json +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/src/rosotacom/resources/examples/scripts/3_comp_occ_grid/machine_a/external_session.yaml +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/src/rosotacom/resources/examples/scripts/3_comp_occ_grid/machine_a/foxglove.json +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/src/rosotacom/resources/examples/scripts/3_comp_occ_grid/machine_a/run_communication.sh +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/src/rosotacom/resources/examples/scripts/3_comp_occ_grid/machine_a/run_external.py +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/src/rosotacom/resources/examples/scripts/3_comp_occ_grid/machine_b/costmap_1second/costmap_1second_0.mcap +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/src/rosotacom/resources/examples/scripts/3_comp_occ_grid/machine_b/costmap_1second/metadata.yaml +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/src/rosotacom/resources/examples/scripts/3_comp_occ_grid/machine_b/external.ros2docker.json +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/src/rosotacom/resources/examples/scripts/3_comp_occ_grid/machine_b/run_communication.sh +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/src/rosotacom/resources/examples/scripts/3_comp_occ_grid/machine_b/run_external.py +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/src/rosotacom/resources/examples/scripts/4_comp_occ_grid_zen/machine_a/external.ros2docker.json +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/src/rosotacom/resources/examples/scripts/4_comp_occ_grid_zen/machine_a/external_session.yaml +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/src/rosotacom/resources/examples/scripts/4_comp_occ_grid_zen/machine_a/foxglove.json +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/src/rosotacom/resources/examples/scripts/4_comp_occ_grid_zen/machine_a/run_communication.sh +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/src/rosotacom/resources/examples/scripts/4_comp_occ_grid_zen/machine_a/run_external.py +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/src/rosotacom/resources/examples/scripts/4_comp_occ_grid_zen/machine_b/costmap_1second/costmap_1second_0.mcap +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/src/rosotacom/resources/examples/scripts/4_comp_occ_grid_zen/machine_b/costmap_1second/metadata.yaml +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/src/rosotacom/resources/examples/scripts/4_comp_occ_grid_zen/machine_b/external.ros2docker.json +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/src/rosotacom/resources/examples/scripts/4_comp_occ_grid_zen/machine_b/run_communication.sh +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/src/rosotacom/resources/examples/scripts/4_comp_occ_grid_zen/machine_b/run_external.py +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/src/rosotacom/resources/examples/scripts/5_sized_payload/machine_a/external.ros2docker.json +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/src/rosotacom/resources/examples/scripts/5_sized_payload/machine_a/external_session.yaml +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/src/rosotacom/resources/examples/scripts/5_sized_payload/machine_a/run_communication.sh +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/src/rosotacom/resources/examples/scripts/5_sized_payload/machine_a/run_external.py +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/src/rosotacom/resources/examples/scripts/5_sized_payload/machine_b/external.ros2docker.json +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/src/rosotacom/resources/examples/scripts/5_sized_payload/machine_b/external_session.yaml +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/src/rosotacom/resources/examples/scripts/5_sized_payload/machine_b/run_communication.sh +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/src/rosotacom/resources/examples/scripts/5_sized_payload/machine_b/run_external.py +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/src/rosotacom/resources/examples/scripts/6_sized_payload_zen/machine_a/external.ros2docker.json +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/src/rosotacom/resources/examples/scripts/6_sized_payload_zen/machine_a/external_session.yaml +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/src/rosotacom/resources/examples/scripts/6_sized_payload_zen/machine_a/run_communication.sh +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/src/rosotacom/resources/examples/scripts/6_sized_payload_zen/machine_a/run_external.py +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/src/rosotacom/resources/examples/scripts/6_sized_payload_zen/machine_b/external.ros2docker.json +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/src/rosotacom/resources/examples/scripts/6_sized_payload_zen/machine_b/external_session.yaml +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/src/rosotacom/resources/examples/scripts/6_sized_payload_zen/machine_b/run_communication.sh +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/src/rosotacom/resources/examples/scripts/6_sized_payload_zen/machine_b/run_external.py +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/src/rosotacom/resources/examples/sessions/10_restamp/session-definition.yaml +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/src/rosotacom/resources/examples/sessions/11_trickle/session-definition.yaml +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/src/rosotacom/resources/examples/sessions/12_content_integrity/session-definition.yaml +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/src/rosotacom/resources/examples/sessions/13_link_latency/session-definition.yaml +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/src/rosotacom/resources/examples/sessions/14_remote_assist_anonymized/session-definition.yaml +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/src/rosotacom/resources/examples/sessions/15_remote_assist_anonymized_costmap/session-definition.yaml +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/src/rosotacom/resources/examples/sessions/16_remote_assist_anonymized_camera/session-definition.yaml +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/src/rosotacom/resources/examples/sessions/17_synthetic_camera_quality/session-definition.yaml +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/src/rosotacom/resources/examples/sessions/1_heartbeat/session-definition.yaml +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/src/rosotacom/resources/examples/sessions/1_heartbeat_status/session-definition.yaml +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/src/rosotacom/resources/examples/sessions/2_native_chatter/session-definition.yaml +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/src/rosotacom/resources/examples/sessions/3_comp_occ_grid/session-definition.yaml +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/src/rosotacom/resources/examples/sessions/4_comp_occ_grid_zen/session-definition.yaml +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/src/rosotacom/resources/examples/sessions/5_sized_payload/session-definition.yaml +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/src/rosotacom/resources/examples/sessions/6_sized_payload_zen/session-definition.yaml +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/src/rosotacom/resources/examples/sessions/7_latched_static/session-definition.yaml +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/src/rosotacom/resources/examples/sessions/8_drop/session-definition.yaml +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/src/rosotacom/resources/examples/sessions/9_throttle/session-definition.yaml +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/src/rosotacom/resources/examples/sessions/bench_1_1_capacity/session-definition.yaml +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/src/rosotacom/resources/examples/sessions/bench_1_2_load_sweep/session-definition.yaml +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/src/rosotacom/resources/examples/sessions/bench_1_3_ramp/session-definition.yaml +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/src/rosotacom/resources/examples/sessions/bench_1_4_recovery/session-definition.yaml +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/src/rosotacom/resources/examples/sessions/bench_1_5_camera/session-definition.yaml +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/src/rosotacom/resources/ros2docker.json.example +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/src/rosotacom/resources/ws/.vscode/c_cpp_properties.json +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/src/rosotacom/resources/ws/.vscode/settings.json +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/src/rosotacom/resources/ws/ota_configs/archive/fastdds_easy_mode.xml.template +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/src/rosotacom/resources/ws/ota_configs/archive/fastdds_initial_peer_list.xml.template +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/src/rosotacom/resources/ws/ota_configs/archive/fastdds_v2.xml.template +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/src/rosotacom/resources/ws/ota_configs/archive/fastdds_v3.xml.template +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/src/rosotacom/resources/ws/ota_configs/archive/fastdds_v4.xml.template +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/src/rosotacom/resources/ws/ota_configs/archive/fastdds_v5.xml.template +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/src/rosotacom/resources/ws/ota_configs/create_zenoh_json5.py +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/src/rosotacom/resources/ws/ota_configs/cyclonedds_minimal.xml.template +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/src/rosotacom/resources/ws/ota_configs/cyclonedds_tuned.xml.template +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/src/rosotacom/resources/ws/ota_configs/fastdds_unicast.xml.template +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/src/rosotacom/resources/ws/ota_configs/get_ota_xml.py +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/src/rosotacom/resources/ws/ota_configs/utils.py +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/src/rosotacom/resources/ws/ota_configs/zenoh.json5.template +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/src/rosotacom/resources/ws/ros2src/.gitkeep +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/src/rosotacom/resources/ws/ros2src/com_cpp/CMakeLists.txt +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/src/rosotacom/resources/ws/ros2src/com_cpp/COLCON_IGNORE +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/src/rosotacom/resources/ws/ros2src/com_cpp/LICENSE.txt +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/src/rosotacom/resources/ws/ros2src/com_cpp/package.xml +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/src/rosotacom/resources/ws/ros2src/com_cpp/src/hz_monitor.cpp +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/src/rosotacom/resources/ws/ros2src/com_cpp/src/universal_compressor.cpp +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/src/rosotacom/resources/ws/ros2src/com_cpp/src/universal_decompressor.cpp +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/src/rosotacom/resources/ws/ros2src/com_msgs/CMakeLists.txt +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/src/rosotacom/resources/ws/ros2src/com_msgs/LICENSE.txt +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/src/rosotacom/resources/ws/ros2src/com_msgs/msg/CompressedData.msg +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/src/rosotacom/resources/ws/ros2src/com_msgs/msg/EchoHeartbeat.msg +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/src/rosotacom/resources/ws/ros2src/com_msgs/msg/OtaStamped.msg +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/src/rosotacom/resources/ws/ros2src/com_msgs/msg/SizedPayload.msg +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/src/rosotacom/resources/ws/ros2src/com_msgs/package.xml +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/src/rosotacom/resources/ws/ros2src/com_py/LICENSE.txt +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/src/rosotacom/resources/ws/ros2src/com_py/com_py/__init__.py +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/src/rosotacom/resources/ws/ros2src/com_py/com_py/base_bridge_relay.py +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/src/rosotacom/resources/ws/ros2src/com_py/com_py/bridge_in.py +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/src/rosotacom/resources/ws/ros2src/com_py/com_py/bridge_out.py +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/src/rosotacom/resources/ws/ros2src/com_py/com_py/heartbeat_echo.py +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/src/rosotacom/resources/ws/ros2src/com_py/com_py/hz_monitor.py +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/src/rosotacom/resources/ws/ros2src/com_py/com_py/image_bandwidth_reducer.py +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/src/rosotacom/resources/ws/ros2src/com_py/com_py/image_pixel_capper.py +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/src/rosotacom/resources/ws/ros2src/com_py/com_py/lanelet_saver.py +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/src/rosotacom/resources/ws/ros2src/com_py/com_py/latch_relay.py +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/src/rosotacom/resources/ws/ros2src/com_py/com_py/legacy/costmap_remapper.py +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/src/rosotacom/resources/ws/ros2src/com_py/com_py/legacy/marker_remapper.py +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/src/rosotacom/resources/ws/ros2src/com_py/com_py/legacy/speed_test.py +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/src/rosotacom/resources/ws/ros2src/com_py/com_py/legacy/tf_remapper.py +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/src/rosotacom/resources/ws/ros2src/com_py/com_py/legacy/traffic_monitor.py +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/src/rosotacom/resources/ws/ros2src/com_py/com_py/legacy/wifi_network_analysis_1.py +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/src/rosotacom/resources/ws/ros2src/com_py/com_py/link_bytes.py +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/src/rosotacom/resources/ws/ros2src/com_py/com_py/link_trace.py +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/src/rosotacom/resources/ws/ros2src/com_py/com_py/local_global_frame_bridge.py +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/src/rosotacom/resources/ws/ros2src/com_py/com_py/localization_map_split_reduce_saver.py +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/src/rosotacom/resources/ws/ros2src/com_py/com_py/msg_transform.py +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/src/rosotacom/resources/ws/ros2src/com_py/com_py/pair_management.py +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/src/rosotacom/resources/ws/ros2src/com_py/com_py/pub_sub_pair.py +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/src/rosotacom/resources/ws/ros2src/com_py/com_py/qos.py +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/src/rosotacom/resources/ws/ros2src/com_py/com_py/relay_in.py +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/src/rosotacom/resources/ws/ros2src/com_py/com_py/relay_out.py +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/src/rosotacom/resources/ws/ros2src/com_py/com_py/restamp.py +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/src/rosotacom/resources/ws/ros2src/com_py/com_py/sized_publisher.py +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/src/rosotacom/resources/ws/ros2src/com_py/com_py/stage_latency.py +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/src/rosotacom/resources/ws/ros2src/com_py/com_py/stage_latency_core.py +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/src/rosotacom/resources/ws/ros2src/com_py/com_py/status_overview.py +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/src/rosotacom/resources/ws/ros2src/com_py/com_py/status_overview_core.py +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/src/rosotacom/resources/ws/ros2src/com_py/com_py/tf_map_to_cart_saver.py +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/src/rosotacom/resources/ws/ros2src/com_py/com_py/topic_monitor.py +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/src/rosotacom/resources/ws/ros2src/com_py/com_py/topic_resolution.py +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/src/rosotacom/resources/ws/ros2src/com_py/com_py/trickle.py +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/src/rosotacom/resources/ws/ros2src/com_py/com_py/universal_compressor.py +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/src/rosotacom/resources/ws/ros2src/com_py/com_py/universal_decompressor.py +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/src/rosotacom/resources/ws/ros2src/com_py/com_py/universal_ota_unwrapper.py +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/src/rosotacom/resources/ws/ros2src/com_py/com_py/universal_ota_wrapper.py +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/src/rosotacom/resources/ws/ros2src/com_py/package.xml +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/src/rosotacom/resources/ws/ros2src/com_py/resource/com_py +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/src/rosotacom/resources/ws/ros2src/com_py/setup.cfg +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/src/rosotacom/resources/ws/ros2src/com_py/setup.py +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/src/rosotacom/resources/ws/ros2src/com_py/test/test_copyright.py +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/src/rosotacom/resources/ws/ros2src/com_py/test/test_flake8.py +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/src/rosotacom/resources/ws/ros2src/com_py/test/test_pep257.py +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/src/rosotacom/resources/ws/session/content/base/session_plugin_base.yaml +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/src/rosotacom/resources/ws/session/content/network/up_connectivity.py +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/src/rosotacom/resources/ws/session/content/network/wifi_network_analysis_2.py +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/src/rosotacom/resources/ws/session/creation/anonymize_bag.py +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/src/rosotacom/resources/ws/session/creation/catmux_log_setup.sh +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/src/rosotacom/resources/ws/session/creation/create_session_yaml.py +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/src/rosotacom/resources/ws/session/creation/generate_session_files.py +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/src/rosotacom/resources/ws/session/creation/run_session.py +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/src/rosotacom/resources/ws/session/creation/run_session_in_external_terminal.py +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/src/rosotacom/resources/ws/session/creation/strip_ansi.py +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/src/rosotacom/status_eval.py +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/src/rosotacom/stream_stats.py +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/src/rosotacom/trace_profiles.py +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/src/rosotacom/transit.py +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/src/rosotacom/video_quality.py +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/src/rosotacom_dev.egg-info/SOURCES.txt +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/src/rosotacom_dev.egg-info/dependency_links.txt +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/src/rosotacom_dev.egg-info/entry_points.txt +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/src/rosotacom_dev.egg-info/requires.txt +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/src/rosotacom_dev.egg-info/scm_file_list.json +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/src/rosotacom_dev.egg-info/top_level.txt +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/stop_session_in_container.py +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/terminology.md +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/tests/contract/test_benched_set_registry.py +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/tests/contract/test_findings.py +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/tests/contract/test_markdown_links.py +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/tests/contract/test_ota_source_bundle.py +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/tests/contract/test_package_metadata.py +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/tests/contract/test_packaged_resources.py +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/tests/contract/test_profile_covers_generated_commands.py +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/tests/contract/test_pytest_policy.py +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/tests/contract/test_readme_examples.py +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/tests/contract/test_security_maintenance_config.py +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/tests/contract/test_workflow_contracts.py +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/tests/e2e/conftest.py +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/tests/e2e/test_anonymize_e2e.py +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/tests/e2e/test_benchmark_ab.py +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/tests/e2e/test_benchmark_capacity.py +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/tests/e2e/test_benchmark_replay.py +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/tests/e2e/test_parallel_smoke.py +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/tests/e2e/test_smoke.py +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/tests/e2e/test_timeline_stepping.py +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/tests/e2e/test_video_quality_e2e.py +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/tests/sessions/generate_rmw_matrix.py +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/tests/sessions/rmw_matrix/1_heartbeat_cyclone-local_zenoh-ros2dds-ota/session-definition.yaml +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/tests/sessions/rmw_matrix/1_heartbeat_cyclone-ota/session-definition.yaml +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/tests/sessions/rmw_matrix/1_heartbeat_cyclone-ota-tuned/session-definition.yaml +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/tests/sessions/rmw_matrix/1_heartbeat_fastdds/session-definition.yaml +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/tests/sessions/rmw_matrix/1_heartbeat_zen-endpoints/session-definition.yaml +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/tests/unit/test_anonymize.py +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/tests/unit/test_bag_ground_truth.py +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/tests/unit/test_benched_set.py +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/tests/unit/test_benchmark.py +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/tests/unit/test_bundle_check.py +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/tests/unit/test_cli_benchmark.py +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/tests/unit/test_concurrency.py +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/tests/unit/test_deployment.py +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/tests/unit/test_ffmpeg_packet.py +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/tests/unit/test_forensics.py +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/tests/unit/test_geomap.py +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/tests/unit/test_link_bytes.py +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/tests/unit/test_link_trace.py +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/tests/unit/test_network_profiles.py +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/tests/unit/test_network_shaper.py +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/tests/unit/test_ota_xml.py +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/tests/unit/test_plots.py +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/tests/unit/test_stage_latency.py +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/tests/unit/test_status_eval.py +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/tests/unit/test_status_overview.py +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/tests/unit/test_stream_stats.py +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/tests/unit/test_trace_profiles.py +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/tests/unit/test_transit.py +0 -0
- {rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/tests/unit/test_video_quality.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: rosotacom-dev
|
|
3
|
-
Version: 2.5.
|
|
3
|
+
Version: 2.5.dev13
|
|
4
4
|
Summary: Host CLI for ROS OTA communication sessions.
|
|
5
5
|
Author: develNor
|
|
6
6
|
License-Expression: BSD-3-Clause
|
|
@@ -439,7 +439,11 @@ rosotacom ota-smoke 2_native_chatter \
|
|
|
439
439
|
|
|
440
440
|
`ota-smoke` accepts sessions and scenarios. It puts rosotacom on each peer,
|
|
441
441
|
stages the active project, runs delivery and isolation checks, collects
|
|
442
|
-
artifacts, stops the run, and removes the remote workdir.
|
|
442
|
+
artifacts, stops the run, and removes the remote workdir. For scenario targets
|
|
443
|
+
the checks start only once every declared application container is running
|
|
444
|
+
(bounded at 10 minutes, covering a cold peer's first image build); an
|
|
445
|
+
application that never comes up fails the run by name instead of as missing
|
|
446
|
+
publishers. Add `--interactive`
|
|
443
447
|
for a local control tmux with
|
|
444
448
|
one attachable communication/catmux window per peer with a live status pane below
|
|
445
449
|
each one. Scenario targets also get one native application-container window per
|
|
@@ -394,7 +394,11 @@ rosotacom ota-smoke 2_native_chatter \
|
|
|
394
394
|
|
|
395
395
|
`ota-smoke` accepts sessions and scenarios. It puts rosotacom on each peer,
|
|
396
396
|
stages the active project, runs delivery and isolation checks, collects
|
|
397
|
-
artifacts, stops the run, and removes the remote workdir.
|
|
397
|
+
artifacts, stops the run, and removes the remote workdir. For scenario targets
|
|
398
|
+
the checks start only once every declared application container is running
|
|
399
|
+
(bounded at 10 minutes, covering a cold peer's first image build); an
|
|
400
|
+
application that never comes up fails the run by name instead of as missing
|
|
401
|
+
publishers. Add `--interactive`
|
|
398
402
|
for a local control tmux with
|
|
399
403
|
one attachable communication/catmux window per peer with a live status pane below
|
|
400
404
|
each one. Scenario targets also get one native application-container window per
|
|
@@ -143,6 +143,10 @@ OTA_DEFAULT_SUDO_MODE = "passwordless"
|
|
|
143
143
|
# meet this because they call an absolute path inside the workdir; checkout mode
|
|
144
144
|
# calls the peer's own command by name, so it has to say where that lives.
|
|
145
145
|
OTA_CHECKOUT_PATH_PREFIX = 'export PATH="$HOME/.local/bin:$PATH"; '
|
|
146
|
+
#: Set for a `--peer-exec` transport when the script it is about to run needs a
|
|
147
|
+
#: terminal on the far side. A transport that does not understand it is not
|
|
148
|
+
#: broken by it, which is why this is an environment variable and not a flag.
|
|
149
|
+
OTA_PEER_TTY_ENV = "ROSOTACOM_PEER_TTY"
|
|
146
150
|
|
|
147
151
|
ws_creation_dir = WS_DIR / "session" / "creation"
|
|
148
152
|
session_gen_path = ws_creation_dir / "generate_session_files.py"
|
|
@@ -1750,11 +1754,23 @@ def _ota_peer_target(peer: OtaSmokePeer) -> str:
|
|
|
1750
1754
|
def _ota_remote_argv(peer: OtaSmokePeer, script: str, *, tty: bool = False, batch: bool = False) -> list[str]:
|
|
1751
1755
|
# A named transport wins over the SSH alias, and it takes the script as its
|
|
1752
1756
|
# last argument because that is the contract `ssh host <script>` already
|
|
1753
|
-
# has. `
|
|
1754
|
-
#
|
|
1755
|
-
#
|
|
1757
|
+
# has. `batch` is dropped rather than guessed at: it is an option of one
|
|
1758
|
+
# particular client, and a transport that is not ssh has no obligation to
|
|
1759
|
+
# understand it.
|
|
1760
|
+
#
|
|
1761
|
+
# `tty` is not droppable, and assuming it was cost a two-host run. The peer
|
|
1762
|
+
# windows start their container with `docker run -i -t`, which refuses
|
|
1763
|
+
# outright when the far side has no terminal — so a transport that cannot be
|
|
1764
|
+
# told "this one is interactive" can carry the probes and not the experiment.
|
|
1765
|
+
# It travels as an environment variable rather than an argument because the
|
|
1766
|
+
# argv contract is what makes any command usable here: a transport that
|
|
1767
|
+
# ignores the variable behaves exactly as before instead of failing on a
|
|
1768
|
+
# flag it never agreed to parse.
|
|
1756
1769
|
if peer.exec_command:
|
|
1757
|
-
|
|
1770
|
+
argv = shlex.split(peer.exec_command)
|
|
1771
|
+
if tty:
|
|
1772
|
+
argv = ["env", f"{OTA_PEER_TTY_ENV}=1", *argv]
|
|
1773
|
+
return [*argv, script]
|
|
1758
1774
|
if peer.ssh:
|
|
1759
1775
|
argv = ["ssh"]
|
|
1760
1776
|
if batch:
|
|
@@ -3433,6 +3449,55 @@ def _ota_stop_peers(
|
|
|
3433
3449
|
_ota_run(peer, command, label=f"{peer_name}: stop {target.name}", dry_run=dry_run, check=False)
|
|
3434
3450
|
|
|
3435
3451
|
|
|
3452
|
+
# How long verification waits for a scenario application container before it
|
|
3453
|
+
# gives up. Covers a first-run image build on a cold peer (observed ~3 min for
|
|
3454
|
+
# an apt-get install alone); the communication-container readiness wait uses
|
|
3455
|
+
# the same bound.
|
|
3456
|
+
OTA_SMOKE_APPLICATION_WAIT_TIMEOUT_S = 600
|
|
3457
|
+
|
|
3458
|
+
|
|
3459
|
+
def _ota_wait_for_scenario_applications(
|
|
3460
|
+
target: InteractiveSmokeTarget,
|
|
3461
|
+
plan: OtaSmokePlan,
|
|
3462
|
+
*,
|
|
3463
|
+
dry_run: bool,
|
|
3464
|
+
) -> list[str]:
|
|
3465
|
+
"""Block until every scenario application container declared for the target
|
|
3466
|
+
is running on its peer. The application windows start their container only
|
|
3467
|
+
after the peer's communication container is up, so on a cold machine the
|
|
3468
|
+
first check would otherwise run against applications that are still being
|
|
3469
|
+
built and report their absence as missing publishers (#218). A session
|
|
3470
|
+
target declares no applications and passes through untouched.
|
|
3471
|
+
|
|
3472
|
+
Running is deliberately the whole bound: whether an application *produces*
|
|
3473
|
+
is exactly what the session's own expectations then check."""
|
|
3474
|
+
definition = target.scenario_definition
|
|
3475
|
+
if definition is None:
|
|
3476
|
+
return []
|
|
3477
|
+
errors: list[str] = []
|
|
3478
|
+
for peer_name in sorted(plan.peers):
|
|
3479
|
+
peer = plan.peers[peer_name]
|
|
3480
|
+
for application in definition.applications.get(peer_name, ()):
|
|
3481
|
+
suffix = _sanitize_docker_name(f"_scenario_{target.name}_{peer_name}_{application.name}")
|
|
3482
|
+
label = f"{peer_name}: wait for application {application.name}"
|
|
3483
|
+
script = _ota_wait_for_running_container_suffix_script(
|
|
3484
|
+
suffix,
|
|
3485
|
+
f"{peer_name}:application:{application.name}",
|
|
3486
|
+
timeout_s=OTA_SMOKE_APPLICATION_WAIT_TIMEOUT_S,
|
|
3487
|
+
)
|
|
3488
|
+
result = _ota_run(peer, script, label=label, dry_run=dry_run, check=False)
|
|
3489
|
+
if result.returncode != 0:
|
|
3490
|
+
_ota_print_failure_output(label, result)
|
|
3491
|
+
errors.append(
|
|
3492
|
+
f"{peer_name}: application '{application.name}' has no running container after "
|
|
3493
|
+
f"{OTA_SMOKE_APPLICATION_WAIT_TIMEOUT_S}s; the scenario never came up, so its "
|
|
3494
|
+
"topics were not checked"
|
|
3495
|
+
)
|
|
3496
|
+
else:
|
|
3497
|
+
_print_completed_output(result)
|
|
3498
|
+
return errors
|
|
3499
|
+
|
|
3500
|
+
|
|
3436
3501
|
def _ota_verify_only(args: argparse.Namespace) -> int:
|
|
3437
3502
|
_runtime, plan, target = _resolve_ota_smoke_context(args)
|
|
3438
3503
|
instance_id = getattr(args, "instance_id", None)
|
|
@@ -3440,6 +3505,11 @@ def _ota_verify_only(args: argparse.Namespace) -> int:
|
|
|
3440
3505
|
raise RuntimeError("ota-smoke --verify-only requires --instance-id.")
|
|
3441
3506
|
dry_run = bool(getattr(args, "dry_run", False))
|
|
3442
3507
|
print(f"OTA smoke verification starting: {target.name} ({target.target_type}), instance={instance_id}")
|
|
3508
|
+
errors = _ota_wait_for_scenario_applications(target, plan, dry_run=dry_run)
|
|
3509
|
+
if errors:
|
|
3510
|
+
for error in errors:
|
|
3511
|
+
print(f"OTA SMOKE ERROR: {error}", file=sys.stderr)
|
|
3512
|
+
return 1
|
|
3443
3513
|
print("OTA smoke: starting synthetic publishers where needed.")
|
|
3444
3514
|
_ota_start_session_publishers(target, plan, dry_run=dry_run)
|
|
3445
3515
|
errors = _ota_verify_delivery(target, plan, instance_id, dry_run=dry_run)
|
|
@@ -3452,15 +3522,35 @@ def _ota_verify_only(args: argparse.Namespace) -> int:
|
|
|
3452
3522
|
return 0
|
|
3453
3523
|
|
|
3454
3524
|
|
|
3455
|
-
def _ota_wait_for_running_container_suffix_script(suffix: str, label: str) -> str:
|
|
3525
|
+
def _ota_wait_for_running_container_suffix_script(suffix: str, label: str, timeout_s: int | None = None) -> str:
|
|
3456
3526
|
pattern = shlex.quote(f"{re.escape(suffix)}$")
|
|
3457
3527
|
quoted_label = shlex.quote(label)
|
|
3458
|
-
|
|
3459
|
-
"container=''
|
|
3460
|
-
f"until container=$(docker ps --filter status=running --format '{{{{.Names}}}}' "
|
|
3528
|
+
find_container = (
|
|
3529
|
+
f"container=$(docker ps --filter status=running --format '{{{{.Names}}}}' "
|
|
3461
3530
|
f"| grep -E {pattern} | head -n 1) "
|
|
3462
|
-
'&& [ -n "$container" ]
|
|
3463
|
-
|
|
3531
|
+
'&& [ -n "$container" ]'
|
|
3532
|
+
)
|
|
3533
|
+
if timeout_s is None:
|
|
3534
|
+
return (
|
|
3535
|
+
"container=''; "
|
|
3536
|
+
f"until {find_container}; do "
|
|
3537
|
+
f"echo '[INFO] waiting for running container:' {quoted_label}; "
|
|
3538
|
+
"sleep 2; "
|
|
3539
|
+
"done; "
|
|
3540
|
+
'echo "[INFO] found running container: $container"'
|
|
3541
|
+
)
|
|
3542
|
+
# Bounded variant for captured (non-interactive) callers: one line up front
|
|
3543
|
+
# instead of a poll-cadence echo, and a hard failure when the bound is hit.
|
|
3544
|
+
attempts = max(1, int(timeout_s) // 2)
|
|
3545
|
+
return (
|
|
3546
|
+
f"echo '[INFO] waiting up to {int(timeout_s)}s for running container:' {quoted_label}; "
|
|
3547
|
+
"container=''; tries=0; "
|
|
3548
|
+
f"until {find_container}; do "
|
|
3549
|
+
"tries=$((tries+1)); "
|
|
3550
|
+
f'if [ "$tries" -ge {attempts} ]; then '
|
|
3551
|
+
f"echo '[ERROR] no running container after {int(timeout_s)}s:' {quoted_label} >&2; "
|
|
3552
|
+
"exit 1; "
|
|
3553
|
+
"fi; "
|
|
3464
3554
|
"sleep 2; "
|
|
3465
3555
|
"done; "
|
|
3466
3556
|
'echo "[INFO] found running container: $container"'
|
|
@@ -3534,7 +3624,7 @@ def _ota_create_tmux(
|
|
|
3534
3624
|
session_name,
|
|
3535
3625
|
"-n",
|
|
3536
3626
|
_safe_path_token(f"{first_peer.name}_communication"),
|
|
3537
|
-
_ota_quote_cmd(_ota_remote_argv(first_peer, first_script, tty=
|
|
3627
|
+
_ota_quote_cmd(_ota_remote_argv(first_peer, first_script, tty=_ota_peer_is_remote(first_peer))),
|
|
3538
3628
|
),
|
|
3539
3629
|
text=True,
|
|
3540
3630
|
capture_output=True,
|
|
@@ -3614,7 +3704,7 @@ def _ota_create_tmux(
|
|
|
3614
3704
|
session_name,
|
|
3615
3705
|
"-n",
|
|
3616
3706
|
_safe_path_token(f"{peer.name}_communication"),
|
|
3617
|
-
_ota_quote_cmd(_ota_remote_argv(peer, script, tty=
|
|
3707
|
+
_ota_quote_cmd(_ota_remote_argv(peer, script, tty=_ota_peer_is_remote(peer))),
|
|
3618
3708
|
),
|
|
3619
3709
|
text=True,
|
|
3620
3710
|
capture_output=True,
|
|
@@ -3645,7 +3735,7 @@ def _ota_create_tmux(
|
|
|
3645
3735
|
session_name,
|
|
3646
3736
|
"-n",
|
|
3647
3737
|
_safe_path_token(f"{peer.name}_{application.name}"),
|
|
3648
|
-
_ota_quote_cmd(_ota_remote_argv(peer, application_script, tty=
|
|
3738
|
+
_ota_quote_cmd(_ota_remote_argv(peer, application_script, tty=_ota_peer_is_remote(peer))),
|
|
3649
3739
|
),
|
|
3650
3740
|
text=True,
|
|
3651
3741
|
capture_output=True,
|
|
@@ -3810,7 +3900,7 @@ def _start_interactive_ota_smoke(args: argparse.Namespace) -> int:
|
|
|
3810
3900
|
if target.target_type == "scenario":
|
|
3811
3901
|
for peer_name, peer in plan.peers.items():
|
|
3812
3902
|
attach = _ota_rosotacom_command(plan, ["scenario", "attach", target.name, "--identity", peer_name], peer)
|
|
3813
|
-
attach_cmd = _ota_quote_cmd(_ota_remote_argv(peer, attach, tty=
|
|
3903
|
+
attach_cmd = _ota_quote_cmd(_ota_remote_argv(peer, attach, tty=_ota_peer_is_remote(peer)))
|
|
3814
3904
|
print(f"Manual remote scenario reattach for {peer_name}: {attach_cmd}")
|
|
3815
3905
|
if mode == "attach":
|
|
3816
3906
|
subprocess.run(_tmux_command(runtime, "attach-session", "-t", created), check=True)
|
|
@@ -3866,6 +3956,9 @@ def _start_noninteractive_ota_smoke(args: argparse.Namespace) -> int:
|
|
|
3866
3956
|
)
|
|
3867
3957
|
if not dry_run:
|
|
3868
3958
|
time.sleep(12)
|
|
3959
|
+
wait_errors = _ota_wait_for_scenario_applications(target, plan, dry_run=dry_run)
|
|
3960
|
+
if wait_errors:
|
|
3961
|
+
raise RuntimeError("OTA smoke verification failed:\n - " + "\n - ".join(wait_errors))
|
|
3869
3962
|
_ota_start_session_publishers(target, plan, dry_run=dry_run)
|
|
3870
3963
|
errors += _ota_verify_delivery(target, plan, instance.instance_id, dry_run=dry_run, profile=profile_name)
|
|
3871
3964
|
errors += _ota_verify_isolation(target, plan, dry_run=dry_run)
|
|
@@ -8566,8 +8659,34 @@ TOP_LEVEL_COMMANDS = {
|
|
|
8566
8659
|
}
|
|
8567
8660
|
|
|
8568
8661
|
|
|
8662
|
+
def _export_named_resource_paths() -> None:
|
|
8663
|
+
"""Put the packaged resource paths in the environment for ros2docker.
|
|
8664
|
+
|
|
8665
|
+
A ros2docker config driven by rosotacom may need to bake a package that
|
|
8666
|
+
lives *inside* the rosotacom install — `com_msgs` above all, since both
|
|
8667
|
+
sides of a link must agree on the message definitions. The install is
|
|
8668
|
+
isolated by design, so the config cannot compute the path and writes
|
|
8669
|
+
`${ROSOTACOM_COM_MSGS}` instead. Something has to put it there, and until
|
|
8670
|
+
now that was every caller's job: a shell snippet each project carried,
|
|
8671
|
+
sourced before every start and stop script.
|
|
8672
|
+
|
|
8673
|
+
That works until the caller is not a shell on the same machine. A two-host
|
|
8674
|
+
OTA run reached the control-centre application on the far side and died with
|
|
8675
|
+
`Could not expand environment variables in host path:
|
|
8676
|
+
'${ROSOTACOM_COM_MSGS}'` — while the identical single-host run passed,
|
|
8677
|
+
because there the peer inherited the variable from the orchestrator's
|
|
8678
|
+
environment. The single-host run could not have caught it by construction.
|
|
8679
|
+
|
|
8680
|
+
rosotacom owns the resource, so rosotacom exports it. `setdefault`, so a
|
|
8681
|
+
caller that deliberately points somewhere else still wins.
|
|
8682
|
+
"""
|
|
8683
|
+
for name, path in NAMED_RESOURCES.items():
|
|
8684
|
+
os.environ.setdefault(f"ROSOTACOM_{name.upper()}", str(path))
|
|
8685
|
+
|
|
8686
|
+
|
|
8569
8687
|
def main(argv: list[str] | None = None) -> int:
|
|
8570
8688
|
argv = list(sys.argv[1:] if argv is None else argv)
|
|
8689
|
+
_export_named_resource_paths()
|
|
8571
8690
|
if not argv:
|
|
8572
8691
|
argv = ["start"]
|
|
8573
8692
|
elif argv[0] not in TOP_LEVEL_COMMANDS and not argv[0].startswith("-"):
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: rosotacom-dev
|
|
3
|
-
Version: 2.5.
|
|
3
|
+
Version: 2.5.dev13
|
|
4
4
|
Summary: Host CLI for ROS OTA communication sessions.
|
|
5
5
|
Author: develNor
|
|
6
6
|
License-Expression: BSD-3-Clause
|
|
@@ -439,7 +439,11 @@ rosotacom ota-smoke 2_native_chatter \
|
|
|
439
439
|
|
|
440
440
|
`ota-smoke` accepts sessions and scenarios. It puts rosotacom on each peer,
|
|
441
441
|
stages the active project, runs delivery and isolation checks, collects
|
|
442
|
-
artifacts, stops the run, and removes the remote workdir.
|
|
442
|
+
artifacts, stops the run, and removes the remote workdir. For scenario targets
|
|
443
|
+
the checks start only once every declared application container is running
|
|
444
|
+
(bounded at 10 minutes, covering a cold peer's first image build); an
|
|
445
|
+
application that never comes up fails the run by name instead of as missing
|
|
446
|
+
publishers. Add `--interactive`
|
|
443
447
|
for a local control tmux with
|
|
444
448
|
one attachable communication/catmux window per peer with a live status pane below
|
|
445
449
|
each one. Scenario targets also get one native application-container window per
|
|
@@ -982,6 +982,133 @@ def test_ota_collect_logs_extracts_each_peer_into_instance(
|
|
|
982
982
|
assert not list(host_dir.glob("**/*.tar.gz.b64"))
|
|
983
983
|
|
|
984
984
|
|
|
985
|
+
def _wait_script_env(tmp_path: Path, docker_stdout: str) -> dict[str, str]:
|
|
986
|
+
"""PATH with a stub docker that prints `docker_stdout` for any invocation."""
|
|
987
|
+
stub = tmp_path / "bin" / "docker"
|
|
988
|
+
stub.parent.mkdir(exist_ok=True)
|
|
989
|
+
stub.write_text(f"#!/bin/sh\nprintf '%s\\n' {rosotacom.shlex.quote(docker_stdout)}\n", encoding="utf-8")
|
|
990
|
+
stub.chmod(0o755)
|
|
991
|
+
return {**os.environ, "PATH": f"{stub.parent}:{os.environ['PATH']}"}
|
|
992
|
+
|
|
993
|
+
|
|
994
|
+
def test_ota_wait_script_is_unbounded_without_timeout() -> None:
|
|
995
|
+
script = rosotacom._ota_wait_for_running_container_suffix_script("_com_to_b", "a:communication")
|
|
996
|
+
|
|
997
|
+
assert "exit 1" not in script
|
|
998
|
+
assert "waiting for running container:" in script
|
|
999
|
+
|
|
1000
|
+
|
|
1001
|
+
def test_ota_bounded_wait_script_fails_clearly_when_the_bound_is_hit(tmp_path: Path) -> None:
|
|
1002
|
+
script = rosotacom._ota_wait_for_running_container_suffix_script(
|
|
1003
|
+
"_scenario_demo_a_local_app", "a:application:local_app", timeout_s=2
|
|
1004
|
+
)
|
|
1005
|
+
|
|
1006
|
+
result = subprocess.run(
|
|
1007
|
+
["bash", "-c", script], env=_wait_script_env(tmp_path, "unrelated_container"), text=True, capture_output=True
|
|
1008
|
+
)
|
|
1009
|
+
|
|
1010
|
+
assert result.returncode == 1
|
|
1011
|
+
assert "[ERROR] no running container after 2s: a:application:local_app" in result.stderr
|
|
1012
|
+
|
|
1013
|
+
|
|
1014
|
+
def test_ota_bounded_wait_script_succeeds_once_the_container_runs(tmp_path: Path) -> None:
|
|
1015
|
+
script = rosotacom._ota_wait_for_running_container_suffix_script(
|
|
1016
|
+
"_scenario_demo_a_local_app", "a:application:local_app", timeout_s=2
|
|
1017
|
+
)
|
|
1018
|
+
runtime, _resolved = _write_test_scenario_project(tmp_path)
|
|
1019
|
+
container = rosotacom._scenario_container_name(runtime, "demo", "a", "local_app", "run1")
|
|
1020
|
+
|
|
1021
|
+
result = subprocess.run(
|
|
1022
|
+
["bash", "-c", script], env=_wait_script_env(tmp_path, container), text=True, capture_output=True
|
|
1023
|
+
)
|
|
1024
|
+
|
|
1025
|
+
assert result.returncode == 0
|
|
1026
|
+
assert f"[INFO] found running container: {container}" in result.stdout
|
|
1027
|
+
|
|
1028
|
+
|
|
1029
|
+
def test_ota_wait_for_scenario_applications_waits_per_declared_application(
|
|
1030
|
+
tmp_path: Path,
|
|
1031
|
+
monkeypatch: pytest.MonkeyPatch,
|
|
1032
|
+
) -> None:
|
|
1033
|
+
runtime, _resolved = _write_test_scenario_project(tmp_path)
|
|
1034
|
+
target = rosotacom._resolve_interactive_smoke_target("demo", runtime, "scenario")
|
|
1035
|
+
plan = _ota_plan(tmp_path)
|
|
1036
|
+
ran: list[tuple[str, str]] = []
|
|
1037
|
+
|
|
1038
|
+
def fake_ota_run(peer: rosotacom.OtaSmokePeer, script: str, **_kwargs: object) -> subprocess.CompletedProcess[str]:
|
|
1039
|
+
ran.append((peer.name, script))
|
|
1040
|
+
return subprocess.CompletedProcess([], 0, "", "")
|
|
1041
|
+
|
|
1042
|
+
monkeypatch.setattr(rosotacom, "_ota_run", fake_ota_run)
|
|
1043
|
+
|
|
1044
|
+
assert rosotacom._ota_wait_for_scenario_applications(target, plan, dry_run=False) == []
|
|
1045
|
+
|
|
1046
|
+
assert [name for name, _script in ran] == ["a", "b"]
|
|
1047
|
+
for identity, script in ran:
|
|
1048
|
+
assert f"_scenario_demo_{identity}_local_app" in script
|
|
1049
|
+
# The bound: verification must not wait forever, unlike the interactive panes.
|
|
1050
|
+
assert "exit 1" in script
|
|
1051
|
+
|
|
1052
|
+
|
|
1053
|
+
def test_ota_wait_for_scenario_applications_reports_the_bound_not_the_topics(
|
|
1054
|
+
tmp_path: Path,
|
|
1055
|
+
monkeypatch: pytest.MonkeyPatch,
|
|
1056
|
+
) -> None:
|
|
1057
|
+
runtime, _resolved = _write_test_scenario_project(tmp_path)
|
|
1058
|
+
target = rosotacom._resolve_interactive_smoke_target("demo", runtime, "scenario")
|
|
1059
|
+
plan = _ota_plan(tmp_path)
|
|
1060
|
+
|
|
1061
|
+
monkeypatch.setattr(
|
|
1062
|
+
rosotacom,
|
|
1063
|
+
"_ota_run",
|
|
1064
|
+
lambda peer, script, **kwargs: subprocess.CompletedProcess([], 0 if peer.name == "a" else 1, "", ""),
|
|
1065
|
+
)
|
|
1066
|
+
|
|
1067
|
+
errors = rosotacom._ota_wait_for_scenario_applications(target, plan, dry_run=False)
|
|
1068
|
+
|
|
1069
|
+
assert len(errors) == 1
|
|
1070
|
+
assert "b: application 'local_app' has no running container" in errors[0]
|
|
1071
|
+
assert "never came up" in errors[0]
|
|
1072
|
+
|
|
1073
|
+
|
|
1074
|
+
def test_ota_verify_only_stops_before_checks_when_applications_never_come_up(
|
|
1075
|
+
tmp_path: Path,
|
|
1076
|
+
monkeypatch: pytest.MonkeyPatch,
|
|
1077
|
+
) -> None:
|
|
1078
|
+
runtime, _resolved = _write_test_scenario_project(tmp_path)
|
|
1079
|
+
target = rosotacom._resolve_interactive_smoke_target("demo", runtime, "scenario")
|
|
1080
|
+
plan = _ota_plan(tmp_path)
|
|
1081
|
+
checks: list[str] = []
|
|
1082
|
+
|
|
1083
|
+
monkeypatch.setattr(rosotacom, "_resolve_ota_smoke_context", lambda args: (runtime, plan, target))
|
|
1084
|
+
monkeypatch.setattr(
|
|
1085
|
+
rosotacom,
|
|
1086
|
+
"_ota_wait_for_scenario_applications",
|
|
1087
|
+
lambda *args, **kwargs: ["b: application 'local_app' has no running container after 600s"],
|
|
1088
|
+
)
|
|
1089
|
+
monkeypatch.setattr(rosotacom, "_ota_start_session_publishers", lambda *args, **kwargs: checks.append("publishers"))
|
|
1090
|
+
monkeypatch.setattr(rosotacom, "_ota_verify_delivery", lambda *args, **kwargs: checks.append("delivery") or [])
|
|
1091
|
+
monkeypatch.setattr(rosotacom, "_ota_verify_isolation", lambda *args, **kwargs: checks.append("isolation") or [])
|
|
1092
|
+
|
|
1093
|
+
rc = rosotacom._ota_verify_only(argparse.Namespace(instance_id="run1", dry_run=False))
|
|
1094
|
+
|
|
1095
|
+
assert rc == 1
|
|
1096
|
+
# The point of #218: no status checks against a scenario that is not up.
|
|
1097
|
+
assert checks == []
|
|
1098
|
+
|
|
1099
|
+
|
|
1100
|
+
def test_ota_wait_for_scenario_applications_ignores_session_targets(
|
|
1101
|
+
tmp_path: Path,
|
|
1102
|
+
monkeypatch: pytest.MonkeyPatch,
|
|
1103
|
+
) -> None:
|
|
1104
|
+
runtime, _resolved = _write_test_scenario_project(tmp_path)
|
|
1105
|
+
target = rosotacom._resolve_interactive_smoke_target("demo", runtime, "session")
|
|
1106
|
+
plan = _ota_plan(tmp_path)
|
|
1107
|
+
monkeypatch.setattr(rosotacom, "_ota_run", lambda *args, **kwargs: pytest.fail("session targets must not wait"))
|
|
1108
|
+
|
|
1109
|
+
assert rosotacom._ota_wait_for_scenario_applications(target, plan, dry_run=False) == []
|
|
1110
|
+
|
|
1111
|
+
|
|
985
1112
|
def test_ota_smoke_parser_accepts_stop_without_peer_arguments(monkeypatch: pytest.MonkeyPatch) -> None:
|
|
986
1113
|
calls: list[argparse.Namespace] = []
|
|
987
1114
|
monkeypatch.setattr(rosotacom, "ota_smoke", lambda args: calls.append(args) or 0)
|
|
@@ -1076,6 +1203,9 @@ def test_noninteractive_ota_smoke_lifecycle_uses_generic_runner(
|
|
|
1076
1203
|
monkeypatch.setattr(rosotacom, "_ota_preflight", lambda *args, **kwargs: calls.append("preflight"))
|
|
1077
1204
|
monkeypatch.setattr(rosotacom, "_ota_prepare_hosts", lambda *args, **kwargs: calls.append("prepare"))
|
|
1078
1205
|
monkeypatch.setattr(rosotacom, "_ota_start_peers", lambda *args, **kwargs: calls.append("start"))
|
|
1206
|
+
monkeypatch.setattr(
|
|
1207
|
+
rosotacom, "_ota_wait_for_scenario_applications", lambda *args, **kwargs: calls.append("wait-apps") or []
|
|
1208
|
+
)
|
|
1079
1209
|
monkeypatch.setattr(rosotacom, "_ota_start_session_publishers", lambda *args, **kwargs: calls.append("publishers"))
|
|
1080
1210
|
monkeypatch.setattr(rosotacom, "_ota_verify_delivery", lambda *args, **kwargs: calls.append("test") or [])
|
|
1081
1211
|
monkeypatch.setattr(rosotacom, "_ota_verify_isolation", lambda *args, **kwargs: calls.append("isolation") or [])
|
|
@@ -1104,6 +1234,7 @@ def test_noninteractive_ota_smoke_lifecycle_uses_generic_runner(
|
|
|
1104
1234
|
"prepare",
|
|
1105
1235
|
"start",
|
|
1106
1236
|
"sleep:12",
|
|
1237
|
+
"wait-apps",
|
|
1107
1238
|
"publishers",
|
|
1108
1239
|
"test",
|
|
1109
1240
|
"isolation",
|
|
@@ -1161,6 +1292,8 @@ def test_ota_smoke_dry_run_exercises_generic_remote_flow(
|
|
|
1161
1292
|
assert "b: reachable: running remote command" in out
|
|
1162
1293
|
assert "a: start demo: running remote command" in out
|
|
1163
1294
|
assert "b: start demo: running remote command" in out
|
|
1295
|
+
assert "a: wait for application local_app: running remote command" in out
|
|
1296
|
+
assert "b: wait for application local_app: running remote command" in out
|
|
1164
1297
|
assert "a: rosotacom test: running remote command" in out
|
|
1165
1298
|
assert "a: publish isolation probe: running remote command" in out
|
|
1166
1299
|
assert "b: check isolation probe absent: running remote command" in out
|
|
@@ -3231,6 +3364,37 @@ def _ota_exec_plan(project_config: Path, command: str = "remote-rosotacom majest
|
|
|
3231
3364
|
)
|
|
3232
3365
|
|
|
3233
3366
|
|
|
3367
|
+
def test_named_resources_reach_ros2docker_through_the_environment(
|
|
3368
|
+
monkeypatch: pytest.MonkeyPatch,
|
|
3369
|
+
) -> None:
|
|
3370
|
+
# A ros2docker config cannot compute a path into an isolated install, so it
|
|
3371
|
+
# writes ${ROSOTACOM_COM_MSGS}. Until this, every caller had to export that
|
|
3372
|
+
# itself -- which works right up to the point where the caller is not a
|
|
3373
|
+
# shell on the same machine. A two-host run died on the far side with
|
|
3374
|
+
# "Could not expand environment variables in host path" while the identical
|
|
3375
|
+
# single-host run passed, because there the peer inherited the variable from
|
|
3376
|
+
# the orchestrator. The single-host run could not have caught it.
|
|
3377
|
+
for name in rosotacom.NAMED_RESOURCES:
|
|
3378
|
+
monkeypatch.delenv(f"ROSOTACOM_{name.upper()}", raising=False)
|
|
3379
|
+
|
|
3380
|
+
rosotacom._export_named_resource_paths()
|
|
3381
|
+
|
|
3382
|
+
assert os.environ["ROSOTACOM_COM_MSGS"] == str(rosotacom.NAMED_RESOURCES["com_msgs"])
|
|
3383
|
+
assert Path(os.environ["ROSOTACOM_COM_MSGS"]).name == "com_msgs"
|
|
3384
|
+
|
|
3385
|
+
|
|
3386
|
+
def test_an_explicit_resource_path_is_not_overridden(
|
|
3387
|
+
monkeypatch: pytest.MonkeyPatch,
|
|
3388
|
+
) -> None:
|
|
3389
|
+
# setdefault, not assignment: a caller pointing somewhere else on purpose --
|
|
3390
|
+
# a checkout under development, say -- still wins.
|
|
3391
|
+
monkeypatch.setenv("ROSOTACOM_COM_MSGS", "/somewhere/else")
|
|
3392
|
+
|
|
3393
|
+
rosotacom._export_named_resource_paths()
|
|
3394
|
+
|
|
3395
|
+
assert os.environ["ROSOTACOM_COM_MSGS"] == "/somewhere/else"
|
|
3396
|
+
|
|
3397
|
+
|
|
3234
3398
|
def test_ota_peer_exec_replaces_the_ssh_client(tmp_path: Path) -> None:
|
|
3235
3399
|
# The point of the flag: a peer can be reached by something that is not a
|
|
3236
3400
|
# shell. The script arrives as the final argument, which is the contract
|
|
@@ -3245,19 +3409,49 @@ def test_ota_peer_exec_replaces_the_ssh_client(tmp_path: Path) -> None:
|
|
|
3245
3409
|
]
|
|
3246
3410
|
|
|
3247
3411
|
|
|
3248
|
-
def
|
|
3249
|
-
# `-
|
|
3250
|
-
#
|
|
3251
|
-
#
|
|
3412
|
+
def test_ota_peer_exec_ignores_batch_mode_which_belongs_to_ssh(tmp_path: Path) -> None:
|
|
3413
|
+
# `-o BatchMode=yes` is an option of one client. Passing it to an arbitrary
|
|
3414
|
+
# transport would be guessing at an interface it never agreed to, and the
|
|
3415
|
+
# failure would look like a broken peer rather than a wrong flag.
|
|
3252
3416
|
plan = _ota_exec_plan(_write_checkout_project(tmp_path))
|
|
3253
3417
|
|
|
3254
|
-
assert rosotacom._ota_remote_argv(plan.peers["a"], "true",
|
|
3418
|
+
assert rosotacom._ota_remote_argv(plan.peers["a"], "true", batch=True) == [
|
|
3255
3419
|
"remote-rosotacom",
|
|
3256
3420
|
"majestic-tks",
|
|
3257
3421
|
"true",
|
|
3258
3422
|
]
|
|
3259
3423
|
|
|
3260
3424
|
|
|
3425
|
+
def test_ota_peer_exec_carries_the_tty_request(tmp_path: Path) -> None:
|
|
3426
|
+
# Dropping this cost a two-host run: the peer windows start their container
|
|
3427
|
+
# with `docker run -i -t`, which refuses outright when the far side has no
|
|
3428
|
+
# terminal, so a transport that cannot be told "this one is interactive"
|
|
3429
|
+
# carries the probes and not the experiment.
|
|
3430
|
+
plan = _ota_exec_plan(_write_checkout_project(tmp_path))
|
|
3431
|
+
|
|
3432
|
+
assert rosotacom._ota_remote_argv(plan.peers["a"], "true", tty=True) == [
|
|
3433
|
+
"env",
|
|
3434
|
+
"ROSOTACOM_PEER_TTY=1",
|
|
3435
|
+
"remote-rosotacom",
|
|
3436
|
+
"majestic-tks",
|
|
3437
|
+
"true",
|
|
3438
|
+
]
|
|
3439
|
+
|
|
3440
|
+
|
|
3441
|
+
def test_ota_peer_exec_tty_is_a_variable_so_an_older_transport_still_works(
|
|
3442
|
+
tmp_path: Path,
|
|
3443
|
+
) -> None:
|
|
3444
|
+
# An environment variable rather than a flag, so a transport that does not
|
|
3445
|
+
# understand it behaves exactly as before instead of dying on an argument it
|
|
3446
|
+
# never agreed to parse. The argv contract is what makes any command usable
|
|
3447
|
+
# as a transport at all.
|
|
3448
|
+
plan = _ota_exec_plan(_write_checkout_project(tmp_path))
|
|
3449
|
+
argv = rosotacom._ota_remote_argv(plan.peers["a"], "true", tty=True)
|
|
3450
|
+
|
|
3451
|
+
assert argv[-1] == "true"
|
|
3452
|
+
assert not any(part.startswith("-") for part in argv)
|
|
3453
|
+
|
|
3454
|
+
|
|
3261
3455
|
def test_ota_peer_exec_makes_a_peer_remote(tmp_path: Path) -> None:
|
|
3262
3456
|
# Everything that used to ask `peer.ssh` meant "is it over there". A peer
|
|
3263
3457
|
# behind a command transport is, and a caller that still reads `.ssh` would
|
{rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/.devcontainer/devcontainer.json.template
RENAMED
|
File without changes
|
{rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/.devcontainer/re_generate_devcontainer_json.py
RENAMED
|
File without changes
|
|
File without changes
|
{rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/.github/ISSUE_TEMPLATE/documentation-audit.md
RENAMED
|
File without changes
|
{rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/.github/ISSUE_TEMPLATE/implementation-cleanup.md
RENAMED
|
File without changes
|
{rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/.github/ISSUE_TEMPLATE/quality-workflow.md
RENAMED
|
File without changes
|
|
File without changes
|
{rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/.github/ISSUE_TEMPLATE/release-process.md
RENAMED
|
File without changes
|
{rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/.github/ISSUE_TEMPLATE/repository-diagnosis.md
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/.github/workflows/benchmark-calibrate.yml
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/calibration/capacity-size-tight-cyclone.json
RENAMED
|
File without changes
|
{rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/calibration/probe-loss-gop-tight-cyclone.json
RENAMED
|
File without changes
|
{rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/calibration/probe-loss-nominal-cyclone.json
RENAMED
|
File without changes
|
{rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/calibration/probe-loss-tight-cyclone.json
RENAMED
|
File without changes
|
{rosotacom_dev-2.5.dev10 → rosotacom_dev-2.5.dev13}/calibration/probe-loss-tight-fastdds.json
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|