(** Fuzz tests for the rpmsg library (wire codec and endpoint transport). *) open Crowbar let truncate s = String.sub s 0 (min (String.length s) 512) (* ── Wire codec ────────────────────────────────────────────────────────── *) let test_codec_roundtrip name src dst = let info = Rpmsg.{ name; src; dst } in let buf = Bytes.create Rpmsg.endpoint_info_size in Wire.Codec.encode Rpmsg.endpoint_info_codec info buf 0; let decoded = Wire.Codec.decode Rpmsg.endpoint_info_codec buf 0 in if decoded.src <> src then fail "src mismatch"; if decoded.dst <> dst then fail "dst mismatch" let test_decode_crash_safety buf = if String.length buf < Rpmsg.endpoint_info_size then () else let b = Bytes.of_string buf in let _ = Wire.Codec.decode Rpmsg.endpoint_info_codec b 0 in () (* ── Endpoint transport ────────────────────────────────────────────────── *) let test_pipe_roundtrip buf = let buf = truncate buf in if String.length buf = 0 then () else Eio_main.run @@ fun env -> Eio.Switch.run @@ fun sw -> let source, sink = Eio.Process.pipe ~sw (Eio.Stdenv.process_mgr env) in let ep = Rpmsg.Endpoint.of_source_sink ~source ~sink in Rpmsg.Endpoint.send ep buf; match Rpmsg.Endpoint.recv ep ~max_size:512 with | None -> fail "expected message" | Some received -> if received <> buf then fail "roundtrip mismatch" let test_max_size_message buf = let max = Rpmsg.Endpoint.max_message_size in let buf = String.sub buf 0 (min (String.length buf) max) in if String.length buf = 0 then () else Eio_main.run @@ fun env -> Eio.Switch.run @@ fun sw -> let source, sink = Eio.Process.pipe ~sw (Eio.Stdenv.process_mgr env) in let ep = Rpmsg.Endpoint.of_source_sink ~source ~sink in Rpmsg.Endpoint.send ep buf; match Rpmsg.Endpoint.recv ep ~max_size:max with | None -> fail "expected message" | Some received -> if received <> buf then fail "max size roundtrip mismatch" let test_binary_payload b1 b2 b3 b4 = let buf = String.init 4 (fun i -> Char.chr ((match i with 0 -> b1 | 1 -> b2 | 2 -> b3 | _ -> b4) mod 256)) in Eio_main.run @@ fun env -> Eio.Switch.run @@ fun sw -> let source, sink = Eio.Process.pipe ~sw (Eio.Stdenv.process_mgr env) in let ep = Rpmsg.Endpoint.of_source_sink ~source ~sink in Rpmsg.Endpoint.send ep buf; match Rpmsg.Endpoint.recv ep ~max_size:4 with | None -> fail "expected message" | Some received -> if received <> buf then fail "binary roundtrip mismatch" (* ── Suite ─────────────────────────────────────────────────────────────── *) let suite = ( "rpmsg", [ (* Wire codec *) test_case "codec roundtrip" [ bytes; range 65536; range 65536 ] test_codec_roundtrip; test_case "decode crash safety" [ bytes ] test_decode_crash_safety; (* Endpoint transport *) test_case "pipe roundtrip" [ bytes ] test_pipe_roundtrip; test_case "max size message" [ bytes ] test_max_size_message; test_case "binary payload" [ uint8; uint8; uint8; uint8 ] test_binary_payload; ] )