Skip to content

Commit

Permalink
Remove recursion from testLeakAfterSessionDispose (apache#1380)
Browse files Browse the repository at this point in the history
* Remove recursion from testLeakAfterSessionDispose

* Raise the leak test timeout
  • Loading branch information
baldimir authored and mariofusco committed Jul 25, 2017
1 parent 2a6dbb3 commit ed74783
Showing 1 changed file with 55 additions and 37 deletions.
Expand Up @@ -16,15 +16,17 @@


package org.drools.compiler; package org.drools.compiler;


import static org.junit.Assert.*;

import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.lang.reflect.Modifier; import java.lang.reflect.Modifier;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.IdentityHashMap; import java.util.IdentityHashMap;
import java.util.List;
import java.util.Set; import java.util.Set;
import java.util.function.Predicate; import java.util.function.Predicate;

import org.drools.core.common.InternalWorkingMemory; import org.drools.core.common.InternalWorkingMemory;
import org.drools.core.common.Memory; import org.drools.core.common.Memory;
import org.drools.core.common.NodeMemories; import org.drools.core.common.NodeMemories;
Expand All @@ -47,8 +49,6 @@
import org.kie.api.runtime.rule.FactHandle; import org.kie.api.runtime.rule.FactHandle;
import org.kie.internal.utils.KieHelper; import org.kie.internal.utils.KieHelper;


import static org.junit.Assert.*;

public class MemoryLeakTest { public class MemoryLeakTest {


@Test @Test
Expand Down Expand Up @@ -185,7 +185,7 @@ public void testBetaMemoryLeakOnFactDelete() {
} }
} }


@Test @Test(timeout = 5000)
public void testLeakAfterSessionDispose() { public void testLeakAfterSessionDispose() {
// DROOLS-1655 // DROOLS-1655
String drl = String drl =
Expand Down Expand Up @@ -214,51 +214,69 @@ public void testLeakAfterSessionDispose() {
} }


private static void checkReachability( Object root, Predicate<Object> condition, boolean reachable ) { private static void checkReachability( Object root, Predicate<Object> condition, boolean reachable ) {
Collection<Object> results = collectObjects( root, condition ); Collection<Object> results = checkObject(root, condition);
assertTrue( reachable ^ results.isEmpty() ); assertTrue( reachable ^ results.isEmpty() );
} }


private static Collection<Object> collectObjects( Object root, Predicate<Object> condition ) { private static Collection<Object> checkObject(final Object object, final Predicate<Object> condition) {
Collection<Object> results = new ArrayList<>(); Collection<Object> results = new ArrayList<>();
collectObjects( root, condition, results, Collections.newSetFromMap( new IdentityHashMap<>() ) ); final Set<Object> visited = Collections.newSetFromMap( new IdentityHashMap<>() );
List<Object> childObjects = checkObject(object, condition, results, visited);
while (childObjects != null && !childObjects.isEmpty()) {
childObjects = checkObjects(childObjects, condition, results, visited);
}
return results; return results;
} }


private static void collectObjects( Object root, Predicate<Object> condition, Collection<Object> results, Set<Object> visited ) { private static List<Object> checkObjects(final List<Object> objects, final Predicate<Object> condition,
if (root == null) { final Collection<Object> results, final Set<Object> visited) {
return; final List<Object> childObjects = new ArrayList<>();
} objects.forEach(object -> childObjects.addAll(checkObject(object, condition, results, visited)));
if (!visited.add(root)) { return childObjects;
return; }
}
if (condition.test(root)) { private static List<Object> checkObject(final Object object, final Predicate<Object> condition,
results.add(root); final Collection<Object> results, final Set<Object> visited) {
} else { final List<Object> childObjects = new ArrayList<>();
if (root instanceof Object[]) { if (object != null) {
for (Object child: (Object[]) root) { if (!visited.add(object)) {
collectObjects(child, condition, results, visited); return childObjects;
}
} }
if (!root.getClass().isArray()) {// ignore primitive arrays if (condition.test(object)) {
for (Class c = root.getClass(); c != Object.class; c = c.getSuperclass()) { results.add(object);
for (Field field: c.getDeclaredFields()) { } else {
if ( Modifier.isStatic( field.getModifiers() )) { if (object instanceof Object[]) {
continue; for (Object child: (Object[]) object) {
} if (child != null) {
if (field.getType().isPrimitive()) { childObjects.addAll(getFieldsFromObject(child));
continue;
}
field.setAccessible(true);
Object child;
try {
child = field.get(root);
} catch (IllegalAccessException e) {
throw new IllegalStateException(e);
} }
collectObjects(child, condition, results, visited);
} }
} else if (!object.getClass().isArray()) {
childObjects.addAll(getFieldsFromObject(object));
}
}
}
return childObjects;
}

private static List<Object> getFieldsFromObject(final Object object) {
final List<Object> childObjects = new ArrayList<>();
for (Class c = object.getClass(); c != Object.class; c = c.getSuperclass()) {
for (Field field: c.getDeclaredFields()) {
if ( Modifier.isStatic( field.getModifiers() )) {
continue;
}
if (field.getType().isPrimitive()) {
continue;
}
field.setAccessible(true);
try {
childObjects.add(field.get(object));
} catch (IllegalAccessException e) {
throw new IllegalStateException(e);
} }
} }
} }
return childObjects;
} }
} }

0 comments on commit ed74783

Please sign in to comment.