rosotacom-dev 2.5.dev5__py3-none-any.whl → 2.5.dev6__py3-none-any.whl

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/cli.py CHANGED
@@ -6540,6 +6540,26 @@ def test_command(args: argparse.Namespace) -> int:
6540
6540
  from . import bag_ground_truth
6541
6541
 
6542
6542
  ground_truth = bag_ground_truth.bag_ground_truth(bag)
6543
+ elif not getattr(args, "suggest", False):
6544
+ # A `vs_bag_ratio` needs the bag's native rate, and without one it is
6545
+ # skipped rather than failed -- so the run would print TEST OK having
6546
+ # checked nothing about completeness. Refuse instead: the declaration
6547
+ # is the statement of intent, and honouring it or failing loudly is
6548
+ # this command's job.
6549
+ needs_bag = status_eval.topics_requiring_bag(expect_by_topic, profile)
6550
+ if needs_bag:
6551
+ listed = "\n".join(f" {base}" for base in needs_bag)
6552
+ print(
6553
+ f"rosotacom test: {len(needs_bag)} topic(s) declare "
6554
+ f"`completeness.vs_bag_ratio`, which compares the delivered rate "
6555
+ f"to the source's native rate and can only be evaluated against "
6556
+ f"the replay bag:\n{listed}\n"
6557
+ f"Pass `--bag <dir>`, or drop the assertion from a session that "
6558
+ f"is not replay-driven. Without a bag it would be skipped in "
6559
+ f"silence and this run would report success.",
6560
+ file=sys.stderr,
6561
+ )
6562
+ return 1
6543
6563
  reports: dict[str, Any] = {}
6544
6564
  failures: list[str] = []
6545
6565
 
rosotacom/status_eval.py CHANGED
@@ -105,6 +105,27 @@ def resolve_expect_for_profile(expect: dict[str, Any], profile: str | None) -> d
105
105
  return resolved
106
106
 
107
107
 
108
+ def topics_requiring_bag(expect_by_topic: dict[str, dict[str, Any]], profile: str | None = None) -> list[str]:
109
+ """Topics whose expectations can only be evaluated against a replay bag.
110
+
111
+ `completeness.vs_bag_ratio` compares the delivered rate to the *source's*
112
+ native rate, which only a bag knows. `_check_bag_completeness` returns
113
+ early when no ground truth was supplied, so without `--bag` such an
114
+ expectation is skipped in silence and the run still prints `TEST OK`.
115
+
116
+ A skipped assertion reads as coverage, which is worse than no assertion at
117
+ all: it is the exact shape of the defect these contracts exist to catch.
118
+ The caller uses this to refuse the run instead.
119
+ """
120
+ required = []
121
+ for base, raw in sorted((expect_by_topic or {}).items()):
122
+ expect = resolve_expect_for_profile(raw or {}, profile)
123
+ completeness = expect.get("completeness") or {}
124
+ if isinstance(completeness, dict) and completeness.get("vs_bag_ratio") is not None:
125
+ required.append(base)
126
+ return required
127
+
128
+
108
129
  def expectations_from_cfg(cfg: dict[str, Any]) -> dict[str, dict[str, Any]]:
109
130
  """Map a topic's base name -> its `expect` block, from a session config."""
110
131
  out: dict[str, dict[str, Any]] = {}
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: rosotacom-dev
3
- Version: 2.5.dev5
3
+ Version: 2.5.dev6
4
4
  Summary: Host CLI for ROS OTA communication sessions.
5
5
  Author: develNor
6
6
  License-Expression: BSD-3-Clause
@@ -5,7 +5,7 @@ rosotacom/bag_ground_truth.py,sha256=FlL34fA2CWZZxsrz7uxfhPt2VntPuS0ldrOPy58XPMk
5
5
  rosotacom/benched_set.py,sha256=PGybWzNKJhg5wouIGo_zxlb7Fu41UzmtgEBxUR-Gkvg,19874
6
6
  rosotacom/benchmark.py,sha256=Xda8WwFKQEIRMO0Qe1Hf7rvykYIgM86gUHBuyX9VvI8,74447
7
7
  rosotacom/bundle_check.py,sha256=l_3BSuYk6juXQmsNU6jkxRbH8ayH2GkiW9ONKMQ1oJY,18270
8
- rosotacom/cli.py,sha256=dFS4Hlyoym2015U0dJ33vKoHomZM_TipPsINq4il5Qg,361905
8
+ rosotacom/cli.py,sha256=5nztYmxzS0rwY1RIFCzvLYcMAN4X-DqcdzMHp-obH-I,363053
9
9
  rosotacom/cli_benchmark.py,sha256=bhdtvvO73g3-vlWTX0hf7I70lKQVT0pyXbIg3YnXfLQ,342197
10
10
  rosotacom/deployment.py,sha256=XVhB8JjxhAsglSEEPtiVSeV6fCG0rgGmDRulh14oIYQ,7318
11
11
  rosotacom/ffmpeg_packet.py,sha256=zB1BHgY1kexr5sETVMkm4bkVnRytj9k2t0uOYiHUZ6M,4267
@@ -15,7 +15,7 @@ rosotacom/network_profiles.py,sha256=fCsZYoSKBjAAYkC7Gbyv4s5L9OVmZs_hAHWTf0xMfHU
15
15
  rosotacom/network_shaper.py,sha256=kjn9ZtiO1SMm8UHKIjmn92JBu_hE5TJF6vaNF1XKtNU,5463
16
16
  rosotacom/plots.py,sha256=YRGRxuGHSHDZmtL0sv1JS7cPVSL9VzjGYuvMxeHAj54,22674
17
17
  rosotacom/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
18
- rosotacom/status_eval.py,sha256=ypnxMV0u-NfNZuf59izPwUmO6gYISkJ1z1TK33vEbcE,22062
18
+ rosotacom/status_eval.py,sha256=V9KVho5DEBYCD_iG1X2Yg6qd6ZEzopdKSY5QJ6K1sP4,23115
19
19
  rosotacom/stream_stats.py,sha256=ey09g4B7y0E-NnsOBW8Ng9kqyMbo2xuabNut9op6uM4,23744
20
20
  rosotacom/trace_profiles.py,sha256=KNM1RExHDXkppWZdqbSPXTjwJ8f7io8IU48HnKzmHKY,20567
21
21
  rosotacom/transit.py,sha256=0BqDO3nfYJ1PMXRz8b3084sDOrCjhO5zwdqC_-qU6bo,10531
@@ -187,9 +187,9 @@ rosotacom/resources/ws/session/creation/generate_session_files.py,sha256=R4HFetZ
187
187
  rosotacom/resources/ws/session/creation/run_session.py,sha256=G2hJhrmLp11gm3JZ6_C-zZcqu_reXlE_wmobB7BiCfU,16849
188
188
  rosotacom/resources/ws/session/creation/run_session_in_external_terminal.py,sha256=Ub_5f-ttUUc-rAPrZmg_Op34s8Z4C91hTyEn8fgyt-E,2633
189
189
  rosotacom/resources/ws/session/creation/strip_ansi.py,sha256=vNjpemcq4xHr0VG4x0bZqvgwEBEfOgN-b4PzbrM5nfM,851
190
- rosotacom_dev-2.5.dev5.dist-info/licenses/LICENSE.txt,sha256=FDB3-fao3lqZ94wsJHKAH7U88kAnfvZhZC8Hm5rN__g,1459
191
- rosotacom_dev-2.5.dev5.dist-info/METADATA,sha256=X7FGmLCUOzXrxBnovCv8Du--a2uYwmwEYaKbqy0DcD4,46417
192
- rosotacom_dev-2.5.dev5.dist-info/WHEEL,sha256=YVMoNqKzERt-wjUZwJ33xBGAwnFl-4cqbYkTtWa4itE,91
193
- rosotacom_dev-2.5.dev5.dist-info/entry_points.txt,sha256=-Hl9WKAfkLjMHUonDTxvz86EgSfZf6oyatRMxypS5iA,147
194
- rosotacom_dev-2.5.dev5.dist-info/top_level.txt,sha256=BZrtQcIVDWn_pQZR3Mlssqy5SaRXHjOa6B-1D9Fy4Ao,10
195
- rosotacom_dev-2.5.dev5.dist-info/RECORD,,
190
+ rosotacom_dev-2.5.dev6.dist-info/licenses/LICENSE.txt,sha256=FDB3-fao3lqZ94wsJHKAH7U88kAnfvZhZC8Hm5rN__g,1459
191
+ rosotacom_dev-2.5.dev6.dist-info/METADATA,sha256=ExbIFkLKV4qhOiGTz1NqBTBKAmk8TctpZ81GsPR2dMU,46417
192
+ rosotacom_dev-2.5.dev6.dist-info/WHEEL,sha256=YVMoNqKzERt-wjUZwJ33xBGAwnFl-4cqbYkTtWa4itE,91
193
+ rosotacom_dev-2.5.dev6.dist-info/entry_points.txt,sha256=-Hl9WKAfkLjMHUonDTxvz86EgSfZf6oyatRMxypS5iA,147
194
+ rosotacom_dev-2.5.dev6.dist-info/top_level.txt,sha256=BZrtQcIVDWn_pQZR3Mlssqy5SaRXHjOa6B-1D9Fy4Ao,10
195
+ rosotacom_dev-2.5.dev6.dist-info/RECORD,,