File: lin.mli

package info (click to toggle)
ocaml-multicoretests 0.9-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 1,532 kB
  • sloc: ml: 8,904; awk: 66; ansic: 23; makefile: 11; sh: 1
file content (338 lines) | stat: -rw-r--r-- 14,759 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
(** This module allows the user to describe the type signature of
    a tested module interface using a DSL of type combinators.
*)

(** Internal module to build test representations.
    This module is exposed for internal uses only, its API may change
    at any time.
 *)
module Internal : sig
  module type CmdSpec = sig
    type t
    (** The type of the system under test *)

    type cmd
    (** The type of commands *)

    val show_cmd : cmd -> string
    (** [show_cmd c] returns a string representing the command [c]. *)

    val gen_cmd : cmd QCheck.Gen.t
    (** A command generator. *)

    val shrink_cmd : cmd QCheck.Shrink.t
    (** A command shrinker.
        To a first approximation you can use {!QCheck.Shrink.nil}. *)

    type res
    (** The command result type *)

    val show_res : res -> string
    (** [show_res r] returns a string representing the result [r]. *)

    val equal_res : res -> res -> bool
    (** equality function over {!res} *)

    val init : unit -> t
    (** Initialize the system under test. *)

    val cleanup : t -> unit
    (** Utility function to clean up [t] after each test instance,
        e.g., for closing sockets, files, or resetting global parameters *)

    val run : cmd -> t -> res
    (** [run c t] should interpret the command [c] over the system under test [t] (typically side-effecting). *)
  end

  module Make(Spec : CmdSpec) : sig
    val arb_cmds_triple : int -> int -> (Spec.cmd list * Spec.cmd list * Spec.cmd list) QCheck.arbitrary
    val check_seq_cons : (Spec.cmd * Spec.res) list -> (Spec.cmd * Spec.res) list -> (Spec.cmd * Spec.res) list -> Spec.t -> Spec.cmd list -> bool
    val interp_plain : Spec.t -> Spec.cmd list -> (Spec.cmd * Spec.res) list
    val lin_test : rep_count:int -> retries:int -> count:int -> name:string -> lin_prop:(Spec.cmd list * Spec.cmd list * Spec.cmd list -> bool) -> QCheck.Test.t
    val neg_lin_test : rep_count:int -> retries:int -> count:int -> name:string -> lin_prop:(Spec.cmd list * Spec.cmd list * Spec.cmd list -> bool) -> QCheck.Test.t
  end
end
  [@@alert internal "This module is exposed for internal uses only, its API may change at any time"]


(** {1 Type-representing values} *)

type constructible
(** Type definition to denote whether a described type can be generated *)

type deconstructible
(** Type definition to denote whether a described type can be deconstructed,
    i.e., tested for equality. *)

type combinable
(** Type definition to denote that a described type can be composed with
    other combinators such as {!list}. *)

type noncombinable
(** Type definition to denote that a described type cannot be composed with
    other combinators such as {!list}. *)

type (_, _, _, _) ty
(** Type definition for type-describing combinators.
    [(typ,con,styp,comb) ty] represents a type [typ] and with an underlying state of type [styp].
    The [con] type parameter indicates whether the combinator type is {!constructible} or {!type-deconstructible}.
    The [comb] type parameter indicates whether the combinator type is {!combinable} or {!noncombinable}.
*)

val gen : 'a QCheck.arbitrary -> ('a -> string) -> ('a, constructible, 's, combinable) ty
(** [gen arb to_str] builds a {!constructible} and {!combinable} type combinator
    from a QCheck generator [arb] and a to-string function [to_str]. *)

val deconstructible : ('a -> string) -> ('a -> 'a -> bool) -> ('a, deconstructible, 's, combinable) ty
(** [deconstructible to_str eq] builds a {!type-deconstructible} and {!combinable} type combinator
    from a to-string function [to_str] and an equality predicate [eq]. *)

val gen_deconstructible : 'a QCheck.arbitrary -> ('a -> string) -> ('a -> 'a -> bool) -> ('a, 'c, 's, combinable) ty
(** [gen_deconstructible arb to_str eq] builds a {!combinable} type combinator
    from a QCheck generator [arb], a to-string function [to_str] and an
    equality predicate [eq]. *)


(** {2 Type combinators} *)

val unit : (unit, 'a, 'b, combinable) ty
(** The [unit] combinator represents the {{!Stdlib.Unit.t}[unit]} type *)

val bool : (bool, 'a, 'b, combinable) ty
(** The [bool] combinator represents the {{!Stdlib.Bool.t}[bool]} type *)

val char : (char, 'a, 'b, combinable) ty
(** The [char] combinator represents the {{!Stdlib.Char.t}[char]} type.
    It uses a uniform generator based on {!QCheck.char}. *)

val char_printable : (char, 'a, 'b, combinable) ty
(** The [char_printable] combinator represents the {{!Stdlib.Char.t}[char]} type.
    The generated characters have character codes 32-126 or 10 (newline)
    and are based on {!QCheck.printable_char}. *)

val nat_small : (int, 'a, 'b, combinable) ty
(** The [nat_small] combinator represents the {{!Stdlib.Int.t}[int]} type.
    The generated integers are non-negative, less than 100,
    and are based on {!QCheck.small_nat}. *)

val int : (int, 'a, 'b, combinable) ty
(** The [int] combinator represents the {{!Stdlib.Int.t}[int]} type.
    It uses a uniform generator based on {!QCheck.int}. *)

val int_small : (int, 'a, 'b, combinable) ty
(** The [int_small] combinator represents the {{!Stdlib.Int.t}[int]} type.
    The generated integers are non-negative
    and are based on {!QCheck.small_int}. *)

val int_pos : (int, 'a, 'b, combinable) ty
(** The [int_pos] combinator represents the {{!Stdlib.Int.t}[int]} type.
    The generated integers are non-negative
    and uniformly distributed. It is based on {!QCheck.pos_int}. *)

val int_bound : int -> (int, 'a, 'b, combinable) ty
(** The [int_bound b] combinator represents the {{!Stdlib.Int.t}[int]} type.
    The generated integers range from [0] to [b], inclusive.
    It uses a uniform generator based on {!QCheck.int_bound}.

    Note: the result of [int_bound my_bound] cannot be used both as an
    argument type and as a result type in type signature descriptions. *)

val int32 : (Int32.t, 'a, 'b, combinable) ty
(** The [int32] combinator represents the {{!Stdlib.Int32.t}[int32]} type.
    It uses a uniform generator based on {!QCheck.int32}. *)

val int64 : (Int64.t, 'a, 'b, combinable) ty
(** The [int64] combinator represents the {{!Stdlib.Int64.t}[int64]} type.
    It uses a uniform generator based on {!QCheck.int64}. *)

val nat64_small : (Int64.t, 'a, 'b, combinable) ty
(** The [nat64_small] combinator represents the {{!Stdlib.Int64.t}[int64]} type.
    The generated integers are non-negative
    and are based on {!QCheck.small_nat}. *)

val float : (float, 'a, 'b, combinable) ty
(** The [float] combinator represents the {{!Stdlib.Float.t}[float]} type.
    The generated floating point numbers do not include nan and infinities.
    It is based on {!QCheck.float}. *)

val string : (String.t, 'a, 'b, combinable) ty
(** The [string] combinator represents the {{!Stdlib.String.t}[string]} type.
    The generated strings have a size generated from {!QCheck.Gen.nat} and
    characters resulting from {!QCheck.Gen.char}. It is based on {!QCheck.string}. *)

val string_small : (String.t, 'a, 'b, combinable) ty
(** The [string_small] combinator represents the {{!Stdlib.String.t}[string]} type.
    The generated strings have a size generated from {!QCheck.Gen.small_nat} and
    characters resulting from {!QCheck.Gen.char}. It is based on {!QCheck.small_string}. *)

val string_small_printable : (String.t, 'a, 'b, combinable) ty
(** The [string_small_printable] combinator represents the {{!Stdlib.String.t}[string]} type.
    The generated strings have a size generated from {!QCheck.Gen.small_nat} and
    characters resulting from {!QCheck.Gen.printable}.
    It is based on {!QCheck.small_printable_string}. *)

val bytes : (Bytes.t, 'a, 'b, combinable) ty
(** The [bytes] combinator represents the {{!Stdlib.Bytes.t}[bytes]} type.
    The generated byte strings have a size generated from {!QCheck.Gen.nat} and
    characters resulting from {!QCheck.Gen.char}. It is based on {!QCheck.bytes}. *)

val bytes_small : (Bytes.t, 'a, 'b, combinable) ty
(** The [bytes_small] combinator represents the {{!Stdlib.Bytes.t}[bytes]} type.
    The generated byte strings have a size generated from {!QCheck.Gen.small_nat} and
    characters resulting from {!QCheck.Gen.char}. It is based on {!QCheck.bytes_small}. *)

val bytes_small_printable : (Bytes.t, 'a, 'b, combinable) ty
(** The [bytes_small_printable] combinator represents the {{!Stdlib.Bytes.t}[string]} type.
    The generated byte strings have a size generated from {!QCheck.Gen.small_nat} and
    characters resulting from {!QCheck.Gen.printable}.
    It is based on {!QCheck.bytes_small_of}. *)

val option :
  ?ratio:float ->
  ('a, 'c, 's, combinable) ty -> ('a option, 'c, 's, combinable) ty
(** The [option] combinator represents the {{!Stdlib.Option.t}[option]} type.
    The generated values from [option t] are either [Some v] or [None]
    with [v] being generated by the [t] combinator.
    An optional [ratio] allows to change the default [0.85] [Some]s.
    It is based on {!QCheck.option}. *)

val opt :
  ?ratio:float ->
  ('a, 'b, 'c, combinable) ty -> ('a option, 'b, 'c, combinable) ty
(** The [opt] combinator is an alias for {!option}. *)

val list : ('a, 'c, 's, combinable) ty -> ('a list, 'c, 's, combinable) ty
(** The [list] combinator represents the {{!Stdlib.List.t}[list]} type.
    The generated lists from [list t] have a length resulting from {!QCheck.Gen.nat}
    and have their elements generated by the [t] combinator.
    It is based on {!QCheck.list}. *)

val list_small : ('a, 'c, 's, combinable) ty -> ('a list, 'c, 's, combinable) ty
(** The [list_small] combinator represents the {{!Stdlib.List.t}[list]} type.
    The generated lists from [list_small t] have a length resulting from {!QCheck.Gen.small_nat}
    and have their elements generated by the [t] combinator.
    It is based on {!QCheck.small_list}. *)

val array : ('a, 'c, 's, combinable) ty -> ('a array, 'c, 's, combinable) ty
(** The [array] combinator represents the {{!Stdlib.Array.t}[array]} type.
    The generated arrays from [array t] have a length resulting from {!QCheck.Gen.nat}
    and have their elements generated by the [t] combinator.
    It is based on {!QCheck.array}. *)

val array_small : ('a, 'c, 's, combinable) ty -> ('a array, 'c, 's, combinable) ty
(** The [array_small] combinator represents the {{!Stdlib.Array.t}[array]} type.
    The generated arrays from [array_small t] have a length resulting from {!QCheck.Gen.small_nat}
    and have their elements generated by the [t] combinator.
    It is based on {!QCheck.array_of_size}. *)

val seq : ('a, 'c, 's, combinable) ty -> ('a Seq.t, 'c, 's, combinable) ty
(** The [seq] combinator represents the {!Stdlib.Seq.t} type.
    The generated sequences from [seq t] have a length resulting from {!QCheck.Gen.nat}
    and have their elements generated by the [t] combinator. *)

val seq_small : ('a, 'c, 's, combinable) ty -> ('a Seq.t, 'c, 's, combinable) ty
(** The [seq_small] combinator represents the {!Stdlib.Seq.t} type.
    The generated sequences from [seq_small t] have a length resulting from {!QCheck.Gen.small_nat}
    and have their elements generated by the [t] combinator. *)

val t : ('a, constructible, 'a, noncombinable) ty
(** The [t] combinator represents the type {!Spec.t} of the system under test. *)

val state : ('a, constructible, 'a, noncombinable) ty
(** The [state] combinator represents the type {!Spec.t} of the system under test.
    It is an alias for the [t] combinator. *)

val or_exn :
  ('a, deconstructible, 'b, combinable) ty ->
  (('a, exn) result, deconstructible, 'c, combinable) ty
(** The [or_exn] combinator transforms a result type representing [t]
  into a [(t, exn)] {{!Stdlib.Result.t}[result]} type. *)

val print_result :
  ('a -> string) -> ('b -> string) -> ('a, 'b) result -> string
(** [print_result pa pb] creates a to-string function for a [(a,b)] {{!Stdlib.Result.t}[result]} type
    given two to-string functions for [a]s and [b]s, respectively. *)

val print : ('a, 'c, 's, 'comb) ty -> 'a -> string
(** Given a description of type ['a], print a value of type ['a]. *)

val equal : ('a, deconstructible, 's, 'comb) ty -> 'a -> 'a -> bool
(** Given a description of type ['a], compare two values of type ['a]. *)


(** {1 Values representing API functions} *)

module Fun : sig
  (** [(ftyp,rtyp,styp) Fun.fn] represents a function type of type [ftyp], with return type [rtyp],
      and with the underlying state type [styp]. *)
  type (_, _, _) fn
end

val returning :
  ('a, deconstructible, 'b, combinable) ty -> ('a, 'a, 'b) Fun.fn
(** [returning t] represents a pure return type. *)

val returning_or_exc :
  ('a, deconstructible, 'b, combinable) ty ->
  ('a, ('a, exn) result, 'b) Fun.fn
(** [returning_or_exc t] represents a return type of a function that may raise an exception. *)

val returning_ : ('a, 'b, 'c, 'd) ty -> ('a, unit, 'c) Fun.fn
(** [returning_ t] represents a return type that should be ignored. *)

val returning_or_exc_ :
  ('a, 'b, 'c, 'd) ty -> ('a, (unit, exn) result, 'c) Fun.fn
(** [returning_or_exc_ t] represents a return type that should be ignored of a function
    that may raise an exception. *)

val ( @-> ) :
  ('a, constructible, 'b, 'c) ty ->
  ('d, 'e, 'b) Fun.fn -> ('a -> 'd, 'e, 'b) Fun.fn
(** [at @-> rt] represents a function type expecting an argument [at]
    and returning [rt]. *)


(** {1 API description} *)

(** Type and constructor to capture a single function signature *)
type !_ elem

type 's api = (int * 's elem) list
(** The type of module signatures *)

val val_ : string -> 'f -> ('f, 'r, 's) Fun.fn -> int * 's elem
(** [val_ str f sig] describes a function signature from a string [str],
    a function value [f], and a signature description [sig]. *)

val val_freq : int -> string -> 'f -> ('f, 'r, 's) Fun.fn -> int * 's elem
(** [val_freq w str f sig] describes a function signature like
    {!val_} [str f sig] but with relative weight [w] rather than 1.
    A function of weight 2 will have twice the probability of being
    invoked compared to a function of weight 1. *)


(** The required description of a module signature *)
module type Spec =
sig
  type t
  (** The type of the system under test *)

  val init : unit -> t
  (** The function to initialize the system under test *)

  val cleanup : t -> unit
  (** The function to cleanup the system under test *)

  val api : (int * t elem) list
  (** A description of the function signatures *)
end


(** {1 Generating a linearization testing module from an API} *)

module MakeCmd (Spec : Spec) : Internal.CmdSpec [@alert "-internal"]
(** Functor to map a combinator-based module signature description
    into a raw {!Lin} description.
    This functor is exposed for internal uses only, its API may change
    at any time.
    *)