diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/TestTooManyChunks.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/TestTooManyChunks.java new file mode 100644 index 0000000000..88022ba9f7 --- /dev/null +++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/TestTooManyChunks.java @@ -0,0 +1,109 @@ +/** + * 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.regionserver; + +import com.google.common.collect.Lists; +import java.util.List; +import org.apache.hadoop.hbase.HBaseClassTestRule; +import org.apache.hadoop.hbase.HBaseTestingUtility; +import org.apache.hadoop.hbase.HConstants; +import org.apache.hadoop.hbase.TableName; +import org.apache.hadoop.hbase.client.Put; +import org.apache.hadoop.hbase.testclassification.MediumTests; +import org.apache.hadoop.hbase.testclassification.RegionServerTests; +import org.apache.hadoop.util.StringUtils; +import org.junit.Assert; +import org.junit.BeforeClass; +import org.junit.ClassRule; +import org.junit.Test; +import org.junit.experimental.categories.Category; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + + +@Category({RegionServerTests.class, MediumTests.class}) +public class TestTooManyChunks { + + @ClassRule + public static final HBaseClassTestRule CLASS_RULE = + HBaseClassTestRule.forClass(TestTooManyChunks.class); + + private static final Logger LOG = LoggerFactory.getLogger(TestTooManyChunks.class); + + + private static HBaseTestingUtility TEST_UTIL; + private static final TableName TEST_TABLE = TableName.valueOf("MultiRegions"); + private static final byte[] FAMILY = "f".getBytes(); + private static int numRegions; + + private static byte[][] splits = null; + + @BeforeClass + public static void setUp() throws Exception { + TEST_UTIL = new HBaseTestingUtility(); + + // For trigger OOM quickly. + TEST_UTIL.getConfiguration() + .setInt(MemStoreLAB.CHUNK_SIZE_KEY, MemStoreLAB.CHUNK_SIZE_DEFAULT * 10); + TEST_UTIL.getConfiguration() + .setInt(HConstants.HBASE_CLIENT_RETRIES_NUMBER, 1); + + TEST_UTIL.startMiniCluster(1); + + int chunkSize = TEST_UTIL.getConfiguration() + .getInt(MemStoreLAB.CHUNK_SIZE_KEY, MemStoreLAB.CHUNK_SIZE_DEFAULT); + + numRegions = (int) ((Runtime.getRuntime().maxMemory() / chunkSize) + 10); + LOG.info("MaxHeap={}, numRegions={}" , + StringUtils.byteDesc(Runtime.getRuntime().maxMemory()), numRegions); + + splits = new byte[numRegions][]; + + for (int i = 0; i < splits.length; i++) { + splits[i] = new byte[3]; + splits[i][0] = (byte) (i & 0xff); + splits[i][1] = (byte) (i >> 8 & 0xff); + } + + TEST_UTIL.createTable(TEST_TABLE, FAMILY, splits); + } + + public static void tearDown() throws Exception { + TEST_UTIL.shutdownMiniCluster(); + } + + @Test + public void testOOM() { + List batch = Lists.newArrayList(); + + for (int i = 0; i < splits.length; i++) { + Put p = new Put(splits[i]); + p.addColumn(FAMILY, "c".getBytes(), "v".getBytes()); + batch.add(p); + } + + try { + // Just do a batch put. + TEST_UTIL.getConnection().getTable(TEST_TABLE).put(batch); + } catch (Throwable t) { + LOG.error("Can not do batch put stably.", t); + Assert.fail("Can not do batch put stably."); + } + } + +}