-
Notifications
You must be signed in to change notification settings - Fork 46
Long integer shrinking from within toplevel/utop #59
Copy link
Copy link
Closed
Labels
Description
Consider the following code:
open QCheck
let rec fac n = match n with
| 0 -> 1
| n -> n * fac (n - 1)
let test_fac =
Test.make ~name:"fac mod'"
(small_int_corners ())
(fun n -> try (fac n) mod n = 0
with Division_by_zero -> (n=0))
;;
QCheck_runner.run_tests ~verbose:true [test_fac]
Assume you save the above to a file bug.ml.
If I compile the example test with the bytecode backend I quickly (0.5s) find the bound (262049) for blowing the bytecode stack:
$ ocamlbuild -use-ocamlfind -package qcheck bug.byte
Finished, 3 targets (0 cached) in 00:00:00.
$ ./bug.byte
random seed: 317373207
generated error fail pass / total time test name
[✗] 4 1 0 3 / 100 0.5s fac mod'
=== Error ======================================================================
Test fac mod' errored on (138 shrink steps):
262049
exception Stack overflow
================================================================================
failure (0 tests failed, 1 tests errored, ran 1 tests)
Similarly I can quickly (0.4s) find the bound (524115) for blowing the native-code stack:
$ ocamlbuild -use-ocamlfind -package qcheck bug.native
Finished, 4 targets (2 cached) in 00:00:00.
$ ./bug.native
random seed: 448617552
generated error fail pass / total time test name
[✗] 4 1 0 3 / 100 0.4s fac mod'
=== Error ======================================================================
Test fac mod' errored on (215 shrink steps):
524115
exception Stack overflow
================================================================================
failure (0 tests failed, 1 tests errored, ran 1 tests)
However, if I try the same thing within the OCaml toplevel or utop -- I consistently get very long shrinking times (237.9s) with many (52578!) shrinking steps - to the point that I thought I had hit an infinite loop:
utop # #require "qcheck";;
─( 17:51:25 )─< command 1 >────────────────────────────────────────────{ counter: 0 }─
utop # #use "bug.ml";;
val fac : int -> int = <fun>
val test_fac : Test.t = QCheck.Test.Test <abstr>
random seed: 175072808
generated error fail pass / total time test name
[✗] 4 1 0 3 / 100 237.9s fac mod'
=== Error ======================================================================
Test fac mod' errored on (52578 shrink steps):
209609
exception Stack overflow
================================================================================
failure (0 tests failed, 1 tests errored, ran 1 tests)
- : int = 1
Is this example triggering a sore point in the built-in integer shrinker, or is something else going on?
This is on Mac OS X with OCaml 4.07.1 and QCheck 0.9.
Reactions are currently unavailable