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    private static final Log LOG = LogFactory.getLog(TestHTableDescriptor.class);
44  
45    @Test (expected=IOException.class)
46    public void testAddCoprocessorTwice() throws IOException {
47      HTableDescriptor htd = new HTableDescriptor(TableName.META_TABLE_NAME);
48      String cpName = "a.b.c.d";
49      htd.addCoprocessor(cpName);
50      htd.addCoprocessor(cpName);
51    }
52  
53    @Test
54    public void testAddCoprocessorWithSpecStr() throws IOException {
55      HTableDescriptor htd = new HTableDescriptor(TableName.META_TABLE_NAME);
56      String cpName = "a.b.c.d";
57      try {
58        htd.addCoprocessorWithSpec(cpName);
59        fail();
60      } catch (IllegalArgumentException iae) {
61        // Expected as cpName is invalid
62      }
63  
64      // Try minimal spec.
65      try {
66        htd.addCoprocessorWithSpec("file:///some/path" + "|" + cpName);
67        fail();
68      } catch (IllegalArgumentException iae) {
69        // Expected to be invalid
70      }
71  
72      // Try more spec.
73      String spec = "hdfs:///foo.jar|com.foo.FooRegionObserver|1001|arg1=1,arg2=2";
74      try {
75        htd.addCoprocessorWithSpec(spec);
76      } catch (IllegalArgumentException iae) {
77        fail();
78      }
79  
80      // Try double add of same coprocessor
81      try {
82        htd.addCoprocessorWithSpec(spec);
83        fail();
84      } catch (IOException ioe) {
85        // Expect that the coprocessor already exists
86      }
87    }
88  
89    @Test
90    public void testPb() throws DeserializationException, IOException {
91      HTableDescriptor htd = new HTableDescriptor(HTableDescriptor.META_TABLEDESC);
92      final int v = 123;
93      htd.setMaxFileSize(v);
94      htd.setDurability(Durability.ASYNC_WAL);
95      htd.setReadOnly(true);
96      htd.setRegionReplication(2);
97      byte [] bytes = htd.toByteArray();
98      HTableDescriptor deserializedHtd = HTableDescriptor.parseFrom(bytes);
99      assertEquals(htd, deserializedHtd);
100     assertEquals(v, deserializedHtd.getMaxFileSize());
101     assertTrue(deserializedHtd.isReadOnly());
102     assertEquals(Durability.ASYNC_WAL, deserializedHtd.getDurability());
103     assertEquals(deserializedHtd.getRegionReplication(), 2);
104   }
105 
106   /**
107    * Test cps in the table description
108    * @throws Exception
109    */
110   @Test
111   public void testGetSetRemoveCP() throws Exception {
112     HTableDescriptor desc = new HTableDescriptor(TableName.valueOf("table"));
113     // simple CP
114     String className = "org.apache.hadoop.hbase.coprocessor.BaseRegionObserver";
115     // add and check that it is present
116     desc.addCoprocessor(className);
117     assertTrue(desc.hasCoprocessor(className));
118     // remove it and check that it is gone
119     desc.removeCoprocessor(className);
120     assertFalse(desc.hasCoprocessor(className));
121   }
122 
123   /**
124    * Test cps in the table description
125    * @throws Exception
126    */
127   @Test
128   public void testSetListRemoveCP() throws Exception {
129     HTableDescriptor desc = new HTableDescriptor(TableName.valueOf("testGetSetRemoveCP"));
130     // simple CP
131     String className1 = "org.apache.hadoop.hbase.coprocessor.BaseRegionObserver";
132     String className2 = "org.apache.hadoop.hbase.coprocessor.SampleRegionWALObserver";
133     // Check that any coprocessor is present.
134     assertTrue(desc.getCoprocessors().size() == 0);
135 
136     // Add the 1 coprocessor and check if present.
137     desc.addCoprocessor(className1);
138     assertTrue(desc.getCoprocessors().size() == 1);
139     assertTrue(desc.getCoprocessors().contains(className1));
140 
141     // Add the 2nd coprocessor and check if present.
142     // remove it and check that it is gone
143     desc.addCoprocessor(className2);
144     assertTrue(desc.getCoprocessors().size() == 2);
145     assertTrue(desc.getCoprocessors().contains(className2));
146 
147     // Remove one and check
148     desc.removeCoprocessor(className1);
149     assertTrue(desc.getCoprocessors().size() == 1);
150     assertFalse(desc.getCoprocessors().contains(className1));
151     assertTrue(desc.getCoprocessors().contains(className2));
152 
153     // Remove the last and check
154     desc.removeCoprocessor(className2);
155     assertTrue(desc.getCoprocessors().size() == 0);
156     assertFalse(desc.getCoprocessors().contains(className1));
157     assertFalse(desc.getCoprocessors().contains(className2));
158   }
159 
160   /**
161    * Test that we add and remove strings from settings properly.
162    * @throws Exception
163    */
164   @Test
165   public void testRemoveString() throws Exception {
166     HTableDescriptor desc = new HTableDescriptor(TableName.valueOf("table"));
167     String key = "Some";
168     String value = "value";
169     desc.setValue(key, value);
170     assertEquals(value, desc.getValue(key));
171     desc.remove(key);
172     assertEquals(null, desc.getValue(key));
173   }
174 
175   String legalTableNames[] = { "foo", "with-dash_under.dot", "_under_start_ok",
176       "with-dash.with_underscore", "02-01-2012.my_table_01-02", "xyz._mytable_", "9_9_0.table_02"
177       , "dot1.dot2.table", "new.-mytable", "with-dash.with.dot", "legal..t2", "legal..legal.t2",
178       "trailingdots..", "trailing.dots...", "ns:mytable", "ns:_mytable_", "ns:my_table_01-02"};
179   String illegalTableNames[] = { ".dot_start_illegal", "-dash_start_illegal", "spaces not ok",
180       "-dash-.start_illegal", "new.table with space", "01 .table", "ns:-illegaldash",
181       "new:.illegaldot", "new:illegalcolon1:", "new:illegalcolon1:2"};
182 
183   @Test
184   public void testLegalHTableNames() {
185     for (String tn : legalTableNames) {
186       TableName.isLegalFullyQualifiedTableName(Bytes.toBytes(tn));
187     }
188   }
189 
190   @Test
191   public void testIllegalHTableNames() {
192     for (String tn : illegalTableNames) {
193       try {
194         TableName.isLegalFullyQualifiedTableName(Bytes.toBytes(tn));
195         fail("invalid tablename " + tn + " should have failed");
196       } catch (Exception e) {
197         // expected
198       }
199     }
200   }
201 
202   @Test
203   public void testLegalHTableNamesRegex() {
204     for (String tn : legalTableNames) {
205       TableName tName = TableName.valueOf(tn);
206       assertTrue("Testing: '" + tn + "'", Pattern.matches(TableName.VALID_USER_TABLE_REGEX,
207           tName.getNameAsString()));
208     }
209   }
210 
211   @Test
212   public void testIllegalHTableNamesRegex() {
213     for (String tn : illegalTableNames) {
214       LOG.info("Testing: '" + tn + "'");
215       assertFalse(Pattern.matches(TableName.VALID_USER_TABLE_REGEX, tn));
216     }
217   }
218 
219     /**
220    * Test default value handling for maxFileSize
221    */
222   @Test
223   public void testGetMaxFileSize() {
224     HTableDescriptor desc = new HTableDescriptor(TableName.valueOf("table"));
225     assertEquals(-1, desc.getMaxFileSize());
226     desc.setMaxFileSize(1111L);
227     assertEquals(1111L, desc.getMaxFileSize());
228   }
229 
230   /**
231    * Test default value handling for memStoreFlushSize
232    */
233   @Test
234   public void testGetMemStoreFlushSize() {
235     HTableDescriptor desc = new HTableDescriptor(TableName.valueOf("table"));
236     assertEquals(-1, desc.getMemStoreFlushSize());
237     desc.setMemStoreFlushSize(1111L);
238     assertEquals(1111L, desc.getMemStoreFlushSize());
239   }
240 
241   /**
242    * Test that we add and remove strings from configuration properly.
243    */
244   @Test
245   public void testAddGetRemoveConfiguration() throws Exception {
246     HTableDescriptor desc = new HTableDescriptor(TableName.valueOf("table"));
247     String key = "Some";
248     String value = "value";
249     desc.setConfiguration(key, value);
250     assertEquals(value, desc.getConfigurationValue(key));
251     desc.removeConfiguration(key);
252     assertEquals(null, desc.getConfigurationValue(key));
253   }
254 
255   @Test
256   public void testClassMethodsAreBuilderStyle() {
257     /* HTableDescriptor should have a builder style setup where setXXX/addXXX methods
258      * can be chainable together:
259      * . For example:
260      * HTableDescriptor htd
261      *   = new HTableDescriptor()
262      *     .setFoo(foo)
263      *     .setBar(bar)
264      *     .setBuz(buz)
265      *
266      * This test ensures that all methods starting with "set" returns the declaring object
267      */
268 
269     BuilderStyleTest.assertClassesAreBuilderStyle(HTableDescriptor.class);
270   }
271 
272   @Test
273   public void testModifyFamily() {
274     HTableDescriptor htd = new HTableDescriptor(TableName.valueOf("table"));
275     byte[] familyName = Bytes.toBytes("cf");
276     HColumnDescriptor hcd = new HColumnDescriptor(familyName);
277     hcd.setBlocksize(1000);
278     hcd.setDFSReplication((short) 3);
279     htd.addFamily(hcd);
280     assertEquals(1000, htd.getFamily(familyName).getBlocksize());
281     assertEquals(3, htd.getFamily(familyName).getDFSReplication());
282     hcd = new HColumnDescriptor(familyName);
283     hcd.setBlocksize(2000);
284     hcd.setDFSReplication((short) 1);
285     htd.modifyFamily(hcd);
286     assertEquals(2000, htd.getFamily(familyName).getBlocksize());
287     assertEquals(1, htd.getFamily(familyName).getDFSReplication());
288   }
289 
290   @Test(expected=IllegalArgumentException.class)
291   public void testModifyInexistentFamily() {
292     HTableDescriptor htd = new HTableDescriptor(TableName.valueOf("table"));
293     byte[] familyName = Bytes.toBytes("cf");
294     HColumnDescriptor hcd = new HColumnDescriptor(familyName);
295     htd.modifyFamily(hcd);
296   }
297 
298   @Test(expected=IllegalArgumentException.class)
299   public void testAddDuplicateFamilies() {
300     HTableDescriptor htd = new HTableDescriptor(TableName.valueOf("table"));
301     byte[] familyName = Bytes.toBytes("cf");
302     HColumnDescriptor hcd = new HColumnDescriptor(familyName);
303     hcd.setBlocksize(1000);
304     htd.addFamily(hcd);
305     assertEquals(1000, htd.getFamily(familyName).getBlocksize());
306     hcd = new HColumnDescriptor(familyName);
307     hcd.setBlocksize(2000);
308     htd.addFamily(hcd);
309   }
310 
311   @Test
312   public void testPriority() {
313     HTableDescriptor htd = new HTableDescriptor(TableName.valueOf("table"));
314     htd.setPriority(42);
315     assertEquals(42, htd.getPriority());
316   }
317 }