Repository: hadoop Updated Branches: refs/heads/branch-2.6 7f8c89c33 -> 1b25855b9
HDFS-9347. Invariant assumption in TestQuorumJournalManager.shutdown() is wrong. Contributed by Wei-Chiu Chuang. Change-Id: Idde8522e11c77f82b376e0c90a9bf33d163d5cb9 (cherry picked from commit ef3f3f6bb14cf44bef1778f1091d8ed8a4b764a3) Conflicts: hadoop-hdfs-project/hadoop-hdfs/CHANGES.txt Project: http://git-wip-us.apache.org/repos/asf/hadoop/repo Commit: http://git-wip-us.apache.org/repos/asf/hadoop/commit/1b25855b Tree: http://git-wip-us.apache.org/repos/asf/hadoop/tree/1b25855b Diff: http://git-wip-us.apache.org/repos/asf/hadoop/diff/1b25855b Branch: refs/heads/branch-2.6 Commit: 1b25855b9b53272007b08f833ab8a9f1fffbad83 Parents: 7f8c89c Author: Zhe Zhang <z...@apache.org> Authored: Fri Dec 18 16:04:47 2015 -0800 Committer: Walter Su <waltersu4...@apache.org> Committed: Tue Feb 9 10:20:40 2016 +0800 ---------------------------------------------------------------------- .../apache/hadoop/test/GenericTestUtils.java | 54 ++++++++++++++++---- hadoop-hdfs-project/hadoop-hdfs/CHANGES.txt | 3 ++ .../client/TestQuorumJournalManager.java | 13 +++-- 3 files changed, 56 insertions(+), 14 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/hadoop/blob/1b25855b/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/test/GenericTestUtils.java ---------------------------------------------------------------------- diff --git a/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/test/GenericTestUtils.java b/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/test/GenericTestUtils.java index 0616887..02207d2 100644 --- a/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/test/GenericTestUtils.java +++ b/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/test/GenericTestUtils.java @@ -352,25 +352,61 @@ public abstract class GenericTestUtils { } /** + * Determine if there are any threads whose name matches the regex. + * @param pattern a Pattern object used to match thread names + * @return true if there is any thread that matches the pattern + */ + public static boolean anyThreadMatching(Pattern pattern) { + ThreadMXBean threadBean = ManagementFactory.getThreadMXBean(); + + ThreadInfo[] infos = + threadBean.getThreadInfo(threadBean.getAllThreadIds(), 20); + for (ThreadInfo info : infos) { + if (info == null) + continue; + if (pattern.matcher(info.getThreadName()).matches()) { + return true; + } + } + return false; + } + + /** * Assert that there are no threads running whose name matches the * given regular expression. * @param regex the regex to match against */ public static void assertNoThreadsMatching(String regex) { Pattern pattern = Pattern.compile(regex); - ThreadMXBean threadBean = ManagementFactory.getThreadMXBean(); - - ThreadInfo[] infos = threadBean.getThreadInfo(threadBean.getAllThreadIds(), 20); - for (ThreadInfo info : infos) { - if (info == null) continue; - if (pattern.matcher(info.getThreadName()).matches()) { - Assert.fail("Leaked thread: " + info + "\n" + - Joiner.on("\n").join(info.getStackTrace())); - } + if (anyThreadMatching(pattern)) { + Assert.fail("Leaked thread matches " + regex); } } /** + * Periodically check and wait for any threads whose name match the + * given regular expression. + * + * @param regex the regex to match against. + * @param checkEveryMillis time (in milliseconds) between checks. + * @param waitForMillis total time (in milliseconds) to wait before throwing + * a time out exception. + * @throws TimeoutException + * @throws InterruptedException + */ + public static void waitForThreadTermination(String regex, + int checkEveryMillis, final int waitForMillis) throws TimeoutException, + InterruptedException { + final Pattern pattern = Pattern.compile(regex); + waitFor(new Supplier<Boolean>() { + @Override public Boolean get() { + return !anyThreadMatching(pattern); + } + }, checkEveryMillis, waitForMillis); + } + + + /** * Skip test if native build profile of Maven is not activated. * Sub-project using this must set 'runningWithNative' property to true * in the definition of native profile in pom.xml. http://git-wip-us.apache.org/repos/asf/hadoop/blob/1b25855b/hadoop-hdfs-project/hadoop-hdfs/CHANGES.txt ---------------------------------------------------------------------- diff --git a/hadoop-hdfs-project/hadoop-hdfs/CHANGES.txt b/hadoop-hdfs-project/hadoop-hdfs/CHANGES.txt index b62ce3d..fbfda69 100644 --- a/hadoop-hdfs-project/hadoop-hdfs/CHANGES.txt +++ b/hadoop-hdfs-project/hadoop-hdfs/CHANGES.txt @@ -15,6 +15,9 @@ Release 2.6.5 - UNRELEASED BUG FIXES + HDFS-9347. Invariant assumption in TestQuorumJournalManager.shutdown() + is wrong. (Wei-Chiu Chuang via zhz) + Release 2.6.4 - UNRELEASED INCOMPATIBLE CHANGES http://git-wip-us.apache.org/repos/asf/hadoop/blob/1b25855b/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/qjournal/client/TestQuorumJournalManager.java ---------------------------------------------------------------------- diff --git a/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/qjournal/client/TestQuorumJournalManager.java b/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/qjournal/client/TestQuorumJournalManager.java index 8bb39f8..0e2e430 100644 --- a/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/qjournal/client/TestQuorumJournalManager.java +++ b/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/qjournal/client/TestQuorumJournalManager.java @@ -38,6 +38,7 @@ import java.net.URL; import java.util.ArrayList; import java.util.List; import java.util.concurrent.ExecutorService; +import java.util.concurrent.TimeoutException; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -103,20 +104,22 @@ public class TestQuorumJournalManager { qjm.recoverUnfinalizedSegments(); assertEquals(1, qjm.getLoggerSetForTests().getEpoch()); } - + @After - public void shutdown() throws IOException { + public void shutdown() throws IOException, InterruptedException, + TimeoutException { IOUtils.cleanup(LOG, toClose.toArray(new Closeable[0])); - + // Should not leak clients between tests -- this can cause flaky tests. // (See HDFS-4643) - GenericTestUtils.assertNoThreadsMatching(".*IPC Client.*"); + // Wait for IPC clients to terminate to avoid flaky tests + GenericTestUtils.waitForThreadTermination(".*IPC Client.*", 100, 1000); if (cluster != null) { cluster.shutdown(); } } - + /** * Enqueue a QJM for closing during shutdown. This makes the code a little * easier to follow, with fewer try..finally clauses necessary.