open OUnit (* let () = Printexc.record_backtrace true ;; *) (* S-1-1-0-1-2-3-4-5-6-7-8-9-10-11-12-13-14 *) let max_sid = Stdint.( Sid.create_unsafe [| Uint32.zero ; Uint32.one ; Uint32.of_int 2 ; Uint32.of_int 3 ; Uint32.of_int 4 ; Uint32.of_int 5 ; Uint32.of_int 6 ; Uint32.of_int 7 ; Uint32.of_int 8 ; Uint32.of_int 9 ; Uint32.of_int 10 ; Uint32.of_int 11 ; Uint32.of_int 12 ; Uint32.of_int 13 ; Uint32.of_int 14 |] Uint64.one ) let sf_parse_ok () = let s = Sid.of_string "S-1-1-0" in let z = Stdint.((Sid.create_unsafe [| Uint32.zero |] Uint64.one)) in assert_bool (Printf.sprintf "[%s] ≠ [%s]" (Sid.to_string s) (Sid.to_string z)) (Sid.equal s z); let w = Sid.WellKnown.world in assert_bool (Printf.sprintf "[%s] ≠ [well known: %s]" (Sid.to_string s) (Sid.to_string w)) (Sid.equal s w) let sf_parse_empty_fail () = assert_raises (Invalid_argument "Invalid SID: ‘’ too short to be a SID in string format") (fun () -> Sid.of_string "") let sf_parse_junk_fail () = assert_raises (Invalid_argument "Invalid SID [not a sid]: expected ‘S’ at position 0, found ‘n’") (fun () -> Sid.of_string "not a sid") let sf_parse_ia_junk_fail () = assert_raises (Invalid_argument "Invalid SID [not a sid]: expected ‘1’ at position 2, found ‘I’") (fun () -> Sid.of_string "S-I-3-3-7") let sf_parse_opt_ok () = let s = Sid.StringFmt.from_string_opt "S-1-1-0" in assert_bool "failure parsing [S-1-1-0] with option" (s <> None) let sf_parse_opt_fail () = let s = Sid.StringFmt.from_string_opt "not a sid" in assert_bool "unexpected success parsing garbage with option" (s = None) let is_error = function Error _ -> true | _ -> false let sf_parse_result_ok () = let s = Sid.StringFmt.from_string_res "S-1-1-0" in assert_bool "failure parsing [S-1-1-0] with result" (not (is_error s)) let sf_parse_result_fail () = let s = Sid.StringFmt.from_string_res "not a sid" in assert_bool "unexpected success parsing garbage with result" (is_error s) let sf_parse_long_ok () = let s = Sid.of_string "S-1-1-0-1-2-3-4-5-6-7-8-9-10-11-12-13-14" and l = max_sid in assert_bool (Printf.sprintf "[%s] ≠ [%s]" (Sid.to_string s) (Sid.to_string l)) (Sid.equal s l) let sf_parse_too_long_ok () = (* must ignore trailing subauths *) let s1 = Sid.of_string "S-1-1-0-1-2-3-4-5-6-7-8-9-10-11-12-13-14-15" and s2 = Sid.of_string "S-1-1-0-1-2-3-4-5-6-7-8-9-10-11-12-13-14-15-16-17" and l = max_sid in assert_bool (Printf.sprintf "[%s] ≠ [%s]" (Sid.to_string s1) (Sid.to_string l)) (Sid.equal s1 l); assert_bool (Printf.sprintf "[%s] ≠ [%s]" (Sid.to_string s2) (Sid.to_string l)) (Sid.equal s2 l) let pr_encode_null_ok () = let x = Sid.WellKnown.null |> Sid.PacketRep.encode |> Xxd.xxd_of_bytes ~blocklen:2 in let expect = "0101 0000 0000 0000 0000 0000" in (* vvcc iiii iiii iiii ssss ssss *) assert_equal ~msg:(Printf.sprintf "[%s] ≠ [%s]" x expect) x expect let pr_encode_all_ok () = let x = Sid.WellKnown.everyone |> Sid.PacketRep.encode |> Xxd.xxd_of_bytes ~blocklen:2 in let expect = "0101 0000 0000 0001 0000 0000" in (* vvcc iiii iiii iiii ssss ssss *) assert_equal ~msg:(Printf.sprintf "[%s] ≠ [%s]" x expect) x expect let pr_decode_all_ok () = let s = match Xxd.bytes_of_xxd "0101 0000 0000 0001 0000 0000" (* vvcc iiii iiii iiii ssss ssss *) |> Sid.PacketRep.decode with | Ok s -> s | Error e -> assert_failure (Printf.sprintf "error decoding SID: %s" e) in let w = Sid.WellKnown.world in assert_bool (Printf.sprintf "[%s] ≠ [%s]" (Sid.to_string s) (Sid.to_string w)) (Sid.equal s w) let pr_decode_version_fail () = let b = Xxd.bytes_of_xxd "0201 0000 0000 0001 0000 0000" in (* vvcc iiii iiii iiii ssss ssss *) match Sid.PacketRep.decode b with | Error e -> let expect = "input malformed: expected SID version=0x01, got 0x02" in assert_equal ~msg:(Printf.sprintf "[%s] ≠ [%s]" e expect) e expect | Ok s -> assert_failure (Printf.sprintf "malformed SID decoded unexpectedly: %s" (Sid.to_string s)) let pr_decode_sacount_fail () = let b = Xxd.bytes_of_xxd "0110 0000 0000 0001 0000 0000" in (* vvcc iiii iiii iiii ssss ssss *) match Sid.PacketRep.decode b with | Error e -> let expect = "input malformed: up to 15 subAuthority elements \ permitted, 16 specified" in assert_equal ~msg:(Printf.sprintf "[%s] ≠ [%s]" e expect) e expect | Ok s -> assert_failure (Printf.sprintf "malformed SID decoded unexpectedly: %s" (Sid.to_string s)) let pr_decode_short_fail () = let b = Xxd.bytes_of_xxd "0105 0000 0000 00" in (* vvcc iiii iiii ii…… *) match Sid.PacketRep.decode b with | Error e -> let expect = "bad input size: expected 8–68 B, got 7 B" in assert_equal ~msg:(Printf.sprintf "[%s] ≠ [%s]" e expect) e expect | Ok s -> assert_failure (Printf.sprintf "malformed SID decoded unexpectedly: %s" (Sid.to_string s)) let pr_decode_long_fail () = let r = "010e 0000 0000 0000 0100 0000 0200 0000 \ 0300 0000 0400 0000 0500 0000 0600 0000 \ 0700 0000 0800 0000 0900 0000 0a00 0000 \ 0b00 0000 0c00 0000 0d00 0000 0e00 0000 \ 0f00 0000 1000 0000" in let b = Xxd.bytes_of_xxd r in match Sid.PacketRep.decode b with | Error e -> let expect = "bad input size: expected 8–68 B, got 72 B" in assert_equal ~msg:(Printf.sprintf "[%s] ≠ [%s]" e expect) e expect | Ok s -> assert_failure (Printf.sprintf "malformed SID decoded unexpectedly: %s" (Sid.to_string s)) let pr_decode_odd_fail () = match Xxd.bytes_of_xxd "0101 0000 0000 0000 0100 0000 0200" (* vvcc iiii iiii iiii ssss ssss ssss … upper half word missing *) |> Sid.PacketRep.decode with | Error e -> let expect = "bad input size: not divisible by word length (4)" in assert_equal ~msg:(Printf.sprintf "[%s] ≠ [%s]" e expect) e expect | Ok s -> assert_failure (Printf.sprintf "malformed SID decoded unexpectedly: %s" (Sid.to_string s)) let string_format_test = "string-format-syntax" >::: [ "parse-ok" >:: sf_parse_ok ; "parse-empty-fail" >:: sf_parse_empty_fail ; "parse-junk-fail" >:: sf_parse_junk_fail ; "parse-opt-ok" >:: sf_parse_opt_ok ; "parse-opt-fail" >:: sf_parse_opt_fail ; "parse-result-ok" >:: sf_parse_result_ok ; "parse-result-fail" >:: sf_parse_result_fail ; "parse-long-ok" >:: sf_parse_long_ok ; "parse-too-long-ok" >:: sf_parse_too_long_ok ] let packet_rep_test = "packet-rep" >::: [ "encode-null-ok" >:: pr_encode_null_ok ; "encode-all-ok" >:: pr_encode_all_ok ; "decode-all-ok" >:: pr_decode_all_ok ; "decode-version-fail" >:: pr_decode_version_fail ; "decode-sacount-fail" >:: pr_decode_sacount_fail ; "decode-short-fail" >:: pr_decode_short_fail ; "decode-long-fail" >:: pr_decode_long_fail ; "decode-odd-fail" >:: pr_decode_odd_fail ] let () = ignore (run_test_tt_main string_format_test); ignore (run_test_tt_main packet_rep_test )