Skip to content

Commit

Permalink
Merge pull request #160 from jmid/QCheck2.Gen.list_size-fix-stack_ove…
Browse files Browse the repository at this point in the history
…rflow

Fix `QCheck2.gen.list_size Stack overflow`
  • Loading branch information
jmid authored Sep 7, 2021
2 parents 2ad6a0f + ce76651 commit f750ccf
Show file tree
Hide file tree
Showing 5 changed files with 28 additions and 33 deletions.
12 changes: 7 additions & 5 deletions src/core/QCheck2.ml
Original file line number Diff line number Diff line change
Expand Up @@ -528,14 +528,16 @@ module Gen = struct

let ui64 : int64 t = map Int64.abs int64

(* A tail-recursive implementation over Tree.t *)
let list_size (size : int t) (gen : 'a t) : 'a list t =
size >>= fun size ->
let rec loop n =
fun st ->
Tree.bind (size st) @@ fun size ->
let rec loop n acc =
if n <= 0
then pure []
else liftA2 List.cons gen (loop (n - 1))
then acc
else (loop [@tailcall]) (n - 1) (Tree.liftA2 List.cons (gen st) acc)
in
loop size
loop size (Tree.pure [])

let list (gen : 'a t) : 'a list t = list_size nat gen

Expand Down
16 changes: 8 additions & 8 deletions test/core/QCheck2_expect_test.ml
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ module Shrink = struct

let strings_are_empty =
Test.make ~name:"strings are empty" ~count:1000 ~print:Print.string
Gen.string (fun s -> (*Printf.printf "\"%s\"\n" (String.escaped s);*) s = "")
Gen.string (fun s -> s = "")

let string_never_has_000_char =
Test.make ~name:"string never has a \\000 char" ~count:1000 ~print:Print.string
Expand All @@ -203,7 +203,7 @@ module Shrink = struct

let list_shorter_10 =
Test.make ~name:"lists shorter than 10" ~print:Print.(list int)
Gen.(list small_int) (fun xs -> (*print_list xs;*) List.length xs < 10)
Gen.(list small_int) (fun xs -> List.length xs < 10)

let length_printer xs =
Printf.sprintf "[...] list length: %i" (List.length xs)
Expand All @@ -212,17 +212,17 @@ module Shrink = struct

let list_shorter_432 =
Test.make ~name:"lists shorter than 432" ~print:length_printer
Gen.(list_size size_gen small_int) (*Gen.(list small_int)*)
(fun xs -> (*print_list xs;*) List.length xs < 432)
Gen.(list_size size_gen small_int)
(fun xs -> List.length xs < 432)

let list_shorter_4332 =
Test.make ~name:"lists shorter than 4332" ~print:length_printer
Gen.(list_size size_gen small_int) (*Gen.(list small_int)*)
(fun xs -> (*print_list xs;*) List.length xs < 4332)
Gen.(list_size size_gen small_int)
(fun xs -> List.length xs < 4332)

let list_equal_dupl =
Test.make ~name:"lists equal to duplication" ~print:length_printer
Gen.(list_size size_gen small_int) (*Gen.(list small_int)*)
Test.make ~name:"lists equal to duplication" ~print:Print.(list int)
Gen.(list_size size_gen small_int)
(fun xs -> try xs = xs @ xs
with Stack_overflow -> false)

Expand Down
13 changes: 6 additions & 7 deletions test/core/QCheck_expect_test.ml
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ module Shrink = struct

let strings_are_empty =
Test.make ~name:"strings are empty" ~count:1000
string (fun s -> (*Printf.printf "\"%s\"\n" (String.escaped s);*) s = "")
string (fun s -> s = "")

let string_never_has_000_char =
Test.make ~name:"string never has a \\000 char" ~count:1000
Expand All @@ -198,7 +198,7 @@ module Shrink = struct

let list_shorter_10 =
Test.make ~name:"lists shorter than 10"
(list small_int) (fun xs -> (*print_list xs;*) List.length xs < 10)
(list small_int) (fun xs -> List.length xs < 10)

let length_printer xs =
Printf.sprintf "[...] list length: %i" (List.length xs)
Expand All @@ -207,18 +207,17 @@ module Shrink = struct

let list_shorter_432 =
Test.make ~name:"lists shorter than 432"
(set_print length_printer (list_of_size size_gen small_int)) (*(list small_int)*)
(fun xs -> (*print_list xs;*) List.length xs < 432)
(set_print length_printer (list_of_size size_gen small_int))
(fun xs -> List.length xs < 432)

let list_shorter_4332 =
Test.make ~name:"lists shorter than 4332"
(set_shrink Shrink.list_spine (set_print length_printer (list_of_size size_gen small_int)))
(fun xs -> (*print_list xs;*) List.length xs < 4332)
(fun xs -> List.length xs < 4332)

let list_equal_dupl =
Test.make ~name:"lists equal to duplication"
(set_print length_printer (list_of_size size_gen small_int))
(*(set_print length_printer (list small_int))*)
(list_of_size size_gen small_int)
(fun xs -> try xs = xs @ xs
with Stack_overflow -> false)

Expand Down
18 changes: 6 additions & 12 deletions test/core/qcheck2_output.txt.expected
Original file line number Diff line number Diff line change
Expand Up @@ -318,27 +318,21 @@ Test lists shorter than 10 failed (16 shrink steps):

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

Test lists shorter than 432 failed:
Test lists shorter than 432 failed (412 shrink steps):

ERROR: uncaught exception in generator for test lists shorter than 432 after 100 steps:
Exception: Stack overflow
Backtrace:
[...] list length: 432

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

Test lists shorter than 4332 failed:
Test lists shorter than 4332 failed (4022 shrink steps):

ERROR: uncaught exception in generator for test lists shorter than 4332 after 100 steps:
Exception: Stack overflow
Backtrace:
[...] list length: 4332

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

Test lists equal to duplication failed:
Test lists equal to duplication failed (4 shrink steps):

ERROR: uncaught exception in generator for test lists equal to duplication after 100 steps:
Exception: Stack overflow
Backtrace:
[0]

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

Expand Down
2 changes: 1 addition & 1 deletion test/core/qcheck_output.txt.expected
Original file line number Diff line number Diff line change
Expand Up @@ -267,7 +267,7 @@ Test lists shorter than 4332 failed (13 shrink steps):

Test lists equal to duplication failed (20 shrink steps):

[...] list length: 1
[0]

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

Expand Down

0 comments on commit f750ccf

Please sign in to comment.