//! Contract tests for the client-origin transport-to-RCT probe. //! //! Scope: statically guard the black-box transport harness and client timeline //! artifacts used for client->server tuning. //! Targets: `scripts/manual/run_client_to_rct_transport_probe.sh`, //! `scripts/manual/client_rct_transport_summary.py`, and //! `scripts/manual/client_rct_uvc_frame_meta_fetch.sh`, and //! `client/src/sync_probe/`. //! Why: this probe is the bridge between synthetic bundled client media and the //! final RCT sync/freshness/smoothness evidence, so it must not drift into //! split-stream or sudo-mutating behavior. const CLIENT_RCT_SCRIPT: &str = include_str!("../../scripts/manual/run_client_to_rct_transport_probe.sh"); const CLIENT_RCT_SUMMARY: &str = include_str!("../../scripts/manual/client_rct_transport_summary.py"); const CLIENT_RCT_LAYERS: &str = include_str!("../../scripts/manual/client_rct_transport_layers.py"); const UVC_FRAME_META_FETCH: &str = include_str!("../../scripts/manual/client_rct_uvc_frame_meta_fetch.sh"); const UVC_FRAME_META_SUMMARY: &str = include_str!("../../scripts/manual/summarize_uvc_frame_meta_log.py"); const SYNC_PROBE_CONFIG: &str = include_str!("../../client/src/sync_probe/config.rs"); const SYNC_PROBE_RUNNER: &str = include_str!("../../client/src/sync_probe/runner.rs"); const SYNC_PROBE_BUNDLED_TRANSPORT: &str = include_str!("../../client/src/sync_probe/runner/bundled_transport.rs"); const SYNC_PROBE_TIMELINE: &str = include_str!("../../client/src/sync_probe/timeline.rs"); #[test] fn client_rct_probe_injects_synthetic_media_through_bundled_transport() { for expected in [ "lesavka-sync-probe", "--event-width-codes \"${PROBE_EVENT_WIDTH_CODES}\"", "PROBE_EVENT_WIDTH_CODES=${PROBE_EVENT_WIDTH_CODES:-1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16}", "--timeline-json \"${LOCAL_CLIENT_TIMELINE_JSON}\"", "stream_webcam_media", "UpstreamMediaBundle", "server does not advertise bundled webcam media", "refusing to measure split upstream", ] { assert!( CLIENT_RCT_SCRIPT.contains(expected) || SYNC_PROBE_RUNNER.contains(expected) || SYNC_PROBE_BUNDLED_TRANSPORT.contains(expected) || SYNC_PROBE_CONFIG.contains(expected), "client-to-RCT transport probe should contain {expected}" ); } for forbidden in [ ".stream_camera(Request::new(outbound))", ".stream_microphone(Request::new(outbound))", ] { assert!( !SYNC_PROBE_RUNNER.contains(forbidden) && !SYNC_PROBE_BUNDLED_TRANSPORT.contains(forbidden), "synthetic transport probe must not use split upstream RPC {forbidden}" ); } } #[test] fn client_rct_probe_preserves_black_box_rct_measurement_artifacts() { for expected in [ "LOCAL_CAPTURE=\"${LOCAL_REPORT_DIR}/capture.mkv\"", "LOCAL_REPORT_JSON=\"${LOCAL_REPORT_DIR}/report.json\"", "LOCAL_EVENTS_CSV=\"${LOCAL_REPORT_DIR}/events.csv\"", "LOCAL_CLIENT_TIMELINE_JSON=\"${LOCAL_REPORT_DIR}/client-transport-timeline.json\"", "LOCAL_TRANSPORT_SUMMARY_JSON=\"${LOCAL_REPORT_DIR}/client-rct-transport-summary.json\"", "LOCAL_RUN_LOG=\"${LOCAL_REPORT_DIR}/client-rct-run.log\"", "capture_start_unix_ns=", "lesavka-sync-analyze", "client_rct_transport_summary.py", "smoothness", "freshness_budget_ms", "freshness_bottleneck", "client_send_summary", "post_client_send_worst_p95_ms", "LESAVKA_CLIENT_RCT_UVC_FRAME_META_LOG_REMOTE", "uvc_frame_meta_log_remote=${LESAVKA_CLIENT_RCT_UVC_FRAME_META_LOG_REMOTE:-disabled}", "client_rct_uvc_frame_meta_fetch.sh", "summarize_uvc_frame_meta_log.py", "required UVC frame metadata log could not be summarized", "optional UVC frame metadata log could not be summarized", "uvc_frame_meta_summary_json", "lesavka.uvc-mjpeg-spool-summary.v1", "uvc_spool", "UVC spool boundary", "synthetic evidence", "video_age_p95_ms", "audio_age_p95_ms", "artifact_dir: ${LOCAL_REPORT_DIR}", ] { assert!( CLIENT_RCT_SCRIPT.contains(expected) || CLIENT_RCT_SUMMARY.contains(expected) || CLIENT_RCT_LAYERS.contains(expected) || UVC_FRAME_META_FETCH.contains(expected) || UVC_FRAME_META_SUMMARY.contains(expected), "client-to-RCT probe should preserve artifact/summary marker {expected}" ); } } #[test] fn client_rct_probe_keeps_shell_harness_focused_under_loc_limit() { for (name, contents) in [ ("run_client_to_rct_transport_probe.sh", CLIENT_RCT_SCRIPT), ("client_rct_uvc_frame_meta_fetch.sh", UVC_FRAME_META_FETCH), ("client_rct_transport_summary.py", CLIENT_RCT_SUMMARY), ] { let loc = contents.lines().count(); assert!( loc <= 500, "{name} should stay under the 500 LOC refactor guard; saw {loc}" ); } } #[test] fn client_rct_probe_is_non_mutating_and_passwordless_by_default() { for expected in [ "SSH_OPTS=${SSH_OPTS:-\"-o BatchMode=yes -o ConnectTimeout=5\"}", "no remote sudo/reconfigure will be attempted by this script", "LESAVKA_SERVER_ADDR=${LESAVKA_SERVER_ADDR:-auto}", "LESAVKA_CLIENT_RCT_MODE=${LESAVKA_CLIENT_RCT_MODE:-auto}", "LESAVKA_CLIENT_RCT_START_DELAY_SECONDS=${LESAVKA_CLIENT_RCT_START_DELAY_SECONDS:-0}", "LESAVKA_CLIENT_RCT_START_DELAY_SECONDS must be a non-negative number", "start_delay=${LESAVKA_CLIENT_RCT_START_DELAY_SECONDS}s", "ExitOnForwardFailure=yes", "127.0.0.1:${local_port}:127.0.0.1:${SERVER_TUNNEL_REMOTE_PORT}", ] { assert!( CLIENT_RCT_SCRIPT.contains(expected), "client-to-RCT probe should keep unattended marker {expected}" ); } for forbidden in ["sudo -S", "read -s", "PASSWORD", "VAULT", "vault"] { assert!( !CLIENT_RCT_SCRIPT.contains(forbidden) && !UVC_FRAME_META_FETCH.contains(forbidden), "client-to-RCT probe should not prompt for or retrieve secrets: {forbidden}" ); } } #[test] fn client_timeline_schema_captures_origin_and_event_timing() { for expected in [ "lesavka.client-transport-probe-timeline.v1", "client-generated", "client-post-capture-uplink-bundle", "client_uplink_included: true", "client_start_unix_ns", "client_capture_unix_ns", "planned_start_us", "planned_end_us", "marker_tick_period", "let client_start_unix_ns = capture.start_unix_ns();", "ProbeTimeline::new(camera, &schedule, config.duration, client_start_unix_ns)", ] { assert!( SYNC_PROBE_TIMELINE.contains(expected) || SYNC_PROBE_RUNNER.contains(expected), "client timeline should contain {expected}" ); } assert!( SYNC_PROBE_RUNNER.find("ProbeTimeline::new").unwrap() < SYNC_PROBE_RUNNER .rfind("run_bundled_probe_stream(") .unwrap(), "timeline should be written before bundled transport starts so origin evidence matches generated media" ); assert!( SYNC_PROBE_BUNDLED_TRANSPORT.contains("let bundled_task = tokio::spawn"), "bundled transport module should own the spawned streaming task" ); }