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 * @deprecated As of release 2.0.0, this will be removed in HBase 3.0.0 together with 046 * {@link HTableDescriptor}. 047 */ 048@Category({MiscTests.class, SmallTests.class}) 049@Deprecated 050public class TestHTableDescriptor { 051 052 @ClassRule 053 public static final HBaseClassTestRule CLASS_RULE = 054 HBaseClassTestRule.forClass(TestHTableDescriptor.class); 055 056 private static final Logger LOG = LoggerFactory.getLogger(TestHTableDescriptor.class); 057 058 @Rule 059 public TestName name = new TestName(); 060 061 @Test (expected=IOException.class) 062 public void testAddCoprocessorTwice() throws IOException { 063 HTableDescriptor htd = new HTableDescriptor(TableName.META_TABLE_NAME); 064 String cpName = "a.b.c.d"; 065 htd.addCoprocessor(cpName); 066 htd.addCoprocessor(cpName); 067 } 068 069 @Test 070 public void testAddCoprocessorWithSpecStr() throws IOException { 071 HTableDescriptor htd = new HTableDescriptor(TableName.META_TABLE_NAME); 072 String cpName = "a.b.c.d"; 073 try { 074 htd.addCoprocessorWithSpec(cpName); 075 fail(); 076 } catch (IllegalArgumentException iae) { 077 // Expected as cpName is invalid 078 } 079 080 // Try minimal spec. 081 try { 082 htd.addCoprocessorWithSpec("file:///some/path" + "|" + cpName); 083 fail(); 084 } catch (IllegalArgumentException iae) { 085 // Expected to be invalid 086 } 087 088 // Try more spec. 089 String spec = "hdfs:///foo.jar|com.foo.FooRegionObserver|1001|arg1=1,arg2=2"; 090 try { 091 htd.addCoprocessorWithSpec(spec); 092 } catch (IllegalArgumentException iae) { 093 fail(); 094 } 095 096 // Try double add of same coprocessor 097 try { 098 htd.addCoprocessorWithSpec(spec); 099 fail(); 100 } catch (IOException ioe) { 101 // Expect that the coprocessor already exists 102 } 103 } 104 105 @Test 106 public void testPb() throws DeserializationException, IOException { 107 HTableDescriptor htd = new HTableDescriptor(TableName.META_TABLE_NAME); 108 final int v = 123; 109 htd.setMaxFileSize(v); 110 htd.setDurability(Durability.ASYNC_WAL); 111 htd.setReadOnly(true); 112 htd.setRegionReplication(2); 113 byte [] bytes = htd.toByteArray(); 114 HTableDescriptor deserializedHtd = HTableDescriptor.parseFrom(bytes); 115 assertEquals(htd, deserializedHtd); 116 assertEquals(v, deserializedHtd.getMaxFileSize()); 117 assertTrue(deserializedHtd.isReadOnly()); 118 assertEquals(Durability.ASYNC_WAL, deserializedHtd.getDurability()); 119 assertEquals(2, deserializedHtd.getRegionReplication()); 120 } 121 122 /** 123 * Test cps in the table description. 124 * 125 * @throws Exception if adding a coprocessor fails 126 */ 127 @Test 128 public void testGetSetRemoveCP() throws Exception { 129 HTableDescriptor desc = new HTableDescriptor(TableName.valueOf(name.getMethodName())); 130 // simple CP 131 String className = "org.apache.hadoop.hbase.coprocessor.SimpleRegionObserver"; 132 // add and check that it is present 133 desc.addCoprocessor(className); 134 assertTrue(desc.hasCoprocessor(className)); 135 // remove it and check that it is gone 136 desc.removeCoprocessor(className); 137 assertFalse(desc.hasCoprocessor(className)); 138 } 139 140 /** 141 * Test cps in the table description. 142 * 143 * @throws Exception if adding a coprocessor fails 144 */ 145 @Test 146 public void testSetListRemoveCP() throws Exception { 147 HTableDescriptor desc = new HTableDescriptor(TableName.valueOf(name.getMethodName())); 148 // simple CP 149 String className1 = "org.apache.hadoop.hbase.coprocessor.SimpleRegionObserver"; 150 String className2 = "org.apache.hadoop.hbase.coprocessor.SampleRegionWALObserver"; 151 // Check that any coprocessor is present. 152 assertTrue(desc.getCoprocessors().isEmpty()); 153 154 // Add the 1 coprocessor and check if present. 155 desc.addCoprocessor(className1); 156 assertTrue(desc.getCoprocessors().size() == 1); 157 assertTrue(desc.getCoprocessors().contains(className1)); 158 159 // Add the 2nd coprocessor and check if present. 160 // remove it and check that it is gone 161 desc.addCoprocessor(className2); 162 assertTrue(desc.getCoprocessors().size() == 2); 163 assertTrue(desc.getCoprocessors().contains(className2)); 164 165 // Remove one and check 166 desc.removeCoprocessor(className1); 167 assertTrue(desc.getCoprocessors().size() == 1); 168 assertFalse(desc.getCoprocessors().contains(className1)); 169 assertTrue(desc.getCoprocessors().contains(className2)); 170 171 // Remove the last and check 172 desc.removeCoprocessor(className2); 173 assertTrue(desc.getCoprocessors().isEmpty()); 174 assertFalse(desc.getCoprocessors().contains(className1)); 175 assertFalse(desc.getCoprocessors().contains(className2)); 176 } 177 178 /** 179 * Test that we add and remove strings from settings properly. 180 */ 181 @Test 182 public void testAddGetRemoveString() { 183 HTableDescriptor desc = new HTableDescriptor(TableName.valueOf(name.getMethodName())); 184 String key = "Some"; 185 String value = "value"; 186 desc.setValue(key, value); 187 assertEquals(value, desc.getValue(key)); 188 desc.remove(key); 189 assertEquals(null, desc.getValue(key)); 190 String keyShouldNotNull = "Some2"; 191 String valueIsNull = null; 192 desc.setValue(keyShouldNotNull, valueIsNull); 193 assertEquals(valueIsNull, desc.getValue(keyShouldNotNull)); 194 desc.remove(keyShouldNotNull); 195 assertEquals(null, desc.getValue(keyShouldNotNull)); 196 } 197 198 String[] legalTableNames = { "foo", "with-dash_under.dot", "_under_start_ok", 199 "with-dash.with_underscore", "02-01-2012.my_table_01-02", "xyz._mytable_", "9_9_0.table_02", 200 "dot1.dot2.table", "new.-mytable", "with-dash.with.dot", "legal..t2", "legal..legal.t2", 201 "trailingdots..", "trailing.dots...", "ns:mytable", "ns:_mytable_", "ns:my_table_01-02", 202 "汉", "汉:字", "_字_", "foo:字", "foo.字", "字.foo"}; 203 // Avoiding "zookeeper" in here as it's tough to encode in regex 204 String[] illegalTableNames = { ".dot_start_illegal", "-dash_start_illegal", "spaces not ok", 205 "-dash-.start_illegal", "new.table with space", "01 .table", "ns:-illegaldash", 206 "new:.illegaldot", "new:illegalcolon1:", "new:illegalcolon1:2", String.valueOf((char)130), 207 String.valueOf((char)5), String.valueOf((char)65530)}; 208 209 @Test 210 public void testLegalHTableNames() { 211 for (String tn : legalTableNames) { 212 TableName.isLegalFullyQualifiedTableName(Bytes.toBytes(tn)); 213 } 214 } 215 216 @Test 217 public void testIllegalHTableNames() { 218 for (String tn : illegalTableNames) { 219 try { 220 TableName.isLegalFullyQualifiedTableName(Bytes.toBytes(tn)); 221 fail("invalid tablename " + tn + " should have failed"); 222 } catch (Exception e) { 223 // expected 224 } 225 } 226 } 227 228 @Test 229 public void testIllegalZooKeeperName() { 230 for (String name : Arrays.asList("zookeeper", "ns:zookeeper", "zookeeper:table")) { 231 try { 232 TableName.isLegalFullyQualifiedTableName(Bytes.toBytes(name)); 233 fail("invalid tablename " + name + " should have failed"); 234 } catch (Exception e) { 235 // expected 236 } 237 } 238 } 239 240 @Test 241 public void testLegalHTableNamesRegex() { 242 for (String tn : legalTableNames) { 243 TableName tName = TableName.valueOf(tn); 244 assertTrue("Testing: '" + tn + "'", Pattern.matches(TableName.VALID_USER_TABLE_REGEX, 245 tName.getNameAsString())); 246 } 247 } 248 249 @Test 250 public void testIllegalHTableNamesRegex() { 251 for (String tn : illegalTableNames) { 252 LOG.info("Testing: '" + tn + "'"); 253 assertFalse(Pattern.matches(TableName.VALID_USER_TABLE_REGEX, tn)); 254 } 255 } 256 257 /** 258 * Test default value handling for maxFileSize 259 */ 260 @Test 261 public void testGetMaxFileSize() { 262 HTableDescriptor desc = new HTableDescriptor(TableName.valueOf(name.getMethodName())); 263 assertEquals(-1, desc.getMaxFileSize()); 264 desc.setMaxFileSize(1111L); 265 assertEquals(1111L, desc.getMaxFileSize()); 266 } 267 268 /** 269 * Test default value handling for memStoreFlushSize 270 */ 271 @Test 272 public void testGetMemStoreFlushSize() { 273 HTableDescriptor desc = new HTableDescriptor(TableName.valueOf(name.getMethodName())); 274 assertEquals(-1, desc.getMemStoreFlushSize()); 275 desc.setMemStoreFlushSize(1111L); 276 assertEquals(1111L, desc.getMemStoreFlushSize()); 277 } 278 279 /** 280 * Test that we add and remove strings from configuration properly. 281 */ 282 @Test 283 public void testAddGetRemoveConfiguration() throws Exception { 284 HTableDescriptor desc = new HTableDescriptor(TableName.valueOf(name.getMethodName())); 285 String key = "Some"; 286 String value = "value"; 287 desc.setConfiguration(key, value); 288 assertEquals(value, desc.getConfigurationValue(key)); 289 desc.removeConfiguration(key); 290 assertEquals(null, desc.getConfigurationValue(key)); 291 } 292 293 @Test 294 public void testClassMethodsAreBuilderStyle() { 295 /* HTableDescriptor should have a builder style setup where setXXX/addXXX methods 296 * can be chainable together: 297 * . For example: 298 * HTableDescriptor htd 299 * = new HTableDescriptor() 300 * .setFoo(foo) 301 * .setBar(bar) 302 * .setBuz(buz) 303 * 304 * This test ensures that all methods starting with "set" returns the declaring object 305 */ 306 307 BuilderStyleTest.assertClassesAreBuilderStyle(HTableDescriptor.class); 308 } 309 310 @Test 311 public void testModifyFamily() { 312 HTableDescriptor htd = new HTableDescriptor(TableName.valueOf(name.getMethodName())); 313 byte[] familyName = Bytes.toBytes("cf"); 314 HColumnDescriptor hcd = new HColumnDescriptor(familyName); 315 hcd.setBlocksize(1000); 316 hcd.setDFSReplication((short) 3); 317 htd.addFamily(hcd); 318 assertEquals(1000, htd.getFamily(familyName).getBlocksize()); 319 assertEquals(3, htd.getFamily(familyName).getDFSReplication()); 320 hcd = new HColumnDescriptor(familyName); 321 hcd.setBlocksize(2000); 322 hcd.setDFSReplication((short) 1); 323 htd.modifyFamily(hcd); 324 assertEquals(2000, htd.getFamily(familyName).getBlocksize()); 325 assertEquals(1, htd.getFamily(familyName).getDFSReplication()); 326 } 327 328 @Test(expected=IllegalArgumentException.class) 329 public void testModifyInexistentFamily() { 330 HTableDescriptor htd = new HTableDescriptor(TableName.valueOf(name.getMethodName())); 331 byte[] familyName = Bytes.toBytes("cf"); 332 HColumnDescriptor hcd = new HColumnDescriptor(familyName); 333 htd.modifyFamily(hcd); 334 } 335 336 @Test(expected=IllegalArgumentException.class) 337 public void testAddDuplicateFamilies() { 338 HTableDescriptor htd = new HTableDescriptor(TableName.valueOf(name.getMethodName())); 339 byte[] familyName = Bytes.toBytes("cf"); 340 HColumnDescriptor hcd = new HColumnDescriptor(familyName); 341 hcd.setBlocksize(1000); 342 htd.addFamily(hcd); 343 assertEquals(1000, htd.getFamily(familyName).getBlocksize()); 344 hcd = new HColumnDescriptor(familyName); 345 hcd.setBlocksize(2000); 346 htd.addFamily(hcd); 347 } 348 349 @Test 350 public void testPriority() { 351 HTableDescriptor htd = new HTableDescriptor(TableName.valueOf(name.getMethodName())); 352 htd.setPriority(42); 353 assertEquals(42, htd.getPriority()); 354 } 355}