module Pure = Mirage_kv_mem.Pure let compare_t = let module M = Pure in (module M: Alcotest.TESTABLE with type t = Pure.t) let we = let module M = struct type t = Mirage_kv_mem.write_error let pp = Mirage_kv_mem.pp_write_error let equal a b = compare a b = 0 end in (module M: Alcotest.TESTABLE with type t = M.t) let compare_write_res = Alcotest.result compare_t we let e = let module M = struct type t = Mirage_kv.error let pp = Mirage_kv.pp_error let equal a b = compare a b = 0 end in (module M: Alcotest.TESTABLE with type t = M.t) let compare_read_res = Alcotest.result Alcotest.string e let key_test = let module M = struct type t = Mirage_kv.Key.t let pp = Mirage_kv.Key.pp let equal = Mirage_kv.Key.equal end in (module M: Alcotest.TESTABLE with type t = M.t) let int63_test = let module M = struct type t = Optint.Int63.t let pp = Optint.Int63.pp let equal = Optint.Int63.equal end in (module M: Alcotest.TESTABLE with type t = M.t) let now = Ptime.epoch let bc = "bc" let neu = "NEU" let add k v m = match Pure.set m k now v with | Error _ -> assert false | Ok m -> m let empty_m = Pure.empty now () let key_of_str = Mirage_kv.Key.v let key_a = key_of_str "a" let map = add key_a bc empty_m let empty () = let expected = empty_m in Alcotest.check compare_t "hello" expected (Pure.empty now ()) let read () = let expected = Ok bc in Alcotest.check compare_read_res "hello" expected (Pure.get map key_a) let read_partial () = Alcotest.check compare_read_res "hello" (Ok "bc") (Pure.get_partial map key_a ~offset:(Optint.Int63.of_int 0) ~length:2); Alcotest.check compare_read_res "hello" (Ok "c") (Pure.get_partial map key_a ~offset:(Optint.Int63.of_int 1) ~length:1); Alcotest.check compare_read_res "hello" (Ok "b") (Pure.get_partial map key_a ~offset:(Optint.Int63.of_int 0) ~length:1); Alcotest.check compare_read_res "hello" (Ok "") (Pure.get_partial map key_a ~offset:(Optint.Int63.of_int 3) ~length:1); Alcotest.check compare_read_res "hello" (Ok "c") (Pure.get_partial map key_a ~offset:(Optint.Int63.of_int 1) ~length:4) let destroy () = let expected = empty_m in Alcotest.check compare_write_res "hello" (Ok expected) (Pure.remove map key_a now) type node = [ `Value | `Dictionary ] let pp_node ppf = function | `Value -> Fmt.string ppf "value" | `Dictionary -> Fmt.string ppf "dictionary" let equal_node a b = match a, b with | `Value, `Value | `Dictionary, `Dictionary -> true | _ -> false let list () = let map_of_three = add (key_of_str "b") "" (add (key_of_str "c") "" map) in let expected = Ok [ (key_of_str "a", `Value) ; (key_of_str "b", `Value) ; (key_of_str "c", `Value) ] in Alcotest.check Alcotest.(result (slist (pair key_test (testable pp_node equal_node)) compare) e) "hello" expected (Pure.list map_of_three Mirage_kv.Key.empty) let write () = let expected = Ok (add key_a bc empty_m) in Alcotest.check compare_write_res "hello" expected (Pure.set empty_m key_a now bc) let write_partial () = let expected = Ok (add key_a bc empty_m) in Alcotest.check compare_write_res __LOC__ expected (Pure.set_partial empty_m key_a now ~offset:(Optint.Int63.of_int 1) bc); Alcotest.check compare_write_res __LOC__ expected (Pure.set_partial empty_m key_a now ~offset:(Optint.Int63.of_int 2) bc); match Pure.set empty_m key_a now bc with | Error _ -> Alcotest.fail "unexpected set result" | Ok m -> let exp = Ok (add key_a "bbc" empty_m) in Alcotest.check compare_write_res __LOC__ exp (Pure.set_partial m key_a now ~offset:(Optint.Int63.of_int 1) bc); let exp = Ok (add key_a "bcbc" empty_m) in Alcotest.check compare_write_res __LOC__ exp (Pure.set_partial m key_a now ~offset:(Optint.Int63.of_int 2) bc); Alcotest.check compare_write_res __LOC__ exp (Pure.set_partial m key_a now ~offset:(Optint.Int63.of_int 10) bc) let write_multiple () = let expected = Ok (add key_a bc (add (key_of_str "b") bc empty_m)) in match Pure.set empty_m (key_of_str "b") now bc with | Ok m -> Alcotest.check compare_write_res "hello" expected (Pure.set m key_a now bc) | Error _ -> Alcotest.fail "Unexpected map write result" let size () = let size = Pure.size map key_a in Alcotest.(check (result int63_test e) __LOC__ (Ok (Optint.Int63.of_int 2)) size) let rename () = let expected = Ok (add key_a bc empty_m) in match Pure.set empty_m (key_of_str "b") now bc with | Ok m -> Alcotest.check compare_write_res "hello" expected (Pure.rename m ~source:(key_of_str "b") ~dest:key_a now) | Error _ -> Alcotest.fail "Unexpected map write result" let rename_replace () = let expected = Ok (add key_a bc empty_m) in match Pure.set empty_m (key_of_str "b") now bc with | Error _ -> Alcotest.fail "Unexpected map write result" | Ok m -> match Pure.set m (key_of_str "a") now neu with | Error _ -> Alcotest.fail "Unexpected map write result" | Ok m -> Alcotest.check compare_write_res "hello" expected (Pure.rename m ~source:(key_of_str "b") ~dest:key_a now) let rename_value_to_dict () = let expected = Ok (add (key_of_str "a/b") bc (add (key_of_str "a/a") neu empty_m)) in match Pure.set empty_m (key_of_str "b") now bc with | Error _ -> Alcotest.fail "Unexpected map write result" | Ok m -> match Pure.set m (key_of_str "a/a") now neu with | Ok m -> Alcotest.check compare_write_res "hello" expected (Pure.rename m ~source:(key_of_str "b") ~dest:key_a now) | Error _ -> Alcotest.fail "Unexpected map write result" let rename_dict () = let expected = Ok (add (key_of_str "b/b") neu (add (key_of_str "b/a") bc empty_m)) in match Pure.set empty_m (key_of_str "a/a") now bc with | Error _ -> Alcotest.fail "Unexpected map write result" | Ok m -> match Pure.set m (key_of_str "a/b") now neu with | Ok m -> Alcotest.check compare_write_res "hello" expected (Pure.rename m ~source:(key_of_str "a") ~dest:(key_of_str "b") now) | Error _ -> Alcotest.fail "Unexpected map write result" let rename_dict_to_value () = let expected = Error (`Value_expected (key_of_str "a")) in match Pure.set empty_m (key_of_str "a/a") now bc with | Error _ -> Alcotest.fail "Unexpected map write result" | Ok m -> match Pure.set m (key_of_str "b") now neu with | Ok m -> Alcotest.check compare_write_res "hello" expected (Pure.rename m ~source:(key_of_str "a") ~dest:(key_of_str "b") now) | Error _ -> Alcotest.fail "Unexpected map write result" let rename_dict_to_dict () = let expected = Ok (add (key_of_str "b/b") neu (add (key_of_str "b/a/a") bc empty_m)) in match Pure.set empty_m (key_of_str "a/a") now bc with | Error _ -> Alcotest.fail "Unexpected map write result" | Ok m -> match Pure.set m (key_of_str "b/b") now neu with | Ok m -> Alcotest.check compare_write_res "hello" expected (Pure.rename m ~source:(key_of_str "a") ~dest:(key_of_str "b") now) | Error _ -> Alcotest.fail "Unexpected map write result" let rename_dict_to_subdir () = let expected = Error (`Rename_source_prefix (key_of_str "a", key_of_str "a/b")) in match Pure.set empty_m (key_of_str "a/a") now bc with | Error _ -> Alcotest.fail "Unexpected map write result" | Ok m -> match Pure.set m (key_of_str "a/b/b") now bc with | Error _ -> Alcotest.fail "Unexpected map write result" | Ok m -> Alcotest.check compare_write_res "hello" expected (Pure.rename m ~source:(key_of_str "a") ~dest:(key_of_str "a/b") now) let tests = [ "create empty key value store", `Quick, empty; "reading a value", `Quick, read; "partial reading a value", `Quick, read_partial; "remove value", `Quick, destroy; "list entries for dictionary", `Quick, list; "writing a value", `Quick, write; "write partial", `Quick, write_partial; "writing multiple values", `Quick, write_multiple; "size", `Quick, size; "rename", `Quick, rename; "rename replace", `Quick, rename_replace; "rename value to dict", `Quick, rename_value_to_dict; "rename dict", `Quick, rename_dict; "rename dict to value", `Quick, rename_dict_to_value; "rename dict to dict", `Quick, rename_dict_to_dict; "rename dict to subdir", `Quick, rename_dict_to_subdir; ] let tests = [ "tests", tests; ] let () = Printexc.record_backtrace true; Alcotest.run "mirage-kv-mem test" tests