View Javadoc

1   /**
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *     http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing, software
13   * distributed under the License is distributed on an "AS IS" BASIS,
14   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15   * See the License for the specific language governing permissions and
16   * limitations under the License.
17   */
18  package org.apache.hadoop.hbase;
19  
20  import static org.junit.Assert.assertEquals;
21  import static org.junit.Assert.assertFalse;
22  import static org.junit.Assert.assertTrue;
23  import static org.junit.Assert.fail;
24  
25  import java.io.IOException;
26  import java.util.regex.Pattern;
27  
28  import org.apache.commons.logging.Log;
29  import org.apache.commons.logging.LogFactory;
30  import org.apache.hadoop.hbase.client.Durability;
31  import org.apache.hadoop.hbase.exceptions.DeserializationException;
32  import org.apache.hadoop.hbase.testclassification.SmallTests;
33  import org.apache.hadoop.hbase.util.BuilderStyleTest;
34  import org.apache.hadoop.hbase.util.Bytes;
35  import org.junit.Test;
36  import org.junit.experimental.categories.Category;
37  
38  /**
39   * Test setting values in the descriptor
40   */
41  @Category(SmallTests.class)
42  public class TestHTableDescriptor {
43    final static Log LOG = LogFactory.getLog(TestHTableDescriptor.class);
44  
45    @Test
46    public void testPb() throws DeserializationException, IOException {
47      HTableDescriptor htd = new HTableDescriptor(HTableDescriptor.META_TABLEDESC);
48      final int v = 123;
49      htd.setMaxFileSize(v);
50      htd.setDurability(Durability.ASYNC_WAL);
51      htd.setReadOnly(true);
52      htd.setRegionReplication(2);
53      byte [] bytes = htd.toByteArray();
54      HTableDescriptor deserializedHtd = HTableDescriptor.parseFrom(bytes);
55      assertEquals(htd, deserializedHtd);
56      assertEquals(v, deserializedHtd.getMaxFileSize());
57      assertTrue(deserializedHtd.isReadOnly());
58      assertEquals(Durability.ASYNC_WAL, deserializedHtd.getDurability());
59      assertEquals(deserializedHtd.getRegionReplication(), 2);
60    }
61  
62    /**
63     * Test cps in the table description
64     * @throws Exception
65     */
66    @Test
67    public void testGetSetRemoveCP() throws Exception {
68      HTableDescriptor desc = new HTableDescriptor(TableName.valueOf("table"));
69      // simple CP
70      String className = "org.apache.hadoop.hbase.coprocessor.BaseRegionObserver";
71      // add and check that it is present
72      desc.addCoprocessor(className);
73      assertTrue(desc.hasCoprocessor(className));
74      // remove it and check that it is gone
75      desc.removeCoprocessor(className);
76      assertFalse(desc.hasCoprocessor(className));
77    }
78  
79    /**
80     * Test cps in the table description
81     * @throws Exception
82     */
83    @Test
84    public void testSetListRemoveCP() throws Exception {
85      HTableDescriptor desc = new HTableDescriptor(TableName.valueOf("testGetSetRemoveCP"));
86      // simple CP
87      String className1 = "org.apache.hadoop.hbase.coprocessor.BaseRegionObserver";
88      String className2 = "org.apache.hadoop.hbase.coprocessor.SampleRegionWALObserver";
89      // Check that any coprocessor is present.
90      assertTrue(desc.getCoprocessors().size() == 0);
91  
92      // Add the 1 coprocessor and check if present.
93      desc.addCoprocessor(className1);
94      assertTrue(desc.getCoprocessors().size() == 1);
95      assertTrue(desc.getCoprocessors().contains(className1));
96  
97      // Add the 2nd coprocessor and check if present.
98      // remove it and check that it is gone
99      desc.addCoprocessor(className2);
100     assertTrue(desc.getCoprocessors().size() == 2);
101     assertTrue(desc.getCoprocessors().contains(className2));
102 
103     // Remove one and check
104     desc.removeCoprocessor(className1);
105     assertTrue(desc.getCoprocessors().size() == 1);
106     assertFalse(desc.getCoprocessors().contains(className1));
107     assertTrue(desc.getCoprocessors().contains(className2));
108 
109     // Remove the last and check
110     desc.removeCoprocessor(className2);
111     assertTrue(desc.getCoprocessors().size() == 0);
112     assertFalse(desc.getCoprocessors().contains(className1));
113     assertFalse(desc.getCoprocessors().contains(className2));
114   }
115 
116   /**
117    * Test that we add and remove strings from settings properly.
118    * @throws Exception
119    */
120   @Test
121   public void testRemoveString() throws Exception {
122     HTableDescriptor desc = new HTableDescriptor(TableName.valueOf("table"));
123     String key = "Some";
124     String value = "value";
125     desc.setValue(key, value);
126     assertEquals(value, desc.getValue(key));
127     desc.remove(key);
128     assertEquals(null, desc.getValue(key));
129   }
130 
131   String legalTableNames[] = { "foo", "with-dash_under.dot", "_under_start_ok",
132       "with-dash.with_underscore", "02-01-2012.my_table_01-02", "xyz._mytable_", "9_9_0.table_02"
133       , "dot1.dot2.table", "new.-mytable", "with-dash.with.dot", "legal..t2", "legal..legal.t2",
134       "trailingdots..", "trailing.dots...", "ns:mytable", "ns:_mytable_", "ns:my_table_01-02"};
135   String illegalTableNames[] = { ".dot_start_illegal", "-dash_start_illegal", "spaces not ok",
136       "-dash-.start_illegal", "new.table with space", "01 .table", "ns:-illegaldash",
137       "new:.illegaldot", "new:illegalcolon1:", "new:illegalcolon1:2"};
138 
139   @Test
140   public void testLegalHTableNames() {
141     for (String tn : legalTableNames) {
142       TableName.isLegalFullyQualifiedTableName(Bytes.toBytes(tn));
143     }
144   }
145 
146   @Test
147   public void testIllegalHTableNames() {
148     for (String tn : illegalTableNames) {
149       try {
150         TableName.isLegalFullyQualifiedTableName(Bytes.toBytes(tn));
151         fail("invalid tablename " + tn + " should have failed");
152       } catch (Exception e) {
153         // expected
154       }
155     }
156   }
157 
158   @Test
159   public void testLegalHTableNamesRegex() {
160     for (String tn : legalTableNames) {
161       TableName tName = TableName.valueOf(tn);
162       assertTrue("Testing: '" + tn + "'", Pattern.matches(TableName.VALID_USER_TABLE_REGEX,
163           tName.getNameAsString()));
164     }
165   }
166 
167   @Test
168   public void testIllegalHTableNamesRegex() {
169     for (String tn : illegalTableNames) {
170       LOG.info("Testing: '" + tn + "'");
171       assertFalse(Pattern.matches(TableName.VALID_USER_TABLE_REGEX, tn));
172     }
173   }
174 
175     /**
176    * Test default value handling for maxFileSize
177    */
178   @Test
179   public void testGetMaxFileSize() {
180     HTableDescriptor desc = new HTableDescriptor(TableName.valueOf("table"));
181     assertEquals(-1, desc.getMaxFileSize());
182     desc.setMaxFileSize(1111L);
183     assertEquals(1111L, desc.getMaxFileSize());
184   }
185 
186   /**
187    * Test default value handling for memStoreFlushSize
188    */
189   @Test
190   public void testGetMemStoreFlushSize() {
191     HTableDescriptor desc = new HTableDescriptor(TableName.valueOf("table"));
192     assertEquals(-1, desc.getMemStoreFlushSize());
193     desc.setMemStoreFlushSize(1111L);
194     assertEquals(1111L, desc.getMemStoreFlushSize());
195   }
196 
197   /**
198    * Test that we add and remove strings from configuration properly.
199    */
200   @Test
201   public void testAddGetRemoveConfiguration() throws Exception {
202     HTableDescriptor desc = new HTableDescriptor(TableName.valueOf("table"));
203     String key = "Some";
204     String value = "value";
205     desc.setConfiguration(key, value);
206     assertEquals(value, desc.getConfigurationValue(key));
207     desc.removeConfiguration(key);
208     assertEquals(null, desc.getConfigurationValue(key));
209   }
210 
211   @Test
212   public void testClassMethodsAreBuilderStyle() {
213     /* HTableDescriptor should have a builder style setup where setXXX/addXXX methods
214      * can be chainable together:
215      * . For example:
216      * HTableDescriptor htd
217      *   = new HTableDescriptor()
218      *     .setFoo(foo)
219      *     .setBar(bar)
220      *     .setBuz(buz)
221      *
222      * This test ensures that all methods starting with "set" returns the declaring object
223      */
224 
225     BuilderStyleTest.assertClassesAreBuilderStyle(HTableDescriptor.class);
226   }
227 
228   @Test
229   public void testModifyFamily() {
230     HTableDescriptor htd = new HTableDescriptor(TableName.valueOf("table"));
231     byte[] familyName = Bytes.toBytes("cf");
232     HColumnDescriptor hcd = new HColumnDescriptor(familyName);
233     hcd.setBlocksize(1000);
234     htd.addFamily(hcd);
235     assertEquals(1000, htd.getFamily(familyName).getBlocksize());
236     hcd = new HColumnDescriptor(familyName);
237     hcd.setBlocksize(2000);
238     htd.modifyFamily(hcd);
239     assertEquals(2000, htd.getFamily(familyName).getBlocksize());
240   }
241 
242   @Test(expected=IllegalArgumentException.class)
243   public void testModifyInexistentFamily() {
244     HTableDescriptor htd = new HTableDescriptor(TableName.valueOf("table"));
245     byte[] familyName = Bytes.toBytes("cf");
246     HColumnDescriptor hcd = new HColumnDescriptor(familyName);
247     htd.modifyFamily(hcd);
248   }
249 
250   @Test(expected=IllegalArgumentException.class)
251   public void testAddDuplicateFamilies() {
252     HTableDescriptor htd = new HTableDescriptor(TableName.valueOf("table"));
253     byte[] familyName = Bytes.toBytes("cf");
254     HColumnDescriptor hcd = new HColumnDescriptor(familyName);
255     hcd.setBlocksize(1000);
256     htd.addFamily(hcd);
257     assertEquals(1000, htd.getFamily(familyName).getBlocksize());
258     hcd = new HColumnDescriptor(familyName);
259     hcd.setBlocksize(2000);
260     htd.addFamily(hcd);
261   }
262 }