+
diff --git a/lucene/licenses/junit4-ant-1.6.0.jar.sha1 b/lucene/licenses/junit4-ant-1.6.0.jar.sha1
deleted file mode 100644
index 9a2ca80..0000000
--- a/lucene/licenses/junit4-ant-1.6.0.jar.sha1
+++ /dev/null
@@ -1 +0,0 @@
-c7a65e96a2c62ba83ca404065305aec5dc7fc8f1
diff --git a/lucene/licenses/junit4-ant-2.0.0.rc2.jar.sha1 b/lucene/licenses/junit4-ant-2.0.0.rc2.jar.sha1
new file mode 100644
index 0000000..633578f
--- /dev/null
+++ b/lucene/licenses/junit4-ant-2.0.0.rc2.jar.sha1
@@ -0,0 +1 @@
+0a5c2f97ad8a5dc45d29166763c9cd625fafc82a
\ No newline at end of file
diff --git a/lucene/licenses/randomizedtesting-runner-1.6.0.jar.sha1 b/lucene/licenses/randomizedtesting-runner-1.6.0.jar.sha1
deleted file mode 100644
index be7ad32..0000000
--- a/lucene/licenses/randomizedtesting-runner-1.6.0.jar.sha1
+++ /dev/null
@@ -1 +0,0 @@
-709f9549a0b0c2e2ecdd5af012d9531325d6551b
diff --git a/lucene/licenses/randomizedtesting-runner-2.0.0.rc2.jar.sha1 b/lucene/licenses/randomizedtesting-runner-2.0.0.rc2.jar.sha1
new file mode 100644
index 0000000..8175fac
--- /dev/null
+++ b/lucene/licenses/randomizedtesting-runner-2.0.0.rc2.jar.sha1
@@ -0,0 +1 @@
+5a538d45ced928566385e8297d0a815f20771b97
\ No newline at end of file
diff --git a/lucene/module-build.xml b/lucene/module-build.xml
index 771016a..87baa3d 100644
--- a/lucene/module-build.xml
+++ b/lucene/module-build.xml
@@ -49,8 +49,8 @@
-
+
diff --git a/lucene/suggest/src/test/org/apache/lucene/search/spell/TestSpellChecker.java b/lucene/suggest/src/test/org/apache/lucene/search/spell/TestSpellChecker.java
index ab7e455..8504b99 100755
--- a/lucene/suggest/src/test/org/apache/lucene/search/spell/TestSpellChecker.java
+++ b/lucene/suggest/src/test/org/apache/lucene/search/spell/TestSpellChecker.java
@@ -39,6 +39,7 @@ import org.apache.lucene.store.AlreadyClosedException;
import org.apache.lucene.store.Directory;
import org.apache.lucene.util.English;
import org.apache.lucene.util.LuceneTestCase;
+import org.apache.lucene.util.NamedThreadFactory;
/**
* Spell checker test case
@@ -413,7 +414,7 @@ public class TestSpellChecker extends LuceneTestCase {
int num_field2 = this.numdoc();
assertEquals(num_field2, num_field1 + 1);
int numThreads = 5 + random().nextInt(5);
- ExecutorService executor = Executors.newFixedThreadPool(numThreads);
+ ExecutorService executor = Executors.newFixedThreadPool(numThreads, new NamedThreadFactory("testConcurrentAccess"));
SpellCheckWorker[] workers = new SpellCheckWorker[numThreads];
for (int i = 0; i < numThreads; i++) {
SpellCheckWorker spellCheckWorker = new SpellCheckWorker(r);
diff --git a/lucene/test-framework/ivy.xml b/lucene/test-framework/ivy.xml
index 4e39a2b..4619a39 100644
--- a/lucene/test-framework/ivy.xml
+++ b/lucene/test-framework/ivy.xml
@@ -33,8 +33,8 @@
-
-
+
+
diff --git a/lucene/test-framework/src/java/org/apache/lucene/util/LuceneTestCase.java b/lucene/test-framework/src/java/org/apache/lucene/util/LuceneTestCase.java
index 11c7bd6..ba07753 100644
--- a/lucene/test-framework/src/java/org/apache/lucene/util/LuceneTestCase.java
+++ b/lucene/test-framework/src/java/org/apache/lucene/util/LuceneTestCase.java
@@ -45,6 +45,10 @@ import org.junit.rules.TestRule;
import org.junit.runner.RunWith;
import com.carrotsearch.randomizedtesting.*;
import com.carrotsearch.randomizedtesting.annotations.*;
+import com.carrotsearch.randomizedtesting.annotations.ThreadLeakAction.Action;
+import com.carrotsearch.randomizedtesting.annotations.ThreadLeakGroup.Group;
+import com.carrotsearch.randomizedtesting.annotations.ThreadLeakScope.Scope;
+import com.carrotsearch.randomizedtesting.annotations.ThreadLeakZombies.Consequence;
import com.carrotsearch.randomizedtesting.generators.RandomPicks;
import com.carrotsearch.randomizedtesting.rules.SystemPropertiesInvariantRule;
@@ -113,7 +117,12 @@ import static com.carrotsearch.randomizedtesting.RandomizedTest.systemPropertyAs
RunListenerPrintReproduceInfo.class
})
@SeedDecorators({MixWithSuiteName.class}) // See LUCENE-3995 for rationale.
-@ThreadLeaks(failTestIfLeaking = false)
+@ThreadLeakScope(Scope.SUITE)
+@ThreadLeakGroup(Group.MAIN)
+@ThreadLeakAction({Action.WARN, Action.INTERRUPT})
+@ThreadLeakLingering(linger = 20000) // Wait long for leaked threads to complete before failure. zk needs this.
+@ThreadLeakZombies(Consequence.IGNORE_REMAINING_TESTS)
+@TimeoutSuite(millis = 10 * (/* minutes */ 1000 * 60)) // max suite execution time.
public abstract class LuceneTestCase extends Assert {
// --------------------------------------------------------------------
@@ -124,6 +133,7 @@ public abstract class LuceneTestCase extends Assert {
public static final String SYSPROP_WEEKLY = "tests.weekly";
public static final String SYSPROP_AWAITSFIX = "tests.awaitsfix";
public static final String SYSPROP_SLOW = "tests.slow";
+ public static final String SYSPROP_BADAPPLES = "tests.badapples";
/** @see #ignoreAfterMaxFailures*/
private static final String SYSPROP_MAXFAILURES = "tests.maxfailures";
@@ -170,7 +180,21 @@ public abstract class LuceneTestCase extends Assert {
@Retention(RetentionPolicy.RUNTIME)
@TestGroup(enabled = true, sysProperty = SYSPROP_SLOW)
public @interface Slow {}
-
+
+ /**
+ * Annotation for tests that fail frequently. You can disable them
+ * if you want to run a long build and not stop on something that
+ * is a known problem.
+ *
+ * -Dtests.badapples=false
+ *
+ */
+ @Documented
+ @Inherited
+ @Retention(RetentionPolicy.RUNTIME)
+ @TestGroup(enabled = true, sysProperty = SYSPROP_BADAPPLES)
+ public @interface BadApple {}
+
/**
* Annotation for test classes that should avoid certain codec types
* (because they are expensive, for example).
@@ -353,7 +377,6 @@ public abstract class LuceneTestCase extends Assert {
.around(new TestRuleNoInstanceHooksOverrides())
.around(new SystemPropertiesInvariantRule(IGNORED_INVARIANT_PROPERTIES))
.around(classNameRule = new TestRuleStoreClassName())
- .around(new TestRuleReportUncaughtExceptions())
.around(classEnvRule = new TestRuleSetupAndRestoreClassEnv());
@@ -380,7 +403,6 @@ public abstract class LuceneTestCase extends Assert {
.outerRule(testFailureMarker)
.around(ignoreAfterMaxFailures)
.around(threadAndTestNameRule)
- .around(new TestRuleReportUncaughtExceptions())
.around(new SystemPropertiesInvariantRule(IGNORED_INVARIANT_PROPERTIES))
.around(new TestRuleSetupAndRestoreInstanceEnv())
.around(new TestRuleFieldCacheSanity())
diff --git a/lucene/test-framework/src/java/org/apache/lucene/util/TestRuleReportUncaughtExceptions.java b/lucene/test-framework/src/java/org/apache/lucene/util/TestRuleReportUncaughtExceptions.java
deleted file mode 100644
index fa75b7c..0000000
--- a/lucene/test-framework/src/java/org/apache/lucene/util/TestRuleReportUncaughtExceptions.java
+++ /dev/null
@@ -1,132 +0,0 @@
-package org.apache.lucene.util;
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-import java.io.PrintWriter;
-import java.io.StringWriter;
-import java.lang.Thread.UncaughtExceptionHandler;
-import java.util.ArrayList;
-import java.util.List;
-
-import org.junit.rules.TestRule;
-import org.junit.runner.Description;
-import org.junit.runners.model.MultipleFailureException;
-import org.junit.runners.model.Statement;
-
-/**
- * Subscribes to
- * {@link Thread#setDefaultUncaughtExceptionHandler(java.lang.Thread.UncaughtExceptionHandler)}
- * and causes test/ suite failures if uncaught exceptions are detected.
- */
-public class TestRuleReportUncaughtExceptions implements TestRule {
- // This was originally volatile, but I don't think it needs to be. It's the same
- // thread accessing it, always.
- private UncaughtExceptionHandler savedUncaughtExceptionHandler;
-
- public static class UncaughtExceptionEntry {
- public final Thread thread;
- public final Throwable exception;
-
- public UncaughtExceptionEntry(Thread thread, Throwable exception) {
- this.thread = thread;
- this.exception = exception;
- }
- }
-
- @SuppressWarnings("serial")
- private static class UncaughtExceptionsInBackgroundThread extends RuntimeException {
- public UncaughtExceptionsInBackgroundThread(UncaughtExceptionEntry e) {
- super("Uncaught exception by thread: " + e.thread, e.exception);
- }
- }
-
- // Lock on uncaughtExceptions to access.
- private final List uncaughtExceptions = new ArrayList();
-
- @Override
- public Statement apply(final Statement s, final Description d) {
- return new Statement() {
- public void evaluate() throws Throwable {
- final ArrayList errors = new ArrayList();
- try {
- setupHandler();
- s.evaluate();
- } catch (Throwable t) {
- errors.add(t);
- } finally {
- restoreHandler();
- }
-
- synchronized (uncaughtExceptions) {
- for (UncaughtExceptionEntry e : uncaughtExceptions) {
- errors.add(new UncaughtExceptionsInBackgroundThread(e));
- }
- uncaughtExceptions.clear();
- }
-
- MultipleFailureException.assertEmpty(errors);
- }
- };
- }
-
- /**
- * Just a check if anything's been caught.
- */
- public boolean hasUncaughtExceptions() {
- synchronized (uncaughtExceptions) {
- return !uncaughtExceptions.isEmpty();
- }
- }
-
- private void restoreHandler() {
- Thread.setDefaultUncaughtExceptionHandler(savedUncaughtExceptionHandler);
- }
-
- private void setupHandler() {
- savedUncaughtExceptionHandler = Thread.getDefaultUncaughtExceptionHandler();
- Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
- public void uncaughtException(Thread t, Throwable e) {
- // org.junit.internal.AssumptionViolatedException in older releases
- // org.junit.Assume.AssumptionViolatedException in recent ones
- if (e.getClass().getName().endsWith("AssumptionViolatedException")) {
- String where = "";
- for (StackTraceElement elem : e.getStackTrace()) {
- if (!elem.getClassName().startsWith("org.junit")) {
- where = elem.toString();
- break;
- }
- }
- System.err.print("NOTE: Uncaught exception handler caught a failed assumption at "
- + where + " (ignored):");
- } else {
- synchronized (uncaughtExceptions) {
- uncaughtExceptions.add(new UncaughtExceptionEntry(t, e));
- }
-
- StringWriter sw = new StringWriter();
- sw.write("\n===>\nUncaught exception by thread: " + t + "\n");
- PrintWriter pw = new PrintWriter(sw);
- e.printStackTrace(pw);
- pw.flush();
- sw.write("<===\n");
- System.err.println(sw.toString());
- }
- }
- });
- }
-}
diff --git a/lucene/tools/custom-tasks.xml b/lucene/tools/custom-tasks.xml
index 959c952..1b409e8 100644
--- a/lucene/tools/custom-tasks.xml
+++ b/lucene/tools/custom-tasks.xml
@@ -51,8 +51,9 @@
+
-
+
diff --git a/lucene/tools/forbiddenApis/executors.txt b/lucene/tools/forbiddenApis/executors.txt
new file mode 100644
index 0000000..dfb9df5
--- /dev/null
+++ b/lucene/tools/forbiddenApis/executors.txt
@@ -0,0 +1,12 @@
+# These methods spawn threads with vague names. Use a custom thread factory and name
+# threads so that you can tell (by its name) which executor it is associated with.
+# see Solr's DefaultSolrThreadFactory
+# see Lucene's NamedThreadFactory
+
+java.util.concurrent.Executors#newFixedThreadPool(int)
+java.util.concurrent.Executors#newSingleThreadExecutor()
+java.util.concurrent.Executors#newCachedThreadPool()
+java.util.concurrent.Executors#newSingleThreadScheduledExecutor()
+java.util.concurrent.Executors#newScheduledThreadPool(int)
+java.util.concurrent.Executors#defaultThreadFactory()
+java.util.concurrent.Executors#privilegedThreadFactory()
diff --git a/lucene/tools/junit4/logging.properties b/lucene/tools/junit4/logging.properties
new file mode 100644
index 0000000..f54ee74
--- /dev/null
+++ b/lucene/tools/junit4/logging.properties
@@ -0,0 +1,10 @@
+
+# root handler
+handlers=java.util.logging.ConsoleHandler
+
+# root logger's cutoff threshold.
+.level=INFO
+
+# configure console handler to emit everything in the default format.
+java.util.logging.ConsoleHandler.level=FINEST
+java.util.logging.ConsoleHandler.formatter=java.util.logging.SimpleFormatter
diff --git a/solr/build.xml b/solr/build.xml
index 127af81..0cbf1fc 100644
--- a/solr/build.xml
+++ b/solr/build.xml
@@ -200,6 +200,7 @@
+
diff --git a/solr/core/src/java/org/apache/solr/cloud/Overseer.java b/solr/core/src/java/org/apache/solr/cloud/Overseer.java
index 7218b67..0b5953f 100644
--- a/solr/core/src/java/org/apache/solr/cloud/Overseer.java
+++ b/solr/core/src/java/org/apache/solr/cloud/Overseer.java
@@ -410,9 +410,10 @@ public class Overseer {
Thread updaterThread = new Thread(tg, new CloudStateUpdater(reader, id));
updaterThread.setDaemon(true);
updaterThread.start();
-
+
ThreadGroup ccTg = new ThreadGroup("Overseer collection creation process.");
- Thread ccThread = new Thread(ccTg, new OverseerCollectionProcessor(reader, id, shardHandler, adminPath));
+ Thread ccThread = new Thread(ccTg, new OverseerCollectionProcessor(reader, id, shardHandler, adminPath),
+ "Overseer-" + id);
ccThread.setDaemon(true);
ccThread.start();
}
diff --git a/solr/core/src/java/org/apache/solr/core/SolrCore.java b/solr/core/src/java/org/apache/solr/core/SolrCore.java
index f7888ff..b58546f 100644
--- a/solr/core/src/java/org/apache/solr/core/SolrCore.java
+++ b/solr/core/src/java/org/apache/solr/core/SolrCore.java
@@ -70,6 +70,7 @@ import org.apache.solr.update.processor.LogUpdateProcessorFactory;
import org.apache.solr.update.processor.RunUpdateProcessorFactory;
import org.apache.solr.update.processor.UpdateRequestProcessorChain;
import org.apache.solr.update.processor.UpdateRequestProcessorFactory;
+import org.apache.solr.util.DefaultSolrThreadFactory;
import org.apache.solr.util.RefCounted;
import org.apache.solr.util.plugin.NamedListInitializedPlugin;
import org.apache.solr.util.plugin.PluginInfoInitialized;
@@ -1070,7 +1071,8 @@ public final class SolrCore implements SolrInfoMBean {
private final LinkedList> _searchers = new LinkedList>();
private final LinkedList> _realtimeSearchers = new LinkedList>();
- final ExecutorService searcherExecutor = Executors.newSingleThreadExecutor();
+ final ExecutorService searcherExecutor = Executors.newSingleThreadExecutor(
+ new DefaultSolrThreadFactory("searcherExecutor"));
private int onDeckSearchers; // number of searchers preparing
// Lock ordering: one can acquire the openSearcherLock and then the searcherLock, but not vice-versa.
private Object searcherLock = new Object(); // the sync object for the searcher
diff --git a/solr/core/src/java/org/apache/solr/handler/SnapPuller.java b/solr/core/src/java/org/apache/solr/handler/SnapPuller.java
index ce3c0f4..f616096 100644
--- a/solr/core/src/java/org/apache/solr/handler/SnapPuller.java
+++ b/solr/core/src/java/org/apache/solr/handler/SnapPuller.java
@@ -31,6 +31,7 @@ import org.apache.solr.common.params.CommonParams;
import org.apache.solr.common.params.ModifiableSolrParams;
import org.apache.solr.common.params.SolrParams;
import org.apache.solr.common.util.FastInputStream;
+import org.apache.solr.util.DefaultSolrThreadFactory;
import org.apache.solr.util.FileUtils;
import org.apache.solr.common.util.NamedList;
import org.apache.solr.core.CachingDirectoryFactory.CloseListener;
@@ -178,7 +179,8 @@ public class SnapPuller {
}
}
};
- executorService = Executors.newSingleThreadScheduledExecutor();
+ executorService = Executors.newSingleThreadScheduledExecutor(
+ new DefaultSolrThreadFactory("snapPuller"));
long initialDelay = pollInterval - (System.currentTimeMillis() % pollInterval);
executorService.scheduleAtFixedRate(task, initialDelay, pollInterval, TimeUnit.MILLISECONDS);
LOG.info("Poll Scheduled at an interval of " + pollInterval + "ms");
@@ -311,7 +313,7 @@ public class SnapPuller {
LOG.info("Number of files in latest index in master: " + filesToDownload.size());
// Create the sync service
- fsyncService = Executors.newSingleThreadExecutor();
+ fsyncService = Executors.newSingleThreadExecutor(new DefaultSolrThreadFactory("fsyncService"));
// use a synchronized list because the list is read by other threads (to show details)
filesDownloaded = Collections.synchronizedList(new ArrayList