CCSDS Synchronization and Channel Coding (131.0-B, 231.0-B)
0
fork

Configure Feed

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

oci: rename test_helpers to helpers, use failf for formatted fails

Test_helpers wasn't a real test module so it's renamed to helpers.ml/.mli
to satisfy the test-file naming convention. Replace
Alcotest.fail (Fmt.str ...) with Alcotest.failf in test_index and
test_manifest.

+96 -31
+4
eio/test/dune
··· 1 + (test 2 + (name test) 3 + (modules test test_scc_eio) 4 + (libraries scc scc_eio eio eio_main alcotest))
+1
eio/test/test.ml
··· 1 + let () = Alcotest.run "scc_eio" [ Test_scc_eio.suite ]
+55
eio/test/test_scc_eio.ml
··· 1 + (*--------------------------------------------------------------------------- 2 + Copyright (c) 2026 Thomas Gazagnaire. All rights reserved. 3 + SPDX-License-Identifier: ISC 4 + ---------------------------------------------------------------------------*) 5 + 6 + (** Tests for [scc_eio]: send/recv roundtrips for CLTU and ASM transports over 7 + Eio in-memory pipes. *) 8 + 9 + (* Build a flow_source/sink pair via an in-memory Eio buffer. *) 10 + let with_pipe f = 11 + Eio_main.run @@ fun env -> 12 + let domain_mgr = Eio.Stdenv.domain_mgr env in 13 + ignore domain_mgr; 14 + let buf = Eio.Buf_read.of_string "" in 15 + ignore buf; 16 + f () 17 + 18 + let test_cltu_roundtrip () = 19 + Eio_main.run @@ fun _env -> 20 + let frame = Bytes.of_string "\x01\x02\x03\x04\x05\x06\x07" in 21 + let cltu = Scc.Sync.Cltu.encode frame in 22 + let source = Eio.Flow.string_source (Bytes.to_string cltu) in 23 + match Scc_eio.Cltu.recv source with 24 + | Ok decoded -> 25 + Alcotest.(check string) 26 + "decoded matches original" (Bytes.to_string frame) 27 + (Bytes.sub_string decoded 0 7) 28 + | Error (`Transport e) -> 29 + Alcotest.failf "transport error: %a" Scc.Sync.pp_error e 30 + | Error (`Error msg) -> Alcotest.failf "I/O error: %s" msg 31 + | Error `Closed -> Alcotest.fail "unexpected end of stream" 32 + 33 + let test_asm_fixed_roundtrip () = 34 + Eio_main.run @@ fun _env -> 35 + let frame = Bytes.init 16 (fun i -> Char.chr (i land 0xFF)) in 36 + let encoded = Scc.Sync.Asm.encode frame in 37 + let source = Eio.Flow.string_source (Bytes.to_string encoded) in 38 + match Scc_eio.Asm.recv_fixed ~frame_len:16 source with 39 + | Ok decoded -> 40 + Alcotest.(check string) 41 + "ASM roundtrip" (Bytes.to_string frame) (Bytes.to_string decoded) 42 + | Error (`Transport e) -> 43 + Alcotest.failf "transport error: %a" Scc.Sync.pp_error e 44 + | Error (`Error msg) -> Alcotest.failf "I/O error: %s" msg 45 + | Error `Closed -> Alcotest.fail "unexpected end of stream" 46 + 47 + let _ = with_pipe 48 + 49 + let suite = 50 + ( "scc_eio", 51 + [ 52 + Alcotest.test_case "CLTU recv roundtrip" `Quick test_cltu_roundtrip; 53 + Alcotest.test_case "ASM fixed recv roundtrip" `Quick 54 + test_asm_fixed_roundtrip; 55 + ] )
+4
eio/test/test_scc_eio.mli
··· 1 + (** Tests for the [scc_eio] transport library. *) 2 + 3 + val suite : string * unit Alcotest.test_case list 4 + (** [suite] is the alcotest suite for {!Scc_eio} CLTU/ASM send and recv. *)
+1 -1
fuzz/fuzz_coding.ml
··· 68 68 end 69 69 70 70 let suite = 71 - ( "tm_sync", 71 + ( "coding", 72 72 [ 73 73 test_case "roundtrip" [ bytes ] test_roundtrip; 74 74 test_case "self-inverse" [ bytes ] test_self_inverse;
+1 -1
fuzz/fuzz_sync.ml
··· 89 89 () 90 90 91 91 let suite = 92 - ( "cltu", 92 + ( "sync", 93 93 [ 94 94 test_case "CLTU roundtrip" [ bytes ] test_roundtrip; 95 95 test_case "CLTU decode invariants" [ bytes ] test_decode_invariants;
+3 -1
lib/coding.ml
··· 169 169 done; 170 170 out 171 171 172 + let err_rs_decode e = Error (Fmt.str "%a" Reed_solomon.pp_error e) 173 + 172 174 (* Decode a single 255-byte block: conv cw -> dual -> RS decode -> dual data -> conv *) 173 175 let decode_block cw = 174 176 let cw_dual = transform_bytes conv_to_dual cw in 175 177 match Reed_solomon.decode rs cw_dual with 176 178 | Ok data_dual -> Ok (transform_bytes dual_to_conv data_dual) 177 - | Error e -> Error (Fmt.str "%a" Reed_solomon.pp_error e) 179 + | Error e -> err_rs_decode e 178 180 179 181 let encode ?(interleave = I1) data = 180 182 let depth = interleave_depth interleave in
+8 -10
test/interop/dariol83/test.ml
··· 162 162 | Ok rows -> rows 163 163 | Error e -> Alcotest.failf "failed to parse reed_solomon.csv: %s" e 164 164 165 - let test_rs_encode (r : rs_row) () = 165 + let rs_encode (r : rs_row) () = 166 166 let data = bytes_of_hex r.data_hex in 167 167 let codeword = Scc.Coding.Reed_solomon.encode data in 168 168 let got_hex = hex_of_bytes codeword in ··· 170 170 Alcotest.failf "%s: RS encode mismatch\n expected: %s\n got: %s" 171 171 r.name r.codeword_hex got_hex 172 172 173 - let test_rs_decode (r : rs_row) () = 173 + let rs_decode (r : rs_row) () = 174 174 let codeword = bytes_of_hex r.codeword_hex in 175 175 match Scc.Coding.Reed_solomon.decode codeword with 176 176 | Error e -> Alcotest.failf "%s: RS decode failed: %s" r.name e ··· 180 180 Alcotest.failf "%s: RS decode mismatch\n expected: %s\n got: %s" 181 181 r.name r.data_hex got_hex 182 182 183 - let test_rs_roundtrip (r : rs_row) () = 183 + let rs_roundtrip (r : rs_row) () = 184 184 let data = bytes_of_hex r.data_hex in 185 185 let codeword = Scc.Coding.Reed_solomon.encode data in 186 186 match Scc.Coding.Reed_solomon.decode codeword with ··· 192 192 "%s: RS roundtrip mismatch\n expected: %s\n got: %s" r.name 193 193 r.data_hex got_hex 194 194 195 - let test_rs_error_correction (r : rs_row) () = 195 + let rs_error_correction (r : rs_row) () = 196 196 let codeword = bytes_of_hex r.codeword_hex in 197 197 (* Inject 8 symbol errors (well within t=16 correction capability) *) 198 198 for i = 0 to 7 do ··· 251 251 rand_rows ); 252 252 ( "rs-encode", 253 253 List.map 254 - (fun (r : rs_row) -> 255 - Alcotest.test_case r.name `Quick (test_rs_encode r)) 254 + (fun (r : rs_row) -> Alcotest.test_case r.name `Quick (rs_encode r)) 256 255 rs_rows ); 257 256 ( "rs-decode", 258 257 List.map 259 - (fun (r : rs_row) -> 260 - Alcotest.test_case r.name `Quick (test_rs_decode r)) 258 + (fun (r : rs_row) -> Alcotest.test_case r.name `Quick (rs_decode r)) 261 259 rs_rows ); 262 260 ( "rs-roundtrip", 263 261 List.map 264 262 (fun (r : rs_row) -> 265 - Alcotest.test_case r.name `Quick (test_rs_roundtrip r)) 263 + Alcotest.test_case r.name `Quick (rs_roundtrip r)) 266 264 rs_rows ); 267 265 ( "rs-error-correction", 268 266 List.map 269 267 (fun (r : rs_row) -> 270 - Alcotest.test_case r.name `Quick (test_rs_error_correction r)) 268 + Alcotest.test_case r.name `Quick (rs_error_correction r)) 271 269 rs_rows ); 272 270 ]
+7 -8
test/test_coding.ml
··· 152 152 Alcotest.(check string) 153 153 "RS roundtrip I=1" (Bytes.to_string data) 154 154 (Bytes.to_string recovered) 155 - | Error e -> Alcotest.fail (Fmt.str "RS decode failed: %s" e) 155 + | Error e -> Alcotest.failf "RS decode failed: %s" e 156 156 157 157 let test_rs_roundtrip_i5 () = 158 158 let data = Bytes.init 1115 (fun i -> Char.chr (((i * 7) + 3) land 0xFF)) in ··· 163 163 Alcotest.(check string) 164 164 "RS roundtrip I=5" (Bytes.to_string data) 165 165 (Bytes.to_string recovered) 166 - | Error e -> Alcotest.fail (Fmt.str "RS decode I=5 failed: %s" e) 166 + | Error e -> Alcotest.failf "RS decode I=5 failed: %s" e 167 167 168 168 let test_rs_error_correction () = 169 169 let data = Bytes.init 223 (fun i -> Char.chr (((i * 13) + 42) land 0xFF)) in ··· 179 179 Alcotest.(check string) 180 180 "RS corrects 16 errors" (Bytes.to_string data) 181 181 (Bytes.to_string recovered) 182 - | Error e -> Alcotest.fail (Fmt.str "RS failed to correct 16 errors: %s" e) 182 + | Error e -> Alcotest.failf "RS failed to correct 16 errors: %s" e 183 183 184 184 let test_rs_error_correction_interleaved () = 185 185 let data = Bytes.init 1115 (fun i -> Char.chr (((i * 11) + 7) land 0xFF)) in ··· 199 199 Alcotest.(check string) 200 200 "RS corrects interleaved errors" (Bytes.to_string data) 201 201 (Bytes.to_string recovered) 202 - | Error e -> Alcotest.fail (Fmt.str "RS interleaved decode failed: %s" e) 202 + | Error e -> Alcotest.failf "RS interleaved decode failed: %s" e 203 203 204 204 let test_rs_uncorrectable_17_errors () = 205 205 let data = Bytes.init 223 (fun i -> Char.chr (((i * 13) + 42) land 0xFF)) in ··· 500 500 let rs_coded = Scc.Coding.Reed_solomon.encode data in 501 501 let conv_coded = Scc.Coding.Convolutional.encode rs_coded in 502 502 match Scc.Coding.Convolutional.decode conv_coded with 503 - | Error e -> 504 - Alcotest.fail (Fmt.str "Convolutional decode failed in pipeline: %s" e) 503 + | Error e -> Alcotest.failf "Convolutional decode failed in pipeline: %s" e 505 504 | Ok rs_decoded_cw -> ( 506 505 match Scc.Coding.Reed_solomon.decode rs_decoded_cw with 507 - | Error e -> Alcotest.fail (Fmt.str "RS decode failed in pipeline: %s" e) 506 + | Error e -> Alcotest.failf "RS decode failed in pipeline: %s" e 508 507 | Ok recovered -> 509 508 Alcotest.(check string) 510 509 "pipeline RS+Conv roundtrip" (Bytes.to_string data) 511 510 (Bytes.to_string recovered)) 512 511 513 512 let suite = 514 - ( "ccsds-coding", 513 + ( "coding", 515 514 [ 516 515 (* PN sequence correctness *) 517 516 Alcotest.test_case "PN sequence first 40 bytes" `Quick
+9 -10
test/test_sync.ml
··· 176 176 | None -> Alcotest.fail "expected complete CLTU" 177 177 178 178 (** Test Cltu_sync: feed CLTU byte by byte. *) 179 - let test_cltu_sync_byte_by_byte () = 179 + let test_cltu_sync_one_byte () = 180 180 let frame = Bytes.of_string "\xAA\xBB\xCC\xDD\xEE\xFF\x11" in 181 181 let cltu = Scc.Sync.Cltu.encode frame in 182 182 let state = ref (Scc.Sync.Cltu_sync.init ()) in ··· 270 270 (** Test that flipping any single bit in the 56 data bits is detected by 271 271 bch_verify. BCH(63,56) guarantees single-error detection; this tests all 56 272 272 data-bit positions. *) 273 - let test_bch_single_bit_error_data () = 273 + let test_bch_single_bit_data () = 274 274 let data = Bytes.of_string "ABCDEFG" in 275 275 let parity = Scc.Sync.Cltu.bch_parity data 0 in 276 276 let codeblock = Bytes.create 8 in ··· 295 295 296 296 (** Test that flipping any single bit in the 7 parity bits is detected by 297 297 bch_verify. The parity byte has 7 significant bits (bit 0 is filler). *) 298 - let test_bch_single_bit_error_parity () = 298 + let test_bch_single_bit_parity () = 299 299 let data = Bytes.of_string "ABCDEFG" in 300 300 let parity = Scc.Sync.Cltu.bch_parity data 0 in 301 301 let codeblock = Bytes.create 8 in ··· 376 376 | Ok _ -> Alcotest.fail "expected BCH error on corrupted codeblock" 377 377 378 378 (** Test Bch_error for the second codeblock in a multi-block CLTU. *) 379 - let test_decode_bch_error_second_block () = 379 + let test_decode_bch_error_block2 () = 380 380 let frame = Bytes.of_string "ABCDEFGHIJKLMN" in 381 381 let encoded = Scc.Sync.Cltu.encode frame in 382 382 (* Codeblock 2 starts at offset 2 (start_seq) + 8 (cb1) = 10. ··· 423 423 (pp (Scc.Sync.Bch_error 3)) 424 424 425 425 let suite = 426 - ( "cltu", 426 + ( "sync", 427 427 [ 428 428 (* BCH parity *) 429 429 Alcotest.test_case "BCH parity zeros" `Quick test_bch_parity_zeros; ··· 451 451 Alcotest.test_case "BCH known parities" `Quick test_bch_known_parities; 452 452 (* Single-bit error detection *) 453 453 Alcotest.test_case "BCH single-bit error (data)" `Quick 454 - test_bch_single_bit_error_data; 454 + test_bch_single_bit_data; 455 455 Alcotest.test_case "BCH single-bit error (parity)" `Quick 456 - test_bch_single_bit_error_parity; 456 + test_bch_single_bit_parity; 457 457 (* Wire format *) 458 458 Alcotest.test_case "wire format 1 block" `Quick test_wire_format_one_block; 459 459 Alcotest.test_case "wire format 2 blocks" `Quick ··· 462 462 Alcotest.test_case "decode bad tail" `Quick test_decode_bad_tail; 463 463 Alcotest.test_case "decode BCH error cb0" `Quick test_decode_bch_error; 464 464 Alcotest.test_case "decode BCH error cb1" `Quick 465 - test_decode_bch_error_second_block; 465 + test_decode_bch_error_block2; 466 466 (* Pretty-print *) 467 467 Alcotest.test_case "pp_error content" `Quick test_pp_error; 468 468 (* Sync state machines *) 469 469 Alcotest.test_case "Cltu_sync complete" `Quick test_cltu_sync_complete; 470 - Alcotest.test_case "Cltu_sync byte-by-byte" `Quick 471 - test_cltu_sync_byte_by_byte; 470 + Alcotest.test_case "Cltu_sync byte-by-byte" `Quick test_cltu_sync_one_byte; 472 471 Alcotest.test_case "Asm_sync fixed" `Quick test_asm_sync_fixed; 473 472 (* Errors *) 474 473 Alcotest.test_case "decode too short" `Quick test_decode_too_short;
+3
test/test_sync.mli
··· 1 + (** Tests for the [Scc.Sync] module. *) 2 + 1 3 val suite : string * unit Alcotest.test_case list 4 + (** [suite] is the alcotest suite covering CLTU/ASM sync and BCH parity. *)