Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Lin_domain.stress_test #443

Merged
merged 16 commits into from
Mar 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

- #415: Remove `--verbose` in internal `mutable_set_v5` expect test to avoid
a test failure on a slow machine
- #443: Add `Lin_domain.stress_test` as a lighter stress test, not
requiring an interleaving search.

## 0.3

Expand Down
18 changes: 15 additions & 3 deletions lib/lin_domain.ml
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,7 @@ module Make_internal (Spec : Internal.CmdSpec [@alert "-internal"]) = struct
let res_arr = Array.map (fun c -> Domain.cpu_relax(); Spec.run c sut) cs_arr in
List.combine cs (Array.to_list res_arr)

(* Linearization property based on [Domain] and an Atomic flag *)
let lin_prop (seq_pref,cmds1,cmds2) =
let run_parallel (seq_pref,cmds1,cmds2) =
let sut = Spec.init () in
let pref_obs = interp sut seq_pref in
let wait = Atomic.make true in
Expand All @@ -22,18 +21,31 @@ module Make_internal (Spec : Internal.CmdSpec [@alert "-internal"]) = struct
Spec.cleanup sut ;
let obs1 = match obs1 with Ok v -> v | Error exn -> raise exn in
let obs2 = match obs2 with Ok v -> v | Error exn -> raise exn in
(pref_obs,obs1,obs2)

(* Linearization property based on [Domain] and an Atomic flag *)
let lin_prop (seq_pref,cmds1,cmds2) =
let pref_obs,obs1,obs2 = run_parallel (seq_pref,cmds1,cmds2) in
let seq_sut = Spec.init () in
check_seq_cons pref_obs obs1 obs2 seq_sut []
|| QCheck.Test.fail_reportf " Results incompatible with sequential execution\n\n%s"
@@ Util.print_triple_vertical ~fig_indent:5 ~res_width:35
(fun (c,r) -> Printf.sprintf "%s : %s" (Spec.show_cmd c) (Spec.show_res r))
(pref_obs,obs1,obs2)

(* "Don't crash under parallel usage" property *)
let stress_prop (seq_pref,cmds1,cmds2) =
let _ = run_parallel (seq_pref,cmds1,cmds2) in
true

let lin_test ~count ~name =
lin_test ~rep_count:50 ~count ~retries:3 ~name ~lin_prop:lin_prop
M.lin_test ~rep_count:50 ~count ~retries:3 ~name ~lin_prop:lin_prop

let neg_lin_test ~count ~name =
neg_lin_test ~rep_count:50 ~count ~retries:3 ~name ~lin_prop:lin_prop

let stress_test ~count ~name =
M.lin_test ~rep_count:25 ~count ~retries:5 ~name ~lin_prop:stress_prop
end

module Make (Spec : Spec) = Make_internal(MakeCmd(Spec))
8 changes: 8 additions & 0 deletions lib/lin_domain.mli
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@ open Lin
module Make_internal (Spec : Internal.CmdSpec [@alert "-internal"]) : sig
val arb_cmds_triple : int -> int -> (Spec.cmd list * Spec.cmd list * Spec.cmd list) QCheck.arbitrary
val lin_prop : (Spec.cmd list * Spec.cmd list * Spec.cmd list) -> bool
val stress_prop : (Spec.cmd list * Spec.cmd list * Spec.cmd list) -> bool
val lin_test : count:int -> name:string -> QCheck.Test.t
val neg_lin_test : count:int -> name:string -> QCheck.Test.t
val stress_test : count:int -> name:string -> QCheck.Test.t
end
[@@alert internal "This module is exposed for internal uses only, its API may change at any time"]

Expand All @@ -24,4 +26,10 @@ module Make (Spec : Spec) : sig
found, and succeeds if a counter example is indeed found, and prints it
afterwards.
*)

val stress_test : count:int -> name:string -> QCheck.Test.t
(** [stress_test ~count:c ~name:n] builds a parallel test with the name
[n] that iterates [c] times. The test fails if an unexpected exception is
raised underway. It is intended as a stress test and does not perform an
interleaving search like {!lin_test} and {!neg_lin_test}. *)
end
8 changes: 7 additions & 1 deletion src/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ Tests utilizing the parallel STM.ml capability:



Tests utilizing the linearization tests of Lin.ml:
Tests utilizing `Lin`:

- [array/lin_internal_tests.ml](array/lin_internal_tests.ml) and [array/lin_tests.ml](array/lin_tests.ml)
contain experimental `Lin.Internal` and `Lin`-tests of `Array`
Expand All @@ -61,6 +61,8 @@ Tests utilizing the linearization tests of Lin.ml:

- [dynlink/lin_tests.ml](dynlink/lin_tests.ml) contains experimental `Lin`-tests of `Dynlink`

- [ephemeron/lin_tests.ml](ephemeron/lin_tests.ml) contains experimental `Lin`-stress tests of `Ephemeron`

- [floatarray/lin_tests.ml](floatarray/lin_tests.ml) contains experimental `Lin`-tests of `Float.Array`

- [hashtbl/lin_internal_tests.ml](hashtbl/lin_internal_tests.ml) and [hashtbl/lin_tests.ml](hashtbl/lin_tests.ml)
Expand All @@ -80,6 +82,10 @@ Tests utilizing the linearization tests of Lin.ml:
- [stack/lin_internal_tests.ml](stack/lin_internal_tests.ml) and [stack/lin_tests.ml](stack/lin_tests.ml)
contain experimental `Lin.Internal` and `Lin`-tests of `Stack`

- [weak/lin_tests.ml](weak/lin_tests.ml) and
[weak/lin_tests_hashset.ml](weak/lin_tests_hashset.ml) contains experimental
`Lin`-stress tests of the `Weak` module



Tests of the underlying spawn/async functionality of `Domain` and
Expand Down
1 change: 1 addition & 0 deletions src/array/lin_tests.ml
Original file line number Diff line number Diff line change
Expand Up @@ -30,4 +30,5 @@ module AT_domain = Lin_domain.Make(AConf)
;;
QCheck_base_runner.run_tests_main [
AT_domain.neg_lin_test ~count:1000 ~name:"Lin Array test with Domain";
AT_domain.stress_test ~count:1000 ~name:"Lin Array stress test with Domain";
]
1 change: 1 addition & 0 deletions src/bigarray/lin_tests.ml
Original file line number Diff line number Diff line change
Expand Up @@ -30,4 +30,5 @@ module BA1T = Lin_domain.Make(BA1Conf)
let _ =
QCheck_base_runner.run_tests_main [
BA1T.neg_lin_test ~count:5000 ~name:"Lin Bigarray.Array1 (of ints) test with Domain";
BA1T.stress_test ~count:1000 ~name:"Lin Bigarray.Array1 stress test with Domain";
]
13 changes: 7 additions & 6 deletions src/dynlink/lin_tests.ml
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,10 @@ end
module DynT = Lin_domain.Make(DynConf)

let _ =
if Sys.win32 then
Printf.printf "negative Lin Dynlink test with Domain disabled under Windows\n\n%!"
else
QCheck_base_runner.run_tests_main [
DynT.neg_lin_test ~count:100 ~name:"negative Lin Dynlink test with Domain";
]
let ts = [DynT.stress_test ~count:1000 ~name:"Lin Dynlink stress test with Domain"] in
let ts =
if Sys.win32 then
(Printf.printf "negative Lin Dynlink test with Domain disabled under Windows\n\n%!"; ts)
else
(DynT.neg_lin_test ~count:100 ~name:"negative Lin Dynlink test with Domain")::ts in
QCheck_base_runner.run_tests_main ts
8 changes: 8 additions & 0 deletions src/ephemeron/dune
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,11 @@
(libraries qcheck-stm.sequential qcheck-stm.domain)
(action (run %{test} --verbose))
)

(test
(name lin_tests)
(modules lin_tests)
(package multicoretests)
(libraries qcheck-lin.domain)
(action (run %{test} --verbose))
)
37 changes: 37 additions & 0 deletions src/ephemeron/lin_tests.ml
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
(* ************************************************************ *)
(* Lin tests of [Ephemeron] *)
(* ************************************************************ *)

module EConf =
struct
module E = Ephemeron.K1.Make(struct
type t = Int.t
let equal = Int.equal
let hash = Fun.id
end)

type t = string E.t
let init () = E.create 42
let cleanup _ = ()

open Lin
let int,string = nat_small, string_small_printable
let api =
[ val_ "Ephemeron.clear" E.clear (t @-> returning unit);
val_ "Ephemeron.add" E.add (t @-> int @-> string @-> returning unit);
val_ "Ephemeron.remove" E.remove (t @-> int @-> returning unit);
val_ "Ephemeron.find" E.find (t @-> int @-> returning_or_exc string);
val_ "Ephemeron.find_opt" E.find_opt (t @-> int @-> returning (option string));
val_ "Ephemeron.find_all" E.find_all (t @-> int @-> returning (list string));
val_ "Ephemeron.replace" E.replace (t @-> int @-> string @-> returning unit);
val_ "Ephemeron.mem" E.mem (t @-> int @-> returning bool);
val_ "Ephemeron.length" E.length (t @-> returning int);
val_ "Ephemeron.clean" E.clean (t @-> returning unit);
]
end

module ET_domain = Lin_domain.Make(EConf)
;;
QCheck_base_runner.run_tests_main [
ET_domain.stress_test ~count:1000 ~name:"Lin Ephemeron stress test with Domain";
]
1 change: 1 addition & 0 deletions src/floatarray/lin_tests.ml
Original file line number Diff line number Diff line change
Expand Up @@ -38,4 +38,5 @@ module FAT = Lin_domain.Make(FAConf)
let _ =
QCheck_base_runner.run_tests_main [
FAT.neg_lin_test ~count:1000 ~name:"Lin Float.Array test with Domain";
FAT.stress_test ~count:1000 ~name:"Lin Float.Array stress test with Domain";
]
1 change: 1 addition & 0 deletions src/hashtbl/lin_tests.ml
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,5 @@ module HT_domain = Lin_domain.Make(HConf)
;;
QCheck_base_runner.run_tests_main [
HT_domain.neg_lin_test ~count:1000 ~name:"Lin Hashtbl test with Domain";
HT_domain.stress_test ~count:1000 ~name:"Lin Hashtbl stress test with Domain";
]
3 changes: 2 additions & 1 deletion src/io/lin_tests_domain.ml
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,6 @@ module IC_domain = Lin_domain.Make(Lin_tests_spec_io.ICConf)

let _ =
QCheck_base_runner.run_tests_main [
IC_domain.neg_lin_test ~count:1000 ~name:"Lin In_channel test with Domain"
IC_domain.neg_lin_test ~count:1000 ~name:"Lin In_channel test with Domain";
IC_domain.stress_test ~count:1000 ~name:"Lin In_channel stress test with Domain";
]
2 changes: 2 additions & 0 deletions src/lazy/lin_tests.ml
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,8 @@ module LTfromfun_domain = Lin_domain.Make(LTfromfunAPI)
QCheck_base_runner.run_tests_main
(let count = 100 in
[LTlazy_domain.neg_lin_test ~count ~name:"Lin Lazy test with Domain";
LTlazy_domain.stress_test ~count ~name:"Lin Lazy stress test with Domain";
LTfromval_domain.lin_test ~count ~name:"Lin Lazy test with Domain from_val";
LTfromfun_domain.neg_lin_test ~count ~name:"Lin Lazy test with Domain from_fun";
LTfromfun_domain.stress_test ~count ~name:"Lin Lazy stress test with Domain from_fun";
])
1 change: 1 addition & 0 deletions src/queue/lin_tests.ml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ module Lin_queue_thread = Lin_thread.Make(Queue_spec) [@alert "-experimental"]
let () =
let tests = [
Lin_queue_domain.neg_lin_test ~count:1000 ~name:"Lin Queue test with Domain";
Lin_queue_domain.stress_test ~count:1000 ~name:"Lin Queue stress test with Domain";
Lin_queue_thread.lin_test ~count:250 ~name:"Lin Queue test with Thread";
] in
let tests =
Expand Down
1 change: 1 addition & 0 deletions src/stack/lin_tests.ml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ module Stack_thread = Lin_thread.Make(Stack_spec) [@alert "-experimental"]
let () =
let tests = [
Stack_domain.neg_lin_test ~count:1000 ~name:"Lin Stack test with Domain";
Stack_domain.stress_test ~count:1000 ~name:"Lin Stack stress test with Domain";
Stack_thread.lin_test ~count:250 ~name:"Lin Stack test with Thread";
] in
let tests =
Expand Down
16 changes: 16 additions & 0 deletions src/weak/dune
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,19 @@
(libraries qcheck-stm.sequential qcheck-stm.domain)
(action (run %{test} --verbose))
)

(test
(name lin_tests)
(modules lin_tests)
(package multicoretests)
(libraries qcheck-lin.domain)
(action (run %{test} --verbose))
)

(test
(name lin_tests_hashset)
(modules lin_tests_hashset)
(package multicoretests)
(libraries qcheck-lin.domain)
(action (run %{test} --verbose))
)
29 changes: 29 additions & 0 deletions src/weak/lin_tests.ml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
(* ********************************************************************** *)
(* Lin Tests [Weak] *)
(* ********************************************************************** *)
module WConf =
struct
type t = int64 Weak.t

let weak_size = 16
let init () = Weak.create weak_size
let cleanup _ = ()

open Lin
let int,int64 = nat_small,nat64_small
let api =
[ val_ "Weak.length" Weak.length (t @-> returning int);
val_ "Weak.set" Weak.set (t @-> int @-> option int64 @-> returning_or_exc unit);
val_ "Weak.get" Weak.get (t @-> int @-> returning_or_exc (option int64));
val_ "Weak.get_copy" Weak.get_copy (t @-> int @-> returning_or_exc (option int64));
val_ "Weak.check" Weak.check (t @-> int @-> returning_or_exc bool);
val_ "Weak.fill" Weak.fill (t @-> int @-> int @-> option int64 @-> returning_or_exc unit);
(*val blit : 'a t -> int -> 'a t -> int -> int -> unit *)
]
end

module WT_domain = Lin_domain.Make(WConf)
;;
QCheck_base_runner.run_tests_main [
WT_domain.stress_test ~count:1000 ~name:"Lin Weak stress test with Domain";
]
34 changes: 34 additions & 0 deletions src/weak/lin_tests_hashset.ml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
(* ********************************************************************** *)
(* Lin tests of [Weak Hashset] *)
(* ********************************************************************** *)
module WHSConf =
struct
module WHS = Weak.Make(String)
type t = WHS.t
let weak_size = 16
let init () = WHS.create weak_size
let cleanup t = WHS.clear t

open Lin
let string = string_small
let api =
[ val_ "Weak.S.clear" WHS.clear (t @-> returning unit);
val_ "Weak.S.merge" WHS.merge (t @-> string @-> returning_or_exc string);
val_ "Weak.S.add" WHS.add (t @-> string @-> returning_or_exc unit);
val_ "Weak.S.remove" WHS.remove (t @-> string @-> returning_or_exc unit);
val_ "Weak.S.find" WHS.find (t @-> string @-> returning_or_exc string);
val_ "Weak.S.find_opt" WHS.find_opt (t @-> string @-> returning_or_exc (option string));
val_ "Weak.S.find_all" WHS.find_all (t @-> string @-> returning_or_exc (list string));
val_ "Weak.S.mem" WHS.mem (t @-> string @-> returning_or_exc bool);
(*val iter : (data -> unit) -> t -> unit*)
(*val fold : (data -> 'a -> 'a) -> t -> 'a -> 'a*)
val_ "Weak.S.count" WHS.count (t @-> returning int);
(*val stats : t -> int * int * int * int * int * int*)
]
end

module WHST_domain = Lin_domain.Make(WHSConf)
;;
QCheck_base_runner.run_tests_main [
WHST_domain.stress_test ~count:1000 ~name:"Lin Weak HashSet stress test with Domain";
]
Loading