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

severalStepsToList_withReversedOrderOfSuppliers sometimes runs into StackOverflowError #431

Open
vlsi opened this issue Dec 14, 2022 · 4 comments

Comments

@vlsi
Copy link
Contributor

vlsi commented Dec 14, 2022

Testing Problem

See https://github.com/jlink/jqwik/actions/runs/3693074859/jobs/6252643488#step:5:211

java.lang.StackOverflowError
      at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:197)
      at java.base/java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1625)
      at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:509)
      at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:499)
      at java.base/java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:921)
      at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
      at java.base/java.util.stream.ReferencePipeline.reduce(ReferencePipeline.java:657)
      at net.jqwik.api.ShrinkingDistance.combine(ShrinkingDistance.java:38)
      at net.jqwik.engine.properties.shrinking.CombinedShrinkable.distance(CombinedShrinkable.java:54)
      at net.jqwik.engine.properties.shrinking.LazyOfShrinkable.distance(LazyOfShrinkable.java:39)
      at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:197)
      at java.base/java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1625)
      at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:509)
      at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:499)
      at java.base/java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:921)
      at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
      at java.base/java.util.stream.ReferencePipeline.reduce(ReferencePipeline.java:657)
      at net.jqwik.api.ShrinkingDistance.combine(ShrinkingDistance.java:38)
      at net.jqwik.engine.properties.shrinking.CombinedShrinkable.distance(CombinedShrinkable.java:54)
      at net.jqwik.engine.properties.shrinking.LazyOfShrinkable.distance(LazyOfShrinkable.java:39)
      at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:197)
      at java.base/java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1625)
      at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:509)
      at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:499)
      at java.base/java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:921)
      at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:[234]
      at java.base/java.util.stream.ReferencePipeline.reduce(ReferencePipeline.java:657)
      at net.jqwik.api.ShrinkingDistance.combine(ShrinkingDistance.java:38)
      at net.jqwik.engine.properties.shrinking.CombinedShrinkable.distance(CombinedShrinkable.java:54)
      at net.jqwik.engine.properties.shrinking.LazyOfShrinkable.distance(LazyOfShrinkable.java:39)
      at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:197)
      at java.base/java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1625)
      at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:509)
      at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:499)
      at java.base/java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:921)
      at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
      at java.base/java.util.stream.ReferencePipeline.reduce(ReferencePipeline.java:657)
      at net.jqwik.api.ShrinkingDistance.combine(ShrinkingDistance.java:38)
      at net.jqwik.engine.properties.shrinking.CombinedShrinkable.distance(CombinedShrinkable.java:54)
      at net.jqwik.engine.properties.shrinking.LazyOfShrinkable.distance(LazyOfShrinkable.java:39)
      at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:197)
      at java.base/java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1625)
      at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:509)
      at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:499)
      at java.base/java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:921)
      at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
      at java.base/java.util.stream.ReferencePipeline.reduce(ReferencePipeline.java:657)
      at net.jqwik.api.ShrinkingDistance.combine(ShrinkingDistance.java:38)
      at net.jqwik.engine.properties.shrinking.CombinedShrinkable.distance(CombinedShrinkable.java:54)
      at net.jqwik.engine.properties.shrinking.LazyOfShrinkable.distance(LazyOfShrinkable.java:39)
      at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:197)
      at java.base/java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1625)
      at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:509)
      at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:499)
      at java.base/java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:921)
      at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
      at java.base/java.util.stream.ReferencePipeline.reduce(ReferencePipeline.java:657)
      at net.jqwik.api.ShrinkingDistance.combine(ShrinkingDistance.java:38)
      at net.jqwik.engine.properties.shrinking.CombinedShrinkable.distance(CombinedShrinkable.java:54)
      at net.jqwik.engine.properties.shrinking.LazyOfShrinkable.distance(LazyOfShrinkable.java:39)
      at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:197)
      at java.base/java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1625)
      at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:509)
      at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:499)
      at java.base/java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:921)
      at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
      at java.base/java.util.stream.ReferencePipeline.reduce(ReferencePipeline.java:657)
      at net.jqwik.api.ShrinkingDistance.combine(ShrinkingDistance.java:38)
      at net.jqwik.engine.properties.shrinking.CombinedShrinkable.distance(CombinedShrinkable.java:54)
      at net.jqwik.engine.properties.shrinking.LazyOfShrinkable.distance(LazyOfShrinkable.java:39)

Suggested Solution

  1. Refrain from Stream API in net.jqwik.api.ShrinkingDistance#combine and net.jqwik.api.ShrinkingDistance#forCollection so the stacktrace is shorter and easier to understand.

  2. Limit the depth of the lazy in tests somehow. I'm not sure it is realistic to test thousands of nested combine calls.
    As I replaced Stream API with a for loop, I got the following failure, which does not seem to have a trivial solution:

java.lang.StackOverflowError
	at net.jqwik.engine.properties.shrinking.ShrinkableBigInteger.checkValueInRange(ShrinkableBigInteger.java:73)
	at net.jqwik.engine.properties.shrinking.ShrinkableBigInteger.<init>(ShrinkableBigInteger.java:19)
	at net.jqwik.engine.properties.arbitraries.randomized.RandomIntegralGenerators.lambda$bigIntegers$1(RandomIntegralGenerators.java:32)
	at net.jqwik.api.RandomGenerator.lambda$mapShrinkable$1(RandomGenerator.java:57)
	at net.jqwik.engine.properties.arbitraries.randomized.ContainerGenerator.nextUntilAccepted(ContainerGenerator.java:108)
	at net.jqwik.engine.properties.arbitraries.randomized.ContainerGenerator.next(ContainerGenerator.java:70)
	at net.jqwik.engine.properties.arbitraries.LazyOfArbitrary.generateCurrent(LazyOfArbitrary.java:107)
	at net.jqwik.engine.properties.arbitraries.LazyOfArbitrary.lambda$generator$1(LazyOfArbitrary.java:58)
	at net.jqwik.engine.properties.arbitraries.combinations.CombineArbitrary.generateShrinkables(CombineArbitrary.java:108)
	at net.jqwik.engine.properties.arbitraries.combinations.CombineArbitrary.lambda$combineGenerator$1(CombineArbitrary.java:85)
	at net.jqwik.engine.properties.arbitraries.LazyOfArbitrary.generateCurrent(LazyOfArbitrary.java:107)
	at net.jqwik.engine.properties.arbitraries.LazyOfArbitrary.lambda$generator$1(LazyOfArbitrary.java:58)
	at net.jqwik.engine.properties.arbitraries.combinations.CombineArbitrary.generateShrinkables(CombineArbitrary.java:108)
	at net.jqwik.engine.properties.arbitraries.combinations.CombineArbitrary.lambda$combineGenerator$1(CombineArbitrary.java:85)
	at net.jqwik.engine.properties.arbitraries.LazyOfArbitrary.generateCurrent(LazyOfArbitrary.java:107)
	at net.jqwik.engine.properties.arbitraries.LazyOfArbitrary.lambda$generator$1(LazyOfArbitrary.java:58)
	at net.jqwik.engine.properties.arbitraries.combinations.CombineArbitrary.generateShrinkables(CombineArbitrary.java:108)
	at net.jqwik.engine.properties.arbitraries.combinations.CombineArbitrary.lambda$combineGenerator$1(CombineArbitrary.java:85)
	at net.jqwik.engine.properties.arbitraries.LazyOfArbitrary.generateCurrent(LazyOfArbitrary.java:107)
	at net.jqwik.engine.properties.arbitraries.LazyOfArbitrary.lambda$generator$1(LazyOfArbitrary.java:58)
	at net.jqwik.engine.properties.arbitraries.combinations.CombineArbitrary.generateShrinkables(CombineArbitrary.java:108)
	at net.jqwik.engine.properties.arbitraries.combinations.CombineArbitrary.lambda$combineGenerator$1(CombineArbitrary.java:85)
vlsi pushed a commit to vlsi/jqwik that referenced this issue Dec 14, 2022
It makes the stacktraces shorter and easier to reason.

See jqwik-team#431
vlsi pushed a commit to vlsi/jqwik that referenced this issue Dec 14, 2022
It makes the stacktraces shorter and easier to reason.

See jqwik-team#431
@jlink
Copy link
Collaborator

jlink commented Dec 17, 2022

In CI the SOE seems to occur only on Java 18. Bad.
Tried to circumvent it temporarily by fixing seed of test.

@vlsi
Copy link
Contributor Author

vlsi commented Dec 17, 2022

In any case, stacktrace without streams is way easier to read

@jlink
Copy link
Collaborator

jlink commented Dec 18, 2022

In any case, stacktrace without streams is way easier to read

The code is so much more involved, though, that I'd like to leave it unchanged until tackling the underlying problem.

@vlsi
Copy link
Contributor Author

vlsi commented Dec 18, 2022

I agree shortening the stacktrace does not really solve the root cause.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants