001/** 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, software 013 * distributed under the License is distributed on an "AS IS" BASIS, 014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 015 * See the License for the specific language governing permissions and 016 * limitations under the License. 017 */ 018package org.apache.hadoop.hbase; 019 020import static org.junit.Assert.assertEquals; 021import static org.junit.Assert.assertFalse; 022import static org.junit.Assert.assertTrue; 023import static org.junit.Assert.fail; 024 025import java.io.IOException; 026import java.util.Arrays; 027import java.util.regex.Pattern; 028import org.apache.hadoop.hbase.client.Durability; 029import org.apache.hadoop.hbase.exceptions.DeserializationException; 030import org.apache.hadoop.hbase.testclassification.MiscTests; 031import org.apache.hadoop.hbase.testclassification.SmallTests; 032import org.apache.hadoop.hbase.util.BuilderStyleTest; 033import org.apache.hadoop.hbase.util.Bytes; 034import org.junit.ClassRule; 035import org.junit.Rule; 036import org.junit.Test; 037import org.junit.experimental.categories.Category; 038import org.junit.rules.TestName; 039import org.slf4j.Logger; 040import org.slf4j.LoggerFactory; 041 042/** 043 * Test setting values in the descriptor 044 */ 045@Category({MiscTests.class, SmallTests.class}) 046@Deprecated 047public class TestHTableDescriptor { 048 049 @ClassRule 050 public static final HBaseClassTestRule CLASS_RULE = 051 HBaseClassTestRule.forClass(TestHTableDescriptor.class); 052 053 private static final Logger LOG = LoggerFactory.getLogger(TestHTableDescriptor.class); 054 055 @Rule 056 public TestName name = new TestName(); 057 058 @Test (expected=IOException.class) 059 public void testAddCoprocessorTwice() throws IOException { 060 HTableDescriptor htd = new HTableDescriptor(TableName.META_TABLE_NAME); 061 String cpName = "a.b.c.d"; 062 htd.addCoprocessor(cpName); 063 htd.addCoprocessor(cpName); 064 } 065 066 @Test 067 public void testAddCoprocessorWithSpecStr() throws IOException { 068 HTableDescriptor htd = new HTableDescriptor(TableName.META_TABLE_NAME); 069 String cpName = "a.b.c.d"; 070 try { 071 htd.addCoprocessorWithSpec(cpName); 072 fail(); 073 } catch (IllegalArgumentException iae) { 074 // Expected as cpName is invalid 075 } 076 077 // Try minimal spec. 078 try { 079 htd.addCoprocessorWithSpec("file:///some/path" + "|" + cpName); 080 fail(); 081 } catch (IllegalArgumentException iae) { 082 // Expected to be invalid 083 } 084 085 // Try more spec. 086 String spec = "hdfs:///foo.jar|com.foo.FooRegionObserver|1001|arg1=1,arg2=2"; 087 try { 088 htd.addCoprocessorWithSpec(spec); 089 } catch (IllegalArgumentException iae) { 090 fail(); 091 } 092 093 // Try double add of same coprocessor 094 try { 095 htd.addCoprocessorWithSpec(spec); 096 fail(); 097 } catch (IOException ioe) { 098 // Expect that the coprocessor already exists 099 } 100 } 101 102 @Test 103 public void testPb() throws DeserializationException, IOException { 104 HTableDescriptor htd = new HTableDescriptor(TableName.META_TABLE_NAME); 105 final int v = 123; 106 htd.setMaxFileSize(v); 107 htd.setDurability(Durability.ASYNC_WAL); 108 htd.setReadOnly(true); 109 htd.setRegionReplication(2); 110 byte [] bytes = htd.toByteArray(); 111 HTableDescriptor deserializedHtd = HTableDescriptor.parseFrom(bytes); 112 assertEquals(htd, deserializedHtd); 113 assertEquals(v, deserializedHtd.getMaxFileSize()); 114 assertTrue(deserializedHtd.isReadOnly()); 115 assertEquals(Durability.ASYNC_WAL, deserializedHtd.getDurability()); 116 assertEquals(2, deserializedHtd.getRegionReplication()); 117 } 118 119 /** 120 * Test cps in the table description 121 * @throws Exception 122 */ 123 @Test 124 public void testGetSetRemoveCP() throws Exception { 125 HTableDescriptor desc = new HTableDescriptor(TableName.valueOf(name.getMethodName())); 126 // simple CP 127 String className = "org.apache.hadoop.hbase.coprocessor.SimpleRegionObserver"; 128 // add and check that it is present 129 desc.addCoprocessor(className); 130 assertTrue(desc.hasCoprocessor(className)); 131 // remove it and check that it is gone 132 desc.removeCoprocessor(className); 133 assertFalse(desc.hasCoprocessor(className)); 134 } 135 136 /** 137 * Test cps in the table description 138 * @throws Exception 139 */ 140 @Test 141 public void testSetListRemoveCP() throws Exception { 142 HTableDescriptor desc = new HTableDescriptor(TableName.valueOf(name.getMethodName())); 143 // simple CP 144 String className1 = "org.apache.hadoop.hbase.coprocessor.SimpleRegionObserver"; 145 String className2 = "org.apache.hadoop.hbase.coprocessor.SampleRegionWALObserver"; 146 // Check that any coprocessor is present. 147 assertTrue(desc.getCoprocessors().isEmpty()); 148 149 // Add the 1 coprocessor and check if present. 150 desc.addCoprocessor(className1); 151 assertTrue(desc.getCoprocessors().size() == 1); 152 assertTrue(desc.getCoprocessors().contains(className1)); 153 154 // Add the 2nd coprocessor and check if present. 155 // remove it and check that it is gone 156 desc.addCoprocessor(className2); 157 assertTrue(desc.getCoprocessors().size() == 2); 158 assertTrue(desc.getCoprocessors().contains(className2)); 159 160 // Remove one and check 161 desc.removeCoprocessor(className1); 162 assertTrue(desc.getCoprocessors().size() == 1); 163 assertFalse(desc.getCoprocessors().contains(className1)); 164 assertTrue(desc.getCoprocessors().contains(className2)); 165 166 // Remove the last and check 167 desc.removeCoprocessor(className2); 168 assertTrue(desc.getCoprocessors().isEmpty()); 169 assertFalse(desc.getCoprocessors().contains(className1)); 170 assertFalse(desc.getCoprocessors().contains(className2)); 171 } 172 173 /** 174 * Test that we add and remove strings from settings properly. 175 * @throws Exception 176 */ 177 @Test 178 public void testRemoveString() throws Exception { 179 HTableDescriptor desc = new HTableDescriptor(TableName.valueOf(name.getMethodName())); 180 String key = "Some"; 181 String value = "value"; 182 desc.setValue(key, value); 183 assertEquals(value, desc.getValue(key)); 184 desc.remove(key); 185 assertEquals(null, desc.getValue(key)); 186 } 187 188 String legalTableNames[] = { "foo", "with-dash_under.dot", "_under_start_ok", 189 "with-dash.with_underscore", "02-01-2012.my_table_01-02", "xyz._mytable_", "9_9_0.table_02" 190 , "dot1.dot2.table", "new.-mytable", "with-dash.with.dot", "legal..t2", "legal..legal.t2", 191 "trailingdots..", "trailing.dots...", "ns:mytable", "ns:_mytable_", "ns:my_table_01-02", 192 "汉", "汉:字", "_字_", "foo:字", "foo.字", "字.foo"}; 193 // Avoiding "zookeeper" in here as it's tough to encode in regex 194 String illegalTableNames[] = { ".dot_start_illegal", "-dash_start_illegal", "spaces not ok", 195 "-dash-.start_illegal", "new.table with space", "01 .table", "ns:-illegaldash", 196 "new:.illegaldot", "new:illegalcolon1:", "new:illegalcolon1:2", String.valueOf((char)130), 197 String.valueOf((char)5), String.valueOf((char)65530)}; 198 199 @Test 200 public void testLegalHTableNames() { 201 for (String tn : legalTableNames) { 202 TableName.isLegalFullyQualifiedTableName(Bytes.toBytes(tn)); 203 } 204 } 205 206 @Test 207 public void testIllegalHTableNames() { 208 for (String tn : illegalTableNames) { 209 try { 210 TableName.isLegalFullyQualifiedTableName(Bytes.toBytes(tn)); 211 fail("invalid tablename " + tn + " should have failed"); 212 } catch (Exception e) { 213 // expected 214 } 215 } 216 } 217 218 @Test 219 public void testIllegalZooKeeperName() { 220 for (String name : Arrays.asList("zookeeper", "ns:zookeeper", "zookeeper:table")) { 221 try { 222 TableName.isLegalFullyQualifiedTableName(Bytes.toBytes(name)); 223 fail("invalid tablename " + name + " should have failed"); 224 } catch (Exception e) { 225 // expected 226 } 227 } 228 } 229 230 @Test 231 public void testLegalHTableNamesRegex() { 232 for (String tn : legalTableNames) { 233 TableName tName = TableName.valueOf(tn); 234 assertTrue("Testing: '" + tn + "'", Pattern.matches(TableName.VALID_USER_TABLE_REGEX, 235 tName.getNameAsString())); 236 } 237 } 238 239 @Test 240 public void testIllegalHTableNamesRegex() { 241 for (String tn : illegalTableNames) { 242 LOG.info("Testing: '" + tn + "'"); 243 assertFalse(Pattern.matches(TableName.VALID_USER_TABLE_REGEX, tn)); 244 } 245 } 246 247 /** 248 * Test default value handling for maxFileSize 249 */ 250 @Test 251 public void testGetMaxFileSize() { 252 HTableDescriptor desc = new HTableDescriptor(TableName.valueOf(name.getMethodName())); 253 assertEquals(-1, desc.getMaxFileSize()); 254 desc.setMaxFileSize(1111L); 255 assertEquals(1111L, desc.getMaxFileSize()); 256 } 257 258 /** 259 * Test default value handling for memStoreFlushSize 260 */ 261 @Test 262 public void testGetMemStoreFlushSize() { 263 HTableDescriptor desc = new HTableDescriptor(TableName.valueOf(name.getMethodName())); 264 assertEquals(-1, desc.getMemStoreFlushSize()); 265 desc.setMemStoreFlushSize(1111L); 266 assertEquals(1111L, desc.getMemStoreFlushSize()); 267 } 268 269 /** 270 * Test that we add and remove strings from configuration properly. 271 */ 272 @Test 273 public void testAddGetRemoveConfiguration() throws Exception { 274 HTableDescriptor desc = new HTableDescriptor(TableName.valueOf(name.getMethodName())); 275 String key = "Some"; 276 String value = "value"; 277 desc.setConfiguration(key, value); 278 assertEquals(value, desc.getConfigurationValue(key)); 279 desc.removeConfiguration(key); 280 assertEquals(null, desc.getConfigurationValue(key)); 281 } 282 283 @Test 284 public void testClassMethodsAreBuilderStyle() { 285 /* HTableDescriptor should have a builder style setup where setXXX/addXXX methods 286 * can be chainable together: 287 * . For example: 288 * HTableDescriptor htd 289 * = new HTableDescriptor() 290 * .setFoo(foo) 291 * .setBar(bar) 292 * .setBuz(buz) 293 * 294 * This test ensures that all methods starting with "set" returns the declaring object 295 */ 296 297 BuilderStyleTest.assertClassesAreBuilderStyle(HTableDescriptor.class); 298 } 299 300 @Test 301 public void testModifyFamily() { 302 HTableDescriptor htd = new HTableDescriptor(TableName.valueOf(name.getMethodName())); 303 byte[] familyName = Bytes.toBytes("cf"); 304 HColumnDescriptor hcd = new HColumnDescriptor(familyName); 305 hcd.setBlocksize(1000); 306 hcd.setDFSReplication((short) 3); 307 htd.addFamily(hcd); 308 assertEquals(1000, htd.getFamily(familyName).getBlocksize()); 309 assertEquals(3, htd.getFamily(familyName).getDFSReplication()); 310 hcd = new HColumnDescriptor(familyName); 311 hcd.setBlocksize(2000); 312 hcd.setDFSReplication((short) 1); 313 htd.modifyFamily(hcd); 314 assertEquals(2000, htd.getFamily(familyName).getBlocksize()); 315 assertEquals(1, htd.getFamily(familyName).getDFSReplication()); 316 } 317 318 @Test(expected=IllegalArgumentException.class) 319 public void testModifyInexistentFamily() { 320 HTableDescriptor htd = new HTableDescriptor(TableName.valueOf(name.getMethodName())); 321 byte[] familyName = Bytes.toBytes("cf"); 322 HColumnDescriptor hcd = new HColumnDescriptor(familyName); 323 htd.modifyFamily(hcd); 324 } 325 326 @Test(expected=IllegalArgumentException.class) 327 public void testAddDuplicateFamilies() { 328 HTableDescriptor htd = new HTableDescriptor(TableName.valueOf(name.getMethodName())); 329 byte[] familyName = Bytes.toBytes("cf"); 330 HColumnDescriptor hcd = new HColumnDescriptor(familyName); 331 hcd.setBlocksize(1000); 332 htd.addFamily(hcd); 333 assertEquals(1000, htd.getFamily(familyName).getBlocksize()); 334 hcd = new HColumnDescriptor(familyName); 335 hcd.setBlocksize(2000); 336 htd.addFamily(hcd); 337 } 338 339 @Test 340 public void testPriority() { 341 HTableDescriptor htd = new HTableDescriptor(TableName.valueOf(name.getMethodName())); 342 htd.setPriority(42); 343 assertEquals(42, htd.getPriority()); 344 } 345}