88import pytest
99
1010import hflow
11- from hflow .testing import synthesize_episode
11+ from hflow .testing import SyntheticEpisodeSpec , synthesize_episode
1212
1313
1414def check_joint_smoothness (joints : np .ndarray , rate_hz : float ) -> dict [str , float ]:
@@ -21,7 +21,23 @@ def check_joint_smoothness(joints: np.ndarray, rate_hz: float) -> dict[str, floa
2121
2222@pytest .fixture (scope = "module" )
2323def source_episode (tmp_path_factory : pytest .TempPathFactory ) -> Path :
24- return synthesize_episode (tmp_path_factory .mktemp ("e2e-source" ) / "episode_0001.mcap" )
24+ return synthesize_episode (
25+ tmp_path_factory .mktemp ("e2e-source" ) / "episode_0001.mcap" ,
26+ SyntheticEpisodeSpec (
27+ duration_s = 2.0 ,
28+ black_segment = (0.5 , 0.75 ),
29+ joint_jump_at_s = 1.0 ,
30+ timestamp_offset_segment = (1.4 , 1.7 ),
31+ ),
32+ )
33+
34+
35+ @pytest .fixture (scope = "module" )
36+ def state_only_source_episode (tmp_path_factory : pytest .TempPathFactory ) -> Path :
37+ return synthesize_episode (
38+ tmp_path_factory .mktemp ("e2e-state-only-source" ) / "episode_0001.mcap" ,
39+ SyntheticEpisodeSpec (duration_s = 2.0 , cameras = (), joint_jump_at_s = 1.0 ),
40+ )
2541
2642
2743@pytest .fixture (scope = "module" )
@@ -109,7 +125,7 @@ def test_builtin_checks_found_the_injected_defects(
109125 assert blackout is not None
110126 black_pct = blackout .measurements ["black_pct" ]
111127 assert isinstance (black_pct , float )
112- # The fixture blacks out 1s of the 8s wrist stream: ~12.5% of frames.
128+ # The fixture blacks out 0.25s of the 2s wrist stream: ~12.5% of frames.
113129 assert 5.0 < black_pct < 25.0
114130
115131
@@ -129,7 +145,7 @@ def test_canonical_episode_accessors(
129145 assert mp4 .is_file () and mp4 .stat ().st_size > 0
130146
131147 frames = episode .frames ("overhead_cam" , fps = 2.0 )
132- assert 12 <= len (frames ) <= 17 # ~8s at 2 fps
148+ assert 3 <= len (frames ) <= 5 # ~2s at 2 fps
133149 assert frames [0 ].path .read_bytes ()[:2 ] == b"\xff \xd8 "
134150 # Frame log times map to SOURCE messages: at t=0.5s the fps filter
135151 # emits the frame visible then -- source frame floor(0.5 * 15) = 7,
@@ -141,7 +157,7 @@ def test_arrow_export(report_and_app: tuple[hflow.TestReport, hflow.App]) -> Non
141157 report , _app = report_and_app
142158 with hflow .Episode (report .canonical_path ) as episode :
143159 table : Any = episode .channel ("/joint_states" ).to_arrow ()
144- assert table .num_rows == 800
160+ assert table .num_rows == 200
145161 assert "log_time_ns" in table .column_names
146162 assert "position" in table .column_names
147163
@@ -171,7 +187,9 @@ def never_reached(ep: hflow.Episode) -> hflow.CheckResult:
171187 assert by_name ["camera_blackout" ].status == "failed"
172188
173189
174- def test_crashing_check_is_infrastructure_not_data (source_episode : Path , tmp_path : Path ) -> None :
190+ def test_crashing_check_is_infrastructure_not_data (
191+ state_only_source_episode : Path , tmp_path : Path
192+ ) -> None :
175193 app = hflow .App ("crashy-pipeline" , data_root = tmp_path )
176194
177195 @app .check ()
@@ -182,7 +200,7 @@ def exploding(ep: hflow.Episode) -> hflow.CheckResult:
182200 def still_runs (ep : hflow .Episode ) -> hflow .CheckResult :
183201 return hflow .CheckResult (measurements = {"ran" : True })
184202
185- report = app .test (source_episode , verbose = False )
203+ report = app .test (state_only_source_episode , verbose = False )
186204 assert not report .quarantined
187205 by_name = {run .check .name : run for run in report .checks }
188206 assert by_name ["exploding" ].status == "error"
@@ -191,7 +209,7 @@ def still_runs(ep: hflow.Episode) -> hflow.CheckResult:
191209
192210
193211def test_resource_declaring_checks_run_after_plain_ones (
194- source_episode : Path , tmp_path : Path
212+ state_only_source_episode : Path , tmp_path : Path
195213) -> None :
196214 app = hflow .App (
197215 "ordered-pipeline" , data_root = tmp_path , endpoints = {"judge" : "http://localhost:9" }
@@ -208,16 +226,18 @@ def cheap(ep: hflow.Episode) -> hflow.CheckResult:
208226 execution_order .append ("cheap" )
209227 return hflow .CheckResult ()
210228
211- app .test (source_episode , verbose = False )
229+ app .test (state_only_source_episode , verbose = False )
212230 assert execution_order == ["cheap" , "expensive" ]
213231
214232
215- def test_missing_provider_alias_fails_preflight (source_episode : Path , tmp_path : Path ) -> None :
233+ def test_missing_provider_alias_fails_preflight (
234+ state_only_source_episode : Path , tmp_path : Path
235+ ) -> None :
216236 app = hflow .App ("misconfigured" , data_root = tmp_path )
217237
218238 @app .check (uses = "judge" )
219239 def needs_endpoint (ep : hflow .Episode ) -> hflow .CheckResult :
220240 return hflow .CheckResult ()
221241
222242 with pytest .raises (ValueError , match = "judge" ):
223- app .test (source_episode , verbose = False )
243+ app .test (state_only_source_episode , verbose = False )
0 commit comments