(* $Id: ps_blockmap.ml 325 2010-11-17 16:30:18Z gerd $ *) (* Tests Nn_blockmap *) open Nn_config open Plasma_util open Printf let bmaprowsizeL = Int64.of_int bmaprowsize let do_test name f = try printf "Test: %s %!" name; if f() then printf "PASSED\n%!" else printf "FAILED\n%!" with | err -> printf "EXCEPTION %s\n%!" (Printexc.to_string err) let overlap l1 l2 = (* whether triv_ranges l1 and l2 overlap with each other *) let s = List.fold_left (fun acc (p,n) -> assert (n >= 1L); let q = Int64.pred (Int64.add p n) in I64RM.add (p,q) (p,q) acc ) I64RM.empty l1 in List.exists (fun (p,n) -> assert (n >= 1L); let q = Int64.pred (Int64.add p n) in let u = I64RM.sub (p,q) s in u <> I64RM.empty ) l2 let count_changed_blocks bm o1 = List.fold_left (fun acc (_,s) -> let n = ref 0 in for k = 0 to String.length s - 1 do if s.[k] = '1' then incr n done; acc + !n ) 0 (bm#get_changes o1) let test1 () = (* reservations do not overlap *) do_test "test1" ( fun () -> let bm = new Nn_blockmap.blockmap 0 "map0" (Int64.mul bmaprowsizeL 10L) in let ri = Nn_blockmap.create_reserve_info () in let o1 = (object end) in let r1 = bm#reserve (5*bmaprowsize) o1 ri in let o2 = (object end) in let r2 = bm#reserve (5*bmaprowsize) o2 ri in let flag1 = overlap r1 r2 in (* printf "flag1=%B used=%Ld trans=%Ld\n" flag1 bm#n_used bm#n_trans; *) not flag1 && bm#n_used = 0L && bm#n_trans = Int64.mul bmaprowsizeL 10L && count_changed_blocks bm o1 = 5*bmaprowsize && count_changed_blocks bm o2 = 5*bmaprowsize ) let test2 () = (* reservation does not overlap with committed block *) do_test "test2" ( fun () -> let bm = new Nn_blockmap.blockmap 0 "map0" (Int64.mul bmaprowsizeL 10L) in let ri = Nn_blockmap.create_reserve_info () in let o1 = (object end) in let r1 = bm#reserve (5*bmaprowsize) o1 ri in bm#commit o1; let o2 = (object end) in let r2 = bm#reserve (5*bmaprowsize) o2 ri in bm#commit o2; let flag1 = overlap r1 r2 in (* printf "flag1=%B used=%Ld trans=%Ld\n" flag1 bm#n_used bm#n_trans; *) not flag1 && bm#n_used = Int64.mul bmaprowsizeL 10L && bm#n_trans = 0L && count_changed_blocks bm o1 = 0 && count_changed_blocks bm o2 = 0 ) let test3 () = (* Reserved then freed blocks are still not available for other owners *) do_test "test3" ( fun () -> let bm = new Nn_blockmap.blockmap 0 "map0" (Int64.mul bmaprowsizeL 10L) in let ri = Nn_blockmap.create_reserve_info () in let o1 = (object end) in let r1 = bm#reserve (5*bmaprowsize) o1 ri in let (p,n) = List.hd r1 in bm#free [p,n] o1; (* printf "n=%Ld\n" n; *) (* i.e. n=bmaprowsize *) let o2 = (object end) in let r2 = bm#reserve (5*bmaprowsize) o2 ri in let flag1 = overlap r1 r2 in let flag2 = try ignore(bm#reserve 1 o2 ri); false with Failure _ -> true in (* printf "flag1=%B used=%Ld trans=%Ld\n" flag1 bm#n_used bm#n_trans; *) not flag1 && flag2 && bm#n_used = 0L && bm#n_trans = Int64.mul bmaprowsizeL 10L && count_changed_blocks bm o1 = 5*bmaprowsize-(Int64.to_int n) && count_changed_blocks bm o2 = 5*bmaprowsize ) let test4 () = (* Reserved then freed then committed blocks are available for other owners *) do_test "test4" ( fun () -> let bm = new Nn_blockmap.blockmap 0 "map0" (Int64.mul bmaprowsizeL 10L) in let ri = Nn_blockmap.create_reserve_info () in let o1 = (object end) in let r1 = bm#reserve (3*bmaprowsize) o1 ri in let (p,n) = List.hd r1 in bm#free [p,n] o1; (* printf "n=%Ld\n" n; *) (* i.e. n=bmaprowsize *) bm#commit o1; let o2 = (object end) in let r2 = bm#reserve (7*bmaprowsize+Int64.to_int n) o2 ri in let flag1 = overlap r1 r2 in (* this is expected now *) (* printf "flag1=%B used=%Ld trans=%Ld\n" flag1 bm#n_used bm#n_trans; *) bm#commit o2; flag1 && bm#n_used = (Int64.mul bmaprowsizeL 10L) && bm#n_trans = 0L && count_changed_blocks bm o1 = 0 && count_changed_blocks bm o2 = 0 ) let test5 () = (* Freed then committed blocks are available for other owners *) do_test "test5" ( fun () -> let bm = new Nn_blockmap.blockmap 0 "map0" (Int64.mul bmaprowsizeL 10L) in let ri = Nn_blockmap.create_reserve_info () in let o1 = (object end) in let r1 = bm#reserve (5*bmaprowsize) o1 ri in bm#commit o1; bm#free r1 o1; bm#commit o1; let o2 = (object end) in let _r2 = bm#reserve (10*bmaprowsize) o2 ri in bm#commit o2; bm#n_used = (Int64.mul bmaprowsizeL 10L) && bm#n_trans = 0L && count_changed_blocks bm o1 = 0 && count_changed_blocks bm o2 = 0 ) let test6 () = (* Kept then freed blocks are not available for other owners *) do_test "test6" ( fun () -> let bm = new Nn_blockmap.blockmap 0 "map0" (Int64.mul bmaprowsizeL 10L) in let ri = Nn_blockmap.create_reserve_info () in let o1 = (object end) in let r1 = bm#reserve (5*bmaprowsize) o1 ri in bm#commit o1; bm#keep r1 o1; let o2 = (object end) in bm#free r1 o2; bm#commit o2; let flag1 = try ignore(bm#reserve (5*bmaprowsize+1) o2 ri); false with Failure _ -> true in flag1 && bm#n_used = 0L && bm#n_trans = (Int64.mul bmaprowsizeL 5L) && count_changed_blocks bm o1 = 0 && count_changed_blocks bm o2 = 0 ) let test7 () = (* Tests reserve_info *) do_test "test7" ( fun () -> let bm = new Nn_blockmap.blockmap 0 "map0" (Int64.mul bmaprowsizeL 10L) in let ri1 = Nn_blockmap.create_reserve_info () in let o1 = (object end) in let r1 = bm#reserve 1 o1 ri1 in bm#commit o1; let ai = { Nn_db.ai_inode = 0L; ai_index = 0L; ai_identity = "map0"; ai_block = fst (List.hd r1) } in let ri2 = Nn_blockmap.create_reserve_info ~blocks:[ai] () in let o2 = (object end) in let r2 = bm#reserve 1 o2 ri2 in bm#commit o2; (* printf "block1=%Ld block2=%Ld\n" (fst (List.hd r1)) (fst (List.hd r2)); *) let flag1 = fst (List.hd r2) = Int64.succ(fst (List.hd r1)) in flag1 && bm#n_used = 2L && bm#n_trans = 0L && count_changed_blocks bm o1 = 0 && count_changed_blocks bm o2 = 0 ) let () = printf "ps_blockmap\n%!"; test1(); test2(); test3(); test4(); test5(); test6(); test7(); printf "ps_blockmap done\n%!"