RPMsg inter-partition messaging
1(** Fuzz tests for the rpmsg library (wire codec and endpoint transport). *)
2
3open Crowbar
4
5let truncate s = String.sub s 0 (min (String.length s) 512)
6
7(* ── Wire codec ────────────────────────────────────────────────────────── *)
8
9let test_codec_roundtrip name src dst =
10 let info = Rpmsg.{ name; src; dst } in
11 let buf = Bytes.create Rpmsg.endpoint_info_size in
12 Wire.Codec.encode Rpmsg.endpoint_info_codec info buf 0;
13 let decoded = Wire.Codec.decode Rpmsg.endpoint_info_codec buf 0 in
14 if decoded.src <> src then fail "src mismatch";
15 if decoded.dst <> dst then fail "dst mismatch"
16
17let test_decode_crash_safety buf =
18 if String.length buf < Rpmsg.endpoint_info_size then ()
19 else
20 let b = Bytes.of_string buf in
21 let _ = Wire.Codec.decode Rpmsg.endpoint_info_codec b 0 in
22 ()
23
24(* ── Endpoint transport ────────────────────────────────────────────────── *)
25
26let test_pipe_roundtrip buf =
27 let buf = truncate buf in
28 if String.length buf = 0 then ()
29 else
30 Eio_main.run @@ fun env ->
31 Eio.Switch.run @@ fun sw ->
32 let source, sink = Eio.Process.pipe ~sw (Eio.Stdenv.process_mgr env) in
33 let ep = Rpmsg.Endpoint.of_source_sink ~source ~sink in
34 Rpmsg.Endpoint.send ep buf;
35 match Rpmsg.Endpoint.recv ep ~max_size:512 with
36 | None -> fail "expected message"
37 | Some received -> if received <> buf then fail "roundtrip mismatch"
38
39let test_max_size_message buf =
40 let max = Rpmsg.Endpoint.max_message_size in
41 let buf = String.sub buf 0 (min (String.length buf) max) in
42 if String.length buf = 0 then ()
43 else
44 Eio_main.run @@ fun env ->
45 Eio.Switch.run @@ fun sw ->
46 let source, sink = Eio.Process.pipe ~sw (Eio.Stdenv.process_mgr env) in
47 let ep = Rpmsg.Endpoint.of_source_sink ~source ~sink in
48 Rpmsg.Endpoint.send ep buf;
49 match Rpmsg.Endpoint.recv ep ~max_size:max with
50 | None -> fail "expected message"
51 | Some received ->
52 if received <> buf then fail "max size roundtrip mismatch"
53
54let test_binary_payload b1 b2 b3 b4 =
55 let buf =
56 String.init 4 (fun i ->
57 Char.chr ((match i with 0 -> b1 | 1 -> b2 | 2 -> b3 | _ -> b4) mod 256))
58 in
59 Eio_main.run @@ fun env ->
60 Eio.Switch.run @@ fun sw ->
61 let source, sink = Eio.Process.pipe ~sw (Eio.Stdenv.process_mgr env) in
62 let ep = Rpmsg.Endpoint.of_source_sink ~source ~sink in
63 Rpmsg.Endpoint.send ep buf;
64 match Rpmsg.Endpoint.recv ep ~max_size:4 with
65 | None -> fail "expected message"
66 | Some received -> if received <> buf then fail "binary roundtrip mismatch"
67
68(* ── Suite ─────────────────────────────────────────────────────────────── *)
69
70let suite =
71 ( "rpmsg",
72 [
73 (* Wire codec *)
74 test_case "codec roundtrip"
75 [ bytes; range 65536; range 65536 ]
76 test_codec_roundtrip;
77 test_case "decode crash safety" [ bytes ] test_decode_crash_safety;
78 (* Endpoint transport *)
79 test_case "pipe roundtrip" [ bytes ] test_pipe_roundtrip;
80 test_case "max size message" [ bytes ] test_max_size_message;
81 test_case "binary payload"
82 [ uint8; uint8; uint8; uint8 ]
83 test_binary_payload;
84 ] )