jetCheck: don't retain generators to avoid OOME by capturing user objects

This commit is contained in:
peter
2018-04-20 20:36:13 +02:00
parent d88b9f1c88
commit ebb532f365
3 changed files with 29 additions and 8 deletions
@@ -12,7 +12,7 @@ import java.util.concurrent.atomic.AtomicInteger;
class NodeId {
private final AtomicInteger counter;
final int number;
@Nullable final Generator<?> generator;
@Nullable final Integer generatorHash;
NodeId(@NotNull Generator<?> generator) {
this(new AtomicInteger(), generator);
@@ -20,7 +20,7 @@ class NodeId {
private NodeId(AtomicInteger counter, @Nullable Generator<?> generator) {
this.counter = counter;
this.generator = generator;
this.generatorHash = generator == null ? null : generator.getGeneratorFunction().hashCode();
number = counter.getAndIncrement();
}
@@ -137,14 +137,14 @@ class StructureNode extends StructureElement {
return false;
}
private void findChildrenWithGenerator(@NotNull Generator<?> generator, List<StructureNode> result) {
private void findChildrenWithGenerator(int generatorHash, List<StructureNode> result) {
for (StructureElement child : children) {
if (child instanceof StructureNode) {
Generator<?> childGen = child.id.generator;
if (childGen != null && generator.getGeneratorFunction().equals(childGen.getGeneratorFunction())) {
Integer childGen = child.id.generatorHash;
if (childGen != null && generatorHash == childGen.intValue()) {
result.add((StructureNode)child);
} else {
((StructureNode)child).findChildrenWithGenerator(generator, result);
((StructureNode)child).findChildrenWithGenerator(generatorHash, result);
}
}
}
@@ -152,9 +152,9 @@ class StructureNode extends StructureElement {
@Nullable
private ShrinkStep shrinkRecursion() {
if (id.generator != null) {
if (id.generatorHash != null) {
List<StructureNode> sameGeneratorChildren = new ArrayList<>();
findChildrenWithGenerator(id.generator, sameGeneratorChildren);
findChildrenWithGenerator(id.generatorHash, sameGeneratorChildren);
return tryReplacing(sameGeneratorChildren, 0);
}
@@ -5,6 +5,7 @@ package org.jetbrains.jetCheck;
import org.jetbrains.annotations.NotNull;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.atomic.AtomicInteger;
@@ -131,6 +132,26 @@ public class StatefulGeneratorTest extends PropertyCheckerTestCase {
sb.delete(start, end);
};
}
private ImperativeCommand heavyCommand() {
Object[] heavyObject = new Object[100_000];
heavyObject[42] = new Object();
return new ImperativeCommand() {
@Override
public void performCommand(@NotNull Environment env) {}
@Override
public String toString() {
return super.toString() + Arrays.toString(heavyObject);
}
};
}
public void testDontFailByOutOfMemoryDueToLeakingObjectsPassedIntoGenerators() {
PropertyChecker.customized().checkScenarios(() -> env ->
env.executeCommands(from(data -> data.generate(sampledFrom(heavyCommand(), heavyCommand(), heavyCommand())))));
}
}
class InsertChar {