(* $Id: ps_blockmap.ml 429 2011-10-04 19:07:05Z 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 = Nn_blockmap.create_owner() in
let r1 = bm#reserve (5*bmaprowsize) o1 ri in
let o2 = Nn_blockmap.create_owner() 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; *)
let (n_used,n_trans,n_free) = bm#stats in
not flag1 && n_used = 0L &&
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 = Nn_blockmap.create_owner() in
let r1 = bm#reserve (5*bmaprowsize) o1 ri in
bm#commit o1;
let o2 = Nn_blockmap.create_owner() 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; *)
let (n_used,n_trans,n_free) = bm#stats in
not flag1 && n_used = Int64.mul bmaprowsizeL 10L &&
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 = Nn_blockmap.create_owner() 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 = Nn_blockmap.create_owner() in
let r2 = bm#reserve (5*bmaprowsize) o2 ri in
let flag1 = overlap r1 r2 in
let flag2 =
try bm#reserve 1 o2 ri = []
with Failure _ -> true in
let (n_used,n_trans,n_free) = bm#stats in
(* printf "flag1=%B flag2=%B used=%Ld trans=%Ld\n" flag1 flag2 n_used n_trans; *)
not flag1 && flag2 && n_used = 0L &&
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 = Nn_blockmap.create_owner() 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;
bm#release o1;
let o2 = Nn_blockmap.create_owner() 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;
bm#release o2;
let (n_used,n_trans,n_free) = bm#stats in
flag1 && n_used = (Int64.mul bmaprowsizeL 10L) &&
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 = Nn_blockmap.create_owner() in
let r1 = bm#reserve (5*bmaprowsize) o1 ri in
bm#commit o1;
bm#release o1;
bm#free r1 o1;
bm#commit o1;
bm#release o1;
let o2 = Nn_blockmap.create_owner() in
let _r2 = bm#reserve (10*bmaprowsize) o2 ri in
bm#commit o2;
bm#release o2;
let (n_used,n_trans,n_free) = bm#stats in
n_used = (Int64.mul bmaprowsizeL 10L) &&
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 = Nn_blockmap.create_owner() in
let r1 = bm#reserve (10*bmaprowsize) o1 ri in
bm#commit o1;
bm#release o1;
bm#pin r1 o1;
let o2 = Nn_blockmap.create_owner() in
bm#free r1 o2;
bm#commit o2;
bm#release o2;
let flag1 =
try bm#reserve 1 o2 ri = []
with Failure _ -> true in
let (n_used,n_trans,n_free) = bm#stats in
flag1 && n_used = 0L &&
n_trans = (Int64.mul bmaprowsizeL 10L) &&
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 = Nn_blockmap.create_owner() in
let r1 = bm#reserve 1 o1 ri1 in
bm#commit o1;
bm#release 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 = Nn_blockmap.create_owner() in
let r2 = bm#reserve 1 o2 ri2 in
bm#commit o2;
bm#release 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
let (n_used,n_trans,n_free) = bm#stats in
flag1 && n_used = 2L &&
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%!"