1   /**
2    * Copyright 2009 The Apache Software Foundation
3    *
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *     http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing, software
15   * distributed under the License is distributed on an "AS IS" BASIS,
16   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17   * See the License for the specific language governing permissions and
18   * limitations under the License.
19   */
20  package org.apache.hadoop.hbase.client;
21  
22  import java.io.IOException;
23  
24  import junit.framework.Assert;
25  
26  import org.apache.hadoop.hbase.HBaseConfiguration;
27  import org.apache.hadoop.hbase.HBaseTestingUtility;
28  import org.apache.hadoop.hbase.HColumnDescriptor;
29  import org.apache.hadoop.hbase.HConstants;
30  import org.apache.hadoop.hbase.HTableDescriptor;
31  import org.apache.hadoop.hbase.util.Bytes;
32  import org.junit.AfterClass;
33  import org.junit.BeforeClass;
34  import org.junit.Test;
35  
36  /**
37   * Tests HTablePool.
38   */
39  public class TestHTablePool  {
40    private static HBaseTestingUtility TEST_UTIL   =  new HBaseTestingUtility();
41    private final static byte [] TABLENAME = Bytes.toBytes("TestHTablePool");
42  
43    @BeforeClass
44    public static void beforeClass() throws Exception {
45      TEST_UTIL.startMiniCluster(1);
46      TEST_UTIL.createTable(TABLENAME, HConstants.CATALOG_FAMILY);
47    }
48  
49    @AfterClass
50    public static void afterClass() throws IOException {
51      TEST_UTIL.shutdownMiniCluster();
52    }
53  
54    @Test
55    public void testTableWithStringName() {
56      HTablePool pool =
57        new HTablePool(TEST_UTIL.getConfiguration(), Integer.MAX_VALUE);
58      String tableName = Bytes.toString(TABLENAME);
59  
60      // Request a table from an empty pool
61      HTableInterface table = pool.getTable(tableName);
62      Assert.assertNotNull(table);
63  
64      // Return the table to the pool
65      pool.putTable(table);
66  
67      // Request a table of the same name
68      HTableInterface sameTable = pool.getTable(tableName);
69      Assert.assertSame(table, sameTable);
70    }
71  
72    @Test
73    public void testTableWithByteArrayName() throws IOException {
74      HTablePool pool = new HTablePool(TEST_UTIL.getConfiguration(), Integer.MAX_VALUE);
75  
76      // Request a table from an empty pool
77      HTableInterface table = pool.getTable(TABLENAME);
78      Assert.assertNotNull(table);
79  
80      // Return the table to the pool
81      pool.putTable(table);
82  
83      // Request a table of the same name
84      HTableInterface sameTable = pool.getTable(TABLENAME);
85      Assert.assertSame(table, sameTable);
86    }
87  
88    @Test
89    public void testTableWithMaxSize() {
90      HTablePool pool = new HTablePool(TEST_UTIL.getConfiguration(), 2);
91  
92      // Request tables from an empty pool
93      HTableInterface table1 = pool.getTable(TABLENAME);
94      HTableInterface table2 = pool.getTable(TABLENAME);
95      HTableInterface table3 = pool.getTable(TABLENAME);
96  
97      // Return the tables to the pool
98      pool.putTable(table1);
99      pool.putTable(table2);
100     // The pool should reject this one since it is already full
101     pool.putTable(table3);
102 
103     // Request tables of the same name
104     HTableInterface sameTable1 = pool.getTable(TABLENAME);
105     HTableInterface sameTable2 = pool.getTable(TABLENAME);
106     HTableInterface sameTable3 = pool.getTable(TABLENAME);
107     Assert.assertSame(table1, sameTable1);
108     Assert.assertSame(table2, sameTable2);
109     Assert.assertNotSame(table3, sameTable3);
110   }
111 
112   @Test
113   public void testTablesWithDifferentNames() throws IOException {
114     HTablePool pool = new HTablePool(TEST_UTIL.getConfiguration(), Integer.MAX_VALUE);
115     byte [] otherTable = Bytes.toBytes("OtherTable");
116     TEST_UTIL.createTable(otherTable, HConstants.CATALOG_FAMILY);
117 
118     // Request a table from an empty pool
119     HTableInterface table1 = pool.getTable(TABLENAME);
120     HTableInterface table2 = pool.getTable(otherTable);
121     Assert.assertNotNull(table2);
122 
123     // Return the tables to the pool
124     pool.putTable(table1);
125     pool.putTable(table2);
126 
127     // Request tables of the same names
128     HTableInterface sameTable1 = pool.getTable(TABLENAME);
129     HTableInterface sameTable2 = pool.getTable(otherTable);
130     Assert.assertSame(table1, sameTable1);
131     Assert.assertSame(table2, sameTable2);
132   }
133 
134 
135   @Test
136   public void testCloseTablePool() throws IOException {
137     HTablePool pool = new HTablePool(TEST_UTIL.getConfiguration(), 4);
138     HBaseAdmin admin = new HBaseAdmin(TEST_UTIL.getConfiguration());
139 
140     if (admin.tableExists(TABLENAME)) {
141       admin.disableTable(TABLENAME);
142       admin.deleteTable(TABLENAME);
143     }
144 
145     HTableDescriptor tableDescriptor = new HTableDescriptor(TABLENAME);
146     tableDescriptor.addFamily(new HColumnDescriptor("randomFamily"));
147     admin.createTable(tableDescriptor);
148 
149 
150     // Request tables from an empty pool
151     HTableInterface[] tables = new HTableInterface[4];
152     for (int i = 0; i < 4; ++i ) {
153       tables[i] = pool.getTable(TABLENAME);
154     }
155 
156     pool.closeTablePool(TABLENAME);
157 
158     for (int i = 0; i < 4; ++i ) {
159       pool.putTable(tables[i]);
160     }
161 
162     Assert.assertEquals(4, pool.getCurrentPoolSize(Bytes.toString(TABLENAME)));
163 
164     pool.closeTablePool(TABLENAME);
165 
166     Assert.assertEquals(0, pool.getCurrentPoolSize(Bytes.toString(TABLENAME)));
167   }
168 }