OCaml wire format DSL with EverParse 3D output for verified parsers
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

refactor(crowbar): Alcotest-style API with suite exports and grouped run

- Change `run` signature to `string -> (string * test_case list) list -> unit`
matching Alcotest's grouping convention
- Fix `_name` bug: pass the name through to Alcotest.run_with_args
- Each fuzz module now exports `let suite = ("name", [test_case ...])`
- Entry points (fuzz.ml) collect suites: `Crowbar.run "pkg" [Fuzz_X.suite]`
- Remove stale `add_test`/`suite` API, keep only `test_case`/`run`
- Remove `let run () = ()` from fuzz_common.ml files
- Update merlint E725 rule to match new `let suite = ("name", ...)` pattern
- Update E725 test fixtures and expected output

+92 -91
+53 -59
fuzz/fuzz_wire.ml
··· 350 350 let _ = decode_record_from_string test_record_codec buf in 351 351 () 352 352 353 - let () = 354 - (* Pretty-printing tests *) 355 - Cr.add_test ~name:"wire: pp_typ uint8" [ Cr.const () ] test_pp_uint8; 356 - Cr.add_test ~name:"wire: pp_typ uint16" [ Cr.const () ] test_pp_uint16; 357 - Cr.add_test ~name:"wire: pp_typ uint32" [ Cr.const () ] test_pp_uint32; 358 - Cr.add_test ~name:"wire: pp_bitfield" [ Cr.range 33 ] test_pp_bitfield; 359 - Cr.add_test ~name:"wire: pp_module_simple" 360 - [ Cr.const () ] 361 - test_pp_module_simple; 362 - Cr.add_test ~name:"wire: struct_random_fields" 363 - [ Cr.range 100 ] 364 - test_struct_random_fields; 365 - Cr.add_test ~name:"wire: enum_random_cases" 366 - [ Cr.range 100 ] 367 - test_enum_random_cases; 368 - Cr.add_test ~name:"wire: casetype_random" 369 - [ Cr.range 100 ] 370 - test_casetype_random; 371 - Cr.add_test ~name:"wire: constraint_expr" [ Cr.int ] test_constraint_expr; 372 - Cr.add_test ~name:"wire: bitfield_constraint" 373 - [ Cr.range 32 ] 374 - test_bitfield_constraint; 375 - Cr.add_test ~name:"wire: array_type" [ Cr.int ] test_array_type; 376 - Cr.add_test ~name:"wire: byte_array" [ Cr.int ] test_byte_array; 377 - Cr.add_test ~name:"wire: param_struct" [ Cr.range 20 ] test_param_struct; 378 - Cr.add_test ~name:"wire: action" [ Cr.const () ] test_action; 379 - Cr.add_test ~name:"wire: complex_nested" [ Cr.const () ] test_complex_nested; 380 - 381 - (* Parsing tests *) 382 - Cr.add_test ~name:"wire: parse uint8" [ Cr.bytes ] test_parse_uint8; 383 - Cr.add_test ~name:"wire: parse uint16" [ Cr.bytes ] test_parse_uint16; 384 - Cr.add_test ~name:"wire: parse uint32" [ Cr.bytes ] test_parse_uint32; 385 - Cr.add_test ~name:"wire: parse uint64" [ Cr.bytes ] test_parse_uint64; 386 - Cr.add_test ~name:"wire: parse bitfield" [ Cr.bytes ] test_parse_bitfield; 387 - Cr.add_test ~name:"wire: parse array" [ Cr.bytes ] test_parse_array; 388 - Cr.add_test ~name:"wire: parse byte_array" [ Cr.bytes ] test_parse_byte_array; 389 - Cr.add_test ~name:"wire: parse enum" [ Cr.bytes ] test_parse_enum; 390 - Cr.add_test ~name:"wire: parse where" [ Cr.bytes ] test_parse_where; 391 - Cr.add_test ~name:"wire: parse all_bytes" [ Cr.bytes ] test_parse_all_bytes; 392 - Cr.add_test ~name:"wire: parse all_zeros" [ Cr.bytes ] test_parse_all_zeros; 393 - Cr.add_test ~name:"wire: parse struct" [ Cr.bytes ] test_parse_struct; 394 - Cr.add_test ~name:"wire: parse struct_constrained" [ Cr.bytes ] 395 - test_parse_struct_constrained; 396 - 397 - (* Roundtrip tests *) 398 - Cr.add_test ~name:"wire: roundtrip uint8" [ Cr.int ] test_roundtrip_uint8; 399 - Cr.add_test ~name:"wire: roundtrip uint16" [ Cr.int ] test_roundtrip_uint16; 400 - Cr.add_test ~name:"wire: roundtrip uint32" [ Cr.int ] test_roundtrip_uint32; 401 - Cr.add_test ~name:"wire: roundtrip uint64" [ Cr.int64 ] test_roundtrip_uint64; 402 - Cr.add_test ~name:"wire: roundtrip array" [ Cr.int; Cr.int; Cr.int ] 403 - test_roundtrip_array; 404 - Cr.add_test ~name:"wire: roundtrip byte_array" [ Cr.bytes ] 405 - test_roundtrip_byte_array; 406 - Cr.add_test ~name:"wire: roundtrip enum" [ Cr.int ] test_roundtrip_enum; 353 + let suite = 354 + ( "wire", 355 + [ 356 + (* Pretty-printing tests *) 357 + Cr.test_case "pp_typ uint8" [ Cr.const () ] test_pp_uint8; 358 + Cr.test_case "pp_typ uint16" [ Cr.const () ] test_pp_uint16; 359 + Cr.test_case "pp_typ uint32" [ Cr.const () ] test_pp_uint32; 360 + Cr.test_case "pp_bitfield" [ Cr.range 33 ] test_pp_bitfield; 361 + Cr.test_case "pp_module_simple" [ Cr.const () ] test_pp_module_simple; 362 + Cr.test_case "struct_random_fields" 363 + [ Cr.range 100 ] 364 + test_struct_random_fields; 365 + Cr.test_case "enum_random_cases" [ Cr.range 100 ] test_enum_random_cases; 366 + Cr.test_case "casetype_random" [ Cr.range 100 ] test_casetype_random; 367 + Cr.test_case "constraint_expr" [ Cr.int ] test_constraint_expr; 368 + Cr.test_case "bitfield_constraint" 369 + [ Cr.range 32 ] 370 + test_bitfield_constraint; 371 + Cr.test_case "array_type" [ Cr.int ] test_array_type; 372 + Cr.test_case "byte_array" [ Cr.int ] test_byte_array; 373 + Cr.test_case "param_struct" [ Cr.range 20 ] test_param_struct; 374 + Cr.test_case "action" [ Cr.const () ] test_action; 375 + Cr.test_case "complex_nested" [ Cr.const () ] test_complex_nested; 376 + (* Parsing tests *) 377 + Cr.test_case "parse uint8" [ Cr.bytes ] test_parse_uint8; 378 + Cr.test_case "parse uint16" [ Cr.bytes ] test_parse_uint16; 379 + Cr.test_case "parse uint32" [ Cr.bytes ] test_parse_uint32; 380 + Cr.test_case "parse uint64" [ Cr.bytes ] test_parse_uint64; 381 + Cr.test_case "parse bitfield" [ Cr.bytes ] test_parse_bitfield; 382 + Cr.test_case "parse array" [ Cr.bytes ] test_parse_array; 383 + Cr.test_case "parse byte_array" [ Cr.bytes ] test_parse_byte_array; 384 + Cr.test_case "parse enum" [ Cr.bytes ] test_parse_enum; 385 + Cr.test_case "parse where" [ Cr.bytes ] test_parse_where; 386 + Cr.test_case "parse all_bytes" [ Cr.bytes ] test_parse_all_bytes; 387 + Cr.test_case "parse all_zeros" [ Cr.bytes ] test_parse_all_zeros; 388 + Cr.test_case "parse struct" [ Cr.bytes ] test_parse_struct; 389 + Cr.test_case "parse struct_constrained" [ Cr.bytes ] 390 + test_parse_struct_constrained; 391 + (* Roundtrip tests *) 392 + Cr.test_case "roundtrip uint8" [ Cr.int ] test_roundtrip_uint8; 393 + Cr.test_case "roundtrip uint16" [ Cr.int ] test_roundtrip_uint16; 394 + Cr.test_case "roundtrip uint32" [ Cr.int ] test_roundtrip_uint32; 395 + Cr.test_case "roundtrip uint64" [ Cr.int64 ] test_roundtrip_uint64; 396 + Cr.test_case "roundtrip array" [ Cr.int; Cr.int; Cr.int ] 397 + test_roundtrip_array; 398 + Cr.test_case "roundtrip byte_array" [ Cr.bytes ] test_roundtrip_byte_array; 399 + Cr.test_case "roundtrip enum" [ Cr.int ] test_roundtrip_enum; 400 + (* Record codec tests *) 401 + Cr.test_case "record roundtrip" [ Cr.int; Cr.int; Cr.int ] 402 + test_record_roundtrip; 403 + Cr.test_case "record decode crash" [ Cr.bytes ] test_record_decode_crash; 404 + ] ) 407 405 408 - (* Record codec tests *) 409 - Cr.add_test ~name:"wire: record roundtrip" [ Cr.int; Cr.int; Cr.int ] 410 - test_record_roundtrip; 411 - Cr.add_test ~name:"wire: record decode crash" [ Cr.bytes ] 412 - test_record_decode_crash 406 + let () = Cr.run "wire" [ suite ]
+27 -23
test/diff/fuzz_diff.ml
··· 295 295 let sub = { ic; oc } in 296 296 297 297 (* Stage 2: register Crowbar tests *) 298 - List.iteri 299 - (fun idx rs -> 300 - let name = Wire.struct_name rs.struct_ in 301 - Cr.add_test ~name:(name ^ " fuzz-diff") [ Cr.bytes ] (fun buf -> 302 - let buf = pad rs.wire_size buf in 303 - let ocaml_result = Wire_diff.Diff.roundtrip_struct rs.struct_ buf in 304 - let c_result = c_roundtrip sub idx buf in 305 - match (ocaml_result, c_result) with 306 - | Ok ocaml_bytes, Some c_bytes -> 307 - if ocaml_bytes <> c_bytes then 308 - Cr.fail 309 - (Fmt.str "%s: roundtrip mismatch (ocaml=%d bytes, c=%d bytes)" 310 - name 311 - (String.length ocaml_bytes) 312 - (String.length c_bytes)) 313 - | Error _, None -> () 314 - | Ok _, None -> 315 - Cr.fail (Fmt.str "%s: OCaml succeeded but C failed" name) 316 - | Error e, Some _ -> 317 - Cr.fail 318 - (Fmt.str "%s: C succeeded but OCaml failed: %a" name 319 - Wire.pp_parse_error e))) 320 - schemas 298 + Cr.run "diff" 299 + (List.mapi 300 + (fun idx rs -> 301 + let name = Wire.struct_name rs.struct_ in 302 + Cr.test_case (name ^ " fuzz-diff") [ Cr.bytes ] (fun buf -> 303 + let buf = pad rs.wire_size buf in 304 + let ocaml_result = 305 + Wire_diff.Diff.roundtrip_struct rs.struct_ buf 306 + in 307 + let c_result = c_roundtrip sub idx buf in 308 + match (ocaml_result, c_result) with 309 + | Ok ocaml_bytes, Some c_bytes -> 310 + if ocaml_bytes <> c_bytes then 311 + Cr.fail 312 + (Fmt.str 313 + "%s: roundtrip mismatch (ocaml=%d bytes, c=%d bytes)" 314 + name 315 + (String.length ocaml_bytes) 316 + (String.length c_bytes)) 317 + | Error _, None -> () 318 + | Ok _, None -> 319 + Cr.fail (Fmt.str "%s: OCaml succeeded but C failed" name) 320 + | Error e, Some _ -> 321 + Cr.fail 322 + (Fmt.str "%s: C succeeded but OCaml failed: %a" name 323 + Wire.pp_parse_error e))) 324 + schemas)
+12 -9
test/diff/test_diff.ml
··· 28 28 Cr.fail (Printf.sprintf "%s: only OCaml succeeded: %s" name msg) 29 29 30 30 let () = 31 - List.iter 32 - (fun (t : D.packed_test) -> 33 - Cr.add_test ~name:(t.name ^ " read") [ Cr.bytes ] (fun buf -> 34 - check t.name (t.test_read (truncate buf))); 35 - Cr.add_test ~name:(t.name ^ " write") [ Cr.bytes ] (fun buf -> 36 - check t.name (t.test_write (pad t.wire_size buf))); 37 - Cr.add_test ~name:(t.name ^ " roundtrip") [ Cr.bytes ] (fun buf -> 38 - check t.name (t.test_roundtrip (pad t.wire_size buf)))) 39 - All_schemas.all 31 + Cr.run "diff" 32 + (List.concat_map 33 + (fun (t : D.packed_test) -> 34 + [ 35 + Cr.test_case (t.name ^ " read") [ Cr.bytes ] (fun buf -> 36 + check t.name (t.test_read (truncate buf))); 37 + Cr.test_case (t.name ^ " write") [ Cr.bytes ] (fun buf -> 38 + check t.name (t.test_write (pad t.wire_size buf))); 39 + Cr.test_case (t.name ^ " roundtrip") [ Cr.bytes ] (fun buf -> 40 + check t.name (t.test_roundtrip (pad t.wire_size buf))); 41 + ]) 42 + All_schemas.all)