From 1111c0fa9aae926c53859cdbd59738656d3556b4 Mon Sep 17 00:00:00 2001 From: Simon Cruanes Date: Sat, 2 Jul 2022 14:46:44 -0400 Subject: [PATCH] wip: convert tests into testlib --- src/data/CCBV.ml | 311 ----------------------------- src/data/CCBijection.ml | 14 -- src/data/CCBitField.ml | 60 ------ src/data/CCCache.ml | 44 ---- src/data/CCDeque.ml | 228 --------------------- src/testlib/containers_testlib.ml | 7 + src/testlib/containers_testlib.mli | 2 + src/threads/CCBlockingQueue.ml | 43 ---- src/threads/CCLock.ml | 63 ------ src/threads/CCPool.ml | 172 ---------------- src/threads/CCSemaphore.ml | 58 ------ src/threads/CCThread.ml | 20 -- src/threads/CCTimer.ml | 40 ---- src/threads/CCTimer.mli | 4 +- tests/data/dune | 5 + tests/data/t.ml | 8 + tests/data/t_bijection.ml | 13 ++ tests/data/t_bitfield.ml | 59 ++++++ tests/data/t_bv.ml | 249 +++++++++++++++++++++++ tests/data/t_cache.ml | 47 +++++ tests/data/t_deque.ml | 193 ++++++++++++++++++ tests/thread/dune | 5 + tests/thread/t.ml | 9 + tests/thread/t_bq.ml | 47 +++++ tests/thread/t_lock.ml | 53 +++++ tests/thread/t_pool.ml | 171 ++++++++++++++++ tests/thread/t_semaphore.ml | 62 ++++++ tests/thread/t_thread.ml | 24 +++ tests/thread/t_timer.ml | 42 ++++ 29 files changed, 997 insertions(+), 1056 deletions(-) create mode 100644 tests/data/dune create mode 100644 tests/data/t.ml create mode 100644 tests/data/t_bijection.ml create mode 100644 tests/data/t_bitfield.ml create mode 100644 tests/data/t_bv.ml create mode 100644 tests/data/t_cache.ml create mode 100644 tests/data/t_deque.ml create mode 100644 tests/thread/dune create mode 100644 tests/thread/t.ml create mode 100644 tests/thread/t_bq.ml create mode 100644 tests/thread/t_lock.ml create mode 100644 tests/thread/t_pool.ml create mode 100644 tests/thread/t_semaphore.ml create mode 100644 tests/thread/t_thread.ml create mode 100644 tests/thread/t_timer.ml diff --git a/src/data/CCBV.ml b/src/data/CCBV.ml index 50191da5..cabdc65a 100644 --- a/src/data/CCBV.ml +++ b/src/data/CCBV.ml @@ -4,10 +4,6 @@ (* TODO: move to [bytes] and replace all [mod] and [/] with bitshifts because width_=8 *) -(*$inject - let ppli = CCFormat.(Dump.list int) -*) - let width_ = Sys.word_size - 1 (** We use OCamls ints to store the bits. We index them from the @@ -62,25 +58,8 @@ let create ~size default = { a; size } ) -(*$Q - (Q.pair Q.small_int Q.bool) (fun (size, b) -> create ~size b |> length = size) -*) - -(*$T - create ~size:17 true |> cardinal = 17 - create ~size:32 true |> cardinal = 32 - create ~size:132 true |> cardinal = 132 - create ~size:200 false |> cardinal = 0 - create ~size:29 true |> to_sorted_list = CCList.range 0 28 -*) - let copy bv = { bv with a = Array.copy bv.a } -(*$Q - (Q.list Q.small_int) (fun l -> \ - let bv = of_list l in to_list bv = to_list (copy bv)) -*) - let capacity bv = width_ * Array.length bv.a let cardinal bv = @@ -93,10 +72,6 @@ let cardinal bv = !n ) -(*$Q - Q.small_int (fun size -> create ~size true |> cardinal = size) -*) - let really_resize_ bv ~desired ~current size = let a' = Array.make desired 0 in Array.blit bv.a 0 a' 0 current; @@ -127,15 +102,6 @@ let resize bv size = then () else grow_ bv size -(*$R - let bv1 = CCBV.create ~size:87 true in - assert_equal ~printer:string_of_int 87 (CCBV.cardinal bv1); -*) - -(*$Q - Q.small_int (fun n -> CCBV.cardinal (CCBV.create ~size:n true) = n) -*) - let is_empty bv = try for i = 0 to Array.length bv.a - 1 do @@ -153,22 +119,6 @@ let get bv i = then (Array.unsafe_get bv.a n) land (1 lsl i) <> 0 else false -(*$R - let bv = CCBV.create ~size:99 false in - assert_bool "32 must be false" (not (CCBV.get bv 32)); - assert_bool "88 must be false" (not (CCBV.get bv 88)); - assert_bool "5 must be false" (not (CCBV.get bv 5)); - CCBV.set bv 32; - CCBV.set bv 88; - CCBV.set bv 5; - assert_bool "32 must be true" (CCBV.get bv 32); - assert_bool "88 must be true" (CCBV.get bv 88); - assert_bool "5 must be true" (CCBV.get bv 5); - assert_bool "33 must be false" (not (CCBV.get bv 33)); - assert_bool "44 must be false" (not (CCBV.get bv 44)); - assert_bool "1 must be false" (not (CCBV.get bv 1)); -*) - let set bv i = if i < 0 then invalid_arg "set: negative index" else ( @@ -178,11 +128,6 @@ let set bv i = Array.unsafe_set bv.a n ((Array.unsafe_get bv.a n) lor (1 lsl j)) ) -(*$T - let bv = create ~size:3 false in set bv 0; get bv 0 - let bv = create ~size:3 false in set bv 1; not (get bv 0) -*) - let reset bv i = if i < 0 then invalid_arg "reset: negative index" else ( @@ -192,10 +137,6 @@ let reset bv i = Array.unsafe_set bv.a n ((Array.unsafe_get bv.a n) land (lnot (1 lsl j))) ) -(*$T - let bv = create ~size:3 false in set bv 0; reset bv 0; not (get bv 0) -*) - let flip bv i = if i < 0 then invalid_arg "reset: negative index" else ( @@ -205,48 +146,13 @@ let flip bv i = Array.unsafe_set bv.a n ((Array.unsafe_get bv.a n) lxor (1 lsl j)) ) -(*$R - let bv = of_list [1;10; 11; 30] in - flip bv 10; - assert_equal ~printer:Q.Print.(list int) [1;11;30] (to_sorted_list bv); - assert_equal ~printer:Q.Print.bool false (get bv 10); - flip bv 10; - assert_equal ~printer:Q.Print.bool true (get bv 10); - flip bv 5; - assert_equal ~printer:Q.Print.(list int) [1;5;10;11;30] (to_sorted_list bv); - assert_equal ~printer:Q.Print.bool true (get bv 5); - flip bv 100; - assert_equal ~printer:Q.Print.(list int) [1;5;10;11;30;100] (to_sorted_list bv); - assert_equal ~printer:Q.Print.bool true (get bv 100); -*) - let clear bv = Array.fill bv.a 0 (Array.length bv.a) 0 -(*$T - let bv = create ~size:37 true in cardinal bv = 37 && (clear bv; cardinal bv= 0) -*) - -(*$R - let bv = CCBV.of_list [1; 5; 200] in - assert_equal ~printer:string_of_int 3 (CCBV.cardinal bv); - CCBV.clear bv; - assert_equal ~printer:string_of_int 0 (CCBV.cardinal bv); - assert_bool "must be empty" (CCBV.is_empty bv); -*) - let equal x y : bool = x.size = y.size && x.a = y.a -(*$T - equal (of_list [1; 3; 4]) (of_list [1; 3; 4]) - equal (empty()) (empty()) - not (equal (empty ()) (of_list [1])) - not (equal (empty ()) (of_list [2; 5])) - not (equal (of_list [1;3]) (of_list [2; 3])) -*) - let iter bv f = let len = array_length_of_size bv.size in assert (len <= Array.length bv.a); @@ -267,95 +173,14 @@ let iter bv f = done ) -(*$R - List.iter - (fun size -> - let bv = create ~size false in - set bv 5; - let n = ref 0 in - iter bv (fun i b -> incr n; assert_equal b (i=5)); - assert_bool "exactly size" (!n = size)) - [30; 100; 255; 256;10_000] -*) - -(*$inject - let iter_zip s k = s (fun x y -> k(x,y)) -*) - -(*$= & ~printer:Q.Print.(list (pair int bool)) - [] (iter (create ~size:0 false) |> iter_zip |> Iter.to_list) - [0, false; 1, true; 2, false] \ - (iter (let bv = create ~size:3 false in set bv 1; bv) |> iter_zip |> Iter.to_list) -*) - -(*$Q - Q.(small_int) (fun n -> \ - assert (n >= 0); \ - let bv = create ~size:n true in \ - let l = iter bv |> iter_zip |> Iter.to_list in \ - List.length l = n && List.for_all (fun (_,b) -> b) l) -*) - let[@inline] iter_true bv f = iter bv (fun i b -> if b then f i else ()) -(*$T - of_list [1;5;7] |> iter_true |> Iter.to_list |> List.sort CCOrd.compare = [1;5;7] -*) - -(*$inject - let _gen = Q.Gen.(map of_list (list nat)) - let _pp bv = Q.Print.(list string) (List.map string_of_int (to_list bv)) - let _small bv = length bv - - let gen_bv = Q.make ~small:_small ~print:_pp _gen -*) - -(*$QR - gen_bv (fun bv -> - let l' = Iter.to_rev_list (CCBV.iter_true bv) in - let bv' = CCBV.of_list l' in - CCBV.cardinal bv = CCBV.cardinal bv' - ) -*) - let to_list bv = let l = ref [] in iter_true bv (fun i -> l := i :: !l); !l -(*$R - let bv = CCBV.of_list [1; 5; 156; 0; 222] in - assert_equal ~printer:string_of_int 5 (CCBV.cardinal bv); - CCBV.set bv 201; - assert_equal ~printer:string_of_int 6 (CCBV.cardinal bv); - let l = CCBV.to_list bv in - let l = List.sort compare l in - assert_equal [0;1;5;156;201;222] l; -*) - -(*$= & ~printer:(CCFormat.to_string ppli) - [1;2;3;4;64;130] (of_list [1;2;3;4;64;130] |> to_sorted_list) -*) - -(*$Q - Q.(small_list small_nat) (fun l -> \ - let l = List.sort_uniq CCOrd.compare l in \ - let l2 = of_list l |> to_sorted_list in \ - if l=l2 then true else Q.Test.fail_reportf "l1=%a, l2=%a" ppli l ppli l2) - Q.(small_list small_nat) (fun l -> \ - let bv = of_list l in \ - let l1 = bv |> to_sorted_list in \ - let l2 = \ - (CCList.init (length bv) (get bv) |> List.mapi (fun i b->i,b) \ - |>CCList.filter_map (function (i,true) -> Some i| _ ->None)) in \ - if l1=l2 then true else Q.Test.fail_reportf "l1=%a, l2=%a" ppli l1 ppli l2) - *) - -(*$= & ~cmp:equal ~printer:(CCFormat.to_string pp) - (of_list [0]) (let bv=empty() in set bv 0; bv) -*) - let to_sorted_list bv = List.rev (to_list bv) @@ -366,12 +191,6 @@ let of_list l = List.iter (fun i -> set bv i) l; bv -(*$T - of_list [1;32;64] |> CCFun.flip get 64 - of_list [1;32;64] |> CCFun.flip get 32 - of_list [1;31;63] |> CCFun.flip get 63 -*) - exception FoundFirst of int let first_exn bv = @@ -385,19 +204,10 @@ let first bv = try Some (first_exn bv) with Not_found -> None -(*$T - of_list [50; 10; 17; 22; 3; 12] |> first = Some 3 -*) - let filter bv p = iter_true bv (fun i -> if not (p i) then reset bv i) -(*$T - let bv = of_list [1;2;3;4;5;6;7] in filter bv (fun x->x mod 2=0); \ - to_sorted_list bv = [2;4;6] -*) - let negate_self b = let len = Array.length b.a in for n = 0 to len - 1 do @@ -408,10 +218,6 @@ let negate_self b = let l = Array.length b.a - 1 in Array.unsafe_set b.a l (lsb_masks_.(r) land (Array.unsafe_get b.a l)) -(*$= & ~printer:(CCFormat.to_string ppli) - [0;3;4;6] (let v = of_list [1;2;5;7;] in negate_self v; to_sorted_list v) -*) - let negate b = let a = Array.map (lnot) b.a in let r = b.size mod width_ in @@ -421,10 +227,6 @@ let negate b = ); { a ; size = b.size } -(*$Q - Q.small_int (fun size -> create ~size false |> negate |> cardinal = size) -*) - let union_into_no_resize_ ~into bv = assert (Array.length into.a >= Array.length bv.a); for i = 0 to Array.length bv.a - 1 do @@ -452,47 +254,6 @@ let union b1 b2 = into ) -(*$R - let bv1 = CCBV.of_list [1;2;3;4] in - let bv2 = CCBV.of_list [4;200;3] in - let bv = CCBV.union bv1 bv2 in - let l = List.sort compare (CCBV.to_list bv) in - assert_equal ~printer:(CCFormat.(to_string (Dump.list int))) - [1;2;3;4;200] l; - () -*) - -(*$R - let bv1 = CCBV.of_list [1;2;3;4;64;130] in - let bv2 = CCBV.of_list [4;64;3;120] in - let bv = CCBV.union bv1 bv2 in - assert_equal ~cmp:equal ~printer:(CCFormat.to_string pp) - (of_list [1;2;3;4;64;120;130]) bv; - () -*) - -(*$R - let bv1 = CCBV.of_list [1;2;3;4] in - let bv2 = CCBV.of_list [4;200;3] in - let bv = CCBV.union bv1 bv2 in - assert_equal ~cmp:equal ~printer:(CCFormat.to_string pp) - (of_list [1;2;3;4;200]) bv; - () -*) - -(*$R - let v1 = CCBV.empty () in - let () = CCBV.set v1 64 in - let v2 = CCBV.diff (CCBV.empty ()) (CCBV.empty ()) in - let v3 = CCBV.union v1 v2 in - assert_equal ~printer:(CCFormat.to_string pp) ~cmp:CCBV.equal v1 v3 -*) - -(*$T - union (of_list [1;2;3;4;5]) (of_list [7;3;5;6]) |> to_sorted_list = CCList.range 1 7 -*) - - let inter_into_no_resize_ ~into bv = assert (Array.length into.a <= Array.length bv.a); for i = 0 to (Array.length into.a) - 1 do @@ -518,28 +279,6 @@ let inter b1 b2 = into ) -(*$T - inter (of_list [1;2;3;4]) (of_list [2;4;6;1]) |> to_sorted_list = [1;2;4] -*) - -(*$R - let bv1 = CCBV.of_list [1;2;3;4;200;201] in - let bv2 = CCBV.of_list [4;200;3] in - let bv = CCBV.inter bv1 bv2 in - let l = List.sort compare (CCBV.to_list bv) in - assert_equal ~printer:(CCFormat.(to_string (Dump.list int))) - [3;4;200] l; - () -*) - -(*$R - let bv1 = CCBV.of_list [1;2;3;4] in - let bv2 = CCBV.of_list [4;200;3] in - CCBV.inter_into ~into:bv1 bv2; - let l = List.sort compare (CCBV.to_list bv1) in - assert_equal [3;4] l; -*) - (* Underlying size depends on the 'in_' set for diff, so we don't change it's size! *) let diff_into ~into bv = @@ -554,21 +293,6 @@ let diff in_ not_in = diff_into ~into not_in; into -(*$T - diff (of_list [1;2;3]) (of_list [1;2;3]) |> to_list = []; - diff (of_list [1;2;3]) (of_list [1;2;3;4]) |> to_list = []; - diff (of_list [1;2;3;4]) (of_list [1;2;3]) |> to_list = [4]; - diff (of_list [1;2;3]) (of_list [1;2;3;400]) |> to_list = []; - diff (of_list [1;2;3;400]) (of_list [1;2;3]) |> to_list = [400]; -*) - -(*$R - let v1 = CCBV.empty () in - set v1 65; - let v2 = CCBV.diff v1 v1 in - assert_bool (CCFormat.asprintf "bv: %a" pp v2) (CCBV.is_empty v2) -*) - let select bv arr = let l = ref [] in begin try @@ -581,13 +305,6 @@ let select bv arr = end; !l -(*$R - let bv = CCBV.of_list [1;2;5;400] in - let arr = [|"a"; "b"; "c"; "d"; "e"; "f"|] in - let l = List.sort compare (CCBV.select bv arr) in - assert_equal ["b"; "c"; "f"] l; -*) - let selecti bv arr = let l = ref [] in begin try @@ -600,29 +317,10 @@ let selecti bv arr = end; !l -(*$R - let bv = CCBV.of_list [1;2;5;400] in - let arr = [|"a"; "b"; "c"; "d"; "e"; "f"|] in - let l = List.sort compare (CCBV.selecti bv arr) in - assert_equal [("b",1); ("c",2); ("f",5)] l; -*) - -(*$= & ~printer:Q.Print.(list (pair int int)) - [1,1; 3,3; 4,4] (selecti (of_list [1;4;3]) [| 0;1;2;3;4;5;6;7;8 |] \ - |> List.sort CCOrd.compare) -*) - type 'a iter = ('a -> unit) -> unit let to_iter bv k = iter_true bv k -(*$Q - Q.(small_int) (fun i -> \ - let i = max 1 i in \ - let bv = create ~size:i true in \ - i = (to_iter bv |> Iter.length)) -*) - let of_iter seq = let l = ref [] and maxi = ref 0 in seq (fun x -> l := x :: !l; maxi := max !maxi x); @@ -630,11 +328,6 @@ let of_iter seq = List.iter (fun i -> set bv i) !l; bv -(*$T - CCList.range 0 10 |> CCList.to_iter |> of_iter |> to_iter \ - |> CCList.of_iter |> List.sort CCOrd.compare = CCList.range 0 10 -*) - let pp out bv = Format.pp_print_string out "bv {"; iter bv @@ -643,8 +336,4 @@ let pp out bv = ); Format.pp_print_string out "}" -(*$= & ~printer:CCFun.id - "bv {00001}" (CCFormat.to_string pp (of_list [4])) -*) - let __to_word_l bv = Array.to_list bv.a diff --git a/src/data/CCBijection.ml b/src/data/CCBijection.ml index 97aef425..113f5d71 100644 --- a/src/data/CCBijection.ml +++ b/src/data/CCBijection.ml @@ -117,17 +117,3 @@ module Make(L : OrderedType)(R : OrderedType) = struct let to_iter m yield = MapL.iter (fun k v -> yield (k,v)) m.left end - -(*$inject - open Containers - module M = Make(Int)(String) - -*) - -(*$= - 2 (M.of_list [1,"1"; 2, "2"] |> M.cardinal) - "1" (M.of_list [1,"1"; 2, "2"] |> M.find_left 1) - "2" (M.of_list [1,"1"; 2, "2"] |> M.find_left 2) - 1 (M.of_list [1,"1"; 2, "2"] |> M.find_right "1") - 2 (M.of_list [1,"1"; 2, "2"] |> M.find_right "2") -*) diff --git a/src/data/CCBitField.ml b/src/data/CCBitField.ml index 7d91b908..871361bd 100644 --- a/src/data/CCBitField.ml +++ b/src/data/CCBitField.ml @@ -7,59 +7,6 @@ exception Frozen let max_width = Sys.word_size - 2 -(*$R - let module B = CCBitField.Make(struct end) in - let x = B.mk_field () in - let y = B.mk_field () in - let z = B.mk_field () in - - let f = B.empty |> B.set x true |> B.set y true in - - assert_bool "z_false" (not (B.get z f)) ; - - assert_bool "z_true" (f |> B.set z true |> B.get z); -*) - -(*$R - let module B = CCBitField.Make(struct end) in - let _ = B.mk_field () in - B.freeze(); - assert_bool "must raise" - (try ignore (B.mk_field()); false with Frozen -> true); - -*) - -(*$R - let module B = CCBitField.Make(struct end) in - - let x = B.mk_field () in - let y = B.mk_field () in - let z = B.mk_field () in - let u = B.mk_field () in - B.freeze(); - - let f = B.empty - |> B.set y true - |> B.set z true - in - - assert_equal ~printer:CCInt.to_string 6 (f :> int) ; - - assert_equal false (B.get x f) ; - assert_equal true (B.get y f) ; - assert_equal true (B.get z f); - - let f' = B.set u true f in - - assert_equal false (B.get x f') ; - assert_equal true (B.get y f') ; - assert_equal true (B.get z f'); - assert_equal true (B.get u f'); - - () -*) - - module type S = sig type t = private int (** Generative type of bitfields. Each instantiation of the functor @@ -94,13 +41,6 @@ let rec all_bits_ acc w = let acc = acc lor (1 lsl w-1) in all_bits_ acc (w-1) -(*$T - all_bits_ 0 1 = 1 - all_bits_ 0 2 = 3 - all_bits_ 0 3 = 7 - all_bits_ 0 4 = 15 -*) - (* increment and return previous value *) let get_then_incr n = let x = !n in diff --git a/src/data/CCCache.ml b/src/data/CCCache.ml index b7a58bc0..32b8d1d6 100644 --- a/src/data/CCCache.ml +++ b/src/data/CCCache.ml @@ -55,20 +55,6 @@ let with_cache_rec ?(cb=default_callback_) c f = let rec f' x = with_cache ~cb c (f f') x in f' -(*$R - let c = unbounded ~eq:Int64.equal 256 in - let fib = with_cache_rec c - (fun self n -> match n with - | 1L | 2L -> 1L - | _ -> CCInt64.(self (n-1L) + self (n-2L)) - ) - in - assert_equal 55L (fib 10L); - assert_equal 832040L (fib 30L); - assert_equal 12586269025L (fib 50L); - assert_equal 190392490709135L (fib 70L) -*) - let size c = c.size () let iter c f = c.iter f @@ -311,36 +297,6 @@ let lru (type a) ~eq ?(hash=default_hash_) size = iter=L.iter c; } -(*$T - let eq (i1,_)(i2,_) = i1=i2 and hash (i,_) = CCInt.hash i in \ - let c = lru ~eq ~hash 2 in \ - ignore (with_cache c CCFun.id (1, true)); \ - ignore (with_cache c CCFun.id (1, false)); \ - with_cache c CCFun.id (1, false) = (1, true) -*) - -(*$T - let f = (let r = ref 0 in fun _ -> incr r; !r) in \ - let c = lru ~eq:CCInt.equal 2 in \ - let res1 = with_cache c f 1 in \ - let res2 = with_cache c f 2 in \ - let res3 = with_cache c f 3 in \ - let res1_bis = with_cache c f 1 in \ - res1 <> res2 && res2 <> res3 && res3 <> res1_bis && res1_bis <> res1 -*) - -(*$R - let f = (let r = ref 0 in fun _ -> incr r; !r) in - let c = lru ~eq:CCEqual.unit 2 in - let x = with_cache c f () in - assert_equal 1 x; - assert_equal 1 (size c); - clear c ; - assert_equal 0 (size c); - let y = with_cache c f () in - assert_equal 2 y ; -*) - module UNBOUNDED(X:HASH) = struct module H = Hashtbl.Make(X) diff --git a/src/data/CCDeque.ml b/src/data/CCDeque.ml index 9488cf33..5e457907 100644 --- a/src/data/CCDeque.ml +++ b/src/data/CCDeque.ml @@ -27,24 +27,6 @@ type 'a t = { } (** The deque, a double linked list of cells *) -(*$inject - let plist l = CCFormat.(to_string (list int)) l - let pint i = string_of_int i -*) - -(*$R - let q = create () in - add_iter_back q Iter.(3 -- 5); - assert_equal [3;4;5] (to_list q); - add_iter_front q Iter.(of_list [2;1]); - assert_equal [1;2;3;4;5] (to_list q); - push_front q 0; - assert_equal [0;1;2;3;4;5] (to_list q); - assert_equal 5 (take_back q); - assert_equal 0 (take_front q); - assert_equal 4 (length q); -*) - exception Empty let create () = @@ -55,15 +37,6 @@ let clear q = q.size <- 0; () -(*$R - let q = of_iter Iter.(1 -- 100) in - assert_equal 100 (length q); - clear q; - assert_equal 0 (length q); - assert_raises Empty (fun () -> peek_front q); - assert_raises Empty (fun () -> peek_back q); -*) - let incr_size_ d = d.size <- d.size + 1 let decr_size_ d = d.size <- d.size - 1 @@ -121,24 +94,6 @@ let peek_front d = match peek_front_opt d with | None -> raise Empty | Some x -> x -(*$T - of_list [1;2;3] |> peek_front = 1 - try (ignore (of_list [] |> peek_front); false) with Empty -> true -*) - -(*$R - let d = of_iter Iter.(1 -- 10) in - let printer = pint in - OUnit2.assert_equal ~printer 1 (peek_front d); - push_front d 42; - OUnit2.assert_equal ~printer 42 (peek_front d); - OUnit2.assert_equal ~printer 42 (take_front d); - OUnit2.assert_equal ~printer 1 (take_front d); - OUnit2.assert_equal ~printer 2 (take_front d); - OUnit2.assert_equal ~printer 3 (take_front d); - OUnit2.assert_equal ~printer 10 (peek_back d); -*) - let peek_back_opt d = match d.cur with | Empty -> None @@ -151,23 +106,6 @@ let peek_back_opt d = let peek_back d = match peek_back_opt d with | None -> raise Empty | Some x -> x -(*$T - of_list [1;2;3] |> peek_back = 3 - try (ignore (of_list [] |> peek_back); false) with Empty -> true -*) - -(*$R - let d = of_iter Iter.(1 -- 10) in - let printer = pint in - OUnit2.assert_equal ~printer 1 (peek_front d); - push_back d 42; - OUnit2.assert_equal ~printer 42 (peek_back d); - OUnit2.assert_equal ~printer 42 (take_back d); - OUnit2.assert_equal ~printer 10 (take_back d); - OUnit2.assert_equal ~printer 9 (take_back d); - OUnit2.assert_equal ~printer 8 (take_back d); - OUnit2.assert_equal ~printer 1 (peek_front d); -*) let take_back_node_ n = match n.cell with | One x -> (true, x) @@ -203,22 +141,11 @@ let take_back d = match take_back_opt d with | None -> raise Empty | Some x -> x -(*$T - let q = of_list [1] in take_back q = 1 && to_list q = [] - let q = of_list [1;2] in take_back q = 2 && to_list q = [1] - let q = of_list [1;2;3] in take_back q = 3 && to_list q = [1;2] - let q = of_list [1;2;3;4;5;6;7;] in take_back q = 7 && to_list q = [1;2;3;4;5;6] -*) - let take_front_node_ n = match n.cell with | One x -> (true, x) | Two (x,y) -> n.cell <- One y; (false, x) | Three (x,y,z) -> n.cell <- Two (y,z); (false, x) -(*$T - let q = of_list [1;2;3] in take_front q = 1 && to_list q = [2;3] -*) - let take_front_opt d = match d.cur with | Empty -> None @@ -247,16 +174,8 @@ let take_front d = match take_front_opt d with let remove_back d = ignore (take_back_opt d) -(*$T remove_back - let q = of_list [1;2;3;4;5;6;7] in remove_back q; to_list q = [1;2;3;4;5;6] -*) - let remove_front d = ignore (take_front_opt d) -(*$T remove_front - let q = of_list [1;2;3;4;5;6;7] in remove_front q; to_list q = [2;3;4;5;6;7] -*) - let update_front d f = match d.cur with | Empty -> () @@ -285,23 +204,6 @@ let update_front d f = | Some x -> cur.cell <- Three (x,y,z) end -(*$T update_front - let q = of_list [1;2;3;4;5;6;7] in update_front q (fun _ -> None); to_list q = [2;3;4;5;6;7] - let q = of_list [1;2;3;4;5;6;7] in update_front q (fun _ -> Some 9); to_list q = [9;2;3;4;5;6;7] -*) -(*$Q update_front - Q.(list int) (fun l -> \ - let q = of_list l in \ - update_front q (fun _ -> None); \ - let output_list = if l = [] then [] else List.tl l in \ - to_list q = output_list) - Q.(list int) (fun l -> \ - let q = of_list l in \ - update_front q (fun x -> Some (x + 42)); \ - let output_list = if l = [] then [] else List.((hd l + 42)::(tl l)) in \ - to_list q = output_list) -*) - let update_back d f = match d.cur with | Empty -> () @@ -326,23 +228,6 @@ let update_back d f = | Some z -> n.cell <- Three (x,y,z) end -(*$T update_back - let q = of_list [1;2;3;4;5;6;7] in update_back q (fun _ -> None); to_list q = [1;2;3;4;5;6] - let q = of_list [1;2;3;4;5;6;7] in update_back q (fun _ -> Some 9); to_list q = [1;2;3;4;5;6;9] -*) -(*$Q update_back - Q.(list int) (fun l -> \ - let q = of_list l in \ - update_back q (fun _ -> None); \ - let output_list = if l = [] then [] else List.(rev l |> tl) in \ - (to_list q |> List.rev) = output_list) - Q.(list int) (fun l -> \ - let q = of_list l in \ - update_back q (fun x -> Some (x + 42)); \ - let output_list = if l = [] then [] else List.(rev l |> fun l -> (hd l + 42)::(tl l)) in \ - (to_list q |> List.rev) = output_list) -*) - let iter f d = let rec iter f ~first n = begin match n.cell with @@ -357,29 +242,10 @@ let iter f d = | Node cur -> iter f ~first:cur cur -(*$T - let n = ref 0 in iter (fun _ -> incr n) (of_list [1;2;3]); !n = 3 -*) - -(*$R - let d = of_iter Iter.(1 -- 5) in - let s = Iter.from_iter (fun k -> iter k d) in - let l = Iter.to_list s in - OUnit2.assert_equal ~printer:plist [1;2;3;4;5] l; -*) - let append_front ~into q = iter (push_front into) q let append_back ~into q = iter (push_back into) q -(*$R - let q = of_list [3;4] in - append_front ~into:q (of_list [2;1]); - assert_equal [1;2;3;4] (to_list q); - append_back ~into:q (of_list [5;6]); - assert_equal [1;2;3;4;5;6] (to_list q); -*) - let fold f acc d = let rec aux ~first f acc n = let acc = match n.cell with @@ -394,26 +260,8 @@ let fold f acc d = | Node cur -> aux ~first:cur f acc cur -(*$T - fold (+) 0 (of_list [1;2;3]) = 6 - fold (fun acc x -> x::acc) [] (of_list [1;2;3]) = [3;2;1] -*) - let length d = d.size -(*$Q - Q.(list int) (fun l -> \ - let q = of_list l in \ - append_front ~into:q (of_list l); \ - append_back ~into:q (of_list l); \ - length q = 3 * List.length l) -*) - -(*$R - let d = of_iter Iter.(1 -- 10) in - OUnit2.assert_equal ~printer:pint 10 (length d) -*) - type 'a iter = ('a -> unit) -> unit type 'a gen = unit -> 'a option @@ -421,14 +269,6 @@ let add_iter_back q seq = seq (fun x -> push_back q x) let add_iter_front q seq = seq (fun x -> push_front q x) -(*$R - let q = of_list [4;5] in - add_iter_front q Iter.(of_list [3;2;1]); - assert_equal [1;2;3;4;5] (to_list q); - add_iter_back q Iter.(of_list [6;7]); - assert_equal [1;2;3;4;5;6;7] (to_list q); -*) - let of_iter seq = let deque = create () in seq (fun x -> push_back deque x); @@ -436,24 +276,11 @@ let of_iter seq = let to_iter d k = iter k d -(*$Q - Q.(list int) (fun l -> \ - Iter.of_list l |> of_iter |> to_iter |> Iter.to_list = l) -*) - let of_list l = let q = create() in List.iter (push_back q) l; q -(*$R - let q = of_list [1;2;3] in - assert_equal 1 (take_front q); - assert_equal 3 (take_back q); - assert_equal 2 (take_front q); - assert_equal true (is_empty q) -*) - let to_rev_list q = fold (fun l x -> x::l) [] q let to_list q = List.rev (to_rev_list q) @@ -546,37 +373,11 @@ let filter_in_place (d:_ t) f : unit = cur.cell <- c; loop ~stop_at:cur cur.next -(*$R - let q = of_list [1;2;3;4;5;6] in - filter_in_place q (fun x -> x mod 2 = 0); - assert_equal [2;4;6] (to_list q) - *) - -(*$R - let q = of_list [2;1;4;6;10;20] in - filter_in_place q (fun x -> x mod 2 = 0); - assert_equal [2;4;6;10;20] (to_list q) - *) - -(*$Q - Q.(list small_nat) (fun l -> \ - let f = fun x -> x mod 2=0 in \ - let q = of_list l in \ - (filter_in_place q f; to_list q) = (List.filter f l)) - *) - let filter f q = let q' = create() in iter (fun x -> if f x then push_back q' x) q; q' -(*$Q - Q.(list small_nat) (fun l -> \ - let f = fun x -> x mod 2=0 in \ - let q = filter f (of_list l) in \ - (to_list q) = (List.filter f l)) - *) - let filter_map f q = let q' = create() in iter (fun x -> match f x with None -> () | Some y -> push_back q' y) q; @@ -613,35 +414,12 @@ let to_gen q = in next -(*$T - of_list [1;2;3] |> to_gen |> of_gen |> to_list = [1;2;3] -*) - -(*$Q - Q.(list int) (fun l -> \ - of_list l |> to_gen |> of_gen |> to_list = l) -*) - (* naive implem of copy, for now *) let copy d = let d' = create () in iter (fun x -> push_back d' x) d; d' -(*$R - let q = of_list [1;2;3;4] in - assert_equal 4 (length q); - let q' = copy q in - let cmp = equal ~eq:CCInt.equal in - assert_equal 4 (length q'); - assert_equal ~cmp q q'; - push_front q 0; - assert_bool "not equal" (not (cmp q q')); - assert_equal 5 (length q); - push_front q' 0; - assert_equal ~cmp q q' -*) - let equal ~eq a b = let rec aux eq a b = match a() , b() with | None, None -> true @@ -660,12 +438,6 @@ let compare ~cmp a b = if c=0 then aux cmp a b else c in aux cmp (to_gen a) (to_gen b) -(*$Q - Q.(pair (list int) (list int)) (fun (l1,l2) -> \ - CCOrd.equiv (compare ~cmp:Stdlib.compare (of_list l1) (of_list l2)) \ - (CCList.compare Stdlib.compare l1 l2)) -*) - type 'a printer = Format.formatter -> 'a -> unit let pp pp_x out d = diff --git a/src/testlib/containers_testlib.ml b/src/testlib/containers_testlib.ml index aa0a7d83..e60731a3 100644 --- a/src/testlib/containers_testlib.ml +++ b/src/testlib/containers_testlib.ml @@ -105,6 +105,8 @@ module type S = sig ?printer:('a -> string) -> ?cmp:('a -> 'a -> bool) -> 'a -> 'a -> unit + val assert_bool : string -> bool -> unit + val assert_failure : string -> 'a val assert_raises : (exn -> bool) -> (unit -> 'b) -> unit @@ -142,6 +144,11 @@ module Make_test(X:sig val file: string end) = struct failwith @@ spf "not equal: lhs=%s, rhs=%s" (p x) (p y) ) + let assert_bool what b = + if not b then ( + failwith what + ) + let assert_failure s = failwith s let assert_raises check f = diff --git a/src/testlib/containers_testlib.mli b/src/testlib/containers_testlib.mli index 217c9331..f1ab9acd 100644 --- a/src/testlib/containers_testlib.mli +++ b/src/testlib/containers_testlib.mli @@ -19,6 +19,8 @@ module type S = sig ?printer:('a -> string) -> ?cmp:('a -> 'a -> bool) -> 'a -> 'a -> unit + val assert_bool : string -> bool -> unit + val assert_failure : string -> 'a val assert_raises : (exn -> bool) -> (unit -> 'b) -> unit diff --git a/src/threads/CCBlockingQueue.ml b/src/threads/CCBlockingQueue.ml index 053c085a..8a22fc52 100644 --- a/src/threads/CCBlockingQueue.ml +++ b/src/threads/CCBlockingQueue.ml @@ -62,20 +62,6 @@ let take q = Condition.broadcast q.cond; x) -(*$R - let q = create 1 in - let t1 = CCThread.spawn (fun () -> push q 1; push q 2) in - let t2 = CCThread.spawn (fun () -> push q 3; push q 4) in - let l = CCLock.create [] in - let t3 = CCThread.spawn (fun () -> for i = 1 to 4 do - let x = take q in - CCLock.update l (fun l -> x :: l) - done) - in - Thread.join t1; Thread.join t2; Thread.join t3; - assert_equal [1;2;3;4] (List.sort Stdlib.compare (CCLock.get l)) -*) - let push_list q l = (* push elements until it's not possible. Assumes the lock is acquired. *) @@ -131,35 +117,6 @@ let take_list q n = in aux [] q n -(*$R - let n = 1000 in - let lists = [| CCList.(1 -- n) ; CCList.(n+1 -- 2*n); CCList.(2*n+1 -- 3*n) |] in - let q = create 2 in - let senders = CCThread.Arr.spawn 3 - (fun i -> - if i=1 - then push_list q lists.(i) (* test push_list *) - else List.iter (push q) lists.(i) - ) - in - let res = CCLock.create [] in - let receivers = CCThread.Arr.spawn 3 - (fun i -> - if i=1 then - let l = take_list q n in - CCLock.update res (fun acc -> l @ acc) - else - for _j = 1 to n do - let x = take q in - CCLock.update res (fun acc -> x::acc) - done - ) - in - CCThread.Arr.join senders; CCThread.Arr.join receivers; - let l = CCLock.get res |> List.sort Stdlib.compare in - assert_equal CCList.(1 -- 3*n) l -*) - let try_take q = with_lock_ q (fun () -> diff --git a/src/threads/CCLock.ml b/src/threads/CCLock.ml index d916f371..dc092099 100644 --- a/src/threads/CCLock.ml +++ b/src/threads/CCLock.ml @@ -25,16 +25,6 @@ let with_lock l f = Mutex.unlock l.mutex; raise e -(*$R - let l = create 0 in - let try_incr l = - update l (fun x -> Thread.yield(); x+1) - in - for i = 1 to 10 do ignore (Thread.create try_incr l) done; - Thread.delay 0.10 ; - assert_equal 10 (get l) -*) - let try_with_lock l f = if Mutex.try_lock l.mutex then @@ -64,35 +54,11 @@ let with_lock_as_ref l ~f = Mutex.unlock l.mutex; raise e -(*$R - let l = create 0 in - let test_it l = - with_lock_as_ref l - ~f:(fun r -> - (* increment and decrement *) - for j = 0 to 100 do - let x = LockRef.get r in - LockRef.set r (x+10); - if j mod 5=0 then Thread.yield (); - let y = LockRef.get r in - LockRef.set r (y - 10); - done - ) - in - for i = 1 to 100 do ignore (Thread.create test_it l) done; - Thread.delay 0.10; - assert_equal 0 (get l) -*) - let mutex l = l.mutex let update l f = with_lock l (fun x -> l.content <- f x) -(*$T - let l = create 5 in update l (fun x->x+1); get l = 6 -*) - let update_map l f = with_lock l (fun x -> @@ -100,10 +66,6 @@ let update_map l f = l.content <- x'; y) -(*$T - let l = create 5 in update_map l (fun x->x+1, string_of_int x) = "5" && get l = 6 -*) - let get l = Mutex.lock l.mutex; let x = l.content in @@ -115,28 +77,10 @@ let set l x = l.content <- x; Mutex.unlock l.mutex -(*$T - let l = create 0 in set l 4; get l = 4 - let l = create 0 in set l 4; set l 5; get l = 5 -*) - let incr l = update l Stdlib.succ let decr l = update l Stdlib.pred - -(*$R - let l = create 0 in - let a = Array.init 100 (fun _ -> Thread.create (fun _ -> incr l) ()) in - Array.iter Thread.join a; - assert_equal ~printer:CCInt.to_string 100 (get l) -*) - -(*$T - let l = create 0 in incr l ; get l = 1 - let l = create 0 in decr l ; get l = ~-1 -*) - let incr_then_get l = Mutex.lock l.mutex; l.content <- l.content + 1; @@ -165,13 +109,6 @@ let get_then_decr l = Mutex.unlock l.mutex; x -(*$T - let l = create 0 in 1 = incr_then_get l && 1 = get l - let l = create 0 in 0 = get_then_incr l && 1 = get l - let l = create 10 in 9 = decr_then_get l && 9 = get l - let l = create 10 in 10 = get_then_decr l && 9 = get l -*) - let get_then_set l = Mutex.lock l.mutex; let x = l.content in diff --git a/src/threads/CCPool.ml b/src/threads/CCPool.ml index fc138a47..6e114e1a 100644 --- a/src/threads/CCPool.ml +++ b/src/threads/CCPool.ml @@ -15,13 +15,6 @@ end exception Stopped -(*$inject - module P = Make(struct let max_size = 30 end) - module P2 = Make(struct let max_size = 15 end) - module Fut = P.Fut - module Fut2 = P2.Fut -*) - (** {2 Thread pool} *) module Make(P : PARAM) = struct type job = @@ -293,38 +286,6 @@ module Make(P : PARAM) = struct let make f = make1 f () - (*$R - List.iter - (fun n -> - let l = Iter.(1 -- n) |> Iter.to_list in - let l = List.rev_map (fun i -> - Fut.make - (fun () -> - Thread.delay 0.01; - 1 - )) l in - let l' = List.map Fut.get l in - OUnit2.assert_equal n (List.fold_left (+) 0 l'); - ) - [ 10; 300; ] - *) - - (*$R - List.iter - (fun n -> - let l = Iter.(1 -- n) |> Iter.to_list in - let l = List.rev_map (fun i -> - Fut2.make - (fun () -> - Thread.delay 0.01; - 1 - )) l in - let l' = List.map Fut2.get l in - OUnit2.assert_equal n (List.fold_left (+) 0 l'); - ) - [ 10; 300; ] - *) - let make2 f x y = let cell = create_cell() in @@ -439,27 +400,6 @@ module Make(P : PARAM) = struct let app_async f x = app_ ~async:true f x - (*$R - let a = Fut.make (fun () -> 1) in - let b = Fut.return 42 in - let c = Fut.monoid_product CCPair.make a b in - OUnit2.assert_equal (1,42) (Fut.get c) - *) - - (*$R - let a = Fut.make (fun () -> 1) in - let b = Fut.make (fun () -> 42) in - let c = Fut.monoid_product CCPair.make a b in - OUnit2.assert_equal (1,42) (Fut.get c) - *) - - (*$R - let a = Fut.make (fun () -> 1) in - let b = Fut.map succ @@ Fut.make (fun () -> 41) in - let c = Fut.monoid_product CCPair.make a b in - OUnit2.assert_equal (1,42) (Fut.get c) - *) - let monoid_product f x y = match x, y with | Return x, Return y -> Return (f x y) | FailNow e, _ @@ -568,96 +508,6 @@ module Make(P : PARAM) = struct sequence_ (L_ l) (fun () -> List.rev_map get_nolock_ l) - (*$= - [2;3] (Fut.get @@ Fut.map_l (fun x -> Fut.return (x+1)) [1;2]) - [] (Fut.get @@ Fut.map_l (fun x -> Fut.return (x+1)) []) - *) - - (*$R - let l = CCList.(1 -- 50) in - let l' = l - |> List.map - (fun x -> Fut.make (fun () -> Thread.delay 0.1; x*10)) - |> Fut.sequence_l - |> Fut.map (List.fold_left (+) 0) - in - let expected = List.fold_left (fun acc x -> acc + 10 * x) 0 l in - OUnit2.assert_equal expected (Fut.get l') - *) - - (*$R - let l = CCList.(1 -- 100_000) in - let l' = l - |> CCList.map - (fun x -> Fut.make (fun () -> 1)) - |> Fut.sequence_l - |> Fut.map (List.fold_left (+) 0) - in - let expected = 100_000 in - OUnit2.assert_equal expected (Fut.get l') - *) - - (*$R - let l = CCList.(1 -- 50) in - let l' = l - |> List.map - (fun x -> Fut.make (fun () -> Thread.delay 0.1; if x = 5 then raise Exit; x)) - |> Fut.sequence_l - |> Fut.map (List.fold_left (+) 0) - in - OUnit2.assert_raises Exit (fun () -> Fut.get l') - *) - - (*$R - let rec fib x = if x<2 then 1 else fib (x-1)+fib(x-2) in - let l = - CCList.(1--10_000) - |> List.rev_map - (fun x-> Fut.make (fun () -> Thread.yield(); fib (x mod 20))) - |> Fut.(map_l (fun x->x>|= fun x->x+1)) - in - OUnit2.assert_bool "not done" (Fut.state l = Waiting); - let l' = Fut.get l in - OUnit2.assert_equal 10_000 (List.length l'); - *) - - (*$R - let l = CCList.(1 -- 50) in - let l' = l - |> List.map - (fun x -> Fut2.make (fun () -> Thread.delay 0.1; x*10)) - |> Fut2.sequence_l - |> Fut2.map (List.fold_left (+) 0) - in - let expected = List.fold_left (fun acc x -> acc + 10 * x) 0 l in - OUnit2.assert_equal expected (Fut2.get l') - *) - - (*$R - let l = CCList.(1 -- 50) in - let l' = l - |> List.map - (fun x -> Fut2.make (fun () -> Thread.delay 0.1; if x = 5 then raise Exit; x)) - |> Fut2.sequence_l - |> Fut2.map (List.fold_left (+) 0) - in - OUnit2.assert_raises Exit (fun () -> Fut2.get l') - *) - - (*$R - let rec fib x = if x<2 then 1 else fib (x-1)+fib(x-2) in - let l = - CCList.(1--10_000) - |> List.rev_map - (fun x-> Fut2.make (fun () -> Thread.yield(); fib (x mod 20))) - |> Fut2.(map_l (fun x->x>|= fun x->x+1)) - in - OUnit2.assert_bool "not done" (Fut2.state l = Waiting); - let l' = Fut2.get l in - OUnit2.assert_equal 10_000 (List.length l'); - *) - - let choose_ : type a. a t array_or_list -> a t = fun aol -> @@ -682,28 +532,6 @@ module Make(P : PARAM) = struct let sleep time = make1 Thread.delay time - (*$R - let start = Unix.gettimeofday () in - let pause = 0.2 and n = 10 in - let l = CCList.(1 -- n) - |> List.map (fun _ -> Fut.make (fun () -> Thread.delay pause)) - in - List.iter Fut.get l; - let stop = Unix.gettimeofday () in - OUnit2.assert_bool "some_parallelism" (stop -. start < float_of_int n *. pause); - *) - - (*$R - let start = Unix.gettimeofday () in - let pause = 0.2 and n = 10 in - let l = CCList.(1 -- n) - |> List.map (fun _ -> Fut2.make (fun () -> Thread.delay pause)) - in - List.iter Fut2.get l; - let stop = Unix.gettimeofday () in - OUnit2.assert_bool "some_parallelism" (stop -. start < float_of_int n *. pause); - *) - module Infix = struct let (>>=) x f = flat_map f x let (>>) a f = and_then a f diff --git a/src/threads/CCSemaphore.ml b/src/threads/CCSemaphore.ml index dcf1fb60..5e99f2f5 100644 --- a/src/threads/CCSemaphore.ml +++ b/src/threads/CCSemaphore.ml @@ -40,18 +40,6 @@ let release m t = release_once_locked_ m t; () -(*$R - let s = create 1 in - let r = CCLock.create false in - let _ = Thread.create (fun s -> acquire 5 s; CCLock.set r true) s in - Thread.yield (); - assert_equal false (CCLock.get r); - release 4 s; - Thread.delay 0.2; - assert_equal true (CCLock.get r); - assert_equal 0 (get s) -*) - let with_acquire ~n t ~f = acquire n t; try @@ -62,22 +50,6 @@ let with_acquire ~n t ~f = release n t; raise e -(*$R - let s = create 5 in - let n = CCLock.create 0 in - let a = Array.init 100 (fun i -> - Thread.create (fun _ -> - for _i = 1 to 100 do - with_acquire ~n:(1 + (i mod 5)) s - ~f:(fun () -> Thread.yield(); CCLock.incr n) - done) - ()) - in - Array.iter Thread.join a; - assert_equal ~printer:CCInt.to_string 5 (get s); - assert_equal ~printer:CCInt.to_string 10_000 (CCLock.get n) -*) - let wait_until_at_least ~n t ~f = Mutex.lock t.mutex; while t.n < n do @@ -86,33 +58,3 @@ let wait_until_at_least ~n t ~f = assert (t.n >= n); Mutex.unlock t.mutex; f () - -(*$R - let output s = () in - let s = create 2 in - let res = CCLock.create false in - let id = Thread.create - (fun () -> - output "start"; - wait_until_at_least ~n:5 s - ~f:(fun () -> - assert (get s >= 5); - output "modify now"; - CCLock.set res true) - ) () - in - output "launched thread"; - Thread.yield(); - assert_bool "start" (not (CCLock.get res)); - output "release 2"; - release 2 s; - Thread.yield(); - assert_bool "after release 2" (not (CCLock.get res)); - output "release 1"; - release 1 s; - (* should work now *) - Thread.delay 0.2; - Thread.join id; - output "check"; - assert_bool "after release 1" (CCLock.get res) -*) diff --git a/src/threads/CCThread.ml b/src/threads/CCThread.ml index 236dd91e..d39eb7a4 100644 --- a/src/threads/CCThread.ml +++ b/src/threads/CCThread.ml @@ -28,14 +28,6 @@ module Arr = struct let join a = Array.iter Thread.join a end -(*$R - let l = CCLock.create 0 in - let a = Arr.spawn 101 (fun i -> CCLock.update l ((+) i)) in - Arr.join a; - let n = Iter.(1 -- 100 |> fold (+) 0) in - assert_equal ~printer:CCInt.to_string n (CCLock.get l) -*) - module Barrier = struct type t = { lock: Mutex.t; @@ -71,15 +63,3 @@ module Barrier = struct let activated b = with_lock_ b (fun () -> b.activated) end - -(*$R - let b = Barrier.create () in - let res = CCLock.create 0 in - let t1 = spawn (fun _ -> Barrier.wait b; CCLock.incr res) - and t2 = spawn (fun _ -> Barrier.wait b; CCLock.incr res) in - Thread.delay 0.2; - assert_equal 0 (CCLock.get res); - Barrier.activate b; - Thread.join t1; Thread.join t2; - assert_equal 2 (CCLock.get res) -*) diff --git a/src/threads/CCTimer.ml b/src/threads/CCTimer.ml index 97783d04..e93b0211 100644 --- a/src/threads/CCTimer.ml +++ b/src/threads/CCTimer.ml @@ -1,8 +1,4 @@ -(* This file is free software, part of containers. See file "license" for more details. *) - -(** {1 Event timer} *) - type job = | Job : float * (unit -> 'a) -> job @@ -153,27 +149,6 @@ let every ?delay timer d ~f = | None -> run() | Some d -> after timer d ~f:run -(*$R - let start = Unix.gettimeofday() in - let timer = create() in - let res = CCLock.create 0 in - let sem = CCSemaphore.create 1 in - CCSemaphore.acquire 1 sem; - let stop = ref 0. in - every timer 0.1 - ~f:(fun () -> - if CCLock.incr_then_get res > 5 then ( - stop := Unix.gettimeofday(); - CCSemaphore.release 1 sem; - raise ExitEvery - )); - CCSemaphore.acquire 1 sem; (* wait *) - OUnit2.assert_equal ~printer:CCInt.to_string 6 (CCLock.get res); - OUnit2.assert_bool "delay >= 0.5" (!stop -. start >= 0.49999); - OUnit2.assert_bool "delay < 2." (!stop -. start < 2.); -*) -(* NOTE: could be tighter bounds, but travis' mac OS seems to be dog slow. *) - let active timer = not timer.stop (** Stop the given timer, cancelling pending tasks *) @@ -188,18 +163,3 @@ let stop timer = awaken_ timer; ) ) - -(*$R - (* scenario: n := 1; n := n*4 ; n := n+2; res := n *) - let timer = create () in - let n = CCLock.create 1 in - let res = CCLock.create 0 in - after timer 0.3 - ~f:(fun () -> CCLock.update n (fun x -> x+2)); - ignore (Thread.create - (fun _ -> Thread.delay 0.4; CCLock.set res (CCLock.get n)) ()); - after timer 0.1 - ~f:(fun () -> CCLock.update n (fun x -> x * 4)); - Thread.delay 0.6 ; - OUnit2.assert_equal ~printer:Q.Print.int 6 (CCLock.get res); -*) diff --git a/src/threads/CCTimer.mli b/src/threads/CCTimer.mli index a8ad53cd..b87a920c 100644 --- a/src/threads/CCTimer.mli +++ b/src/threads/CCTimer.mli @@ -1,7 +1,5 @@ -(* This file is free software, part of containers. See file "license" for more details. *) - -(** {1 Event timer} +(** Event timer Used to be part of [CCFuture]. @since 0.16 *) diff --git a/tests/data/dune b/tests/data/dune new file mode 100644 index 00000000..ce956cc4 --- /dev/null +++ b/tests/data/dune @@ -0,0 +1,5 @@ +(test + (name t) + (flags :standard -strict-sequence -warn-error -a+8 -open CCShims_) + (modes native) + (libraries containers containers-data containers_testlib iter)) diff --git a/tests/data/t.ml b/tests/data/t.ml new file mode 100644 index 00000000..22060cf6 --- /dev/null +++ b/tests/data/t.ml @@ -0,0 +1,8 @@ + +Containers_testlib.run_all ~descr:"containers-data" [ + T_bv.Test.get(); + T_bijection.Test.get(); + T_bitfield.Test.get(); + T_cache.Test.get(); + T_deque.Test.get(); +];; diff --git a/tests/data/t_bijection.ml b/tests/data/t_bijection.ml new file mode 100644 index 00000000..87f3649d --- /dev/null +++ b/tests/data/t_bijection.ml @@ -0,0 +1,13 @@ + +module Test = (val Containers_testlib.make ~__FILE__()) +open Test +open CCBijection;; + +module M = Make(Int)(String);; + + +eq 2 (M.of_list [1,"1"; 2, "2"] |> M.cardinal);; +eq "1" (M.of_list [1,"1"; 2, "2"] |> M.find_left 1);; +eq "2" (M.of_list [1,"1"; 2, "2"] |> M.find_left 2);; +eq 1 (M.of_list [1,"1"; 2, "2"] |> M.find_right "1");; +eq 2 (M.of_list [1,"1"; 2, "2"] |> M.find_right "2");; diff --git a/tests/data/t_bitfield.ml b/tests/data/t_bitfield.ml new file mode 100644 index 00000000..1bfd96a1 --- /dev/null +++ b/tests/data/t_bitfield.ml @@ -0,0 +1,59 @@ + + +module Test = (val Containers_testlib.make ~__FILE__()) +open Test +open CCBitField;; + +t @@ fun () -> + let module B = CCBitField.Make(struct end) in + let x = B.mk_field () in + let y = B.mk_field () in + let z = B.mk_field () in + + let f = B.empty |> B.set x true |> B.set y true in + + assert_bool "z_false" (not (B.get z f)) ; + + assert_bool "z_true" (f |> B.set z true |> B.get z); + true;; + +t @@ fun () -> + let module B = CCBitField.Make(struct end) in + let _ = B.mk_field () in + B.freeze(); + assert_bool "must raise" + (try ignore (B.mk_field()); false with Frozen -> true); + true;; + +t @@ fun () -> + let module B = CCBitField.Make(struct end) in + + let x = B.mk_field () in + let y = B.mk_field () in + let z = B.mk_field () in + let u = B.mk_field () in + B.freeze(); + + let f = B.empty + |> B.set y true + |> B.set z true + in + + assert_equal ~printer:CCInt.to_string 6 (f :> int) ; + + assert_equal false (B.get x f) ; + assert_equal true (B.get y f) ; + assert_equal true (B.get z f); + + let f' = B.set u true f in + + assert_equal false (B.get x f') ; + assert_equal true (B.get y f') ; + assert_equal true (B.get z f'); + assert_equal true (B.get u f'); + true;; + +t @@ fun () -> all_bits_ 0 1 = 1;; +t @@ fun () -> all_bits_ 0 2 = 3;; +t @@ fun () -> all_bits_ 0 3 = 7;; +t @@ fun () -> all_bits_ 0 4 = 15;; diff --git a/tests/data/t_bv.ml b/tests/data/t_bv.ml new file mode 100644 index 00000000..f21e7e24 --- /dev/null +++ b/tests/data/t_bv.ml @@ -0,0 +1,249 @@ + +module Test = (val Containers_testlib.make ~__FILE__()) +open Test +open CCBV;; + +let ppli = CCFormat.(Dump.list int);; + +q (Q.pair Q.small_int Q.bool) (fun (size, b) -> create ~size b |> length = size);; + +t @@ fun () -> create ~size:17 true |> cardinal = 17;; +t @@ fun () -> create ~size:32 true |> cardinal = 32;; +t @@ fun () -> create ~size:132 true |> cardinal = 132;; +t @@ fun () -> create ~size:200 false |> cardinal = 0;; +t @@ fun () -> create ~size:29 true |> to_sorted_list = CCList.range 0 28;; + +q (Q.list Q.small_int) (fun l -> + let bv = of_list l in to_list bv = to_list (copy bv));; + +q Q.small_int (fun size -> create ~size true |> cardinal = size);; + +t @@ fun () -> + let bv1 = CCBV.create ~size:87 true in + assert_equal ~printer:string_of_int 87 (CCBV.cardinal bv1); + true;; + +q Q.small_int (fun n -> CCBV.cardinal (CCBV.create ~size:n true) = n);; + +t @@ fun () -> + let bv = CCBV.create ~size:99 false in + assert_bool "32 must be false" (not (CCBV.get bv 32)); + assert_bool "88 must be false" (not (CCBV.get bv 88)); + assert_bool "5 must be false" (not (CCBV.get bv 5)); + CCBV.set bv 32; + CCBV.set bv 88; + CCBV.set bv 5; + assert_bool "32 must be true" (CCBV.get bv 32); + assert_bool "88 must be true" (CCBV.get bv 88); + assert_bool "5 must be true" (CCBV.get bv 5); + assert_bool "33 must be false" (not (CCBV.get bv 33)); + assert_bool "44 must be false" (not (CCBV.get bv 44)); + assert_bool "1 must be false" (not (CCBV.get bv 1)); + true;; + +t @@ fun () -> let bv = create ~size:3 false in set bv 0; get bv 0;; +t @@ fun () -> let bv = create ~size:3 false in set bv 1; not (get bv 0);; +t @@ fun () -> let bv = create ~size:3 false in set bv 0; reset bv 0; not (get bv 0);; + +t @@ fun () -> + let bv = of_list [1;10; 11; 30] in + flip bv 10; + assert_equal ~printer:Q.Print.(list int) [1;11;30] (to_sorted_list bv); + assert_equal ~printer:Q.Print.bool false (get bv 10); + flip bv 10; + assert_equal ~printer:Q.Print.bool true (get bv 10); + flip bv 5; + assert_equal ~printer:Q.Print.(list int) [1;5;10;11;30] (to_sorted_list bv); + assert_equal ~printer:Q.Print.bool true (get bv 5); + flip bv 100; + assert_equal ~printer:Q.Print.(list int) [1;5;10;11;30;100] (to_sorted_list bv); + assert_equal ~printer:Q.Print.bool true (get bv 100); + true;; + +t @@ fun () -> let bv = create ~size:37 true in cardinal bv = 37 && (clear bv; cardinal bv= 0);; + +t @@ fun () -> + let bv = CCBV.of_list [1; 5; 200] in + assert_equal ~printer:string_of_int 3 (CCBV.cardinal bv); + CCBV.clear bv; + assert_equal ~printer:string_of_int 0 (CCBV.cardinal bv); + assert_bool "must be empty" (CCBV.is_empty bv); + true;; + +t @@ fun () -> equal (of_list [1; 3; 4]) (of_list [1; 3; 4]);; +t @@ fun () -> equal (empty()) (empty());; +t @@ fun () -> not (equal (empty ()) (of_list [1]));; +t @@ fun () -> not (equal (empty ()) (of_list [2; 5]));; +t @@ fun () -> not (equal (of_list [1;3]) (of_list [2; 3]));; + +t @@ fun () -> + List.iter + (fun size -> + let bv = create ~size false in + set bv 5; + let n = ref 0 in + iter bv (fun i b -> incr n; assert_equal b (i=5)); + assert_bool "exactly size" (!n = size)) + [30; 100; 255; 256;10_000]; + true;; + +let iter_zip s k = s (fun x y -> k(x,y));; + +let eq' = eq ~printer:Q.Print.(list (pair int bool)) ;; +eq' [] (iter (create ~size:0 false) |> iter_zip |> Iter.to_list);; +eq' [0, false; 1, true; 2, false] +(iter (let bv = create ~size:3 false in set bv 1; bv) |> iter_zip |> Iter.to_list);; + +q Q.(small_int) (fun n -> + assert (n >= 0); + let bv = create ~size:n true in + let l = iter bv |> iter_zip |> Iter.to_list in + List.length l = n && List.for_all (fun (_,b) -> b) l);; + +t @@ fun () -> of_list [1;5;7] |> iter_true |> Iter.to_list |> List.sort CCOrd.poly = [1;5;7];; + +let _gen = Q.Gen.(map of_list (list nat)) +let _pp bv = Q.Print.(list string) (List.map string_of_int (to_list bv)) +let _small bv = length bv + +let gen_bv = Q.make ~small:_small ~print:_pp _gen;; + +q gen_bv (fun bv -> + let l' = Iter.to_rev_list (CCBV.iter_true bv) in + let bv' = CCBV.of_list l' in + CCBV.cardinal bv = CCBV.cardinal bv' +);; + +t @@ fun () -> + let bv = CCBV.of_list [1; 5; 156; 0; 222] in + assert_equal ~printer:string_of_int 5 (CCBV.cardinal bv); + CCBV.set bv 201; + assert_equal ~printer:string_of_int 6 (CCBV.cardinal bv); + let l = CCBV.to_list bv in + let l = List.sort compare l in + assert_equal [0;1;5;156;201;222] l; + true;; + +eq ~printer:(CCFormat.to_string ppli) + [1;2;3;4;64;130] (of_list [1;2;3;4;64;130] |> to_sorted_list);; + +q Q.(small_list small_nat) (fun l -> + let l = List.sort_uniq CCOrd.poly l in + let l2 = of_list l |> to_sorted_list in + if l=l2 then true else Q.Test.fail_reportf "l1=%a, l2=%a" ppli l ppli l2);; +q Q.(small_list small_nat) (fun l -> + let bv = of_list l in + let l1 = bv |> to_sorted_list in + let l2 = + (CCList.init (length bv) (get bv) |> List.mapi (fun i b->i,b) + |>CCList.filter_map (function (i,true) -> Some i| _ ->None)) in + if l1=l2 then true else Q.Test.fail_reportf "l1=%a, l2=%a" ppli l1 ppli l2) ;; + +eq ~cmp:equal ~printer:(CCFormat.to_string pp) + (of_list [0]) (let bv=empty() in set bv 0; bv);; + +t @@ fun () -> of_list [1;32;64] |> CCFun.flip get 64;; +t @@ fun () -> of_list [1;32;64] |> CCFun.flip get 32;; +t @@ fun () -> of_list [1;31;63] |> CCFun.flip get 63;; +t @@ fun () -> of_list [50; 10; 17; 22; 3; 12] |> first = Some 3;; +t @@ fun () -> let bv = of_list [1;2;3;4;5;6;7] in filter bv (fun x->x mod 2=0); + to_sorted_list bv = [2;4;6];; + +eq ~printer:(CCFormat.to_string ppli) + [0;3;4;6] (let v = of_list [1;2;5;7;] in negate_self v; to_sorted_list v);; + +q Q.small_int (fun size -> create ~size false |> negate |> cardinal = size);; + +t @@ fun () -> + let bv1 = CCBV.of_list [1;2;3;4] in + let bv2 = CCBV.of_list [4;200;3] in + let bv = CCBV.union bv1 bv2 in + let l = List.sort compare (CCBV.to_list bv) in + assert_equal ~printer:(CCFormat.(to_string (Dump.list int))) + [1;2;3;4;200] l; + true;; + +t @@ fun () -> + let bv1 = CCBV.of_list [1;2;3;4;64;130] in + let bv2 = CCBV.of_list [4;64;3;120] in + let bv = CCBV.union bv1 bv2 in + assert_equal ~cmp:equal ~printer:(CCFormat.to_string pp) + (of_list [1;2;3;4;64;120;130]) bv; + true;; + +t @@ fun () -> + let bv1 = CCBV.of_list [1;2;3;4] in + let bv2 = CCBV.of_list [4;200;3] in + let bv = CCBV.union bv1 bv2 in + assert_equal ~cmp:equal ~printer:(CCFormat.to_string pp) + (of_list [1;2;3;4;200]) bv; + true;; + +t @@ fun () -> + let v1 = CCBV.empty () in + let () = CCBV.set v1 64 in + let v2 = CCBV.diff (CCBV.empty ()) (CCBV.empty ()) in + let v3 = CCBV.union v1 v2 in + assert_equal ~printer:(CCFormat.to_string pp) ~cmp:CCBV.equal v1 v3; + true;; + +t @@ fun () -> union (of_list [1;2;3;4;5]) (of_list [7;3;5;6]) |> to_sorted_list = CCList.range 1 7;; +t @@ fun () -> inter (of_list [1;2;3;4]) (of_list [2;4;6;1]) |> to_sorted_list = [1;2;4];; + +t @@ fun () -> + let bv1 = CCBV.of_list [1;2;3;4;200;201] in + let bv2 = CCBV.of_list [4;200;3] in + let bv = CCBV.inter bv1 bv2 in + let l = List.sort compare (CCBV.to_list bv) in + assert_equal ~printer:(CCFormat.(to_string (Dump.list int))) + [3;4;200] l; + true;; + +t @@ fun () -> + let bv1 = CCBV.of_list [1;2;3;4] in + let bv2 = CCBV.of_list [4;200;3] in + CCBV.inter_into ~into:bv1 bv2; + let l = List.sort compare (CCBV.to_list bv1) in + assert_equal [3;4] l; + true;; + +t @@ fun () -> diff (of_list [1;2;3]) (of_list [1;2;3]) |> to_list = [];; +t @@ fun () -> diff (of_list [1;2;3]) (of_list [1;2;3;4]) |> to_list = [];; +t @@ fun () -> diff (of_list [1;2;3;4]) (of_list [1;2;3]) |> to_list = [4];; +t @@ fun () -> diff (of_list [1;2;3]) (of_list [1;2;3;400]) |> to_list = [];; +t @@ fun () -> diff (of_list [1;2;3;400]) (of_list [1;2;3]) |> to_list = [400];; + +t @@ fun () -> + let v1 = CCBV.empty () in + set v1 65; + let v2 = CCBV.diff v1 v1 in + CCBV.is_empty v2 ;; + +t @@ fun () -> + let bv = CCBV.of_list [1;2;5;400] in + let arr = [|"a"; "b"; "c"; "d"; "e"; "f"|] in + let l = List.sort compare (CCBV.select bv arr) in + assert_equal ["b"; "c"; "f"] l; + true;; + +t @@ fun () -> + let bv = CCBV.of_list [1;2;5;400] in + let arr = [|"a"; "b"; "c"; "d"; "e"; "f"|] in + let l = List.sort compare (CCBV.selecti bv arr) in + assert_equal [("b",1); ("c",2); ("f",5)] l; + true;; + +eq ~printer:Q.Print.(list (pair int int)) + [1,1; 3,3; 4,4] (selecti (of_list [1;4;3]) [| 0;1;2;3;4;5;6;7;8 |] + |> List.sort CCOrd.poly);; + +q Q.(small_int) (fun i -> + let i = max 1 i in + let bv = create ~size:i true in + i = (to_iter bv |> Iter.length));; + +t @@ fun () -> CCList.range 0 10 |> CCList.to_iter |> of_iter |> to_iter + |> CCList.of_iter |> List.sort CCOrd.poly = CCList.range 0 10;; + +eq ~printer:CCFun.id + "bv {00001}" (CCFormat.to_string pp (of_list [4]));; diff --git a/tests/data/t_cache.ml b/tests/data/t_cache.ml new file mode 100644 index 00000000..430b5847 --- /dev/null +++ b/tests/data/t_cache.ml @@ -0,0 +1,47 @@ + +module Test = (val Containers_testlib.make ~__FILE__()) +open Test +open CCCache;; + +t @@ fun () -> + let c = unbounded ~eq:Int64.equal 256 in + let fib = with_cache_rec c + (fun self n -> match n with + | 1L | 2L -> 1L + | _ -> CCInt64.(self (n-1L) + self (n-2L)) + ) + in + assert_equal 55L (fib 10L); + assert_equal 832040L (fib 30L); + assert_equal 12586269025L (fib 50L); + assert_equal 190392490709135L (fib 70L); + true;; + + +t @@ fun () -> + let eq (i1,_)(i2,_) = i1=i2 and hash (i,_) = CCInt.hash i in + let c = lru ~eq ~hash 2 in + ignore (with_cache c CCFun.id (1, true)); + ignore (with_cache c CCFun.id (1, false)); + with_cache c CCFun.id (1, false) = (1, true);; + +t @@ fun () -> + let f = (let r = ref 0 in fun _ -> incr r; !r) in + let c = lru ~eq:CCInt.equal 2 in + let res1 = with_cache c f 1 in + let res2 = with_cache c f 2 in + let res3 = with_cache c f 3 in + let res1_bis = with_cache c f 1 in + res1 <> res2 && res2 <> res3 && res3 <> res1_bis && res1_bis <> res1;; + +t @@ fun () -> + let f = (let r = ref 0 in fun _ -> incr r; !r) in + let c = lru ~eq:CCEqual.unit 2 in + let x = with_cache c f () in + assert_equal 1 x; + assert_equal 1 (size c); + clear c ; + assert_equal 0 (size c); + let y = with_cache c f () in + assert_equal 2 y; + true;; diff --git a/tests/data/t_deque.ml b/tests/data/t_deque.ml new file mode 100644 index 00000000..d4923d5c --- /dev/null +++ b/tests/data/t_deque.ml @@ -0,0 +1,193 @@ + +module Test = (val Containers_testlib.make ~__FILE__()) +open Test +open CCDeque;; + +let plist l = CCFormat.(to_string (list int)) l +let pint i = string_of_int i;; + +t @@ fun () -> + let q = create () in + add_iter_back q Iter.(3 -- 5); + assert_equal [3;4;5] (to_list q); + add_iter_front q Iter.(of_list [2;1]); + assert_equal [1;2;3;4;5] (to_list q); + push_front q 0; + assert_equal [0;1;2;3;4;5] (to_list q); + assert_equal 5 (take_back q); + assert_equal 0 (take_front q); + assert_equal 4 (length q); + true;; + +t @@ fun () -> + let q = of_iter Iter.(1 -- 100) in + assert_equal 100 (length q); + clear q; + assert_equal 0 (length q); + assert_raises ((=)Empty) (fun () -> peek_front q); + assert_raises ((=)Empty) (fun () -> peek_back q); + true;; + +t @@ fun () -> of_list [1;2;3] |> peek_front = 1;; +t @@ fun () -> try (ignore (of_list [] |> peek_front); false) with Empty -> true;; + +t @@ fun () -> + let d = of_iter Iter.(1 -- 10) in + let printer = pint in + assert_equal ~printer 1 (peek_front d); + push_front d 42; + assert_equal ~printer 42 (peek_front d); + assert_equal ~printer 42 (take_front d); + assert_equal ~printer 1 (take_front d); + assert_equal ~printer 2 (take_front d); + assert_equal ~printer 3 (take_front d); + assert_equal ~printer 10 (peek_back d); + true;; + +t @@ fun () -> of_list [1;2;3] |> peek_back = 3;; +t @@ fun () -> try (ignore (of_list [] |> peek_back); false) with Empty -> true;; + +t @@ fun () -> + let d = of_iter Iter.(1 -- 10) in + let printer = pint in + assert_equal ~printer 1 (peek_front d); + push_back d 42; + assert_equal ~printer 42 (peek_back d); + assert_equal ~printer 42 (take_back d); + assert_equal ~printer 10 (take_back d); + assert_equal ~printer 9 (take_back d); + assert_equal ~printer 8 (take_back d); + assert_equal ~printer 1 (peek_front d); + true;; + +t @@ fun () -> let q = of_list [1] in take_back q = 1 && to_list q = [];; +t @@ fun () -> let q = of_list [1;2] in take_back q = 2 && to_list q = [1];; +t @@ fun () -> let q = of_list [1;2;3] in take_back q = 3 && to_list q = [1;2];; +t @@ fun () -> let q = of_list [1;2;3;4;5;6;7;] in take_back q = 7 && to_list q = [1;2;3;4;5;6];; + +t @@ fun () -> let q = of_list [1;2;3] in take_front q = 1 && to_list q = [2;3];; +t @@ fun () -> let q = of_list [1;2;3;4;5;6;7] in remove_back q; to_list q = [1;2;3;4;5;6];; +t @@ fun () -> let q = of_list [1;2;3;4;5;6;7] in remove_front q; to_list q = [2;3;4;5;6;7];; +t @@ fun () -> let q = of_list [1;2;3;4;5;6;7] in update_front q (fun _ -> None); to_list q = [2;3;4;5;6;7];; +t @@ fun () -> let q = of_list [1;2;3;4;5;6;7] in update_front q (fun _ -> Some 9); to_list q = [9;2;3;4;5;6;7];; + +q Q.(list int) (fun l -> + let q = of_list l in + update_front q (fun _ -> None); + let output_list = if l = [] then [] else List.tl l in + to_list q = output_list) ;; +q Q.(list int) (fun l -> + let q = of_list l in + update_front q (fun x -> Some (x + 42)); + let output_list = if l = [] then [] else List.((hd l + 42)::(tl l)) in + to_list q = output_list) ;; + +t @@ fun () -> let q = of_list [1;2;3;4;5;6;7] in update_back q (fun _ -> None); to_list q = [1;2;3;4;5;6];; +t @@ fun () -> let q = of_list [1;2;3;4;5;6;7] in update_back q (fun _ -> Some 9); to_list q = [1;2;3;4;5;6;9];; + +q Q.(list int) (fun l -> + let q = of_list l in + update_back q (fun _ -> None); + let output_list = if l = [] then [] else List.(rev l |> tl) in + (to_list q |> List.rev) = output_list);; +q Q.(list int) (fun l -> + let q = of_list l in + update_back q (fun x -> Some (x + 42)); + let output_list = if l = [] then [] else List.(rev l |> fun l -> (hd l + 42)::(tl l)) in + (to_list q |> List.rev) = output_list);; + +t @@ fun () -> let n = ref 0 in iter (fun _ -> incr n) (of_list [1;2;3]); !n = 3;; + +t @@ fun () -> + let d = of_iter Iter.(1 -- 5) in + let s = Iter.from_iter (fun k -> iter k d) in + let l = Iter.to_list s in + assert_equal ~printer:plist [1;2;3;4;5] l; + true;; + +t @@ fun () -> + let q = of_list [3;4] in + append_front ~into:q (of_list [2;1]); + assert_equal [1;2;3;4] (to_list q); + append_back ~into:q (of_list [5;6]); + assert_equal [1;2;3;4;5;6] (to_list q); + true;; + +t @@ fun () -> fold (+) 0 (of_list [1;2;3]) = 6;; +t @@ fun () -> fold (fun acc x -> x::acc) [] (of_list [1;2;3]) = [3;2;1];; + +q Q.(list int) (fun l -> + let q = of_list l in + append_front ~into:q (of_list l); + append_back ~into:q (of_list l); + length q = 3 * List.length l);; + + +t @@ fun () -> + let d = of_iter Iter.(1 -- 10) in + assert_equal ~printer:pint 10 (length d); + true;; + +t @@ fun () -> + let q = of_list [4;5] in + add_iter_front q Iter.(of_list [3;2;1]); + assert_equal [1;2;3;4;5] (to_list q); + add_iter_back q Iter.(of_list [6;7]); + assert_equal [1;2;3;4;5;6;7] (to_list q); + true;; + +q Q.(list int) (fun l -> + Iter.of_list l |> of_iter |> to_iter |> Iter.to_list = l);; + +t @@ fun () -> + let q = of_list [1;2;3] in + assert_equal 1 (take_front q); + assert_equal 3 (take_back q); + assert_equal 2 (take_front q); + assert_equal true (is_empty q); + true;; + +t @@ fun () -> + let q = of_list [1;2;3;4;5;6] in + filter_in_place q (fun x -> x mod 2 = 0); + assert_equal [2;4;6] (to_list q); + true;; + +t @@ fun () -> + let q = of_list [2;1;4;6;10;20] in + filter_in_place q (fun x -> x mod 2 = 0); + assert_equal [2;4;6;10;20] (to_list q); + true;; + +q Q.(list small_nat) (fun l -> + let f = fun x -> x mod 2=0 in + let q = of_list l in + (filter_in_place q f; to_list q) = (List.filter f l));; + +q Q.(list small_nat) (fun l -> + let f = fun x -> x mod 2=0 in + let q = filter f (of_list l) in + (to_list q) = (List.filter f l));; + +t @@ fun () -> of_list [1;2;3] |> to_gen |> of_gen |> to_list = [1;2;3];; + +q Q.(list int) (fun l -> + of_list l |> to_gen |> of_gen |> to_list = l);; + +t @@ fun () -> + let q = of_list [1;2;3;4] in + assert_equal 4 (length q); + let q' = copy q in + let cmp = equal ~eq:CCInt.equal in + assert_equal 4 (length q'); + assert_equal ~cmp q q'; + push_front q 0; + assert_bool "not equal" (not (cmp q q')); + assert_equal 5 (length q); + push_front q' 0; + assert_equal ~cmp q q'; + true;; + +q Q.(pair (list int) (list int)) (fun (l1,l2) -> + CCOrd.equiv (compare ~cmp:Stdlib.compare (of_list l1) (of_list l2)) + (CCList.compare Stdlib.compare l1 l2));; diff --git a/tests/thread/dune b/tests/thread/dune new file mode 100644 index 00000000..d8293c67 --- /dev/null +++ b/tests/thread/dune @@ -0,0 +1,5 @@ +(test + (name t) + (flags :standard -strict-sequence -warn-error -a+8 -open CCShims_) + (modes native) + (libraries containers containers-thread containers_testlib iter threads)) diff --git a/tests/thread/t.ml b/tests/thread/t.ml new file mode 100644 index 00000000..f5804ea7 --- /dev/null +++ b/tests/thread/t.ml @@ -0,0 +1,9 @@ + +Containers_testlib.run_all ~descr:"containers-thread" [ + T_bq.Test.get(); + T_lock.Test.get(); + T_pool.Test.get(); + T_semaphore.Test.get(); + T_thread.Test.get(); + T_timer.Test.get(); +];; diff --git a/tests/thread/t_bq.ml b/tests/thread/t_bq.ml new file mode 100644 index 00000000..2437083c --- /dev/null +++ b/tests/thread/t_bq.ml @@ -0,0 +1,47 @@ + +module Test = (val Containers_testlib.make ~__FILE__()) +open Test +open CCBlockingQueue;; + +t @@ fun () -> + let q = create 1 in + let t1 = CCThread.spawn (fun () -> push q 1; push q 2) in + let t2 = CCThread.spawn (fun () -> push q 3; push q 4) in + let l = CCLock.create [] in + let t3 = CCThread.spawn (fun () -> for _i = 1 to 4 do + let x = take q in + CCLock.update l (fun l -> x :: l) + done) + in + Thread.join t1; Thread.join t2; Thread.join t3; + assert_equal [1;2;3;4] (List.sort Stdlib.compare (CCLock.get l)); + true;; + +t @@ fun () -> + let n = 1000 in + let lists = [| CCList.(1 -- n) ; CCList.(n+1 -- 2*n); CCList.(2*n+1 -- 3*n) |] in + let q = create 2 in + let senders = CCThread.Arr.spawn 3 + (fun i -> + if i=1 + then push_list q lists.(i) (* test push_list *) + else List.iter (push q) lists.(i) + ) + in + let res = CCLock.create [] in + let receivers = CCThread.Arr.spawn 3 + (fun i -> + if i=1 then + let l = take_list q n in + CCLock.update res (fun acc -> l @ acc) + else + for _j = 1 to n do + let x = take q in + CCLock.update res (fun acc -> x::acc) + done + ) + in + CCThread.Arr.join senders; CCThread.Arr.join receivers; + let l = CCLock.get res |> List.sort Stdlib.compare in + assert_equal CCList.(1 -- 3*n) l; + true diff --git a/tests/thread/t_lock.ml b/tests/thread/t_lock.ml new file mode 100644 index 00000000..c46c4867 --- /dev/null +++ b/tests/thread/t_lock.ml @@ -0,0 +1,53 @@ + + +module Test = (val Containers_testlib.make ~__FILE__()) +open Test;; +open CCLock;; + +t @@ fun () -> + let l = create 0 in + let try_incr l = + update l (fun x -> Thread.yield(); x+1) + in + for _i = 1 to 10 do ignore (Thread.create try_incr l) done; + Thread.delay 0.10 ; + assert_equal 10 (get l); + true;; + +t @@ fun () -> + let l = create 0 in + let test_it l = + with_lock_as_ref l + ~f:(fun r -> + (* increment and decrement *) + for j = 0 to 100 do + let x = LockRef.get r in + LockRef.set r (x+10); + if j mod 5=0 then Thread.yield (); + let y = LockRef.get r in + LockRef.set r (y - 10); + done + ) + in + for _i = 1 to 100 do ignore (Thread.create test_it l) done; + Thread.delay 0.10; + 0 =get l;; + +t @@ fun () -> let l = create 5 in update l (fun x->x+1); get l = 6;; +t @@ fun () -> let l = create 5 in update_map l (fun x->x+1, string_of_int x) = "5" && get l = 6;; +t @@ fun () -> let l = create 0 in set l 4; get l = 4;; +t @@ fun () -> let l = create 0 in set l 4; set l 5; get l = 5;; + +t @@ fun () -> + let l = create 0 in + let a = Array.init 100 (fun _ -> Thread.create (fun _ -> incr l) ()) in + Array.iter Thread.join a; + assert_equal ~printer:CCInt.to_string 100 (get l); + true;; + +t @@ fun () -> let l = create 0 in incr l ; get l = 1;; +t @@ fun () -> let l = create 0 in decr l ; get l = ~-1;; +t @@ fun () -> let l = create 0 in 1 = incr_then_get l && 1 = get l;; +t @@ fun () -> let l = create 0 in 0 = get_then_incr l && 1 = get l;; +t @@ fun () -> let l = create 10 in 9 = decr_then_get l && 9 = get l;; +t @@ fun () -> let l = create 10 in 10 = get_then_decr l && 9 = get l;; diff --git a/tests/thread/t_pool.ml b/tests/thread/t_pool.ml new file mode 100644 index 00000000..2e7087a3 --- /dev/null +++ b/tests/thread/t_pool.ml @@ -0,0 +1,171 @@ + +module Test = (val Containers_testlib.make ~__FILE__()) +open Test +open CCPool;; + +module P = Make(struct let max_size = 30 end) +module P2 = Make(struct let max_size = 15 end) +module Fut = P.Fut +module Fut2 = P2.Fut;; + +t @@ fun () -> + List.iter + (fun n -> + let l = Iter.(1 -- n) |> Iter.to_list in + let l = List.rev_map (fun _i -> + Fut.make + (fun () -> + Thread.delay 0.01; + 1 + )) l in + let l' = List.map Fut.get l in + assert_equal n (List.fold_left (+) 0 l'); + ) + [ 10; 300; ]; + true;; + +t @@ fun () -> + List.iter + (fun n -> + let l = Iter.(1 -- n) |> Iter.to_list in + let l = List.rev_map (fun _i -> + Fut2.make + (fun () -> + Thread.delay 0.01; + 1 + )) l in + let l' = List.map Fut2.get l in + assert_equal n (List.fold_left (+) 0 l'); + ) + [ 10; 300; ]; + true;; + +t @@ fun () -> + let a = Fut.make (fun () -> 1) in + let b = Fut.return 42 in + let c = Fut.monoid_product CCPair.make a b in + assert_equal (1,42) (Fut.get c); + true;; + +t @@ fun () -> + let a = Fut.make (fun () -> 1) in + let b = Fut.make (fun () -> 42) in + let c = Fut.monoid_product CCPair.make a b in + assert_equal (1,42) (Fut.get c); + true;; + +t @@ fun () -> + let a = Fut.make (fun () -> 1) in + let b = Fut.map succ @@ Fut.make (fun () -> 41) in + let c = Fut.monoid_product CCPair.make a b in + assert_equal (1,42) (Fut.get c); + true;; + +eq [2;3] (Fut.get @@ Fut.map_l (fun x -> Fut.return (x+1)) [1;2]);; +eq [] (Fut.get @@ Fut.map_l (fun x -> Fut.return (x+1)) []);; + +t @@ fun () -> + let l = CCList.(1 -- 50) in + let l' = l + |> List.map + (fun x -> Fut.make (fun () -> Thread.delay 0.1; x*10)) + |> Fut.sequence_l + |> Fut.map (List.fold_left (+) 0) + in + let expected = List.fold_left (fun acc x -> acc + 10 * x) 0 l in + assert_equal expected (Fut.get l'); + true;; + +t @@ fun () -> + let l = CCList.(1 -- 100_000) in + let l' = l + |> CCList.map + (fun _x -> Fut.make (fun () -> 1)) + |> Fut.sequence_l + |> Fut.map (List.fold_left (+) 0) + in + let expected = 100_000 in + assert_equal expected (Fut.get l'); + true;; + +t @@ fun () -> + let l = CCList.(1 -- 50) in + let l' = l + |> List.map + (fun x -> Fut.make (fun () -> Thread.delay 0.1; if x = 5 then raise Exit; x)) + |> Fut.sequence_l + |> Fut.map (List.fold_left (+) 0) + in + assert_raises ((=)Exit) (fun () -> Fut.get l'); + true;; + +t @@ fun () -> + let rec fib x = if x<2 then 1 else fib (x-1)+fib(x-2) in + let l = + CCList.(1--10_000) + |> List.rev_map + (fun x-> Fut.make (fun () -> Thread.yield(); fib (x mod 20))) + |> Fut.(map_l (fun x->x>|= fun x->x+1)) + in + assert (Fut.state l = Waiting); + let l' = Fut.get l in + assert_equal 10_000 (List.length l'); + true;; + +t @@ fun () -> + let l = CCList.(1 -- 50) in + let l' = l + |> List.map + (fun x -> Fut2.make (fun () -> Thread.delay 0.1; x*10)) + |> Fut2.sequence_l + |> Fut2.map (List.fold_left (+) 0) + in + let expected = List.fold_left (fun acc x -> acc + 10 * x) 0 l in + assert_equal expected (Fut2.get l'); + true;; + +t @@ fun () -> + let l = CCList.(1 -- 50) in + let l' = l + |> List.map + (fun x -> Fut2.make (fun () -> Thread.delay 0.1; if x = 5 then raise Exit; x)) + |> Fut2.sequence_l + |> Fut2.map (List.fold_left (+) 0) + in + assert_raises ((=)Exit) (fun () -> Fut2.get l'); + true;; + +t @@ fun () -> + let rec fib x = if x<2 then 1 else fib (x-1)+fib(x-2) in + let l = + CCList.(1--10_000) + |> List.rev_map + (fun x-> Fut2.make (fun () -> Thread.yield(); fib (x mod 20))) + |> Fut2.(map_l (fun x->x>|= fun x->x+1)) + in + assert (Fut2.state l = Waiting); + let l' = Fut2.get l in + assert_equal 10_000 (List.length l'); + true;; + +t @@ fun () -> + let start = Unix.gettimeofday () in + let pause = 0.2 and n = 10 in + let l = CCList.(1 -- n) + |> List.map (fun _ -> Fut.make (fun () -> Thread.delay pause)) + in + List.iter Fut.get l; + let stop = Unix.gettimeofday () in + assert (stop -. start < float_of_int n *. pause); + true;; + +t @@ fun () -> + let start = Unix.gettimeofday () in + let pause = 0.2 and n = 10 in + let l = CCList.(1 -- n) + |> List.map (fun _ -> Fut2.make (fun () -> Thread.delay pause)) + in + List.iter Fut2.get l; + let stop = Unix.gettimeofday () in + assert (stop -. start < float_of_int n *. pause); + true;; diff --git a/tests/thread/t_semaphore.ml b/tests/thread/t_semaphore.ml new file mode 100644 index 00000000..df1e9aac --- /dev/null +++ b/tests/thread/t_semaphore.ml @@ -0,0 +1,62 @@ + +module Test = (val Containers_testlib.make ~__FILE__()) +open Test +open CCSemaphore;; + +t @@ fun () -> + let s = create 1 in + let r = CCLock.create false in + let _ = Thread.create (fun s -> acquire 5 s; CCLock.set r true) s in + Thread.yield (); + assert_equal false (CCLock.get r); + release 4 s; + Thread.delay 0.2; + assert_equal true (CCLock.get r); + assert_equal 0 (get s); + true;; + +t @@ fun () -> + let s = create 5 in + let n = CCLock.create 0 in + let a = Array.init 100 (fun i -> + Thread.create (fun _ -> + for _i = 1 to 100 do + with_acquire ~n:(1 + (i mod 5)) s + ~f:(fun () -> Thread.yield(); CCLock.incr n) + done) + ()) + in + Array.iter Thread.join a; + assert_equal ~printer:CCInt.to_string 5 (get s); + assert_equal ~printer:CCInt.to_string 10_000 (CCLock.get n); + true;; + +t @@ fun () -> + let output _s = () in + let s = create 2 in + let res = CCLock.create false in + let id = Thread.create + (fun () -> + output "start"; + wait_until_at_least ~n:5 s + ~f:(fun () -> + assert (get s >= 5); + output "modify now"; + CCLock.set res true) + ) () + in + output "launched thread"; + Thread.yield(); + assert (not (CCLock.get res)); + output "release 2"; + release 2 s; + Thread.yield(); + assert (not (CCLock.get res)); + output "release 1"; + release 1 s; + (* should work now *) + Thread.delay 0.2; + Thread.join id; + output "check"; + assert (CCLock.get res); + true;; diff --git a/tests/thread/t_thread.ml b/tests/thread/t_thread.ml new file mode 100644 index 00000000..9e60b5d9 --- /dev/null +++ b/tests/thread/t_thread.ml @@ -0,0 +1,24 @@ + +module Test = (val Containers_testlib.make ~__FILE__()) +open Test +open CCThread;; + +t @@ fun () -> + let l = CCLock.create 0 in + let a = Arr.spawn 101 (fun i -> CCLock.update l ((+) i)) in + Arr.join a; + let n = Iter.(1 -- 100 |> fold (+) 0) in + assert_equal ~printer:CCInt.to_string n (CCLock.get l); + true;; + +t @@ fun () -> + let b = Barrier.create () in + let res = CCLock.create 0 in + let t1 = spawn (fun _ -> Barrier.wait b; CCLock.incr res) + and t2 = spawn (fun _ -> Barrier.wait b; CCLock.incr res) in + Thread.delay 0.2; + assert_equal 0 (CCLock.get res); + Barrier.activate b; + Thread.join t1; Thread.join t2; + assert_equal 2 (CCLock.get res); + true;; diff --git a/tests/thread/t_timer.ml b/tests/thread/t_timer.ml new file mode 100644 index 00000000..ff232379 --- /dev/null +++ b/tests/thread/t_timer.ml @@ -0,0 +1,42 @@ + +module Test = (val Containers_testlib.make ~__FILE__()) +open Test +open CCTimer;; + + +(* NOTE: could be tighter bounds, but travis' mac OS seems to be dog slow. *) + +t @@ fun () -> + let start = Unix.gettimeofday() in + let timer = create() in + let res = CCLock.create 0 in + let sem = CCSemaphore.create 1 in + CCSemaphore.acquire 1 sem; + let stop = ref 0. in + every timer 0.1 + ~f:(fun () -> + if CCLock.incr_then_get res > 5 then ( + stop := Unix.gettimeofday(); + CCSemaphore.release 1 sem; + raise ExitEvery + )); + CCSemaphore.acquire 1 sem; (* wait *) + assert_equal ~printer:CCInt.to_string 6 (CCLock.get res); + assert (!stop -. start >= 0.49999); + assert (!stop -. start < 2.); + true;; + +t @@ fun () -> + (* scenario: n := 1; n := n*4 ; n := n+2; res := n *) + let timer = create () in + let n = CCLock.create 1 in + let res = CCLock.create 0 in + after timer 0.3 + ~f:(fun () -> CCLock.update n (fun x -> x+2)); + ignore (Thread.create + (fun _ -> Thread.delay 0.4; CCLock.set res (CCLock.get n)) ()); + after timer 0.1 + ~f:(fun () -> CCLock.update n (fun x -> x * 4)); + Thread.delay 0.6 ; + assert_equal ~printer:Q.Print.int 6 (CCLock.get res); + true;;