LUCENE-4252: Detect/Fail tests when they leak RAM in static fields.

git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1383841 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Dawid Weiss 2012-09-12 08:20:32 +00:00
parent 15b4b09ff3
commit e8ed39cb01
3 changed files with 28 additions and 1 deletions

View File

@ -165,6 +165,9 @@ Optimizations
Build
* LUCENE-4252: Detect/Fail tests when they leak RAM in static fields
(Robert Muir, Dawid Weiss)
* LUCENE-4360: Support running the same test suite multiple times in
parallel (Dawid Weiss)

View File

@ -52,6 +52,7 @@ import com.carrotsearch.randomizedtesting.annotations.ThreadLeakZombies.Conseque
import com.carrotsearch.randomizedtesting.generators.RandomPicks;
import com.carrotsearch.randomizedtesting.rules.NoClassHooksShadowingRule;
import com.carrotsearch.randomizedtesting.rules.NoInstanceHooksOverridesRule;
import com.carrotsearch.randomizedtesting.rules.StaticFieldsInvariantRule;
import com.carrotsearch.randomizedtesting.rules.SystemPropertiesInvariantRule;
import static com.carrotsearch.randomizedtesting.RandomizedTest.systemPropertyAsBoolean;
@ -364,6 +365,18 @@ public abstract class LuceneTestCase extends Assert {
ignoreAfterMaxFailures = new TestRuleIgnoreAfterMaxFailures(maxFailures);
}
/**
* Max 10mb of static data stored in a test suite class after the suite is complete.
* Prevents static data structures leaking and causing OOMs in subsequent tests.
*/
private final static long STATIC_LEAK_THRESHOLD = 10 * 1024 * 1024;
/** By-name list of ignored types like loggers etc. */
private final static Set<String> STATIC_LEAK_IGNORED_TYPES =
Collections.unmodifiableSet(new HashSet<String>(Arrays.asList(
"org.slf4j.Logger",
"org.apache.solr.SolrLogFormatter")));
/**
* This controls how suite-level rules are nested. It is important that _all_ rules declared
* in {@link LuceneTestCase} are executed in proper order if they depend on each
@ -375,6 +388,14 @@ public abstract class LuceneTestCase extends Assert {
.around(ignoreAfterMaxFailures)
.around(suiteFailureMarker)
.around(new TestRuleAssertionsRequired())
.around(new StaticFieldsInvariantRule(STATIC_LEAK_THRESHOLD, true) {
protected boolean accept(java.lang.reflect.Field field) {
if (STATIC_LEAK_IGNORED_TYPES.contains(field.getType().getName())) {
return false;
}
return super.accept(field);
}
})
.around(new NoClassHooksShadowingRule())
.around(new NoInstanceHooksOverridesRule() {
@Override

View File

@ -32,7 +32,10 @@ public class TestRuleAssertionsRequired implements TestRule {
public void evaluate() throws Throwable {
try {
assert false;
throw new Exception("Test class requires assertions, enable assertions globally (-ea) or for Solr/Lucene subpackages only.");
String msg = "Test class requires enabled assertions, enable globally (-ea)" +
" or for Solr/Lucene subpackages only: " + description.getClassName();
System.err.println(msg);
throw new Exception(msg);
} catch (AssertionError e) {
// Ok, enabled.
}