Package org.apache.hadoop.hbase.index.coprocessor.regionserver

Source Code of org.apache.hadoop.hbase.index.coprocessor.regionserver.TestIndexRegionObserver

/**
* Copyright 2011 The Apache Software Foundation
*
* 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.
*/
package org.apache.hadoop.hbase.index.coprocessor.regionserver;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.hbase.HBaseTestingUtility;
import org.apache.hadoop.hbase.HColumnDescriptor;
import org.apache.hadoop.hbase.HRegionInfo;
import org.apache.hadoop.hbase.HTableDescriptor;
import org.apache.hadoop.hbase.KeyValue;
import org.apache.hadoop.hbase.LargeTests;
import org.apache.hadoop.hbase.client.Delete;
import org.apache.hadoop.hbase.client.Get;
import org.apache.hadoop.hbase.client.HBaseAdmin;
import org.apache.hadoop.hbase.client.HTable;
import org.apache.hadoop.hbase.client.Put;
import org.apache.hadoop.hbase.client.Result;
import org.apache.hadoop.hbase.client.ResultScanner;
import org.apache.hadoop.hbase.client.RetriesExhaustedWithDetailsException;
import org.apache.hadoop.hbase.client.RowMutations;
import org.apache.hadoop.hbase.client.Scan;
import org.apache.hadoop.hbase.coprocessor.CoprocessorHost;
import org.apache.hadoop.hbase.coprocessor.ObserverContext;
import org.apache.hadoop.hbase.coprocessor.RegionCoprocessorEnvironment;
import org.apache.hadoop.hbase.index.ColumnQualifier.ValueType;
import org.apache.hadoop.hbase.index.Constants;
import org.apache.hadoop.hbase.index.IndexSpecification;
import org.apache.hadoop.hbase.index.IndexedHTableDescriptor;
import org.apache.hadoop.hbase.index.coprocessor.master.IndexMasterObserver;
import org.apache.hadoop.hbase.index.coprocessor.wal.IndexWALObserver;
import org.apache.hadoop.hbase.index.manager.IndexManager;
import org.apache.hadoop.hbase.index.util.IndexUtils;
import org.apache.hadoop.hbase.regionserver.HRegion;
import org.apache.hadoop.hbase.regionserver.HRegionServer;
import org.apache.hadoop.hbase.regionserver.SplitTransaction;
import org.apache.hadoop.hbase.regionserver.SplitTransaction.SplitInfo;
import org.apache.hadoop.hbase.regionserver.StoreFile;
import org.apache.hadoop.hbase.regionserver.wal.HLog;
import org.apache.hadoop.hbase.util.Bytes;
import org.apache.hadoop.hbase.util.Threads;
import org.apache.hadoop.hbase.zookeeper.ZKAssign;
import org.apache.hadoop.hbase.zookeeper.ZooKeeperWatcher;
import org.apache.zookeeper.KeeperException;
import org.junit.AfterClass;
import org.junit.Assert;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.experimental.categories.Category;

@Category(LargeTests.class)
public class TestIndexRegionObserver {

  private static HBaseTestingUtility UTIL = new HBaseTestingUtility();
  private static final int TTL_SECONDS = 2;
  private static final int TTL_MS = TTL_SECONDS * 1000;

  @BeforeClass
  public static void setupBeforeClass() throws Exception {
    Configuration conf = UTIL.getConfiguration();
    conf.set(CoprocessorHost.MASTER_COPROCESSOR_CONF_KEY, IndexMasterObserver.class.getName());
    conf.set(CoprocessorHost.REGION_COPROCESSOR_CONF_KEY, MockIndexRegionObserver.class.getName());
    conf.set(CoprocessorHost.WAL_COPROCESSOR_CONF_KEY, IndexWALObserver.class.getName());
    conf.setBoolean("hbase.use.secondary.index", true);
    UTIL.startMiniCluster(1);
  }

  @AfterClass
  public static void tearDownAfterClass() throws Exception {
    UTIL.shutdownMiniCluster();
  }

  @Before
  public void setUp() {
    MockIndexRegionObserver.count = 0;
    MockIndexRegionObserver.isnullIndexRegion = false;
  }

  @Test(timeout = 180000)
  public void testPutWithAndWithoutTheIndexedColumn() throws IOException, KeeperException,
      InterruptedException {
    HBaseAdmin admin = UTIL.getHBaseAdmin();

    ZooKeeperWatcher zkw = HBaseTestingUtility.getZooKeeperWatcher(UTIL);

    Configuration conf = UTIL.getConfiguration();
    String userTableName = "testPutContainingTheIndexedColumn";
    IndexedHTableDescriptor ihtd = new IndexedHTableDescriptor(userTableName);
    HColumnDescriptor hcd = new HColumnDescriptor("col");
    IndexSpecification iSpec = new IndexSpecification("Index1");
    iSpec.addIndexColumn(hcd, "ql", ValueType.String, 10);
    ihtd.addFamily(hcd);
    ihtd.addIndex(iSpec);
    admin.createTable(ihtd);
    ZKAssign.blockUntilNoRIT(zkw);

    HTable table = new HTable(conf, userTableName);
    // test put with the indexed column
    Put p = new Put("row1".getBytes());
    p.add("col".getBytes(), "ql".getBytes(), "myValue".getBytes());
    table.put(p);

    // Thread.sleep(2000);
    int i = countNumberOfRows(userTableName);
    Assert.assertEquals(1, i);
    i = countNumberOfRows(userTableName + Constants.INDEX_TABLE_SUFFIX);
    Assert.assertEquals(1, i);

    // Test put without the indexed column
    Put p1 = new Put("row2".getBytes());
    p1.add("col".getBytes(), "ql1".getBytes(), "myValue".getBytes());
    table.put(p1);

    i = countNumberOfRows(userTableName);
    Assert.assertEquals(2, i);
    i = countNumberOfRows(userTableName + Constants.INDEX_TABLE_SUFFIX);
    Assert.assertEquals(1, i);
  }

  public int countNumberOfRows(String tableName) throws IOException {
    Configuration conf = UTIL.getConfiguration();
    HTable table = new HTable(conf, tableName);
    Scan s = new Scan();
    int i = 0;
    ResultScanner scanner = table.getScanner(s);
    Result[] result = scanner.next(1);
    while (result != null && result.length > 0) {
      i++;
      result = scanner.next(1);
    }
    return i;
  }

  public Result[] getTheLastRow(String tableName) throws IOException {
    Configuration conf = UTIL.getConfiguration();
    HTable table = new HTable(conf, tableName);
    Scan s = new Scan();
    ResultScanner scanner = table.getScanner(s);
    Result[] result = scanner.next(1);
    Result[] result1 = result;
    while (result1 != null && result1.length > 0) {
      result1 = scanner.next(1);
      if (null == result1 || result1.length <= 0) break;
      else result = result1;
    }
    return result;
  }

  @Test(timeout = 180000)
  public void testPostOpenCoprocessor() throws IOException, KeeperException, InterruptedException {
    HBaseAdmin admin = UTIL.getHBaseAdmin();
    ZooKeeperWatcher zkw = HBaseTestingUtility.getZooKeeperWatcher(UTIL);
    String userTableName = "testPostOpenCoprocessor";
    IndexedHTableDescriptor ihtd = new IndexedHTableDescriptor(userTableName);
    HColumnDescriptor hcd = new HColumnDescriptor("col");
    IndexSpecification iSpec = new IndexSpecification("Index1");
    iSpec.addIndexColumn(hcd, "ql", ValueType.String, 10);
    ihtd.addFamily(hcd);
    ihtd.addIndex(iSpec);
    admin.createTable(ihtd);
    ZKAssign.blockUntilNoRIT(zkw);

    // Check the number of indices
    List<IndexSpecification> list = IndexManager.getInstance().getIndicesForTable(userTableName);
    Assert.assertEquals(1, list.size());

    // Check the index name
    boolean bool = false;
    for (IndexSpecification e : list) {
      if (e.getName().equals("Index1")) bool = true;
    }
    Assert.assertTrue(bool);
  }

  @Test(timeout = 180000)
  public void testMultipleIndicesOnUniqueColumns() throws IOException, KeeperException,
      InterruptedException {
    HBaseAdmin admin = UTIL.getHBaseAdmin();
    ZooKeeperWatcher zkw = HBaseTestingUtility.getZooKeeperWatcher(UTIL);
    Configuration conf = UTIL.getConfiguration();
    String userTableName = "testMultipleIndicesOnUniqueColumns";
    IndexedHTableDescriptor ihtd = new IndexedHTableDescriptor(userTableName);
    HColumnDescriptor hcd = new HColumnDescriptor("col");
    IndexSpecification iSpec1 = new IndexSpecification("Index1");
    IndexSpecification iSpec2 = new IndexSpecification("Index2");
    iSpec1.addIndexColumn(hcd, "ql1", ValueType.String, 10);
    iSpec2.addIndexColumn(hcd, "ql2", ValueType.String, 10);
    ihtd.addFamily(hcd);
    ihtd.addIndex(iSpec1);
    ihtd.addIndex(iSpec2);
    admin.createTable(ihtd);
    ZKAssign.blockUntilNoRIT(zkw);

    HTable table = new HTable(conf, userTableName);
    Put p = new Put("row1".getBytes());
    p.add("col".getBytes(), "ql3".getBytes(), "myValue".getBytes());
    p.add("col".getBytes(), "ql4".getBytes(), "myValue".getBytes());
    table.put(p);
    int i = countNumberOfRows(userTableName);
    Assert.assertEquals(1, i);
    i = countNumberOfRows(userTableName + Constants.INDEX_TABLE_SUFFIX);
    Assert.assertEquals(0, i);

    p = new Put("row2".getBytes());
    p.add("col".getBytes(), "ql1".getBytes(), "myValue".getBytes());
    p.add("col".getBytes(), "ql2".getBytes(), "myValue".getBytes());
    table.put(p);
    i = countNumberOfRows(userTableName);
    Assert.assertEquals(2, i);
    i = countNumberOfRows(userTableName + Constants.INDEX_TABLE_SUFFIX);
    Assert.assertEquals(2, i);

  }

  @Test(timeout = 180000)
  public void testIndexOnMultipleCols() throws IOException, KeeperException, InterruptedException {
    HBaseAdmin admin = UTIL.getHBaseAdmin();
    ZooKeeperWatcher zkw = HBaseTestingUtility.getZooKeeperWatcher(UTIL);
    Configuration conf = UTIL.getConfiguration();
    String userTableName = "testSingleIndexOnMultipleCols";
    IndexedHTableDescriptor ihtd = new IndexedHTableDescriptor(userTableName);

    // Creating and adding the column families
    HColumnDescriptor hcd1 = new HColumnDescriptor("col1");
    HColumnDescriptor hcd2 = new HColumnDescriptor("col2");
    HColumnDescriptor hcd3 = new HColumnDescriptor("col3");
    ihtd.addFamily(hcd1);
    ihtd.addFamily(hcd2);
    ihtd.addFamily(hcd3);

    // Create and add indices
    IndexSpecification iSpec1 = new IndexSpecification("Index1");
    IndexSpecification iSpec2 = new IndexSpecification("Index2");
    iSpec1.addIndexColumn(hcd1, "ql1", ValueType.String, 10);
    iSpec2.addIndexColumn(hcd2, "ql1", ValueType.String, 10);
    iSpec2.addIndexColumn(hcd3, "ql1", ValueType.String, 10);
    ihtd.addIndex(iSpec1);
    ihtd.addIndex(iSpec2);
    admin.createTable(ihtd);
    ZKAssign.blockUntilNoRIT(zkw);

    HTable table = new HTable(conf, userTableName);
    Put p = new Put("row1".getBytes());
    p.add("col1".getBytes(), "ql1".getBytes(), "myValue".getBytes());
    p.add("col2".getBytes(), "ql1".getBytes(), "myValue".getBytes());
    p.add("col3".getBytes(), "ql1".getBytes(), "myValue".getBytes());
    table.put(p);
    int i = countNumberOfRows(userTableName);
    Assert.assertEquals(1, i);
    i = countNumberOfRows(userTableName + Constants.INDEX_TABLE_SUFFIX);
    Assert.assertEquals(2, i);

    p = new Put("row2".getBytes());
    p.add("col1".getBytes(), "ql1".getBytes(), "myValue".getBytes());
    p.add("col2".getBytes(), "ql1".getBytes(), "myValue".getBytes());
    table.put(p);
    i = countNumberOfRows(userTableName);
    Assert.assertEquals(2, i);
    i = countNumberOfRows(userTableName + Constants.INDEX_TABLE_SUFFIX);
    Assert.assertEquals(4, i);

    p = new Put("row3".getBytes());
    p.add("col1".getBytes(), "ql1".getBytes(), "myValue".getBytes());
    p.add("col3".getBytes(), "ql1".getBytes(), "myValue".getBytes());
    table.put(p);
    i = countNumberOfRows(userTableName);
    Assert.assertEquals(3, i);
    i = countNumberOfRows(userTableName + Constants.INDEX_TABLE_SUFFIX);
    Assert.assertEquals(6, i);

    p = new Put("row4".getBytes());
    p.add("col2".getBytes(), "ql1".getBytes(), "myValue".getBytes());
    p.add("col3".getBytes(), "ql1".getBytes(), "myValue".getBytes());
    table.put(p);
    i = countNumberOfRows(userTableName);
    Assert.assertEquals(4, i);
    i = countNumberOfRows(userTableName + Constants.INDEX_TABLE_SUFFIX);
    Assert.assertEquals(7, i);
  }

  @Test(timeout = 180000)
  public void testPutsWithPadding() throws IOException, KeeperException, InterruptedException {
    HBaseAdmin admin = UTIL.getHBaseAdmin();
    ZooKeeperWatcher zkw = HBaseTestingUtility.getZooKeeperWatcher(UTIL);
    Configuration conf = UTIL.getConfiguration();
    String userTableName = "testPutsWithPadding";
    IndexedHTableDescriptor ihtd = new IndexedHTableDescriptor(userTableName);

    // Creating and adding the column families
    HColumnDescriptor hcd2 = new HColumnDescriptor("col2");
    HColumnDescriptor hcd3 = new HColumnDescriptor("col3");
    HColumnDescriptor hcd4 = new HColumnDescriptor("col4");

    ihtd.addFamily(hcd2);
    ihtd.addFamily(hcd3);
    ihtd.addFamily(hcd4);

    // Create and add indices
    IndexSpecification iSpec2 = new IndexSpecification("Index2");
    iSpec2.addIndexColumn(hcd2, "ql1", ValueType.String, 10);
    iSpec2.addIndexColumn(hcd3, "ql1", ValueType.String, 10);
    iSpec2.addIndexColumn(hcd4, "ql1", ValueType.String, 10);
    ihtd.addIndex(iSpec2);
    admin.createTable(ihtd);
    ZKAssign.blockUntilNoRIT(zkw);

    HTable table = new HTable(conf, userTableName);
    Put p = new Put("row1".getBytes());
    p.add("col2".getBytes(), "ql1".getBytes(), "myValue".getBytes());
    table.put(p);
    int i = countNumberOfRows(userTableName);
    Assert.assertEquals(1, i);
    i = countNumberOfRows(userTableName + Constants.INDEX_TABLE_SUFFIX);
    Assert.assertEquals(1, i);

    Result[] result = getTheLastRow(userTableName + Constants.INDEX_TABLE_SUFFIX);
    byte[] rowKey1 = result[0].getRow();

    p = new Put("row2".getBytes());
    p.add("col3".getBytes(), "ql1".getBytes(), "myValue".getBytes());
    table.put(p);
    i = countNumberOfRows(userTableName);
    Assert.assertEquals(2, i);
    i = countNumberOfRows(userTableName + Constants.INDEX_TABLE_SUFFIX);
    Assert.assertEquals(2, i);

    result = getTheLastRow(userTableName + Constants.INDEX_TABLE_SUFFIX);
    byte[] rowKey2 = result[0].getRow();

    Assert.assertEquals(rowKey1.length, rowKey2.length);

    p = new Put("row3".getBytes());
    p.add("col3".getBytes(), "ql1".getBytes(), "myValue".getBytes());
    table.put(p);
    i = countNumberOfRows(userTableName);
    Assert.assertEquals(3, i);
    i = countNumberOfRows(userTableName + Constants.INDEX_TABLE_SUFFIX);
    Assert.assertEquals(3, i);

    result = getTheLastRow(userTableName + Constants.INDEX_TABLE_SUFFIX);
    byte[] rowKey3 = result[0].getRow();
    Assert.assertEquals(rowKey2.length, rowKey3.length);

    /*
     * p = new Put("row4".getBytes()); p.add("col3".getBytes(), "ql1".getBytes(),
     * "myValuefgacfgn".getBytes()); p.add("col2".getBytes(), "ql1".getBytes(),
     * "myValue".getBytes()); p.add("col4".getBytes(), "ql1".getBytes(), "myValue".getBytes());
     * table.put(p); i = countNumberOfRows(userTableName); Assert.assertEquals(4, i); i =
     * countNumberOfRows(userTableName + Constants.INDEX_TABLE_SUFFIX); Assert.assertEquals(4, i);
     * result = getTheLastRow(userTableName + Constants.INDEX_TABLE_SUFFIX); byte[] rowKey4 =
     * result[0].getRow(); Assert.assertEquals(rowKey3.length, rowKey4.length);
     */
  }

  @Test(timeout = 180000)
  public void testBulkPut() throws IOException, KeeperException, InterruptedException {
    HBaseAdmin admin = UTIL.getHBaseAdmin();
    ZooKeeperWatcher zkw = HBaseTestingUtility.getZooKeeperWatcher(UTIL);
    Configuration conf = UTIL.getConfiguration();
    String userTableName = "testBulkPut";
    IndexedHTableDescriptor ihtd = new IndexedHTableDescriptor(userTableName);

    // Creating and adding the column families
    HColumnDescriptor hcd1 = new HColumnDescriptor("col1");
    HColumnDescriptor hcd2 = new HColumnDescriptor("col2");
    HColumnDescriptor hcd3 = new HColumnDescriptor("col3");
    ihtd.addFamily(hcd1);
    ihtd.addFamily(hcd2);
    ihtd.addFamily(hcd3);

    // Create and add indices
    IndexSpecification iSpec1 = new IndexSpecification("Index1");
    IndexSpecification iSpec2 = new IndexSpecification("Index2");
    iSpec1.addIndexColumn(hcd1, "ql1", ValueType.String, 10);
    iSpec2.addIndexColumn(hcd3, "ql1", ValueType.String, 10);
    ihtd.addIndex(iSpec1);
    ihtd.addIndex(iSpec2);
    admin.createTable(ihtd);
    ZKAssign.blockUntilNoRIT(zkw);

    Thread[] t = new Thread[10];
    for (int i = 0; i < 10; i++) {
      t[i] = new Testthread(conf, userTableName);
    }
    for (int i = 0; i < 10; i++) {
      t[i].start();
    }

    for (int i = 0; i < 10; i++) {
      t[i].join();
    }

    // System.out.println("Woke up");
    int i = countNumberOfRows(userTableName);
    Assert.assertEquals(5000, i);
    i = countNumberOfRows(userTableName + Constants.INDEX_TABLE_SUFFIX);
    Assert.assertEquals(10000, i);
    /*
     * HLog log = UTIL.getHBaseCluster().getRegionServer(0).getWAL(); log.getHLogDirectoryName
     * (UTIL.getHBaseCluster().getRegionServer(0).toString()); log.getReader(
     * UTIL.getMiniHBaseCluster().getRegionServer(0).getFileSystem(), path,
     * UTIL.getMiniHBaseCluster().getConfiguration());
     */
  }

  class Testthread extends Thread {
    Configuration conf;
    String userTableName;
    HTable table;

    public Testthread(Configuration conf, String userTableName) throws IOException {
      this.conf = conf;
      this.userTableName = userTableName;
      this.table = new HTable(conf, userTableName);
    }

    public void run() {
      for (int j = 0; j < 500; j++) {
        double d = Math.random();
        byte[] rowKey = Bytes.toBytes(d);
        Put p = new Put(rowKey);
        p.add(Bytes.toBytes("col1"), Bytes.toBytes("ql1"), Bytes.toBytes("myValue"));
        p.add(Bytes.toBytes("col2"), Bytes.toBytes("ql1"), Bytes.toBytes("myValue"));
        p.add(Bytes.toBytes("col3"), Bytes.toBytes("ql1"), Bytes.toBytes("myValue"));
        try {
          table.put(p);
        } catch (IOException e) {
        }
      }
    }
  }

  @Test(timeout = 180000)
  public void testBulkPutWithRepeatedRows() throws IOException, KeeperException,
      InterruptedException {
    HBaseAdmin admin = UTIL.getHBaseAdmin();
    ZooKeeperWatcher zkw = HBaseTestingUtility.getZooKeeperWatcher(UTIL);
    final Configuration conf = UTIL.getConfiguration();
    final String userTableName = "TestBulkPutWithRepeatedRows";
    IndexedHTableDescriptor ihtd = new IndexedHTableDescriptor(userTableName);

    // Creating and adding the column families
    HColumnDescriptor hcd1 = new HColumnDescriptor("col1");

    ihtd.addFamily(hcd1);

    // Create and add indices
    IndexSpecification iSpec1 = new IndexSpecification("Index1");

    iSpec1.addIndexColumn(hcd1, "ql1", ValueType.String, 10);

    ihtd.addIndex(iSpec1);

    admin.createTable(ihtd);
    ZKAssign.blockUntilNoRIT(zkw);

    new Thread() {
      @Override
      public void run() {
        try {
          HTable table = new HTable(conf, userTableName);
          List<Put> puts = new ArrayList<Put>(5);
          Put p = new Put("row1".getBytes());
          p.add(Bytes.toBytes("col1"), Bytes.toBytes("ql1"), Bytes.toBytes("myValue"));
          puts.add(p);
          p = new Put("row2".getBytes());
          p.add(Bytes.toBytes("col1"), Bytes.toBytes("ql1"), Bytes.toBytes("myValue"));
          puts.add(p);
          p = new Put("row3".getBytes());
          p.add(Bytes.toBytes("col1"), Bytes.toBytes("ql1"), Bytes.toBytes("myValue"));
          puts.add(p);
          p = new Put("row4".getBytes());
          p.add(Bytes.toBytes("col1"), Bytes.toBytes("ql1"), Bytes.toBytes("myValue"));
          puts.add(p);
          p = new Put("row5".getBytes());
          p.add(Bytes.toBytes("col1"), Bytes.toBytes("ql1"), Bytes.toBytes("myValue"));
          puts.add(p);
          table.put(puts);
        } catch (IOException e) {
        }
      }
    }.start();

    new Thread() {
      @Override
      public void run() {
        try {
          HTable table = new HTable(conf, userTableName);
          List<Put> puts = new ArrayList<Put>(5);
          Put p = new Put("row6".getBytes());
          p.add(Bytes.toBytes("col1"), Bytes.toBytes("ql1"), Bytes.toBytes("myValue"));
          puts.add(p);
          p = new Put("row7".getBytes());
          p.add(Bytes.toBytes("col1"), Bytes.toBytes("ql1"), Bytes.toBytes("myValue"));
          puts.add(p);
          p = new Put("row3".getBytes());
          p.add(Bytes.toBytes("col1"), Bytes.toBytes("ql1"), Bytes.toBytes("myValue"));
          puts.add(p);
          p = new Put("row4".getBytes());
          p.add(Bytes.toBytes("col1"), Bytes.toBytes("ql1"), Bytes.toBytes("myValue"));
          puts.add(p);
          p = new Put("row10".getBytes());
          p.add(Bytes.toBytes("col1"), Bytes.toBytes("ql1"), Bytes.toBytes("myValue"));
          puts.add(p);
          table.put(puts);
        } catch (IOException e) {
        }
      }
    }.start();
    Thread.sleep(2000);
    int i = countNumberOfRows(userTableName);
    Assert.assertEquals(8, i);
    i = countNumberOfRows(userTableName + Constants.INDEX_TABLE_SUFFIX);
    Assert.assertEquals(8, i);

  }

  @Test(timeout = 180000)
  public void testIndexPutRowkeyWithAllTheValues() throws IOException {
    String DIR = UTIL.getDataTestDir("TestStore").toString();
    Path basedir = new Path(DIR + "TestIndexPut");
    // Path logdir = new Path(DIR+"TestIndexPut"+"/logs");
    FileSystem fs = UTIL.getTestFileSystem();
    Configuration conf = UTIL.getConfiguration();
    HTableDescriptor htd = new HTableDescriptor("TestIndexPut");
    HRegionInfo info = new HRegionInfo(htd.getName(), "A".getBytes(), "B".getBytes(), false);
    HLog hlog = UTIL.getMiniHBaseCluster().getRegionServer(0).getWAL();
    HRegion region = new HRegion(basedir, hlog, fs, conf, info, htd, null);
    IndexSpecification spec = new IndexSpecification("testSpec");
    spec.addIndexColumn(new HColumnDescriptor("cf1"), "ql1", ValueType.String, 10);
    spec.addIndexColumn(new HColumnDescriptor("cf2"), "ql1", ValueType.String, 10);

    // Scenario where both the indexed cols are there in the put
    byte[] rowKey = "Arow1".getBytes();
    Put p = new Put(rowKey);
    long time = 1234567;
    p.add("cf1".getBytes(), "ql1".getBytes(), time, "testvalue1".getBytes());
    p.add("cf2".getBytes(), "ql1".getBytes(), time + 10, "testvalue1".getBytes());
    Put indexPut = IndexUtils.prepareIndexPut(p, spec, region);
    Assert.assertEquals(region.getStartKey().length + 1 + Constants.DEF_MAX_INDEX_NAME_LENGTH + 2
        * 10 + rowKey.length, indexPut.getRow().length);
    Assert.assertEquals(time + 10, indexPut.get(Constants.IDX_COL_FAMILY, "".getBytes()).get(0)
        .getTimestamp());

  }

  @Test(timeout = 180000)
  public void testIndexPutWithOnlyOneValue() throws IOException {
    String DIR = UTIL.getDataTestDir("TestStore").toString();
    Path basedir = new Path(DIR + "TestIndexPut");
    // Path logdir = new Path(DIR+"TestIndexPut"+"/logs");
    FileSystem fs = UTIL.getTestFileSystem();
    Configuration conf = UTIL.getConfiguration();
    HTableDescriptor htd = new HTableDescriptor("TestIndexPut");
    HRegionInfo info = new HRegionInfo(htd.getName(), "A".getBytes(), "B".getBytes(), false);
    HLog hlog = UTIL.getMiniHBaseCluster().getRegionServer(0).getWAL();
    HRegion region = new HRegion(basedir, hlog, fs, conf, info, htd, null);
    IndexSpecification spec = new IndexSpecification("testSpec");
    spec.addIndexColumn(new HColumnDescriptor("cf1"), "ql1", ValueType.String, 10);
    spec.addIndexColumn(new HColumnDescriptor("cf2"), "ql1", ValueType.String, 10);

    byte[] rowKey = "Arow1".getBytes();
    Put p = new Put(rowKey);
    long time = 1234567;
    p.add("cf1".getBytes(), "ql1".getBytes(), time, "testvalue1".getBytes());
    Put indexPut = IndexUtils.prepareIndexPut(p, spec, region);
    Assert.assertEquals(region.getStartKey().length + 1 + Constants.DEF_MAX_INDEX_NAME_LENGTH + 2
        * 10 + rowKey.length, indexPut.getRow().length);
    Assert.assertEquals(time, indexPut.get(Constants.IDX_COL_FAMILY, "".getBytes()).get(0)
        .getTimestamp());
    // asserting pad........this has to be hardcoded.
    byte[] pad = new byte[10];
    System.arraycopy(indexPut.getRow(), region.getStartKey().length + 1
        + Constants.DEF_MAX_INDEX_NAME_LENGTH + 10, pad, 0, 10);
    Assert.assertTrue(Bytes.equals(pad, new byte[10]));
  }

  @Test(timeout = 180000)
  public void testIndexPutWithValueGreaterThanLength() throws IOException {
    String DIR = UTIL.getDataTestDir("TestStore").toString();
    Path basedir = new Path(DIR + "TestIndexPut");
    // Path logdir = new Path(DIR+"TestIndexPut"+"/logs");
    FileSystem fs = UTIL.getTestFileSystem();
    Configuration conf = UTIL.getConfiguration();
    HTableDescriptor htd = new HTableDescriptor("TestIndexPut");
    HRegionInfo info = new HRegionInfo(htd.getName(), "A".getBytes(), "B".getBytes(), false);
    HLog hlog = UTIL.getMiniHBaseCluster().getRegionServer(0).getWAL();
    HRegion region = new HRegion(basedir, hlog, fs, conf, info, htd, null);
    IndexSpecification spec = new IndexSpecification("testSpec");
    spec.addIndexColumn(new HColumnDescriptor("cf1"), "ql1", ValueType.String, 10);
    spec.addIndexColumn(new HColumnDescriptor("cf2"), "ql1", ValueType.String, 10);

    // assert IOException when value length goes beyond the limit.
    byte[] rowKey = "Arow1".getBytes();
    Put p = new Put(rowKey);
    long time = 1234567;
    boolean returnVal = false;
    try {
      p.add("cf1".getBytes(), "ql1".getBytes(), time, "testvalue11".getBytes());
      IndexUtils.prepareIndexPut(p, spec, region);
    } catch (IOException e) {
      returnVal = true;
    }
    Assert.assertTrue(returnVal);
  }

  @Test(timeout = 180000)
  public void testIndexPutSequence() throws IOException {
    String DIR = UTIL.getDataTestDir("TestStore").toString();
    Path basedir = new Path(DIR + "TestIndexPut");
    // Path logdir = new Path(DIR+"TestIndexPut"+"/logs");
    FileSystem fs = UTIL.getTestFileSystem();
    Configuration conf = UTIL.getConfiguration();
    HTableDescriptor htd = new HTableDescriptor("TestIndexPut");
    HRegionInfo info = new HRegionInfo(htd.getName(), "A".getBytes(), "B".getBytes(), false);
    HLog hlog = UTIL.getMiniHBaseCluster().getRegionServer(0).getWAL();
    HRegion region = new HRegion(basedir, hlog, fs, conf, info, htd, null);
    IndexSpecification spec = new IndexSpecification("index");
    spec.addIndexColumn(new HColumnDescriptor("cf1"), "ql1", ValueType.String, 10);
    spec.addIndexColumn(new HColumnDescriptor("cf2"), "ql1", ValueType.String, 10);

    // scenario where same indexName but diff colvalues can disturb the order if
    // used without pad
    byte[] rowKey = "Arow1".getBytes();
    Put p1 = new Put(rowKey);
    long time = 1234567;
    p1.add("cf1".getBytes(), "ql1".getBytes(), time, "testcase".getBytes());
    p1.add("cf2".getBytes(), "ql1".getBytes(), time, "value".getBytes());
    Put indexPut1 = IndexUtils.prepareIndexPut(p1, spec, region);
    Put p2 = new Put(rowKey);
    p2.add("cf1".getBytes(), "ql1".getBytes(), time, "test".getBytes());
    p2.add("cf2".getBytes(), "ql1".getBytes(), time, "value".getBytes());
    Put indexPut2 = IndexUtils.prepareIndexPut(p2, spec, region);
    // (spaces just for easier reading...not present in actual)
    // Index Row key For p1 = "A index testcase value Arow1"
    // Index Row key For p2 = "A index test value Arow1"
    // NOW acc. to the lexographical ordering p2 should come second but we need
    // it to come 1st datz where pad is needed.
    byte[] rowKey1 = indexPut1.getRow();
    byte[] rowKey2 = indexPut2.getRow();

    int result = Bytes.compareTo(rowKey1, rowKey2);
    Assert.assertTrue(result > 0);

    // scenario where the index names are diff and padding is needed.
    IndexSpecification spec1 = new IndexSpecification("ind");
    spec1.addIndexColumn(new HColumnDescriptor("cf3"), "ql1", ValueType.String, 10);
    p1 = new Put(rowKey);
    p1.add("cf3".getBytes(), "ql1".getBytes(), time, "testcase".getBytes());
    indexPut1 = IndexUtils.prepareIndexPut(p1, spec1, region);
    // (spaces just for easier reading...not present in actual)
    // Index Row key For p1 = "A ind testcase value Arow1"
    // Index Row key For p2 = "A index test value Arow1"
    // NOW acc. to the lexographical ordering p1 should come second but we need
    // it to come 1st datz where pad is needed.
    rowKey1 = indexPut1.getRow();
    result = Bytes.compareTo(rowKey1, rowKey2);
    Assert.assertTrue(result < 0);

  }

  @Test(timeout = 180000)
  public void testIndexTableValue() throws IOException {
    String DIR = UTIL.getDataTestDir("TestStore").toString();
    Path basedir = new Path(DIR + "TestIndexPut");
    // Path logdir = new Path(DIR+"TestIndexPut"+"/logs");
    FileSystem fs = UTIL.getTestFileSystem();
    Configuration conf = UTIL.getConfiguration();
    HTableDescriptor htd = new HTableDescriptor("TestIndexPut");
    HRegionInfo info = new HRegionInfo(htd.getName(), "ABC".getBytes(), "BBB".getBytes(), false);
    HLog hlog = UTIL.getMiniHBaseCluster().getRegionServer(0).getWAL();
    HRegion region = new HRegion(basedir, hlog, fs, conf, info, htd, null);
    IndexSpecification spec = new IndexSpecification("index");
    spec.addIndexColumn(new HColumnDescriptor("cf1"), "ql1", ValueType.String, 10);
    spec.addIndexColumn(new HColumnDescriptor("cf2"), "ql1", ValueType.String, 10);

    byte[] rowKey = "Arow1".getBytes();
    Put p1 = new Put(rowKey);
    long time = 1234567;
    p1.add("cf1".getBytes(), "ql1".getBytes(), time, "testcase".getBytes());
    p1.add("cf2".getBytes(), "ql1".getBytes(), time, "value".getBytes());
    Put indexPut1 = IndexUtils.prepareIndexPut(p1, spec, region);

    List<KeyValue> kvs = indexPut1.get(Constants.IDX_COL_FAMILY, "".getBytes());
    KeyValue kv = null;
    if (null != kvs) {
      kv = kvs.get(0);
    }
    byte[] val = kv.getValue();
    byte[] startKeyLengthInBytes = new byte[2];
    System.arraycopy(val, 0, startKeyLengthInBytes, 0, startKeyLengthInBytes.length);
    int startkeylen = (int) (Bytes.toShort(startKeyLengthInBytes));
    Assert.assertEquals(3, startkeylen);

    byte[] rowKeyOffset = new byte[2];
    System.arraycopy(val, startKeyLengthInBytes.length, rowKeyOffset, 0, rowKeyOffset.length);
    int rowKeyOffsetInt = Bytes.toShort(rowKeyOffset);
    Assert.assertEquals(42, rowKeyOffsetInt);
  }

  @Test(timeout = 180000)
  public void testIndexedRegionAfterSplitShouldReplaceStartKeyAndValue() throws IOException,
      KeeperException, InterruptedException {
    HBaseAdmin admin = UTIL.getHBaseAdmin();
    Configuration conf = UTIL.getConfiguration();
    conf.setBoolean("hbase.use.secondary.index", true);
    conf.setInt("hbase.regionserver.lease.period", 90000000);
    ZooKeeperWatcher zkw = HBaseTestingUtility.getZooKeeperWatcher(UTIL);
    String userTableName = "testIndexRegionSplit";
    IndexedHTableDescriptor ihtd = new IndexedHTableDescriptor(userTableName);
    HColumnDescriptor hcd = new HColumnDescriptor("col");
    IndexSpecification iSpec = new IndexSpecification("ScanIndexf");
    iSpec.addIndexColumn(new HColumnDescriptor("col"), "ql", ValueType.String, 10);
    ihtd.addFamily(hcd);
    ihtd.addIndex(iSpec);
    admin.createTable(ihtd);
    ZKAssign.blockUntilNoRIT(zkw);
    HTable table = new HTable(conf, userTableName);
    // test put with the indexed column
    for (int i = 0; i < 10; i++) {
      String row = "row" + i;
      Put p = new Put(row.getBytes());
      String val = "Val" + i;
      p.add("col".getBytes(), "ql".getBytes(), val.getBytes());
      table.put(p);
    }

    List<HRegionInfo> regionsOfTable =
        UTIL.getMiniHBaseCluster().getMaster().getAssignmentManager()
            .getRegionsOfTable(userTableName.getBytes());
    HRegionInfo hRegionInfo = regionsOfTable.get(0);
    hRegionInfo.getRegionName();
    HTable tableidx = new HTable(conf, userTableName + "_idx");
    Scan s = new Scan();
    int i = 0;
    ResultScanner scanner = table.getScanner(s);
    for (Result rr = scanner.next(); rr != null; rr = scanner.next()) {
      i++;
    }
    admin.split(hRegionInfo.getRegionName(), "row5".getBytes());
    Scan s1 = new Scan();
    int i1 = 0;
    String indexTable = userTableName + "_idx";
    List<HRegionInfo> mainTableRegions =
        UTIL.getMiniHBaseCluster().getMaster().getAssignmentManager()
            .getRegionsOfTable(userTableName.getBytes());

    List<HRegionInfo> indexTableRegions =
        UTIL.getMiniHBaseCluster().getMaster().getAssignmentManager()
            .getRegionsOfTable(indexTable.getBytes());
    while (mainTableRegions.size() != 2) {
      Thread.sleep(2000);
      mainTableRegions =
          UTIL.getMiniHBaseCluster().getMaster().getAssignmentManager()
              .getRegionsOfTable(userTableName.getBytes());
    }
    while (indexTableRegions.size() != 2) {
      Thread.sleep(2000);
      indexTableRegions =
          UTIL.getMiniHBaseCluster().getMaster().getAssignmentManager()
              .getRegionsOfTable(indexTable.getBytes());
    }
    Assert.assertEquals(2, mainTableRegions.size());
    Assert.assertEquals(2, indexTableRegions.size());
    ResultScanner scanner1 = tableidx.getScanner(s1);
    for (Result rr = scanner1.next(); rr != null; rr = scanner1.next()) {
      i1++;
    }
    Assert.assertEquals("count should be equal", i, i1);
  }

  @Test(timeout = 180000)
  public void
      testIndexedRegionAfterSplitShouldNotThrowExceptionIfThereAreNoSplitFilesForIndexedTable()
          throws IOException, KeeperException, InterruptedException {
    HBaseAdmin admin = UTIL.getHBaseAdmin();
    Configuration conf = UTIL.getConfiguration();
    conf.setBoolean("hbase.use.secondary.index", true);
    conf.setInt("hbase.regionserver.lease.period", 90000000);
    ZooKeeperWatcher zkw = HBaseTestingUtility.getZooKeeperWatcher(UTIL);
    String userTableName = "testIndexRegionSplit1";
    IndexedHTableDescriptor ihtd = new IndexedHTableDescriptor(userTableName);
    HColumnDescriptor hcd = new HColumnDescriptor("col");
    HColumnDescriptor hcd2 = new HColumnDescriptor("col2");
    IndexSpecification iSpec = new IndexSpecification("ScanIndexf");
    iSpec.addIndexColumn(hcd, "ql", ValueType.String, 10);
    ihtd.addFamily(hcd);
    ihtd.addFamily(hcd2);
    ihtd.addIndex(iSpec);
    admin.createTable(ihtd);
    ZKAssign.blockUntilNoRIT(zkw);
    HTable table = new HTable(conf, userTableName);
    // test put with the indexed column
    for (int i = 0; i < 10; i++) {
      String row = "row" + i;
      Put p = new Put(row.getBytes());
      String val = "Val" + i;
      p.add("col2".getBytes(), "ql".getBytes(), val.getBytes());
      table.put(p);
    }

    List<HRegionInfo> regionsOfTable =
        UTIL.getMiniHBaseCluster().getMaster().getAssignmentManager()
            .getRegionsOfTable(userTableName.getBytes());
    HRegionInfo hRegionInfo = regionsOfTable.get(0);
    HTable tableidx = new HTable(conf, userTableName + "_idx");
    Scan s = new Scan();
    int i = 0;
    ResultScanner scanner = table.getScanner(s);
    for (Result rr = scanner.next(); rr != null; rr = scanner.next()) {
      i++;
    }
    admin.split(hRegionInfo.getRegionName(), "row5".getBytes());
    Scan s1 = new Scan();
    int i1 = 0;
    String indexTable = userTableName + "_idx";
    List<HRegionInfo> mainTableRegions =
        UTIL.getMiniHBaseCluster().getMaster().getAssignmentManager()
            .getRegionsOfTable(userTableName.getBytes());

    List<HRegionInfo> indexTableRegions =
        UTIL.getMiniHBaseCluster().getMaster().getAssignmentManager()
            .getRegionsOfTable(indexTable.getBytes());
    while (mainTableRegions.size() != 2) {
      Thread.sleep(2000);
      mainTableRegions =
          UTIL.getMiniHBaseCluster().getMaster().getAssignmentManager()
              .getRegionsOfTable(userTableName.getBytes());
    }
    while (indexTableRegions.size() != 2) {
      Thread.sleep(2000);
      indexTableRegions =
          UTIL.getMiniHBaseCluster().getMaster().getAssignmentManager()
              .getRegionsOfTable(indexTable.getBytes());
    }
    Assert.assertEquals(2, mainTableRegions.size());
    Assert.assertEquals(2, indexTableRegions.size());
    Assert.assertEquals("Main table count shud be 10", 10, i);
    ResultScanner scanner1 = tableidx.getScanner(s1);
    for (Result rr = scanner1.next(); rr != null; rr = scanner1.next()) {
      i1++;
    }
    Assert.assertEquals("Index table count shud be 0", 0, i1);

    // Trying to put data for indexed col
    for (int k = 10; k < 20; k++) {
      String row = "row" + k;
      Put p = new Put(row.getBytes());
      String val = "Val" + k;
      p.add("col".getBytes(), "ql".getBytes(), val.getBytes());
      table.put(p);
    }
    int z = 0;
    Scan s2 = new Scan();
    ResultScanner scanner2 = tableidx.getScanner(s2);

    admin.flush(userTableName + "_idx");

    for (Result rr = scanner2.next(); rr != null; rr = scanner2.next()) {
      z++;
    }
    Assert.assertEquals("Index table count shud be now 10", 10, z);

    List<HRegionInfo> regionsOfTable1 =
        UTIL.getMiniHBaseCluster().getMaster().getAssignmentManager()
            .getRegionsOfTable(userTableName.getBytes());
    HRegionInfo hRegionInfo1 = regionsOfTable1.get(0);

    admin.split(hRegionInfo1.getRegionName(), "row3".getBytes());
    List<HRegionInfo> mainTableRegions1 =
        UTIL.getMiniHBaseCluster().getMaster().getAssignmentManager()
            .getRegionsOfTable(userTableName.getBytes());

    List<HRegionInfo> indexTableRegions1 =
        UTIL.getMiniHBaseCluster().getMaster().getAssignmentManager()
            .getRegionsOfTable(indexTable.getBytes());
    while (mainTableRegions1.size() != 3) {
      Thread.sleep(2000);
      mainTableRegions1 =
          UTIL.getMiniHBaseCluster().getMaster().getAssignmentManager()
              .getRegionsOfTable(userTableName.getBytes());
    }
    while (indexTableRegions1.size() != 3) {
      Thread.sleep(2000);
      indexTableRegions1 =
          UTIL.getMiniHBaseCluster().getMaster().getAssignmentManager()
              .getRegionsOfTable(indexTable.getBytes());
    }
    // It shud be 3 after one more split
    Assert.assertEquals(3, mainTableRegions1.size());
    Assert.assertEquals(3, indexTableRegions1.size());
    Scan s3 = new Scan();
    int a = 0;
    ResultScanner scanner3 = tableidx.getScanner(s3);
    for (Result rr = scanner3.next(); rr != null; rr = scanner3.next()) {
      a++;
    }
    int b = 0;
    Scan s4 = new Scan();
    ResultScanner scanner4 = table.getScanner(s4);
    for (Result rr = scanner4.next(); rr != null; rr = scanner4.next()) {
      b++;
    }
    // subracting 10 coz addtional 10 is for other col family which is not indexed
    Assert.assertEquals("count should be equal", a, b - 10);

  }

  @Test(timeout = 180000)
  public void testSeekToInIndexHalfStoreFileReaderShouldRetreiveClosestRowCorrectly()
      throws IOException, KeeperException, InterruptedException {
    HBaseAdmin admin = UTIL.getHBaseAdmin();
    Configuration conf = UTIL.getConfiguration();
    conf.setInt("hbase.regionserver.lease.period", 900000000);
    conf.setBoolean("hbase.use.secondary.index", true);
    ZooKeeperWatcher zkw = HBaseTestingUtility.getZooKeeperWatcher(UTIL);
    String userTableName = "testIndexSplitWithClosestRow";
    IndexedHTableDescriptor ihtd = new IndexedHTableDescriptor(userTableName);
    HColumnDescriptor hcd = new HColumnDescriptor("col");
    IndexSpecification iSpec = new IndexSpecification("ScanIndexf");
    iSpec.addIndexColumn(new HColumnDescriptor("col"), "ql", ValueType.String, 10);
    ihtd.addFamily(hcd);
    ihtd.addIndex(iSpec);
    admin.createTable(ihtd);
    ZKAssign.blockUntilNoRIT(zkw);
    HTable table = new HTable(conf, userTableName);
    // test put with the indexed column
    for (int i = 0; i <= 10; i++) {
      // Don't put row4 alone so that when getRowOrBefore for row4 is specifiesd row3 shud be
      // returned
      if (i != 4) {
        String row = "row" + i;
        Put p = new Put(row.getBytes());
        String val = "Val" + i;
        p.add("col".getBytes(), "ql".getBytes(), val.getBytes());
        table.put(p);
      }
    }
    List<HRegionInfo> regionsOfTable =
        UTIL.getMiniHBaseCluster().getMaster().getAssignmentManager()
            .getRegionsOfTable(userTableName.getBytes());
    HRegionInfo hRegionInfo = regionsOfTable.get(0);
    hRegionInfo.getRegionName();
    HTable tableidx = new HTable(conf, userTableName + "_idx");
    admin.split(hRegionInfo.getRegionName(), "row6".getBytes());
    String indexTable = userTableName + "_idx";
    List<HRegionInfo> mainTableRegions =
        UTIL.getMiniHBaseCluster().getMaster().getAssignmentManager()
            .getRegionsOfTable(userTableName.getBytes());

    List<HRegionInfo> indexTableRegions =
        UTIL.getMiniHBaseCluster().getMaster().getAssignmentManager()
            .getRegionsOfTable(indexTable.getBytes());
    while (mainTableRegions.size() != 2) {
      Thread.sleep(2000);
      mainTableRegions =
          UTIL.getMiniHBaseCluster().getMaster().getAssignmentManager()
              .getRegionsOfTable(userTableName.getBytes());
    }
    while (indexTableRegions.size() != 2) {
      Thread.sleep(2000);
      indexTableRegions =
          UTIL.getMiniHBaseCluster().getMaster().getAssignmentManager()
              .getRegionsOfTable(indexTable.getBytes());
    }
    Assert.assertEquals(2, mainTableRegions.size());
    Assert.assertEquals(2, indexTableRegions.size());
    Scan s1 = new Scan();
    ResultScanner scanner1 = tableidx.getScanner(s1);
    Result next = null;
    for (int i = 0; i < 6; i++) {
      next = scanner1.next();
    }
    String row1 = "row4";
    Put row4Put = new Put(row1.getBytes());
    String val = "Val4";
    row4Put.add("col".getBytes(), "ql".getBytes(), val.getBytes());

    byte[] row4 = row4Put.getRow();
    byte[] nextRow = next.getRow();
    byte[] replacedRow = new byte[nextRow.length];
    System.arraycopy(nextRow, 0, replacedRow, 0, nextRow.length);
    System.arraycopy(row4, 0, replacedRow, replacedRow.length - row4.length, row4.length);
    Result rowOrBefore = tableidx.getRowOrBefore(replacedRow, "d".getBytes());

    String expectedRow = "row3";
    Put p1 = new Put(expectedRow.getBytes());
    String actualStr = Bytes.toString(rowOrBefore.getRow());
    int lastIndexOf = actualStr.lastIndexOf("row3");
    Assert.assertEquals("SeekTo should return row3 as closestRowBefore",
      Bytes.toString(p1.getRow()), actualStr.substring(lastIndexOf, actualStr.length()));
  }

  @Test(timeout = 180000)
  public
      void
      testSeekToInIndexHalfStoreFileReaderShouldRetreiveClosestRowCorrectlyWhenRowIsNotFoundInMainTable()
          throws IOException, KeeperException, InterruptedException {
    HBaseAdmin admin = UTIL.getHBaseAdmin();
    Configuration conf = UTIL.getConfiguration();
    conf.setBoolean("hbase.use.secondary.index", true);
    ZooKeeperWatcher zkw = HBaseTestingUtility.getZooKeeperWatcher(UTIL);
    String userTableName = "testIndexSplitWithClosestRowNotInMainTable";
    IndexedHTableDescriptor ihtd = new IndexedHTableDescriptor(userTableName);
    HColumnDescriptor hcd = new HColumnDescriptor("col");
    IndexSpecification iSpec = new IndexSpecification("ScanIndexf");
    iSpec.addIndexColumn(new HColumnDescriptor("col"), "ql", ValueType.String, 10);
    ihtd.addFamily(hcd);
    ihtd.addIndex(iSpec);
    admin.createTable(ihtd);
    ZKAssign.blockUntilNoRIT(zkw);
    HTable table = new HTable(conf, userTableName);
    // test put with the indexed column
    for (int i = 0; i <= 10; i++) {
      // Don't put row8 alone so that when getRowOrBefore for row8 is specifiesd row7 shud be
      // returned
      if (i != 8) {
        String row = "row" + i;
        Put p = new Put(row.getBytes());
        String val = "Val" + i;
        p.add("col".getBytes(), "ql".getBytes(), val.getBytes());
        table.put(p);
      }
    }
    List<HRegionInfo> regionsOfTable =
        UTIL.getMiniHBaseCluster().getMaster().getAssignmentManager()
            .getRegionsOfTable(userTableName.getBytes());
    HRegionInfo hRegionInfo = regionsOfTable.get(0);
    hRegionInfo.getRegionName();
    HTable tableidx = new HTable(conf, userTableName + "_idx");
    admin.split(hRegionInfo.getRegionName(), "row4".getBytes());

    String indexTable = userTableName + "_idx";
    List<HRegionInfo> mainTableRegions =
        UTIL.getMiniHBaseCluster().getMaster().getAssignmentManager()
            .getRegionsOfTable(userTableName.getBytes());

    List<HRegionInfo> indexTableRegions =
        UTIL.getMiniHBaseCluster().getMaster().getAssignmentManager()
            .getRegionsOfTable(indexTable.getBytes());
    while (mainTableRegions.size() != 2) {
      Thread.sleep(2000);
      mainTableRegions =
          UTIL.getMiniHBaseCluster().getMaster().getAssignmentManager()
              .getRegionsOfTable(userTableName.getBytes());
    }
    while (indexTableRegions.size() != 2) {
      Thread.sleep(2000);
      indexTableRegions =
          UTIL.getMiniHBaseCluster().getMaster().getAssignmentManager()
              .getRegionsOfTable(indexTable.getBytes());
    }
    Assert.assertEquals(2, mainTableRegions.size());
    Assert.assertEquals(2, indexTableRegions.size());

    Scan s1 = new Scan();
    ResultScanner scanner1 = tableidx.getScanner(s1);
    Result next1 = null;
    Thread.sleep(3000);
    for (int i = 0; i < 10; i++) {
      next1 = scanner1.next();
    }
    String row1 = "row8";
    Put row4Put = new Put(row1.getBytes());
    String val = "Val8";
    row4Put.add("col".getBytes(), "ql".getBytes(), val.getBytes());
    byte[] row4 = row4Put.getRow();
    byte[] nextRow = next1.getRow();
    byte[] replacedRow = new byte[nextRow.length];
    System.arraycopy(nextRow, 0, replacedRow, 0, nextRow.length);
    System.arraycopy(row4, 0, replacedRow, replacedRow.length - row4.length, row4.length);
    Result rowOrBefore = tableidx.getRowOrBefore(replacedRow, "d".getBytes());

    String expectedRow = "row7";
    Put p1 = new Put(expectedRow.getBytes());
    String actualStr = Bytes.toString(rowOrBefore.getRow());
    int lastIndexOf = actualStr.lastIndexOf("row7");
    Assert.assertTrue("Expected row should have the start key replaced to split key ", Bytes
        .toString(rowOrBefore.getRow()).startsWith("row4"));
    Assert.assertEquals("SeekTo should return row7 as closestRowBefore and split is completed ",
      Bytes.toString(p1.getRow()), actualStr.substring(lastIndexOf, actualStr.length()));
  }

  @Test(timeout = 180000)
  public void testPutWithValueLengthMoreThanMaxValueLength() throws IOException, KeeperException,
      InterruptedException {
    HBaseAdmin admin = UTIL.getHBaseAdmin();
    Configuration conf = UTIL.getConfiguration();
    String userTableName = "testPutWithValueLengthMoreThanMaxValueLength";
    IndexedHTableDescriptor ihtd = new IndexedHTableDescriptor(userTableName);
    HColumnDescriptor hcd = new HColumnDescriptor("col");
    IndexSpecification iSpec1 = new IndexSpecification("Index1");
    iSpec1.addIndexColumn(hcd, "ql1", ValueType.String, 10);
    ihtd.addFamily(hcd);
    ihtd.addIndex(iSpec1);
    admin.createTable(ihtd);

    HTable table = new HTable(conf, userTableName);
    table.setAutoFlush(false);
    List<Put> putList = new ArrayList<Put>(3);
    putList.add(new Put("row1".getBytes()).add("col".getBytes(), "ql1".getBytes(),
      "valueLengthMoreThanMaxValueLength".getBytes()));
    putList.add(new Put("row2".getBytes()).add("col".getBytes(), "ql1".getBytes(),
      "myValue".getBytes()));
    putList.add(new Put("row3".getBytes()).add("col".getBytes(), "ql1".getBytes(),
      "myValue".getBytes()));
    table.put(putList);
    try {
      table.flushCommits();
    } catch (RetriesExhaustedWithDetailsException e) {
      // nothing to do.
    }
    Assert.assertEquals(1, table.getWriteBuffer().size());
  }

  @Test(timeout = 180000)
  public void testIfPrepareFailsFor2ndSplitShouldFailTheMainTableSplitAlso() throws Exception {
    HBaseAdmin admin = UTIL.getHBaseAdmin();
    Configuration conf = UTIL.getConfiguration();
    conf.setInt("hbase.regionserver.lease.period", 90000000);
    ZooKeeperWatcher zkw = HBaseTestingUtility.getZooKeeperWatcher(UTIL);
    String userTableName = "testPrepareFailForIdx";
    IndexedHTableDescriptor ihtd = new IndexedHTableDescriptor(userTableName);
    HColumnDescriptor hcd = new HColumnDescriptor("col");
    IndexSpecification iSpec = new IndexSpecification("ScanIndexf");
    iSpec.addIndexColumn(hcd, "ql", ValueType.String, 10);
    ihtd.addFamily(hcd);
    ihtd.addIndex(iSpec);
    admin.createTable(ihtd);
    ZKAssign.blockUntilNoRIT(zkw);
    HTable table = new HTable(conf, userTableName);
    // test put with the indexed column
    for (int i = 0; i < 10; i++) {
      String row = "row" + i;
      Put p = new Put(row.getBytes());
      String val = "Val" + i;
      p.add("col".getBytes(), "ql".getBytes(), val.getBytes());
      table.put(p);
    }
    List<HRegionInfo> regionsOfTable =
        UTIL.getMiniHBaseCluster().getMaster().getAssignmentManager()
            .getRegionsOfTable(userTableName.getBytes());
    HRegionInfo hRegionInfo = regionsOfTable.get(0);
    MockIndexRegionObserver.count++;
    admin.split(hRegionInfo.getRegionName(), "row5".getBytes());
    String indexTable = userTableName + "_idx";
    List<HRegionInfo> mainTableRegions =
        UTIL.getMiniHBaseCluster().getMaster().getAssignmentManager()
            .getRegionsOfTable(userTableName.getBytes());
    List<HRegionInfo> indexTableRegions =
        UTIL.getMiniHBaseCluster().getMaster().getAssignmentManager()
            .getRegionsOfTable(indexTable.getBytes());
    while (mainTableRegions.size() != 2) {
      Thread.sleep(2000);
      mainTableRegions =
          UTIL.getMiniHBaseCluster().getMaster().getAssignmentManager()
              .getRegionsOfTable(userTableName.getBytes());
    }
    while (indexTableRegions.size() != 2) {
      Thread.sleep(2000);
      indexTableRegions =
          UTIL.getMiniHBaseCluster().getMaster().getAssignmentManager()
              .getRegionsOfTable(indexTable.getBytes());
    }
    Assert.assertEquals(2, mainTableRegions.size());
    Assert.assertEquals(2, indexTableRegions.size());

    MockIndexRegionObserver.count++;
    List<HRegionInfo> regionsOfTable2 =
        UTIL.getMiniHBaseCluster().getMaster().getAssignmentManager()
            .getRegionsOfTable(userTableName.getBytes());
    HRegionInfo hRegionInfo1 = regionsOfTable2.get(0);
    admin.split(hRegionInfo1.getRegionName(), "row3".getBytes());
    List<HRegionInfo> mainTableRegions1 =
        UTIL.getMiniHBaseCluster().getMaster().getAssignmentManager()
            .getRegionsOfTable(userTableName.getBytes());
    List<HRegionInfo> indexTableRegions1 =
        UTIL.getMiniHBaseCluster().getMaster().getAssignmentManager()
            .getRegionsOfTable(indexTable.getBytes());
    Assert.assertEquals(2, mainTableRegions1.size());
    Assert.assertEquals(2, indexTableRegions1.size());
  }

  public static class MockIndexRegionObserver extends IndexRegionObserver {
    static int count = 0;
    static boolean isnullIndexRegion = false;

    public SplitInfo preSplitBeforePONR(ObserverContext<RegionCoprocessorEnvironment> e,
        byte[] splitKey) throws IOException {
      if (e.getEnvironment().getRegion().getRegionInfo().getTableNameAsString()
          .equals("testIndexManagerWithFailedSplitOfIndexRegion")) {
        throw new IOException();
      }
      if (isnullIndexRegion) {
        return null;
      }
      if (count == 2) {
        splitThreadLocal.remove();
        return null;
      } else {
        return super.preSplitBeforePONR(e, splitKey);
      }
    }

    @Override
    public void preSplit(ObserverContext<RegionCoprocessorEnvironment> e) throws IOException {
      super.preSplit(e);
    }
  }

  @Test(timeout = 180000)
  public void testShouldNotSplitIfIndexRegionIsNullForIndexTable() throws Exception {
    HBaseAdmin admin = UTIL.getHBaseAdmin();
    Configuration conf = UTIL.getConfiguration();
    conf.setBoolean("hbase.use.secondary.index", true);
    conf.setInt("hbase.regionserver.lease.period", 90000000);
    ZooKeeperWatcher zkw = HBaseTestingUtility.getZooKeeperWatcher(UTIL);
    String userTableName = "testIndexRegionSplit12";
    IndexedHTableDescriptor ihtd = new IndexedHTableDescriptor(userTableName);
    HColumnDescriptor hcd = new HColumnDescriptor("col");
    IndexSpecification iSpec = new IndexSpecification("ScanIndexf");
    iSpec.addIndexColumn(hcd, "ql", ValueType.String, 10);
    ihtd.addFamily(hcd);
    ihtd.addIndex(iSpec);
    admin.createTable(ihtd);
    ZKAssign.blockUntilNoRIT(zkw);
    HTable table = new HTable(conf, userTableName);
    // test put with the indexed column
    for (int i = 0; i < 10; i++) {
      String row = "row" + i;
      Put p = new Put(row.getBytes());
      String val = "Val" + i;
      p.add("col".getBytes(), "ql".getBytes(), val.getBytes());
      table.put(p);
    }
    List<HRegionInfo> regionsOfTable =
        UTIL.getMiniHBaseCluster().getMaster().getAssignmentManager()
            .getRegionsOfTable(userTableName.getBytes());
    HRegionInfo hRegionInfo = regionsOfTable.get(0);
    MockIndexRegionObserver.isnullIndexRegion = true;
    admin.split(hRegionInfo.getRegionName(), "row5".getBytes());
    List<HRegionInfo> mainTableRegions =
        UTIL.getMiniHBaseCluster().getMaster().getAssignmentManager()
            .getRegionsOfTable(userTableName.getBytes());
    String indexTable = userTableName + "_idx";
    List<HRegionInfo> indexTableRegions =
        UTIL.getMiniHBaseCluster().getMaster().getAssignmentManager()
            .getRegionsOfTable(indexTable.getBytes());
    Assert.assertEquals(1, mainTableRegions.size());
    Assert.assertEquals(1, indexTableRegions.size());
  }

  @Test(timeout = 180000)
  public void testCheckAndPutFor1PutShouldHav2PutsInIndexTableAndShouldReplaceWithNewValue()
      throws Exception {
    HBaseAdmin admin = UTIL.getHBaseAdmin();
    ZooKeeperWatcher zkw = HBaseTestingUtility.getZooKeeperWatcher(UTIL);
    Configuration conf = UTIL.getConfiguration();
    String userTableName = "testCheckAndPutContainingTheIndexedColumn";
    IndexedHTableDescriptor ihtd = new IndexedHTableDescriptor(userTableName);
    HColumnDescriptor hcd = new HColumnDescriptor("col");
    IndexSpecification iSpec = new IndexSpecification("Index1");
    iSpec.addIndexColumn(hcd, "q1", ValueType.String, 10);
    ihtd.addFamily(hcd);
    ihtd.addIndex(iSpec);
    admin.createTable(ihtd);
    ZKAssign.blockUntilNoRIT(zkw);
    String idxTableName = userTableName + Constants.INDEX_TABLE_SUFFIX;
    HTable table = new HTable(conf, userTableName);
    // test put with the indexed column
    Put p = new Put("row1".getBytes());
    p.add("col".getBytes(), "q1".getBytes(), "myValue".getBytes());
    table.put(p);

    int usertableCount = countNumberOfRows(userTableName);
    Assert.assertEquals(1, usertableCount);
    int idxtableCount = countNumberOfRows(idxTableName);
    Assert.assertEquals(1, idxtableCount);

    // Test check and put
    Put p1 = new Put("row1".getBytes());
    p1.add("col".getBytes(), "q1".getBytes(), "myNewValue".getBytes());
    Assert.assertTrue(table.checkAndPut("row1".getBytes(), "col".getBytes(), "q1".getBytes(),
      "myValue".getBytes(), p1));
    usertableCount = countNumberOfRows(userTableName);
    Assert.assertEquals(1, usertableCount);
    idxtableCount = countNumberOfRows(idxTableName);
    Assert.assertEquals(2, idxtableCount);

    Get get = new Get("row1".getBytes());
    get.addColumn(Bytes.toBytes("col"), Bytes.toBytes("q1"));
    Result result = table.get(get);
    byte[] val = result.getValue(Bytes.toBytes("col"), Bytes.toBytes("q1"));
    Assert.assertEquals("myNewValue", Bytes.toString(val));
  }

  @Test(timeout = 180000)
  public void testCheckAndPutAndNormalPutInParallel() throws Exception {
    HBaseAdmin admin = UTIL.getHBaseAdmin();
    ZooKeeperWatcher zkw = HBaseTestingUtility.getZooKeeperWatcher(UTIL);
    Configuration conf = UTIL.getConfiguration();
    String userTableName = "testCheckAndPutAndNormalPutInParallel";
    IndexedHTableDescriptor ihtd = new IndexedHTableDescriptor(userTableName);
    HColumnDescriptor hcd = new HColumnDescriptor("col");
    IndexSpecification iSpec = new IndexSpecification("Index1");
    iSpec.addIndexColumn(hcd, "q1", ValueType.String, 10);
    ihtd.addFamily(hcd);
    ihtd.addIndex(iSpec);
    admin.createTable(ihtd);
    ZKAssign.blockUntilNoRIT(zkw);
    String idxTableName = userTableName + Constants.INDEX_TABLE_SUFFIX;
    final HTable table = new HTable(conf, userTableName);
    // test put with the indexed column
    Put p = new Put("row1".getBytes());
    p.add("col".getBytes(), "q1".getBytes(), "myValue".getBytes());
    table.put(p);

    int usertableCount = countNumberOfRows(userTableName);
    Assert.assertEquals(1, usertableCount);
    int idxtableCount = countNumberOfRows(idxTableName);
    Assert.assertEquals(1, idxtableCount);

    // Test check and put
    Put p1 = new Put("row1".getBytes());
    p1.add("col".getBytes(), "q1".getBytes(), "myNewValue".getBytes());
    Assert.assertTrue(table.checkAndPut("row1".getBytes(), "col".getBytes(), "q1".getBytes(),
      "myValue".getBytes(), p1));
    new Thread() {
      public void run() {
        Put p = new Put("row1".getBytes());
        p.add("col".getBytes(), "q1".getBytes(), "myValue1".getBytes());
        try {
          table.put(p);
        } catch (IOException e) {
          e.printStackTrace();
        }
      }
    }.start();
    Thread.sleep(3000);
    usertableCount = countNumberOfRows(userTableName);
    Assert.assertEquals(1, usertableCount);
    idxtableCount = countNumberOfRows(idxTableName);
    Assert.assertEquals(3, idxtableCount);

  }

  @Test(timeout = 180000)
  public void testCheckAndDeleteShudDeleteTheRowSuccessfullyInBothIndexAndMainTable()
      throws Exception {
    HBaseAdmin admin = UTIL.getHBaseAdmin();
    ZooKeeperWatcher zkw = HBaseTestingUtility.getZooKeeperWatcher(UTIL);
    Configuration conf = UTIL.getConfiguration();
    String userTableName = "testCheckAndDeleteContainingTheIndexedColumn";
    IndexedHTableDescriptor ihtd = new IndexedHTableDescriptor(userTableName);
    HColumnDescriptor hcd = new HColumnDescriptor("col");
    IndexSpecification iSpec = new IndexSpecification("Index1");
    iSpec.addIndexColumn(hcd, "q1", ValueType.String, 10);
    ihtd.addFamily(hcd);
    ihtd.addIndex(iSpec);
    admin.createTable(ihtd);
    ZKAssign.blockUntilNoRIT(zkw);
    String idxTableName = userTableName + Constants.INDEX_TABLE_SUFFIX;
    HTable table = new HTable(conf, userTableName);
    // test put with the indexed column
    Put p = new Put("row1".getBytes());
    p.add("col".getBytes(), "q1".getBytes(), "myValue".getBytes());
    table.put(p);

    int usertableCount = countNumberOfRows(userTableName);
    Assert.assertEquals(1, usertableCount);
    int idxtableCount = countNumberOfRows(idxTableName);
    Assert.assertEquals(1, idxtableCount);

    Delete delete = new Delete("row1".getBytes());
    delete.deleteFamily("col".getBytes());
    // CheckandDelete
    Assert.assertTrue(table.checkAndDelete("row1".getBytes(), "col".getBytes(), "q1".getBytes(),
      "myValue".getBytes(), delete));

    Get get = new Get("row1".getBytes());
    get.addFamily("col".getBytes());
    Result r = table.get(get);
    Assert.assertEquals(0, r.size());

    usertableCount = countNumberOfRows(userTableName);
    Assert.assertEquals(0, usertableCount);
    idxtableCount = countNumberOfRows(idxTableName);
    Assert.assertEquals(0, idxtableCount);
  }

  @Test(timeout = 180000)
  public void testRowMutations() throws Exception {
    HBaseAdmin admin = UTIL.getHBaseAdmin();
    ZooKeeperWatcher zkw = HBaseTestingUtility.getZooKeeperWatcher(UTIL);
    Configuration conf = UTIL.getConfiguration();
    String userTableName = "testMutateRows";
    IndexedHTableDescriptor ihtd = new IndexedHTableDescriptor(userTableName);
    HColumnDescriptor hcd = new HColumnDescriptor("col");
    IndexSpecification iSpec = new IndexSpecification("Index1");
    iSpec.addIndexColumn(hcd, "q1", ValueType.String, 10);
    iSpec.addIndexColumn(hcd, "q2", ValueType.String, 10);
    ihtd.addFamily(hcd);
    ihtd.addIndex(iSpec);
    admin.createTable(ihtd);
    ZKAssign.blockUntilNoRIT(zkw);
    String idxTableName = userTableName + Constants.INDEX_TABLE_SUFFIX;
    HTable table = new HTable(conf, userTableName);
    HTable idxtable = new HTable(conf, idxTableName);
    byte[] row = Bytes.toBytes("rowA");

    Put put = new Put(row);
    put.add("col".getBytes(), "q2".getBytes(), "delValue".getBytes());
    table.put(put);

    int usertableCount = countNumberOfRows(userTableName);
    Assert.assertEquals(1, usertableCount);
    int idxtableCount = countNumberOfRows(idxTableName);
    Assert.assertEquals(1, idxtableCount);

    RowMutations rm = new RowMutations(row);
    Put p = new Put(row);
    p.add("col".getBytes(), "q1".getBytes(), "q1value".getBytes());
    rm.add(p);
    Delete d = new Delete(row);
    d.deleteColumns("col".getBytes(), "q2".getBytes());
    rm.add(d);

    // Mutate rows
    table.mutateRow(rm);

    admin.flush(userTableName);
    admin.majorCompact(userTableName);
    // Now after one put and one delete it shud be 1
    usertableCount = countNumberOfRows(userTableName);
    Assert.assertEquals(1, usertableCount);

    int idxTableCount = countNumberOfRows(idxTableName);
    Assert.assertEquals(1, idxTableCount);

    Get get = new Get(row);
    get.addFamily("col".getBytes());
    Result r = table.get(get);
    Assert.assertEquals(1, r.size());

    String del = Bytes.toString(r.getValue("col".getBytes(), "q2".getBytes()));
    Assert.assertNull(del);
    String putval = Bytes.toString(r.getValue("col".getBytes(), "q1".getBytes()));
    Assert.assertEquals("q1value", putval);

    // Result of index table shud contain one keyvalue for "q1value" put only
    Scan s = new Scan();
    ResultScanner scanner = idxtable.getScanner(s);
    Result result = scanner.next();
    Assert.assertEquals(1, result.size());

    String idxRow = Bytes.toString(result.getRow());
    int len = IndexUtils.getMaxIndexNameLength() + "q1value".length();
    String value = idxRow.substring(IndexUtils.getMaxIndexNameLength() + 1, len + 1);
    // asserting value in idx table is for the put which has the value "q1value"
    Assert.assertEquals("q1value", value);
  }

  @Test(timeout = 180000)
  public void testWithPutsAndDeletesAfterSplitShouldRetreiveTheRowsCorrectly() throws Exception {
    HBaseAdmin admin = UTIL.getHBaseAdmin();
    Configuration conf = UTIL.getConfiguration();
    conf.setInt("hbase.regionserver.lease.period", 900000000);
    conf.setBoolean("hbase.use.secondary.index", true);
    ZooKeeperWatcher zkw = HBaseTestingUtility.getZooKeeperWatcher(UTIL);
    String userTableName = "testPutsAndDeletes";
    IndexedHTableDescriptor ihtd = new IndexedHTableDescriptor(userTableName);
    HColumnDescriptor hcd = new HColumnDescriptor("col");
    IndexSpecification iSpec = new IndexSpecification("ScanIndexf");
    iSpec.addIndexColumn(new HColumnDescriptor("col"), "ql", ValueType.String, 10);
    ihtd.addFamily(hcd);
    ihtd.addIndex(iSpec);
    admin.createTable(ihtd);
    ZKAssign.blockUntilNoRIT(zkw);
    HTable table = new HTable(conf, userTableName);
    // test put with the indexed column
    for (int i = 0; i <= 5; i++) {
      String row = "row" + i;
      Put p = new Put(row.getBytes());
      String val = "Val" + i;
      p.add("col".getBytes(), "ql".getBytes(), val.getBytes());
      table.put(p);
      admin.flush(userTableName);
      admin.flush(userTableName + "_idx");

      if (i < 3) {
        Delete d = new Delete(row.getBytes());
        // Do a normal delete
        table.delete(d);
      } else {
        if (i > 4) {
          Delete d = new Delete(row.getBytes());
          // Do column family delete
          d.deleteFamily("col".getBytes());
          table.delete(d);
        } else {
          Delete d = new Delete(row.getBytes());
          // Do delete column
          d.deleteColumn("col".getBytes(), "ql".getBytes());
          table.delete(d);
        }
      }
      admin.flush(userTableName);
      admin.flush(userTableName + "_idx");
    }
    List<HRegionInfo> regionsOfTable =
        UTIL.getMiniHBaseCluster().getMaster().getAssignmentManager()
            .getRegionsOfTable(userTableName.getBytes());
    HRegionInfo hRegionInfo = regionsOfTable.get(0);
    hRegionInfo.getRegionName();
    HTable tableidx = new HTable(conf, userTableName + "_idx");
    admin.split(hRegionInfo.getRegionName(), "row5".getBytes());
    String indexTable = userTableName + "_idx";
    List<HRegionInfo> mainTableRegions =
        UTIL.getMiniHBaseCluster().getMaster().getAssignmentManager()
            .getRegionsOfTable(userTableName.getBytes());

    List<HRegionInfo> indexTableRegions =
        UTIL.getMiniHBaseCluster().getMaster().getAssignmentManager()
            .getRegionsOfTable(indexTable.getBytes());
    while (mainTableRegions.size() != 2) {
      Thread.sleep(2000);
      mainTableRegions =
          UTIL.getMiniHBaseCluster().getMaster().getAssignmentManager()
              .getRegionsOfTable(userTableName.getBytes());
    }
    while (indexTableRegions.size() != 2) {
      Thread.sleep(2000);
      indexTableRegions =
          UTIL.getMiniHBaseCluster().getMaster().getAssignmentManager()
              .getRegionsOfTable(indexTable.getBytes());
    }
    Assert.assertEquals(2, mainTableRegions.size());
    Assert.assertEquals(2, indexTableRegions.size());
    Scan s = new Scan();
    ResultScanner scanner = table.getScanner(s);
    int mainTableCount = 0;
    for (Result rr = scanner.next(); rr != null; rr = scanner.next()) {
      mainTableCount++;
    }
    Assert.assertEquals(0, mainTableCount);
    Scan s1 = new Scan();
    ResultScanner scanner1 = tableidx.getScanner(s1);

    int indexTableCount = 0;
    for (Result rr = scanner1.next(); rr != null; rr = scanner1.next()) {
      indexTableCount++;
    }
    Assert.assertEquals(0, indexTableCount);

    Put p = new Put("row7".getBytes());
    String val = "Val" + "7";
    p.add("col".getBytes(), "ql".getBytes(), val.getBytes());
    table.put(p);
    Scan s2 = new Scan();
    ResultScanner scanner2 = table.getScanner(s2);
    for (Result rr = scanner2.next(); rr != null; rr = scanner2.next()) {
      mainTableCount++;
    }
    Scan s3 = new Scan();
    ResultScanner scanner3 = tableidx.getScanner(s3);
    for (Result rr = scanner3.next(); rr != null; rr = scanner3.next()) {
      indexTableCount++;
    }
    Assert.assertEquals(1, mainTableCount);
    Assert.assertEquals(1, indexTableCount);

  }

  @Test(timeout = 180000)
  public void test6PutsAnd3DeletesAfterSplitShouldRetreiveRowsSuccessfully() throws Exception {
    HBaseAdmin admin = UTIL.getHBaseAdmin();
    Configuration conf = UTIL.getConfiguration();
    conf.setInt("hbase.regionserver.lease.period", 900000000);
    conf.setBoolean("hbase.use.secondary.index", true);
    ZooKeeperWatcher zkw = HBaseTestingUtility.getZooKeeperWatcher(UTIL);
    String userTableName = "test6Puts3Deletes";
    IndexedHTableDescriptor ihtd = new IndexedHTableDescriptor(userTableName);
    HColumnDescriptor hcd = new HColumnDescriptor("col");
    IndexSpecification iSpec = new IndexSpecification("ScanIndexf");
    iSpec.addIndexColumn(new HColumnDescriptor("col"), "ql", ValueType.String, 10);
    ihtd.addFamily(hcd);
    ihtd.addIndex(iSpec);
    admin.createTable(ihtd);
    ZKAssign.blockUntilNoRIT(zkw);
    HTable table = new HTable(conf, userTableName);
    // test put with the indexed column
    for (int i = 0; i <= 5; i++) {
      String row = "row" + i;
      Put p = new Put(row.getBytes());
      String val = "Val" + i;
      p.add("col".getBytes(), "ql".getBytes(), val.getBytes());
      table.put(p);
      admin.flush(userTableName);
      admin.flush(userTableName + "_idx");
      if (i < 3) {
        Delete d = new Delete(row.getBytes());
        // Do a normal delete
        table.delete(d);
      }
      admin.flush(userTableName);
      admin.flush(userTableName + "_idx");
    }
    List<HRegionInfo> regionsOfTable =
        UTIL.getMiniHBaseCluster().getMaster().getAssignmentManager()
            .getRegionsOfTable(userTableName.getBytes());
    HRegionInfo hRegionInfo = regionsOfTable.get(0);
    hRegionInfo.getRegionName();

    HTable tableidx = new HTable(conf, userTableName + "_idx");
    admin.split(hRegionInfo.getRegionName(), "row5".getBytes());
    String indexTable = userTableName + "_idx";
    List<HRegionInfo> mainTableRegions =
        UTIL.getMiniHBaseCluster().getMaster().getAssignmentManager()
            .getRegionsOfTable(userTableName.getBytes());

    List<HRegionInfo> indexTableRegions =
        UTIL.getMiniHBaseCluster().getMaster().getAssignmentManager()
            .getRegionsOfTable(indexTable.getBytes());
    while (mainTableRegions.size() != 2) {
      Thread.sleep(2000);
      mainTableRegions =
          UTIL.getMiniHBaseCluster().getMaster().getAssignmentManager()
              .getRegionsOfTable(userTableName.getBytes());
    }
    while (indexTableRegions.size() != 2) {
      Thread.sleep(2000);
      indexTableRegions =
          UTIL.getMiniHBaseCluster().getMaster().getAssignmentManager()
              .getRegionsOfTable(indexTable.getBytes());
    }
    Assert.assertEquals(2, mainTableRegions.size());
    Assert.assertEquals(2, indexTableRegions.size());
    Scan s = new Scan();
    ResultScanner scanner = table.getScanner(s);
    int mainTableCount = 0;
    for (Result rr = scanner.next(); rr != null; rr = scanner.next()) {
      mainTableCount++;
    }
    Assert.assertEquals(3, mainTableCount);
    Scan s1 = new Scan();
    ResultScanner scanner1 = tableidx.getScanner(s1);

    int indexTableCount = 0;
    for (Result rr = scanner1.next(); rr != null; rr = scanner1.next()) {
      indexTableCount++;
    }
    Assert.assertEquals(3, indexTableCount);

  }

  @Test(timeout = 180000)
  public void testSplitForMainTableWithoutIndexShouldBeSuccessfUl() throws Exception {
    HBaseAdmin admin = UTIL.getHBaseAdmin();
    Configuration conf = UTIL.getConfiguration();
    conf.setInt("hbase.regionserver.lease.period", 900000000);
    conf.setBoolean("hbase.use.secondary.index", true);
    ZooKeeperWatcher zkw = HBaseTestingUtility.getZooKeeperWatcher(UTIL);
    String userTableName = "test6Puts3Deletes34534";
    HTableDescriptor ihtd = new HTableDescriptor(userTableName);
    HColumnDescriptor hcd = new HColumnDescriptor("col");
    ihtd.addFamily(hcd);
    admin.createTable(ihtd);
    ZKAssign.blockUntilNoRIT(zkw);
    HTable table = new HTable(conf, userTableName);

    for (int i = 0; i < 10; i++) {
      String row = "row" + i;
      Put p = new Put(row.getBytes());
      String val = "Val" + i;
      p.add("col".getBytes(), "ql".getBytes(), val.getBytes());
      table.put(p);
    }
    List<HRegionInfo> regionsOfTable =
        UTIL.getMiniHBaseCluster().getMaster().getAssignmentManager()
            .getRegionsOfTable(userTableName.getBytes());
    HRegionInfo hRegionInfo = regionsOfTable.get(0);
    hRegionInfo.getRegionName();
    admin.split(hRegionInfo.getRegionName(), "row5".getBytes());

    List<HRegionInfo> mainTableRegions =
        UTIL.getMiniHBaseCluster().getMaster().getAssignmentManager()
            .getRegionsOfTable(userTableName.getBytes());

    while (mainTableRegions.size() != 2) {
      Thread.sleep(2000);
      mainTableRegions =
          UTIL.getMiniHBaseCluster().getMaster().getAssignmentManager()
              .getRegionsOfTable(userTableName.getBytes());
    }
    for (int i = 20; i < 30; i++) {
      String row = "row" + i;
      Put p = new Put(row.getBytes());
      String val = "Val" + i;
      p.add("col".getBytes(), "ql".getBytes(), val.getBytes());
      table.put(p);
    }
    Scan s = new Scan();
    ResultScanner scanner = table.getScanner(s);
    int mainTableCount = 0;
    for (Result rr = scanner.next(); rr != null; rr = scanner.next()) {
      mainTableCount++;
    }
    Assert.assertEquals(20, mainTableCount);

  }

  @Test(timeout = 180000)
  public void testSplittingIndexRegionExplicitly() throws Exception {
    HBaseAdmin admin = UTIL.getHBaseAdmin();
    Configuration conf = UTIL.getConfiguration();
    conf.setInt("hbase.regionserver.lease.period", 900000000);
    conf.setBoolean("hbase.use.secondary.index", true);
    ZooKeeperWatcher zkw = HBaseTestingUtility.getZooKeeperWatcher(UTIL);
    String userTableName = "testSplitTransaction";
    String indexTableName = "testSplitTransaction_idx";
    IndexedHTableDescriptor ihtd = new IndexedHTableDescriptor(userTableName);
    HColumnDescriptor hcd = new HColumnDescriptor("col");
    IndexSpecification iSpec = new IndexSpecification("ScanIndexf");
    iSpec.addIndexColumn(new HColumnDescriptor("col"), "ql", ValueType.String, 10);
    ihtd.addFamily(hcd);
    ihtd.addIndex(iSpec);
    admin.createTable(ihtd);
    ZKAssign.blockUntilNoRIT(zkw);
    HTable table = new HTable(conf, userTableName);

    for (int i = 0; i < 10; i++) {
      String row = "row" + i;
      Put p = new Put(row.getBytes());
      String val = "Val" + i;
      p.add("col".getBytes(), "ql".getBytes(), val.getBytes());
      table.put(p);
    }

    List<HRegionInfo> regionsOfUserTable =
        UTIL.getMiniHBaseCluster().getMaster().getAssignmentManager()
            .getRegionsOfTable(userTableName.getBytes());

    List<HRegionInfo> regionsOfIndexTable =
        UTIL.getMiniHBaseCluster().getMaster().getAssignmentManager()
            .getRegionsOfTable(indexTableName.getBytes());

    // try splitting index.
    admin.split(indexTableName.getBytes());
    Thread.sleep(2000);
    regionsOfIndexTable =
        UTIL.getMiniHBaseCluster().getMaster().getAssignmentManager()
            .getRegionsOfTable(indexTableName.getBytes());
    Assert.assertEquals("Index table should not get splited", 1, regionsOfIndexTable.size());

    // try splitting the user region.
    admin.split(userTableName.getBytes(), "row5".getBytes());
    while (regionsOfUserTable.size() != 2) {
      Thread.sleep(2000);
      regionsOfUserTable =
          UTIL.getMiniHBaseCluster().getMaster().getAssignmentManager()
              .getRegionsOfTable(userTableName.getBytes());
    }
    while (regionsOfIndexTable.size() != 2) {
      Thread.sleep(2000);
      regionsOfIndexTable =
          UTIL.getMiniHBaseCluster().getMaster().getAssignmentManager()
              .getRegionsOfTable(indexTableName.getBytes());
    }
    Assert.assertEquals(2, regionsOfUserTable.size());
    Assert.assertEquals(2, regionsOfIndexTable.size());
  }

  @Test(timeout = 180000)
  public void testIndexManagerCleanUp() throws Exception {
    HBaseAdmin admin = new HBaseAdmin(UTIL.getConfiguration());
    Configuration conf = admin.getConfiguration();
    conf.setBoolean("hbase.use.secondary.index", true);
    ZooKeeperWatcher zkw = HBaseTestingUtility.getZooKeeperWatcher(UTIL);
    String userTableName = "testIndexManagerCleanUp";
    IndexedHTableDescriptor ihtd = new IndexedHTableDescriptor(userTableName);
    HColumnDescriptor hcd = new HColumnDescriptor("col1");
    ihtd.addFamily(hcd);
    IndexSpecification iSpec = new IndexSpecification("Index1");
    iSpec.addIndexColumn(hcd, "ql", ValueType.String, 10);
    ihtd.addIndex(iSpec);

    byte[][] splits = new byte[10][];
    char c = 'A';
    for (int i = 0; i < 10; i++) {
      byte[] b = { (byte) c };
      splits[i] = b;
      c++;
    }
    admin.createTable(ihtd, splits);
    ZKAssign.blockUntilNoRIT(zkw);
    IndexManager instance = IndexManager.getInstance();
    int regionCount = instance.getTableRegionCount(userTableName);
    Assert.assertEquals(11, regionCount);

    admin.disableTable(Bytes.toBytes(userTableName));
    ZKAssign.blockUntilNoRIT(zkw);
    regionCount = instance.getTableRegionCount(userTableName);
    Assert.assertEquals(0, regionCount);

    admin.enableTable(userTableName);
    ZKAssign.blockUntilNoRIT(zkw);
    regionCount = instance.getTableRegionCount(userTableName);
    Assert.assertEquals(11, regionCount);
  }

  @Test(timeout = 180000)
  public void testHDP2938() throws Exception {
    HBaseAdmin admin = new HBaseAdmin(UTIL.getConfiguration());
    ZooKeeperWatcher zkw = HBaseTestingUtility.getZooKeeperWatcher(UTIL);
    String userTableName = "testHDP2938";
    IndexedHTableDescriptor ihtd = new IndexedHTableDescriptor(userTableName);

    HColumnDescriptor hcd1 = new HColumnDescriptor("col1").setMaxVersions(Integer.MAX_VALUE);
    IndexSpecification iSpec = new IndexSpecification("ScanIndexf");
    iSpec.addIndexColumn(hcd1, "q2", ValueType.String, 10);
    ihtd.addFamily(hcd1);
    ihtd.addIndex(iSpec);
    admin.createTable(ihtd);
    ZKAssign.blockUntilNoRIT(zkw);

    admin.disableTable(userTableName);
    admin.deleteTable(userTableName);

    ihtd = new IndexedHTableDescriptor(userTableName);
    hcd1 =
        new HColumnDescriptor("col1").setMaxVersions(Integer.MAX_VALUE).setTimeToLive(
          TTL_SECONDS - 1);
    iSpec = new IndexSpecification("ScanIndexf");
    iSpec.addIndexColumn(hcd1, "q2", ValueType.String, 10);
    ihtd.addFamily(hcd1);
    ihtd.addIndex(iSpec);
    admin.createTable(ihtd);
    ZKAssign.blockUntilNoRIT(zkw);

    Configuration conf = UTIL.getConfiguration();
    HTable table = new HTable(conf, userTableName);

    // test put with the indexed column

    Put p = new Put("row1".getBytes());
    p.add("col1".getBytes(), "q2".getBytes(), Bytes.toBytes("ValForCF2"));
    table.put(p);
    admin.flush(userTableName + "_idx");

    Put p1 = new Put("row01".getBytes());
    p1.add("col1".getBytes(), "q2".getBytes(), Bytes.toBytes("ValForCF2"));
    table.put(p1);
    admin.flush(userTableName + "_idx");

    Put p2 = new Put("row010".getBytes());
    p2.add("col1".getBytes(), "q2".getBytes(), Bytes.toBytes("ValForCF2"));
    table.put(p2);
    admin.flush(userTableName + "_idx");

    Put p3 = new Put("row001".getBytes());
    p3.add("col1".getBytes(), "q2".getBytes(), Bytes.toBytes("ValForCF2"));
    table.put(p3);

    admin.flush(userTableName);
    admin.flush(userTableName + "_idx");

    HRegionServer regionServer = UTIL.getHBaseCluster().getRegionServer(0);
    List<HRegion> onlineRegions = regionServer.getOnlineRegions(Bytes.toBytes(userTableName));
    List<String> storeFileList =
        regionServer.getStoreFileList(onlineRegions.get(0).getRegionName());
    onlineRegions = regionServer.getOnlineRegions(Bytes.toBytes(userTableName + "_idx"));
    storeFileList = regionServer.getStoreFileList(onlineRegions.get(0).getRegionName());
    while (storeFileList.size() < 4) {
      Thread.sleep(1000);
      storeFileList = regionServer.getStoreFileList(onlineRegions.get(0).getRegionName());
    }
    int prevSize = storeFileList.size();
    Assert.assertEquals("The total store files for the index table should be 4", 4, prevSize);
    Scan s = new Scan();
    HTable indexTable = new HTable(conf, userTableName + "_idx");
    ResultScanner scanner = indexTable.getScanner(s);
    // Result res = scanner.next();
    for (Result result : scanner) {
      System.out.println(result);
    }
    for (String store : storeFileList) {
      Threads.sleepWithoutInterrupt(TTL_MS);
    }
    admin.compact(userTableName + "_idx");

    onlineRegions = regionServer.getOnlineRegions(Bytes.toBytes(userTableName + "_idx"));
    storeFileList = regionServer.getStoreFileList(onlineRegions.get(0).getRegionName());
    while (storeFileList.size() != 1) {
      Thread.sleep(1000);
      storeFileList = regionServer.getStoreFileList(onlineRegions.get(0).getRegionName());
    }
    Assert.assertEquals("The total store files for the index table should be 1", 1,
      storeFileList.size());
    s = new Scan();
    indexTable = new HTable(conf, userTableName + "_idx");
    scanner = indexTable.getScanner(s);
    // Result res = scanner.next();
    boolean dataAvailable = false;
    for (Result result : scanner) {
      dataAvailable = true;
      System.out.println(result);
    }
    Assert.assertFalse("dataShould not be retrieved", dataAvailable);
  }

  @Test(timeout = 180000)
  public void testIndexManagerWithSplitTransactions() throws Exception {
    HBaseAdmin admin = new HBaseAdmin(UTIL.getConfiguration());
    Configuration conf = admin.getConfiguration();
    conf.setBoolean("hbase.use.secondary.index", true);
    ZooKeeperWatcher zkw = HBaseTestingUtility.getZooKeeperWatcher(UTIL);
    String userTableName = "testIndexManagerWithSplitTransactions";
    IndexedHTableDescriptor ihtd = new IndexedHTableDescriptor(userTableName);
    HColumnDescriptor hcd = new HColumnDescriptor("col1");
    ihtd.addFamily(hcd);
    IndexSpecification iSpec = new IndexSpecification("Index1");
    iSpec.addIndexColumn(hcd, "ql", ValueType.String, 10);
    ihtd.addIndex(iSpec);
    admin.createTable(ihtd);
    ZKAssign.blockUntilNoRIT(zkw);

    IndexManager manager = IndexManager.getInstance();
    int count = manager.getTableRegionCount(userTableName);
    Assert.assertEquals(1, count);

    HTable table = new HTable(conf, userTableName);
    Put p = null;
    for (int i = 0; i < 10; i++) {
      p = new Put(Bytes.toBytes("row" + i));
      p.add(Bytes.toBytes("col1"), Bytes.toBytes("ql"), Bytes.toBytes("test_val"));
      table.put(p);
    }

    admin.split(userTableName, "row5");
    ZKAssign.blockUntilNoRIT(zkw);

    count = manager.getTableRegionCount(userTableName);
    Assert.assertEquals(2, count);
  }

  @Test(timeout = 180000)
  public void testIndexManagerWithFailedSplitOfIndexRegion() throws Exception {
    HBaseAdmin admin = new HBaseAdmin(UTIL.getConfiguration());
    Configuration conf = admin.getConfiguration();
    conf.setBoolean("hbase.use.secondary.index", true);
    ZooKeeperWatcher zkw = HBaseTestingUtility.getZooKeeperWatcher(UTIL);
    String userTableName = "testIndexManagerWithFailedSplitOfIndexRegion";
    IndexedHTableDescriptor ihtd = new IndexedHTableDescriptor(userTableName);
    HColumnDescriptor hcd = new HColumnDescriptor("col1");
    ihtd.addFamily(hcd);
    IndexSpecification iSpec = new IndexSpecification("Index1");
    iSpec.addIndexColumn(hcd, "ql", ValueType.String, 10);
    ihtd.addIndex(iSpec);
    admin.createTable(ihtd);
    ZKAssign.blockUntilNoRIT(zkw);

    IndexManager manager = IndexManager.getInstance();
    int count = manager.getTableRegionCount(userTableName);
    Assert.assertEquals(1, count);

    HTable table = new HTable(conf, userTableName);
    Put p = null;
    for (int i = 0; i < 10; i++) {
      p = new Put(Bytes.toBytes("row" + i));
      p.add(Bytes.toBytes("col1"), Bytes.toBytes("ql"), Bytes.toBytes("test_val"));
      table.put(p);
    }

    admin.split(userTableName);
    ZKAssign.blockUntilNoRIT(zkw);

    count = manager.getTableRegionCount(userTableName);
    Assert.assertEquals(1, count);
  }

  @Test(timeout = 180000)
  public void testIndexManagerWithFailedSplitTransaction() throws Exception {
    HBaseAdmin admin = new HBaseAdmin(UTIL.getConfiguration());
    Configuration conf = admin.getConfiguration();
    conf.setBoolean("hbase.use.secondary.index", true);
    ZooKeeperWatcher zkw = HBaseTestingUtility.getZooKeeperWatcher(UTIL);
    String userTableName = "testIndexManagerWithFailedSplitTransaction";
    IndexedHTableDescriptor ihtd = new IndexedHTableDescriptor(userTableName);
    HColumnDescriptor hcd = new HColumnDescriptor("col1");
    ihtd.addFamily(hcd);
    IndexSpecification iSpec = new IndexSpecification("Index1");
    iSpec.addIndexColumn(hcd, "ql", ValueType.String, 10);
    ihtd.addIndex(iSpec);
    admin.createTable(ihtd);
    ZKAssign.blockUntilNoRIT(zkw);

    IndexManager manager = IndexManager.getInstance();
    int count = manager.getTableRegionCount(userTableName);
    Assert.assertEquals(1, count);

    HTable table = new HTable(conf, userTableName);
    Put p = null;
    for (int i = 0; i < 10; i++) {
      p = new Put(Bytes.toBytes("row" + i));
      p.add(Bytes.toBytes("col1"), Bytes.toBytes("ql"), Bytes.toBytes("test_val"));
      table.put(p);
    }
    List<HRegion> regions = UTIL.getMiniHBaseCluster().getRegions(Bytes.toBytes(userTableName));
    HRegionServer rs = UTIL.getMiniHBaseCluster().getRegionServer(0);
    SplitTransaction st = null;

    st = new MockedSplitTransaction(regions.get(0), null) {
      @Override
      protected void splitStoreFiles(final Path splitdir, final List<StoreFile> hstoreFilesToSplit)
          throws IOException {
        throw new IOException();
      }
    };

    try {
      st.execute(rs, rs);
    } catch (IOException e) {
      st.rollback(rs, rs);
    }

    count = manager.getTableRegionCount(userTableName);
    Assert.assertEquals(1, count);
  }

  public static class MockedSplitTransaction extends SplitTransaction {

    public MockedSplitTransaction(HRegion r, byte[] splitrow) {
      super(r, splitrow);
    }
  }
}
TOP

Related Classes of org.apache.hadoop.hbase.index.coprocessor.regionserver.TestIndexRegionObserver

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.