001/*
002 * Licensed to the Apache Software Foundation (ASF) under one
003 * or more contributor license agreements.  See the NOTICE file
004 * distributed with this work for additional information
005 * regarding copyright ownership.  The ASF licenses this file
006 * to you under the Apache License, Version 2.0 (the
007 * "License"); you may not use this file except in compliance
008 * with the License.  You may obtain a copy of the License at
009 *
010 *     http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing, software
013 * distributed under the License is distributed on an "AS IS" BASIS,
014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015 * See the License for the specific language governing permissions and
016 * limitations under the License.
017 */
018package org.apache.hadoop.hbase.client;
019
020import static org.junit.Assert.assertFalse;
021import static org.junit.Assert.assertNull;
022import static org.junit.Assert.assertTrue;
023
024import java.util.Arrays;
025import org.apache.hadoop.hbase.CompatibilityFactory;
026import org.apache.hadoop.hbase.HBaseClassTestRule;
027import org.apache.hadoop.hbase.HBaseTestingUtility;
028import org.apache.hadoop.hbase.HConstants;
029import org.apache.hadoop.hbase.HTableDescriptor;
030import org.apache.hadoop.hbase.TableName;
031import org.apache.hadoop.hbase.ipc.MetricsHBaseServerSource;
032import org.apache.hadoop.hbase.test.MetricsAssertHelper;
033import org.apache.hadoop.hbase.testclassification.LargeTests;
034import org.apache.hadoop.hbase.util.Bytes;
035import org.junit.After;
036import org.junit.AfterClass;
037import org.junit.Before;
038import org.junit.BeforeClass;
039import org.junit.ClassRule;
040import org.junit.Rule;
041import org.junit.Test;
042import org.junit.experimental.categories.Category;
043import org.junit.rules.TestName;
044import org.slf4j.Logger;
045import org.slf4j.LoggerFactory;
046
047@Category(LargeTests.class)
048public class TestLeaseRenewal {
049
050  @ClassRule
051  public static final HBaseClassTestRule CLASS_RULE =
052    HBaseClassTestRule.forClass(TestLeaseRenewal.class);
053
054  public MetricsAssertHelper HELPER = CompatibilityFactory.getInstance(MetricsAssertHelper.class);
055
056  final Logger LOG = LoggerFactory.getLogger(getClass());
057  private final static HBaseTestingUtility TEST_UTIL = new HBaseTestingUtility();
058  private static byte[] FAMILY = Bytes.toBytes("testFamily");
059  private static final byte[] ANOTHERROW = Bytes.toBytes("anotherrow");
060  private final static byte[] COL_QUAL = Bytes.toBytes("f1");
061  private final static byte[] VAL_BYTES = Bytes.toBytes("v1");
062  private final static byte[] ROW_BYTES = Bytes.toBytes("r1");
063  private final static int leaseTimeout =
064    HConstants.DEFAULT_HBASE_CLIENT_SCANNER_TIMEOUT_PERIOD / 4;
065
066  @Rule
067  public TestName name = new TestName();
068
069  /**
070   * @throws java.lang.Exception
071   */
072  @BeforeClass
073  public static void setUpBeforeClass() throws Exception {
074    TEST_UTIL.getConfiguration().setInt(HConstants.HBASE_CLIENT_SCANNER_TIMEOUT_PERIOD,
075      leaseTimeout);
076    TEST_UTIL.startMiniCluster();
077  }
078
079  /**
080   * @throws java.lang.Exception
081   */
082  @AfterClass
083  public static void tearDownAfterClass() throws Exception {
084    TEST_UTIL.shutdownMiniCluster();
085  }
086
087  /**
088   * @throws java.lang.Exception
089   */
090  @Before
091  public void setUp() throws Exception {
092    // Nothing to do.
093  }
094
095  /**
096   * @throws java.lang.Exception
097   */
098  @After
099  public void tearDown() throws Exception {
100    for (HTableDescriptor htd : TEST_UTIL.getAdmin().listTables()) {
101      LOG.info("Tear down, remove table=" + htd.getTableName());
102      TEST_UTIL.deleteTable(htd.getTableName());
103    }
104  }
105
106  @Test
107  public void testLeaseRenewal() throws Exception {
108    Table table = TEST_UTIL.createTable(TableName.valueOf(name.getMethodName()), FAMILY);
109    Put p = new Put(ROW_BYTES);
110    p.addColumn(FAMILY, COL_QUAL, VAL_BYTES);
111    table.put(p);
112    p = new Put(ANOTHERROW);
113    p.addColumn(FAMILY, COL_QUAL, VAL_BYTES);
114    table.put(p);
115    Scan s = new Scan();
116    s.setCaching(1);
117    ResultScanner rs = table.getScanner(s);
118    // we haven't open the scanner yet so nothing happens
119    assertFalse(rs.renewLease());
120    assertTrue(Arrays.equals(rs.next().getRow(), ANOTHERROW));
121    // renew the lease a few times, long enough to be sure
122    // the lease would have expired otherwise
123    Thread.sleep(leaseTimeout / 2);
124    assertTrue(rs.renewLease());
125    Thread.sleep(leaseTimeout / 2);
126    assertTrue(rs.renewLease());
127    Thread.sleep(leaseTimeout / 2);
128    assertTrue(rs.renewLease());
129    // make sure we haven't advanced the scanner
130    assertTrue(Arrays.equals(rs.next().getRow(), ROW_BYTES));
131    // renewLease should return false now as we have read all the data already
132    assertFalse(rs.renewLease());
133    // make sure scanner is exhausted now
134    assertNull(rs.next());
135    // renewLease should return false now
136    assertFalse(rs.renewLease());
137    rs.close();
138    table.close();
139    MetricsHBaseServerSource serverSource = TEST_UTIL.getMiniHBaseCluster().getRegionServer(0)
140      .getRpcServer().getMetrics().getMetricsSource();
141    HELPER.assertCounter("exceptions.OutOfOrderScannerNextException", 0, serverSource);
142  }
143}