Out of Mem when using @DataPoints with Iterator type, request lazy fetch
"willmcqueen" <[email protected]> Thu, 02 May 2013 04:23:55 -0000
| Newsgroups | gmane.comp.java.junit.user |
|---|---|
| Message-ID | <[email protected]> |
Hi,
I see that in the current master branch of JUnit, the JUnit 4.12 release notes say:
> "Pull request #658: Iterables can now be used as datapoints
> Previously when building sets of datapoints for Theory parameters
> the only valid multi-valued @DataPoints types were arrays. This has
> now been extended to also take parameters from iterable @DataPoints
> methods and fields."
Fantastic. To me this means that we can now have something similar to TestNG's DataProvider that returns an 'Iterator<Object[]>' (http://testng.org/doc/documentation-main.html):
> An Iterator<Object[]>. The only difference with Object[][] is that an Iterator
> lets you create your test data lazily. TestNG will invoke the iterator and then
> the test method with the parameters returned by this iterator one by one.
> This is particularly useful if you have a lot of parameter sets to pass to the
> method and you don't want to create all of them upfront.
...but just one problem -- the JUnit Iterable @DataPoints doesn't seem to get the data lazily... it looks like it slurps everything into memory before passing it to the Theory test. I'd like to request that we please change the implementation of this method so that the data is ingested lazily (one element at a time, or maybe in batches) to avoid OOME. As a quick test, what I'd consider to be a desirable implementation would be one that passes a test that uses this infinite @DataPoints:
import com.google.common.collect.Iterables
@DataPoints
public static Iterable<String> infiniteDataStream() {
return Iterables.cycle("one", "two"); //continuously alternate between 2 values
}
[Ref: http://docs.guava-libraries.googlecode.com/git-history/v14.0.1/javadoc/com/google/common/collect/Iterables.html#cycle(T...)]
Alternatively, here's a finite test that still results in OOME:
import com.google.common.collect.Iterables
import java.util.Arrays;
import java.util.Collections;
public static Iterable<String> finiteDataStream() {
//return 200 million copies of "aaa" and "bbb"
return Iterables.concat(Collections.nCopies(200000000, Arrays.asList("aaa", "bbb")));
}
Here's the OOME:
java.lang.OutOfMemoryError: Java heap space
at java.lang.AbstractStringBuilder.<init>(AbstractStringBuilder.java:45)
at java.lang.StringBuilder.<init>(StringBuilder.java:68)
at org.junit.experimental.theories.internal.AllMembersSupplier.addIterableValues(AllMembersSupplier.java:147)
at org.junit.experimental.theories.internal.AllMembersSupplier.addDataPointsValues(AllMembersSupplier.java:128)
at org.junit.experimental.theories.internal.AllMembersSupplier.addMultiPointMethods(AllMembersSupplier.java:83)
at org.junit.experimental.theories.internal.AllMembersSupplier.getValueSources(AllMembersSupplier.java:71)
at org.junit.experimental.theories.internal.Assignments.potentialsForNextUnassigned(Assignments.java:78)
at org.junit.experimental.theories.Theories$TheoryAnchor.runWithIncompleteAssignment(Theories.java:162)
at org.junit.experimental.theories.Theories$TheoryAnchor.runWithAssignment(Theories.java:153)
at org.junit.experimental.theories.Theories$TheoryAnchor.evaluate(Theories.java:138)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:72)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:51)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
at org.junit.runner.JUnitCore.run(JUnitCore.java:160)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:77)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:195)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:63)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:120)
Thank you for considering this request.
Cheers,
Will
------------------------------------
Yahoo! Groups Links
<*> To visit your group on the web, go to:
http://groups.yahoo.com/group/junit/
<*> Your email settings:
Individual Email | Traditional
<*> To change settings online go to:
http://groups.yahoo.com/group/junit/join
(Yahoo! ID required)
<*> To change settings via email:
[email protected]
[email protected]
<*> To unsubscribe from this group, send an email to:
[email protected]
<*> Your use of Yahoo! Groups is subject to:
http://docs.yahoo.com/info/terms/