Skip to content

Commit 3e72b8c

Browse files
committed
Fix Lin libraries after split
Add a Lin_base module, as the entrypoint of the qcheck-lin.base library
1 parent 2eba64c commit 3e72b8c

File tree

8 files changed

+101
-76
lines changed

8 files changed

+101
-76
lines changed

lib/dune

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,28 @@
2323
(libraries threads qcheck-core STM_base))
2424

2525
(library
26-
(name lin)
27-
(wrapped false)
28-
(public_name qcheck-lin)
29-
(modules lin lin_api)
30-
(libraries threads qcheck-core qcheck-core.runner qcheck-multicoretests-util))
26+
(name lin_base)
27+
(public_name qcheck-lin.base)
28+
(modules lin_internal lin_common lin_base)
29+
(libraries qcheck-core qcheck-core.runner qcheck-multicoretests-util))
30+
31+
(library
32+
(name lin_domain)
33+
(public_name qcheck-lin.domain)
34+
(modules lin_domain)
35+
(libraries qcheck-core qcheck-core.runner qcheck-multicoretests-util qcheck-lin.base))
36+
37+
(library
38+
(name lin_effect)
39+
(public_name qcheck-lin.effect)
40+
(modules lin_effect)
41+
(libraries qcheck-core qcheck-core.runner qcheck-multicoretests-util qcheck-lin.base))
42+
43+
(library
44+
(name lin_thread)
45+
(public_name qcheck-lin.thread)
46+
(modules lin_thread)
47+
(libraries threads qcheck-core qcheck-core.runner qcheck-multicoretests-util qcheck-lin.base))
3148

3249
(library
3350
(name util)

lib/lin_base.ml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
module Lin_internal = Lin_internal
2+
module Lin_common = Lin_common
3+
include Lin_common

lib/lin_common.ml

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@ module type ApiSpec = sig
140140
val api : (int * t elem) list
141141
end
142142

143-
module MakeCmd (ApiSpec : ApiSpec) : Lin.CmdSpec = struct
143+
module MakeCmd (ApiSpec : ApiSpec) : Lin_internal.CmdSpec = struct
144144

145145
type t = ApiSpec.t
146146

@@ -333,5 +333,3 @@ module MakeCmd (ApiSpec : ApiSpec) : Lin.CmdSpec = struct
333333
Res (rty, apply_f f args state)
334334

335335
end
336-
337-
module Make (ApiSpec : ApiSpec) = Lin.Make (MakeCmd (ApiSpec))

lib/lin_common.mli

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -237,11 +237,6 @@ module type ApiSpec =
237237

238238
(** {1 Generation of linearizability testing module from an API} *)
239239

240-
module MakeCmd : functor (ApiSpec : ApiSpec) -> Lin.CmdSpec
240+
module MakeCmd : functor (Spec : ApiSpec) -> Lin_internal.CmdSpec
241241
(** Functor to map a combinator-based module signature description
242242
into a raw [Lin] description *)
243-
244-
module Make :
245-
functor (ApiSpec : ApiSpec) -> module type of Lin.Make (MakeCmd (ApiSpec))
246-
(** Functor to create linearizability tests from an combinator-based module
247-
signature description *)

lib/lin_domain.ml

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
open Lin_base
2+
3+
module Make_internal (Spec : Lin_internal.CmdSpec) = struct
4+
module M = Lin_internal.Make(Spec)
5+
include M
6+
17
(* operate over arrays to avoid needless allocation underway *)
28
let interp sut cs =
39
let cs_arr = Array.of_list cs in
@@ -17,19 +23,17 @@
1723
let obs2 = match obs2 with Ok v -> v | Error exn -> raise exn in
1824
let seq_sut = Spec.init () in
1925
check_seq_cons pref_obs obs1 obs2 seq_sut []
20-
|| Test.fail_reportf " Results incompatible with sequential execution\n\n%s"
21-
@@ print_triple_vertical ~fig_indent:5 ~res_width:35
26+
|| QCheck.Test.fail_reportf " Results incompatible with sequential execution\n\n%s"
27+
@@ Util.print_triple_vertical ~fig_indent:5 ~res_width:35
2228
(fun (c,r) -> Printf.sprintf "%s : %s" (Spec.show_cmd c) (Spec.show_res r))
2329
(pref_obs,obs1,obs2)
2430

25-
| `Domain ->
26-
let arb_cmd_triple = arb_cmds_par seq_len par_len in
27-
let rep_count = 50 in
28-
Test.make ~count ~retries:3 ~name
29-
arb_cmd_triple (repeat rep_count lin_prop_domain)
31+
let lin_test ~count ~name =
32+
lin_test ~rep_count:50 ~count ~retries:3 ~name ~lin_prop:lin_prop_domain
33+
34+
let neg_lin_test ~count ~name =
35+
neg_lin_test ~rep_count:50 ~count ~retries:3 ~name ~lin_prop:lin_prop_domain
36+
end
3037

31-
| `Domain ->
32-
let arb_cmd_triple = arb_cmds_par seq_len par_len in
33-
let rep_count = 50 in
34-
Test.make_neg ~count ~retries:3 ~name
35-
arb_cmd_triple (repeat rep_count lin_prop_domain)
38+
module Make (Spec : Lin_common.ApiSpec) =
39+
Make_internal(Lin_common.MakeCmd(Spec))

lib/lin_effect.ml

Lines changed: 29 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
open Lin_base
2+
13
(** Definitions for Effect interpretation *)
24

35
(* Scheduler adapted from https://kcsrk.info/slides/retro_effects_simcorp.pdf *)
@@ -31,11 +33,13 @@ let start_sched main =
3133
let fork f = perform (Fork f)
3234
let yield () = perform Yield
3335

36+
module Make_internal (Spec : Lin_internal.CmdSpec) = struct
3437

3538

3639
(** A refined [CmdSpec] specification with generator-controlled [Yield] effects *)
3740
module EffSpec
3841
= struct
42+
open QCheck
3943

4044
type t = Spec.t
4145
let init = Spec.init
@@ -75,10 +79,16 @@ let yield () = perform Yield
7579
UserRes res
7680
end
7781

78-
module EffTest = MakeDomThr(EffSpec)
82+
module EffTest = Lin_internal.Make(EffSpec)
7983

8084
let filter_res rs = List.filter (fun (c,_) -> c <> EffSpec.SchedYield) rs
8185

86+
let rec interp sut cs = match cs with
87+
| [] -> []
88+
| c::cs ->
89+
let res = EffSpec.run c sut in
90+
(c,res)::interp sut cs
91+
8292
(* Parallel agreement property based on effect-handler scheduler *)
8393
let lin_prop_effect =
8494
(fun (seq_pref,cmds1,cmds2) ->
@@ -87,29 +97,30 @@ let yield () = perform Yield
8797
let pref_obs = EffTest.interp_plain sut (List.filter (fun c -> c <> EffSpec.SchedYield) seq_pref) in
8898
let obs1,obs2 = ref [], ref [] in
8999
let main () =
90-
(* For now, we reuse [interp_thread] which performs useless [Thread.yield] on single-domain/fibered program *)
91-
fork (fun () -> let tmp1 = EffTest.interp_thread sut cmds1 in obs1 := tmp1);
92-
fork (fun () -> let tmp2 = EffTest.interp_thread sut cmds2 in obs2 := tmp2); in
100+
fork (fun () -> let tmp1 = interp sut cmds1 in obs1 := tmp1);
101+
fork (fun () -> let tmp2 = interp sut cmds2 in obs2 := tmp2); in
93102
let () = start_sched main in
94103
let () = Spec.cleanup sut in
95104
let seq_sut = Spec.init () in
96105
(* exclude [Yield]s from sequential executions when searching for an interleaving *)
97106
EffTest.check_seq_cons (filter_res pref_obs) (filter_res !obs1) (filter_res !obs2) seq_sut []
98-
|| Test.fail_reportf " Results incompatible with linearized model\n\n%s"
107+
|| QCheck.Test.fail_reportf " Results incompatible with linearized model\n\n%s"
99108
@@ Util.print_triple_vertical ~fig_indent:5 ~res_width:35
100109
(fun (c,r) -> Printf.sprintf "%s : %s" (EffSpec.show_cmd c) (EffSpec.show_res r))
101110
(pref_obs,!obs1,!obs2))
102111

103-
| `Effect ->
104-
(* this generator is over [EffSpec.cmd] including [SchedYield], not [Spec.cmd] like the above two *)
105-
let arb_cmd_triple = EffTest.arb_cmds_par seq_len par_len in
106-
let rep_count = 1 in
107-
Test.make ~count ~retries:10 ~name
108-
arb_cmd_triple (repeat rep_count lin_prop_effect)
109-
110-
| `Effect ->
111-
(* this generator is over [EffSpec.cmd] including [SchedYield], not [Spec.cmd] like the above two *)
112-
let arb_cmd_triple = EffTest.arb_cmds_par seq_len par_len in
113-
let rep_count = 1 in
114-
Test.make_neg ~count ~retries:10 ~name
115-
arb_cmd_triple (repeat rep_count lin_prop_effect)
112+
let lin_test ~count ~name =
113+
let arb_cmd_triple = EffTest.arb_cmds_par 20 12 in
114+
let rep_count = 1 in
115+
QCheck.Test.make ~count ~retries:10 ~name
116+
arb_cmd_triple (Util.repeat rep_count lin_prop_effect)
117+
118+
let neg_lin_test ~count ~name =
119+
let arb_cmd_triple = EffTest.arb_cmds_par 20 12 in
120+
let rep_count = 1 in
121+
QCheck.Test.make_neg ~count ~retries:10 ~name
122+
arb_cmd_triple (Util.repeat rep_count lin_prop_effect)
123+
end
124+
125+
module Make (Spec : Lin_common.ApiSpec) =
126+
Make_internal(Lin_common.MakeCmd(Spec))

lib/lin_internal.ml

Lines changed: 13 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,9 @@ module type CmdSpec = sig
3737
(** [run c t] should interpret the command [c] over the system under test [t] (typically side-effecting). *)
3838
end
3939

40-
(** A functor to create Domain and Thread test setups.
40+
(** A functor to create test setups, for all backends (Domain, Thread and Effect).
4141
We use it below, but it can also be used independently *)
42-
module MakeDomThr(Spec : CmdSpec)
42+
module Make(Spec : CmdSpec)
4343
= struct
4444

4545
(* plain interpreter of a cmd list *)
@@ -115,23 +115,16 @@ module MakeDomThr(Spec : CmdSpec)
115115
if Spec.equal_res res2 (Spec.run c2 seq_sut')
116116
then check_seq_cons pref cs1 cs2' seq_sut' (c2::seq_trace)
117117
else (Spec.cleanup seq_sut'; false))
118-
end
119-
120-
(** A functor to create all three (Domain, Thread, and Effect) test setups.
121-
The result [include]s the output module from the [MakeDomThr] functor above *)
122-
module Make(Spec : CmdSpec)
123-
= struct
124-
125-
module FirstTwo = MakeDomThr(Spec)
126-
include FirstTwo
127-
128-
(* Linearizability test based on [Domain], [Thread], or [Effect] *)
129-
let lin_test ~count ~name (lib : [ `Domain | `Thread | `Effect ]) =
130-
let seq_len,par_len = 20,12 in
131-
match lib with
132118

133-
(* Negative linearizability test based on [Domain], [Thread], or [Effect] *)
134-
let neg_lin_test ~count ~name (lib : [ `Domain | `Thread | `Effect ]) =
135-
let seq_len,par_len = 20,12 in
136-
match lib with
119+
(* Linearizability test *)
120+
let lin_test ~rep_count ~count ~retries ~name ~lin_prop =
121+
let arb_cmd_triple = arb_cmds_par 20 12 in
122+
Test.make ~count ~retries ~name
123+
arb_cmd_triple (repeat rep_count lin_prop)
124+
125+
(* Negative linearizability test *)
126+
let neg_lin_test ~rep_count ~count ~retries ~name ~lin_prop =
127+
let arb_cmd_triple = arb_cmds_par 20 12 in
128+
Test.make_neg ~count ~retries ~name
129+
arb_cmd_triple (repeat rep_count lin_prop)
137130
end

lib/lin_thread.ml

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
open Lin_base
2+
3+
module Make_internal (Spec : Lin_internal.CmdSpec) = struct
4+
module M = Lin_internal.Make(Spec)
5+
include M
6+
17
(* Note: On purpose we use
28
- a non-tail-recursive function and
39
- an (explicit) allocation in the loop body
@@ -24,19 +30,17 @@
2430
let seq_sut = Spec.init () in
2531
(* we reuse [check_seq_cons] to linearize and interpret sequentially *)
2632
check_seq_cons pref_obs !obs1 !obs2 seq_sut []
27-
|| Test.fail_reportf " Results incompatible with sequential execution\n\n%s"
28-
@@ print_triple_vertical ~fig_indent:5 ~res_width:35
33+
|| QCheck.Test.fail_reportf " Results incompatible with sequential execution\n\n%s"
34+
@@ Util.print_triple_vertical ~fig_indent:5 ~res_width:35
2935
(fun (c,r) -> Printf.sprintf "%s : %s" (Spec.show_cmd c) (Spec.show_res r))
3036
(pref_obs,!obs1,!obs2))
3137

32-
| `Thread ->
33-
let arb_cmd_triple = arb_cmds_par seq_len par_len in
34-
let rep_count = 100 in
35-
Test.make ~count ~retries:5 ~name
36-
arb_cmd_triple (repeat rep_count lin_prop_thread)
38+
let lin_test ~count ~name =
39+
lin_test ~rep_count:100 ~count ~retries:5 ~name ~lin_prop:lin_prop_thread
40+
41+
let neg_lin_test ~count ~name =
42+
neg_lin_test ~rep_count:100 ~count ~retries:5 ~name ~lin_prop:lin_prop_thread
43+
end
3744

38-
| `Thread ->
39-
let arb_cmd_triple = arb_cmds_par seq_len par_len in
40-
let rep_count = 100 in
41-
Test.make_neg ~count ~retries:5 ~name
42-
arb_cmd_triple (repeat rep_count lin_prop_thread)
45+
module Make (Spec : Lin_common.ApiSpec) =
46+
Make_internal(Lin_common.MakeCmd(Spec))

0 commit comments

Comments
 (0)