Return-Path: X-Original-To: archive-asf-public-internal@cust-asf2.ponee.io Delivered-To: archive-asf-public-internal@cust-asf2.ponee.io Received: from cust-asf.ponee.io (cust-asf.ponee.io [163.172.22.183]) by cust-asf2.ponee.io (Postfix) with ESMTP id 8C66B200CF0 for ; Tue, 22 Aug 2017 01:03:33 +0200 (CEST) Received: by cust-asf.ponee.io (Postfix) id 8AAF6165D4B; Mon, 21 Aug 2017 23:03:33 +0000 (UTC) Delivered-To: archive-asf-public@cust-asf.ponee.io Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by cust-asf.ponee.io (Postfix) with SMTP id 829E2165D48 for ; Tue, 22 Aug 2017 01:03:32 +0200 (CEST) Received: (qmail 96909 invoked by uid 500); 21 Aug 2017 23:03:30 -0000 Mailing-List: contact commits-help@hbase.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@hbase.apache.org Delivered-To: mailing list commits@hbase.apache.org Received: (qmail 96900 invoked by uid 99); 21 Aug 2017 23:03:30 -0000 Received: from git1-us-west.apache.org (HELO git1-us-west.apache.org) (140.211.11.23) by apache.org (qpsmtpd/0.29) with ESMTP; Mon, 21 Aug 2017 23:03:30 +0000 Received: by git1-us-west.apache.org (ASF Mail Server at git1-us-west.apache.org, from userid 33) id 2A756E053D; Mon, 21 Aug 2017 23:03:30 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: stack@apache.org To: commits@hbase.apache.org Message-Id: <263899c3291941188d0581691ea170e1@git.apache.org> X-Mailer: ASF-Git Admin Mailer Subject: hbase git commit: HBASE-16615 Fix flaky TestScannerHeartbeatMessages (Duo Zhang) Date: Mon, 21 Aug 2017 23:03:30 +0000 (UTC) archived-at: Mon, 21 Aug 2017 23:03:33 -0000 Repository: hbase Updated Branches: refs/heads/branch-1.3 6e5661c1f -> 65fda491f HBASE-16615 Fix flaky TestScannerHeartbeatMessages (Duo Zhang) Project: http://git-wip-us.apache.org/repos/asf/hbase/repo Commit: http://git-wip-us.apache.org/repos/asf/hbase/commit/65fda491 Tree: http://git-wip-us.apache.org/repos/asf/hbase/tree/65fda491 Diff: http://git-wip-us.apache.org/repos/asf/hbase/diff/65fda491 Branch: refs/heads/branch-1.3 Commit: 65fda491fd64bd096944e42e182639049d558bb0 Parents: 6e5661c Author: Michael Stack Authored: Mon Aug 21 16:01:26 2017 -0700 Committer: Michael Stack Committed: Mon Aug 21 16:03:23 2017 -0700 ---------------------------------------------------------------------- .../TestScannerHeartbeatMessages.java | 105 ++++++++----------- 1 file changed, 41 insertions(+), 64 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/hbase/blob/65fda491/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/TestScannerHeartbeatMessages.java ---------------------------------------------------------------------- diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/TestScannerHeartbeatMessages.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/TestScannerHeartbeatMessages.java index c85e41c..fe938b3 100644 --- a/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/TestScannerHeartbeatMessages.java +++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/TestScannerHeartbeatMessages.java @@ -22,6 +22,9 @@ import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; +import com.google.protobuf.RpcController; +import com.google.protobuf.ServiceException; + import java.io.IOException; import java.util.ArrayList; import java.util.List; @@ -58,6 +61,7 @@ import org.apache.hadoop.hbase.protobuf.generated.ClientProtos.ScanResponse; import org.apache.hadoop.hbase.regionserver.HRegion.RegionScannerImpl; import org.apache.hadoop.hbase.testclassification.MediumTests; import org.apache.hadoop.hbase.util.Bytes; +import org.apache.hadoop.hbase.util.Threads; import org.apache.hadoop.hbase.wal.WAL; import org.apache.log4j.Level; import org.junit.After; @@ -67,9 +71,6 @@ import org.junit.BeforeClass; import org.junit.Test; import org.junit.experimental.categories.Category; -import com.google.protobuf.RpcController; -import com.google.protobuf.ServiceException; - /** * Here we test to make sure that scans return the expected Results when the server is sending the * Client heartbeat messages. Heartbeat messages are essentially keep-alive messages (they prevent @@ -117,12 +118,10 @@ public class TestScannerHeartbeatMessages { // In this test, we sleep after reading each row. So we should make sure after we get some number // of rows and sleep same times we must reach time limit, and do not timeout after next sleeping. - // So set this to 200, we will get 3 rows and reach time limit at the start of 4th row, then sleep - // for the 4th time. Total time is 800 ms so we will not timeout. - private static int DEFAULT_ROW_SLEEP_TIME = 200; + private static int DEFAULT_ROW_SLEEP_TIME = 300; // Similar with row sleep time. - private static int DEFAULT_CF_SLEEP_TIME = 200; + private static int DEFAULT_CF_SLEEP_TIME = 300; @BeforeClass public static void setUpBeforeClass() throws Exception { @@ -182,7 +181,6 @@ public class TestScannerHeartbeatMessages { @AfterClass public static void tearDownAfterClass() throws Exception { - TEST_UTIL.deleteTable(TABLE_NAME); TEST_UTIL.shutdownMiniCluster(); } @@ -197,26 +195,13 @@ public class TestScannerHeartbeatMessages { } /** - * Test a variety of scan configurations to ensure that they return the expected Results when - * heartbeat messages are necessary. These tests are accumulated under one test case to ensure - * that they don't run in parallel. If the tests ran in parallel, they may conflict with each - * other due to changing static variables - */ - @Test - public void testScannerHeartbeatMessages() throws Exception { - testImportanceOfHeartbeats(testHeartbeatBetweenRows()); - testImportanceOfHeartbeats(testHeartbeatBetweenColumnFamilies()); - testImportanceOfHeartbeats(testHeartbeatWithSparseFilter()); - } - - /** * Run the test callable when heartbeats are enabled/disabled. We expect all tests to only pass * when heartbeat messages are enabled (otherwise the test is pointless). When heartbeats are * disabled, the test should throw an exception. * @param testCallable * @throws InterruptedException */ - public void testImportanceOfHeartbeats(Callable testCallable) throws InterruptedException { + private void testImportanceOfHeartbeats(Callable testCallable) throws InterruptedException { HeartbeatRPCServices.heartbeatsEnabled = true; try { @@ -243,8 +228,9 @@ public class TestScannerHeartbeatMessages { * fetched. * @throws Exception */ - public Callable testHeartbeatBetweenRows() throws Exception { - return new Callable() { + @Test + public void testHeartbeatBetweenRows() throws Exception { + testImportanceOfHeartbeats(new Callable() { @Override public Void call() throws Exception { @@ -257,15 +243,16 @@ public class TestScannerHeartbeatMessages { testEquivalenceOfScanWithHeartbeats(scan, DEFAULT_ROW_SLEEP_TIME, -1, false); return null; } - }; + }); } /** * Test the case that the time limit for scans is reached in between column families * @throws Exception */ - public Callable testHeartbeatBetweenColumnFamilies() throws Exception { - return new Callable() { + @Test + public void testHeartbeatBetweenColumnFamilies() throws Exception { + testImportanceOfHeartbeats(new Callable() { @Override public Void call() throws Exception { // Configure the scan so that it can read the entire table in a single RPC. We want to test @@ -282,24 +269,23 @@ public class TestScannerHeartbeatMessages { testEquivalenceOfScanWithHeartbeats(scanCopy, -1, DEFAULT_CF_SLEEP_TIME, true); return null; } - }; + }); } - public static class SparseFilter extends FilterBase{ + public static class SparseFilter extends FilterBase { @Override public ReturnCode filterKeyValue(Cell v) throws IOException { try { - Thread.sleep(CLIENT_TIMEOUT/2 + 10); + Thread.sleep(CLIENT_TIMEOUT / 2 + 100); } catch (InterruptedException e) { Thread.currentThread().interrupt(); } - return Bytes.equals(CellUtil.cloneRow(v), ROWS[NUM_ROWS - 1]) ? - ReturnCode.INCLUDE : - ReturnCode.SKIP; + return Bytes.equals(CellUtil.cloneRow(v), ROWS[NUM_ROWS - 1]) ? ReturnCode.INCLUDE + : ReturnCode.SKIP; } - public static Filter parseFrom(final byte [] pbBytes){ + public static Filter parseFrom(final byte[] pbBytes) { return new SparseFilter(); } } @@ -308,8 +294,9 @@ public class TestScannerHeartbeatMessages { * Test the case that there is a filter which filters most of cells * @throws Exception */ - public Callable testHeartbeatWithSparseFilter() throws Exception { - return new Callable() { + @Test + public void testHeartbeatWithSparseFilter() throws Exception { + testImportanceOfHeartbeats(new Callable() { @Override public Void call() throws Exception { Scan scan = new Scan(); @@ -339,7 +326,7 @@ public class TestScannerHeartbeatMessages { return null; } - }; + }); } /** @@ -352,7 +339,7 @@ public class TestScannerHeartbeatMessages { * that column family are fetched * @throws Exception */ - public void testEquivalenceOfScanWithHeartbeats(final Scan scan, int rowSleepTime, + private void testEquivalenceOfScanWithHeartbeats(final Scan scan, int rowSleepTime, int cfSleepTime, boolean sleepBeforeCf) throws Exception { disableSleeping(); final ResultScanner scanner = TABLE.getScanner(scan); @@ -427,14 +414,14 @@ public class TestScannerHeartbeatMessages { * Custom RSRpcServices instance that allows heartbeat support to be toggled */ private static class HeartbeatRPCServices extends RSRpcServices { - private static boolean heartbeatsEnabled = true; + private static volatile boolean heartbeatsEnabled = true; public HeartbeatRPCServices(HRegionServer rs) throws IOException { super(rs); } @Override - public ScanResponse scan(RpcController controller, ScanRequest request) + public ScanResponse scan(RpcController controller, ScanRequest request) throws ServiceException { ScanRequest.Builder builder = ScanRequest.newBuilder(request); builder.setClientHandlesHeartbeats(heartbeatsEnabled); @@ -449,17 +436,17 @@ public class TestScannerHeartbeatMessages { */ private static class HeartbeatHRegion extends HRegion { // Row sleeps occur AFTER each row worth of cells is retrieved. - private static int rowSleepTime = DEFAULT_ROW_SLEEP_TIME; - private static boolean sleepBetweenRows = false; + private static volatile int rowSleepTime = DEFAULT_ROW_SLEEP_TIME; + private static volatile boolean sleepBetweenRows = false; // The sleep for column families can be initiated before or after we fetch the cells for the // column family. If the sleep occurs BEFORE then the time limits will be reached inside // StoreScanner while we are fetching individual cells. If the sleep occurs AFTER then the time // limit will be reached inside RegionScanner after all the cells for a column family have been // retrieved. - private static boolean sleepBeforeColumnFamily = false; - private static int columnFamilySleepTime = DEFAULT_CF_SLEEP_TIME; - private static boolean sleepBetweenColumnFamilies = false; + private static volatile boolean sleepBeforeColumnFamily = false; + private static volatile int columnFamilySleepTime = DEFAULT_CF_SLEEP_TIME; + private static volatile boolean sleepBetweenColumnFamilies = false; public HeartbeatHRegion(Path tableDir, WAL wal, FileSystem fs, Configuration confParam, HRegionInfo regionInfo, HTableDescriptor htd, RegionServerServices rsServices) { @@ -472,20 +459,14 @@ public class TestScannerHeartbeatMessages { } private static void columnFamilySleep() { - if (HeartbeatHRegion.sleepBetweenColumnFamilies) { - try { - Thread.sleep(HeartbeatHRegion.columnFamilySleepTime); - } catch (InterruptedException e) { - } + if (sleepBetweenColumnFamilies) { + Threads.sleepWithoutInterrupt(columnFamilySleepTime); } } private static void rowSleep() { - try { - if (HeartbeatHRegion.sleepBetweenRows) { - Thread.sleep(HeartbeatHRegion.rowSleepTime); - } - } catch (InterruptedException e) { + if (sleepBetweenRows) { + Threads.sleepWithoutInterrupt(rowSleepTime); } } @@ -514,8 +495,7 @@ public class TestScannerHeartbeatMessages { } @Override - public boolean nextRaw(List outResults, ScannerContext context) - throws IOException { + public boolean nextRaw(List outResults, ScannerContext context) throws IOException { boolean moreRows = super.nextRaw(outResults, context); HeartbeatHRegion.rowSleep(); return moreRows; @@ -542,8 +522,7 @@ public class TestScannerHeartbeatMessages { } @Override - public boolean nextRaw(List outResults, ScannerContext context) - throws IOException { + public boolean nextRaw(List outResults, ScannerContext context) throws IOException { boolean moreRows = super.nextRaw(outResults, context); HeartbeatHRegion.rowSleep(); return moreRows; @@ -575,8 +554,7 @@ public class TestScannerHeartbeatMessages { } @Override - public boolean next(List result, ScannerContext context) - throws IOException { + public boolean next(List result, ScannerContext context) throws IOException { if (HeartbeatHRegion.sleepBeforeColumnFamily) HeartbeatHRegion.columnFamilySleep(); boolean moreRows = super.next(result, context); if (!HeartbeatHRegion.sleepBeforeColumnFamily) HeartbeatHRegion.columnFamilySleep(); @@ -589,14 +567,13 @@ public class TestScannerHeartbeatMessages { * cells. */ private static final class HeartbeatReversedKVHeap extends ReversedKeyValueHeap { - public HeartbeatReversedKVHeap(List scanners, + public HeartbeatReversedKVHeap(List scanners, KVComparator comparator) throws IOException { super(scanners, comparator); } @Override - public boolean next(List result, ScannerContext context) - throws IOException { + public boolean next(List result, ScannerContext context) throws IOException { if (HeartbeatHRegion.sleepBeforeColumnFamily) HeartbeatHRegion.columnFamilySleep(); boolean moreRows = super.next(result, context); if (!HeartbeatHRegion.sleepBeforeColumnFamily) HeartbeatHRegion.columnFamilySleep();