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

Fix function generation reproducability #240

Merged
merged 3 commits into from
Apr 20, 2022
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
12 changes: 6 additions & 6 deletions example/output.txt.expected
Original file line number Diff line number Diff line change
Expand Up @@ -59,19 +59,19 @@ stats num:

--- Failure --------------------------------------------------------------------

Test FAIL_pred_map_commute failed (127 shrink steps):
Test FAIL_pred_map_commute failed (107 shrink steps):

([3], {_ -> 0}, {3 -> false; _ -> true})
([0], {_ -> -21}, {-21 -> true; _ -> false})

--- Failure --------------------------------------------------------------------

Test FAIL_fun2_pred_strings failed (1 shrink steps):

{some random string -> true; _ -> false}
{some other string -> false; _ -> true}

--- Failure --------------------------------------------------------------------

Test fold_left fold_right failed (25 shrink steps):
Test fold_left fold_right failed (24 shrink steps):

(0, [1], {(1, 0) -> 1; _ -> 0})

Expand All @@ -84,9 +84,9 @@ l=[1], fold_left=1, fold_right=0

--- Failure --------------------------------------------------------------------

Test fold_left fold_right uncurried failed (111 shrink steps):
Test fold_left fold_right uncurried failed (97 shrink steps):

({(5, 7) -> 0; _ -> 7}, 0, [5; 0])
({(1, 7) -> 0; _ -> 7}, 0, [1; 0])

--- Failure --------------------------------------------------------------------

Expand Down
22 changes: 20 additions & 2 deletions src/core/QCheck.ml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,23 @@ all rights reserved.
let poly_compare=compare
open Printf

module RS = Random.State
module RS = struct
(* Poor man's splitter for version < 5.0 *)
(* This definition is shadowed by the [include] on OCaml >=5.0 *)
let split rs =
let bits = Random.State.bits rs in
let rs' = Random.State.make [|bits|] in
rs'
include Random.State
(* This is how OCaml 5.0 splits: *)
(* Split a new PRNG off the given PRNG *)
(*
let split s =
let i1 = bits64 s in let i2 = bits64 s in
let i3 = bits64 s in let i4 = bits64 s in
mk i1 i2 i3 i4
*)
end

let (|>) x f = f x

Expand Down Expand Up @@ -1308,14 +1324,16 @@ end = struct
List.iter (fun (k,v) -> T.add tbl k v) l;
tbl
in
(* split random state to avoid later failed [get]s to side-effect the current [st] *)
let st' = RS.split st in
(* make a table
@param extend if true, extend table on the fly *)
let rec make ~extend tbl = {
get=(fun x ->
try Some (T.find tbl x)
with Not_found ->
if extend then (
let v = v.gen st in
let v = v.gen st' in
T.add tbl x v;
Some v
) else None);
Expand Down
22 changes: 20 additions & 2 deletions src/core/QCheck2.ml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,23 @@ all rights reserved.

let poly_compare=compare

module RS = Random.State
module RS = struct
(* Poor man's splitter for version < 5.0 *)
(* This definition is shadowed by the [include] on OCaml >=5.0 *)
let split rs =
let bits = Random.State.bits rs in
let rs' = Random.State.make [|bits|] in
rs'
include Random.State
(* This is how OCaml 5.0 splits: *)
(* Split a new PRNG off the given PRNG *)
(*
let split s =
let i1 = bits64 s in let i2 = bits64 s in
let i3 = bits64 s in let i4 = bits64 s in
mk i1 i2 i3 i4
*)
end

let rec foldn ~f ~init:acc i =
if i = 0 then acc else foldn ~f ~init:(f acc i) (i-1)
Expand Down Expand Up @@ -1063,6 +1079,8 @@ end = struct
let equal = k_obs.Observable.eq
let hash = k_obs.Observable.hash
end) in
(* split random state to avoid later failed [get]s to side-effect the current [st] *)
let st' = RS.split st in
(* make a table
@param extend if [true], extend table [tbl] on the fly (during test execution, to "record" input values and generate an associated output value). [false] during shrinking (use the default value if the input value is not in the table). *)
let make ~extend tbl =
Expand All @@ -1073,7 +1091,7 @@ end = struct
with Not_found ->
if extend then (
(* Generate a new value and "record" the binding for potential future display/shrinking *)
let value_tree = v_gen st in
let value_tree = v_gen st' in
p_tree_bindings_rev := (key, value_tree) :: !p_tree_bindings_rev;
let v = Tree.root value_tree in
T.add tbl key v;
Expand Down
30 changes: 19 additions & 11 deletions test/core/QCheck2_expect_test.expected
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
random seed: 1234
50 7 0 0 0 0 0 0 0 0 0 0 3 3 3 3 3 3 3 3 3 3 5 5 5 5 5 5 5 5 5 5 6 6 6 6 6 6 6 6 6 6 2724675603984413065
50 7 0 0 0 0 0 0 0 0 0 0 3 3 3 3 3 3 3 3 3 3 5 5 5 5 5 5 5 5 5 5 6 6 6 6 6 6 6 6 6 6 (6,fun,50) (0,fun,2) (7,fun,66) (54,fun,9) (2,fun,5) (90,fun,4) (1,fun,4) (37,fun,7) (7,fun,1) (8,fun,5)
(6,fun,50) (0,fun,2) (7,fun,66) (54,fun,9) (2,fun,5) (90,fun,4) (1,fun,4) (37,fun,7) (7,fun,1) (8,fun,5)
(6,fun,50) (0,fun,2) (7,fun,66) (54,fun,9) (2,fun,5) (90,fun,4) (1,fun,4) (37,fun,7) (7,fun,1) (8,fun,5)
(6,fun,50) (0,fun,2) (7,fun,66) (54,fun,9) (2,fun,5) (90,fun,4) (1,fun,4) (37,fun,7) (7,fun,1) (8,fun,5)
(6,fun,50) (0,fun,2) (7,fun,66) (54,fun,9) (2,fun,5) (90,fun,4) (1,fun,4) (37,fun,7) (7,fun,1) (8,fun,5)
(6,fun,50) (0,fun,2) (7,fun,66) (54,fun,9) (2,fun,5) (90,fun,4) (1,fun,4) (37,fun,7) (7,fun,1) (8,fun,5)
(6,fun,50) (0,fun,2) (7,fun,66) (54,fun,9) (2,fun,5) (90,fun,4) (1,fun,4) (37,fun,7) (7,fun,1) (8,fun,5)
(6,fun,50) (0,fun,2) (7,fun,66) (54,fun,9) (2,fun,5) (90,fun,4) (1,fun,4) (37,fun,7) (7,fun,1) (8,fun,5)
2724675603984413065
0
1362337801992206532
0
Expand Down Expand Up @@ -530,21 +538,21 @@ Leaf 0

--- Failure --------------------------------------------------------------------

Test fail_pred_map_commute failed (16 shrink steps):
Test fail_pred_map_commute failed (122 shrink steps):

([2], {_ -> 0}, {1 -> false; 2 -> true; _ -> false})
([0], {0 -> 1; 2 -> 0; 20 -> 0; 4 -> 0; 54 -> 0; 6 -> 0; 8 -> 0; 60 -> 0; 12 -> 0; _ -> 0}, {0 -> true; -1487654178632829215 -> false; -2792235260416531278 -> false; 2 -> false; 3324124342680534771 -> false; 20 -> false; 4 -> false; -2849913598173370635 -> false; 54 -> false; 6 -> false; 8 -> false; 815755449952469177 -> false; 4035005642433201833 -> false; -2961585594425353332 -> false; 60 -> false; 12 -> false; 3780670741311086221 -> false; _ -> false})

--- Failure --------------------------------------------------------------------

Test fail_pred_strings failed (1 shrink steps):
Test fail_pred_strings failed (2 shrink steps):

{"some random string" -> true; _ -> false}

--- Failure --------------------------------------------------------------------

Test fold_left fold_right failed (22 shrink steps):
Test fold_left fold_right failed (56 shrink steps):

(0, [1], {(1, 0) -> 1; (8, 0) -> 0; (8, 8) -> 0; (8, 93) -> 0; (7, 7) -> 0; (24, 5) -> 0; (7, 0) -> 0; (0, 2) -> 0; (2, 4) -> 0; (9, 8) -> 0; (4, 9) -> 0; (1, 24) -> 0; (9, 5) -> 0; (80, 9) -> 0; (24, 0) -> 0; (1, 8) -> 0; (5, 7) -> 0; (0, 7) -> 0; (7, 8) -> 0; (0, 24) -> 0; _ -> 0})
(0, [1], {(1, 0) -> 1; (8, 0) -> 0; (6, 4) -> 0; (2, 6) -> 0; (3, 6) -> 0; (2, 16) -> 0; (0, 60) -> 0; (20, 3) -> 0; (12, 60) -> 0; (0, 2) -> 0; (2, 4) -> 0; (1, 6) -> 0; (6, 1) -> 0; (60, 83) -> 0; (3, 5) -> 0; (7, 12) -> 0; (6, 8) -> 0; (2, 2) -> 0; (56, 6) -> 0; (6, 5) -> 0; (12, 3) -> 0; (6, 6) -> 0; (0, 8) -> 0; (0, 58) -> 0; (5, 5) -> 0; (20, 2) -> 0; (54, 0) -> 0; (0, 6) -> 0; (4, 6) -> 0; (4, 56) -> 0; (5, 54) -> 0; (9, 8) -> 0; (8, 6) -> 0; (60, 47) -> 0; (9, 12) -> 0; (4, 20) -> 0; (0, 20) -> 0; (1, 2) -> 0; (28, 2) -> 0; (4, 1) -> 0; (0, 4) -> 0; (8, 3) -> 0; (4, 28) -> 0; (42, 8) -> 0; (6, 0) -> 0; (58, 65) -> 0; (12, 12) -> 0; (5, 6) -> 0; _ -> 0})

+++ Messages ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Expand All @@ -555,15 +563,15 @@ l=[1], fold_left=1, fold_right=0

--- Failure --------------------------------------------------------------------

Test fold_left fold_right uncurried failed (325 shrink steps):
Test fold_left fold_right uncurried failed (376 shrink steps):

({(23, 62) -> 0; (9, 42) -> 0; (8, 61) -> 0; (8, 5) -> 0; (30, 5) -> 0; (9, 6) -> 0; (76, 6) -> 0; (19, 31) -> 0; (7, 62) -> 0; (0, 7) -> 1; (7, 1) -> 0; (78, 4) -> 0; (8, 2) -> 0; (78, 0) -> 0; (3, 47) -> 0; (4, 8) -> 0; (98, 9) -> 0; (1, 38) -> 0; (0, 26) -> 0; (1, 7) -> 0; (86, 3) -> 0; (9, 37) -> 0; (8, 1) -> 0; (79, 9) -> 0; (3, 5) -> 0; (56, 8) -> 0; (2, 5) -> 0; (8, 8) -> 0; (56, 67) -> 0; (5, 60) -> 0; (2, 31) -> 0; (61, 6) -> 0; (12, 5) -> 0; (76, 2) -> 0; (78, 8) -> 0; (1, 1) -> 0; (8, 9) -> 0; (7, 8) -> 0; (2, 9) -> 0; (29, 7) -> 0; (5, 8) -> 0; (28, 6) -> 0; (1, 4) -> 0; (9, 79) -> 0; (0, 1) -> 0; (1, 41) -> 0; (82, 98) -> 0; (6, 79) -> 0; (7, 6) -> 0; (4, 3) -> 0; (8, 12) -> 0; (5, 1) -> 0; (39, 1) -> 0; (3, 6) -> 0; (1, 2) -> 0; (76, 31) -> 0; (4, 1) -> 0; (6, 5) -> 0; (0, 8) -> 0; (8, 7) -> 0; (2, 6) -> 0; (52, 5) -> 0; (8, 47) -> 0; (5, 3) -> 0; (7, 9) -> 0; (13, 13) -> 0; (0, 87) -> 0; (82, 0) -> 0; (34, 8) -> 0; (1, 14) -> 0; (2, 71) -> 0; (52, 4) -> 0; (1, 3) -> 0; (85, 6) -> 0; (8, 19) -> 0; (3, 13) -> 0; (69, 1) -> 0; (5, 62) -> 0; (0, 15) -> 0; (34, 0) -> 0; (9, 4) -> 0; (0, 6) -> 0; (1, 8) -> 0; (86, 6) -> 0; (4, 5) -> 0; (3, 1) -> 0; (57, 2) -> 0; (3, 3) -> 0; (4, 0) -> 0; (30, 6) -> 0; (5, 34) -> 0; (0, 4) -> 0; (2, 3) -> 0; (5, 6) -> 0; (5, 7) -> 0; (5, 0) -> 0; (4, 4) -> 0; (7, 5) -> 0; (78, 2) -> 0; (9, 8) -> 0; (7, 70) -> 0; (35, 1) -> 0; (64, 7) -> 0; (60, 0) -> 0; (1, 9) -> 0; _ -> 0}, 0, [0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 7])
({(0, 2) -> 0; (13, 0) -> 0; (22, 3) -> 0; (20, 5) -> 0; (2, 93) -> 0; (65, 34) -> 0; (2, 7) -> 0; (0, 7) -> 0; (49, 3) -> 0; (8, 62) -> 0; (8, 2) -> 0; (54, 6) -> 0; (38, 4) -> 0; (7, 0) -> 1; (6, 25) -> 0; (0, 0) -> 0; (3, 4) -> 0; (1, 7) -> 0; (4, 6) -> 0; (8, 1) -> 0; (48, 42) -> 0; (18, 1) -> 0; (90, 14) -> 0; (8, 70) -> 0; (9, 1) -> 0; (38, 2) -> 0; (3, 5) -> 0; (8, 8) -> 0; (9, 3) -> 0; (2, 36) -> 0; (45, 2) -> 0; (18, 6) -> 0; (7, 98) -> 0; (3, 9) -> 0; (2, 31) -> 0; (86, 2) -> 0; (4, 7) -> 0; (1, 1) -> 0; (0, 5) -> 0; (2, 9) -> 0; (1, 5) -> 0; (44, 0) -> 0; (77, 7) -> 0; (5, 8) -> 0; (1, 4) -> 0; (9, 79) -> 0; (48, 1) -> 0; (30, 7) -> 0; (6, 79) -> 0; (5, 1) -> 0; (65, 4) -> 0; (2, 1) -> 0; (4, 1) -> 0; (66, 12) -> 0; (6, 5) -> 0; (7, 3) -> 0; (3, 7) -> 0; (9, 7) -> 0; (9, 9) -> 0; (2, 6) -> 0; (3, 15) -> 0; (5, 3) -> 0; (67, 1) -> 0; (3, 28) -> 0; (1, 87) -> 0; (7, 31) -> 0; (9, 13) -> 0; (32, 1) -> 0; (0, 27) -> 0; (6, 15) -> 0; (20, 0) -> 0; (6, 8) -> 0; (1, 6) -> 0; (0, 6) -> 0; (3, 1) -> 0; (9, 71) -> 0; (95, 4) -> 0; (97, 1) -> 0; (7, 4) -> 0; (84, 3) -> 0; (92, 6) -> 0; (6, 2) -> 0; (8, 4) -> 0; (5, 0) -> 0; (7, 5) -> 0; (9, 8) -> 0; (90, 26) -> 0; (0, 19) -> 0; (1, 13) -> 0; (6, 1) -> 0; (9, 28) -> 0; (9, 6) -> 0; (8, 6) -> 0; (3, 8) -> 0; (7, 62) -> 0; (86, 0) -> 0; (65, 1) -> 0; (7, 1) -> 0; (6, 6) -> 0; (30, 4) -> 0; (7, 67) -> 0; (0, 9) -> 0; (78, 5) -> 0; (17, 3) -> 0; (9, 60) -> 0; (3, 71) -> 0; (88, 1) -> 0; (4, 61) -> 0; (9, 0) -> 0; (45, 0) -> 0; (2, 5) -> 0; (9, 47) -> 0; (18, 5) -> 0; (66, 0) -> 0; (0, 76) -> 0; (8, 3) -> 0; (74, 6) -> 0; (5, 60) -> 0; (5, 80) -> 0; (8, 9) -> 0; (7, 8) -> 0; (39, 4) -> 0; (72, 8) -> 0; (4, 38) -> 0; (70, 31) -> 0; (19, 5) -> 0; (4, 9) -> 0; (0, 1) -> 0; (1, 37) -> 0; (7, 6) -> 0; (6, 3) -> 0; (9, 5) -> 0; (58, 4) -> 0; (54, 5) -> 0; (7, 86) -> 0; (67, 6) -> 0; (0, 8) -> 0; (8, 7) -> 0; (44, 18) -> 0; (3, 0) -> 0; (4, 41) -> 0; (0, 31) -> 0; (1, 51) -> 0; (6, 0) -> 0; (1, 3) -> 0; (70, 1) -> 0; (9, 4) -> 0; (4, 5) -> 0; (1, 8) -> 0; (5, 9) -> 0; (0, 14) -> 0; (3, 3) -> 0; (4, 0) -> 0; (78, 9) -> 0; (0, 4) -> 0; (2, 3) -> 0; (9, 62) -> 0; (35, 1) -> 0; (55, 1) -> 0; _ -> 0}, 0, [7; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0])

--- Failure --------------------------------------------------------------------

Test fold_left fold_right uncurried fun last failed (25 shrink steps):
Test fold_left fold_right uncurried fun last failed (56 shrink steps):

(0, [1], {(0, 2) -> 0; (8, 80) -> 0; (93, 9) -> 0; (7, 24) -> 0; (8, 0) -> 0; (9, 7) -> 0; (0, 24) -> 0; (0, 7) -> 0; (7, 1) -> 0; (8, 9) -> 0; (24, 0) -> 0; (5, 8) -> 0; (1, 0) -> 1; (4, 8) -> 0; (7, 0) -> 0; (5, 7) -> 0; (8, 4) -> 0; (24, 5) -> 0; (0, 1) -> 0; (2, 8) -> 0; (9, 1) -> 0; (8, 8) -> 0; _ -> 0})
(0, [1], {(0, 2) -> 0; (3, 6) -> 0; (0, 20) -> 0; (20, 4) -> 0; (6, 42) -> 0; (47, 6) -> 0; (6, 12) -> 0; (2, 6) -> 0; (0, 58) -> 0; (8, 2) -> 0; (6, 6) -> 0; (8, 60) -> 0; (12, 3) -> 0; (6, 4) -> 0; (16, 8) -> 0; (6, 0) -> 0; (3, 4) -> 0; (12, 0) -> 0; (60, 5) -> 0; (8, 1) -> 0; (6, 8) -> 0; (2, 5) -> 0; (2, 42) -> 0; (5, 4) -> 0; (4, 20) -> 0; (54, 0) -> 0; (12, 4) -> 0; (3, 2) -> 0; (8, 0) -> 0; (4, 7) -> 0; (28, 3) -> 0; (2, 9) -> 0; (65, 54) -> 0; (5, 28) -> 0; (20, 2) -> 0; (6, 2) -> 0; (83, 6) -> 0; (58, 5) -> 0; (5, 6) -> 0; (56, 12) -> 0; (1, 60) -> 0; (4, 9) -> 0; (0, 1) -> 1; (2, 8) -> 0; (2, 0) -> 0; (6, 1) -> 0; (1, 12) -> 0; (60, 0) -> 0; _ -> 0})

--- Failure --------------------------------------------------------------------

Expand Down Expand Up @@ -1242,7 +1250,7 @@ stats dist:
4150517416584649600.. 4611686018427387903: ################# 189
================================================================================
1 warning(s)
failure (57 tests failed, 1 tests errored, ran 114 tests)
failure (57 tests failed, 1 tests errored, ran 122 tests)
random seed: 153870556

+++ Stats for int_dist_empty_bucket ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Expand Down
31 changes: 31 additions & 0 deletions test/core/QCheck2_tests.ml
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,28 @@ module Overall = struct
~gen:(fun rs -> Random.State.int rs))
(fun _i -> false)

(* [apply_n f x n] computes f(f(...f(x))) with n applications of f *)
let rec apply_n f x n =
if n=0
then x
else apply_n f (f x) (pred n)

(* test from #236 *)
let bad_fun_repro =
let sleep_time = 0.175 in
let count = ref 0 in
Test.make ~count:10 ~name:"bad function reproducability"
Gen.(triple small_int (fun1 Observable.int small_int) small_int)
(fun (i,f,j) ->
incr count;
Printf.printf "(%i,fun,%i)%s%!" i j (if !count mod 10 = 0 then "\n" else " ");
Unix.sleepf sleep_time;
if 1 = Float.to_int (Unix.time ()) mod 2
then
(ignore(apply_n (Fn.apply f) i j > 0); true)
else
(ignore(apply_n (Fn.apply f) i i > 0); true))

let tests = [
passing;
failing;
Expand All @@ -112,6 +134,15 @@ module Overall = struct
bad_assume_fail;
bad_gen_fail;
(*bad_shrinker_fail;*)
(* we repeat the following multiple times to check the expected output for duplicate lines *)
bad_fun_repro;
bad_fun_repro;
bad_fun_repro;
bad_fun_repro;
bad_fun_repro;
bad_fun_repro;
bad_fun_repro;
bad_fun_repro;
]
end

Expand Down
28 changes: 18 additions & 10 deletions test/core/QCheck_expect_test.expected
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
random seed: 1234
50 7 4 2 2 2 2 2 2 2 2 2 2 3 3 3 3 3 3 3 3 3 3 2724675603984413065
50 7 4 2 2 2 2 2 2 2 2 2 2 3 3 3 3 3 3 3 3 3 3 (6,fun,50) (0,fun,2) (7,fun,66) (54,fun,9) (2,fun,5) (90,fun,4) (1,fun,4) (37,fun,7) (7,fun,1) (8,fun,5)
(6,fun,50) (0,fun,2) (7,fun,66) (54,fun,9) (2,fun,5) (90,fun,4) (1,fun,4) (37,fun,7) (7,fun,1) (8,fun,5)
(6,fun,50) (0,fun,2) (7,fun,66) (54,fun,9) (2,fun,5) (90,fun,4) (1,fun,4) (37,fun,7) (7,fun,1) (8,fun,5)
(6,fun,50) (0,fun,2) (7,fun,66) (54,fun,9) (2,fun,5) (90,fun,4) (1,fun,4) (37,fun,7) (7,fun,1) (8,fun,5)
(6,fun,50) (0,fun,2) (7,fun,66) (54,fun,9) (2,fun,5) (90,fun,4) (1,fun,4) (37,fun,7) (7,fun,1) (8,fun,5)
(6,fun,50) (0,fun,2) (7,fun,66) (54,fun,9) (2,fun,5) (90,fun,4) (1,fun,4) (37,fun,7) (7,fun,1) (8,fun,5)
(6,fun,50) (0,fun,2) (7,fun,66) (54,fun,9) (2,fun,5) (90,fun,4) (1,fun,4) (37,fun,7) (7,fun,1) (8,fun,5)
(6,fun,50) (0,fun,2) (7,fun,66) (54,fun,9) (2,fun,5) (90,fun,4) (1,fun,4) (37,fun,7) (7,fun,1) (8,fun,5)
2724675603984413065
1362337801992206533
681168900996103267
340584450498051634
Expand Down Expand Up @@ -465,19 +473,19 @@ Leaf 0

--- Failure --------------------------------------------------------------------

Test fail_pred_map_commute failed (127 shrink steps):
Test fail_pred_map_commute failed (107 shrink steps):

([3], {_ -> 0}, {3 -> false; _ -> true})
([0], {_ -> -21}, {-21 -> true; _ -> false})

--- Failure --------------------------------------------------------------------

Test fail_pred_strings failed (1 shrink steps):

{some random string -> true; _ -> false}
{some other string -> false; _ -> true}

--- Failure --------------------------------------------------------------------

Test fold_left fold_right failed (25 shrink steps):
Test fold_left fold_right failed (24 shrink steps):

(0, [1], {(1, 0) -> 1; _ -> 0})

Expand All @@ -490,15 +498,15 @@ l=[1], fold_left=1, fold_right=0

--- Failure --------------------------------------------------------------------

Test fold_left fold_right uncurried failed (111 shrink steps):
Test fold_left fold_right uncurried failed (97 shrink steps):

({(5, 7) -> 0; _ -> 7}, 0, [5; 0])
({(1, 7) -> 0; _ -> 7}, 0, [1; 0])

--- Failure --------------------------------------------------------------------

Test fold_left fold_right uncurried fun last failed (26 shrink steps):
Test fold_left fold_right uncurried fun last failed (21 shrink steps):

(0, [1], {(0, 1) -> 1; _ -> 0})
(0, [1], {(0, 1) -> 0; _ -> 1})

--- Failure --------------------------------------------------------------------

Expand Down Expand Up @@ -1203,7 +1211,7 @@ stats dist:
4150517416584649600.. 4611686018427387903: ################# 189
================================================================================
1 warning(s)
failure (57 tests failed, 1 tests errored, ran 121 tests)
failure (57 tests failed, 1 tests errored, ran 129 tests)
random seed: 153870556

+++ Stats for int_dist_empty_bucket ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Expand Down
31 changes: 31 additions & 0 deletions test/core/QCheck_tests.ml
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,28 @@ module Overall = struct
Gen.int)
(fun _i -> false)

(* [apply_n f x n] computes f(f(...f(x))) with n applications of f *)
let rec apply_n f x n =
if n=0
then x
else apply_n f (f x) (pred n)

(* test from #236 *)
let bad_fun_repro =
let sleep_time = 0.175 in
let count = ref 0 in
Test.make ~count:10 ~name:"bad function reproducability"
(set_shrink Shrink.nil (triple small_int (fun1 Observable.int small_int) small_int))
(fun (i,f,j) ->
incr count;
Printf.printf "(%i,fun,%i)%s%!" i j (if !count mod 10 = 0 then "\n" else " ");
Unix.sleepf sleep_time;
if 1 = Float.to_int (Unix.time ()) mod 2
then
(ignore(apply_n (Fn.apply f) i j > 0); true)
else
(ignore(apply_n (Fn.apply f) i i > 0); true))

let tests = [
passing;
failing;
Expand All @@ -122,6 +144,15 @@ module Overall = struct
bad_assume_fail;
bad_gen_fail;
(*bad_shrinker_fail;*)
(* we repeat the following multiple times to check the expected output for duplicate lines *)
bad_fun_repro;
bad_fun_repro;
bad_fun_repro;
bad_fun_repro;
bad_fun_repro;
bad_fun_repro;
bad_fun_repro;
bad_fun_repro;
]
end

Expand Down