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