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.jupiter.api.Assertions.assertArrayEquals; 021import static org.junit.jupiter.api.Assertions.assertEquals; 022import static org.junit.jupiter.api.Assertions.assertSame; 023import static org.junit.jupiter.api.Assertions.assertThrows; 024 025import java.nio.ByteBuffer; 026import java.util.HashMap; 027import java.util.Map; 028import org.apache.hadoop.conf.Configuration; 029import org.apache.hadoop.hbase.testclassification.MiscTests; 030import org.apache.hadoop.hbase.testclassification.SmallTests; 031import org.apache.hadoop.hbase.util.Bytes; 032import org.junit.jupiter.api.Tag; 033import org.junit.jupiter.api.Test; 034 035/** 036 * Tests for various kinds of TableNames. 037 */ 038@Tag(MiscTests.TAG) 039@Tag(SmallTests.TAG) 040public class TestTableName { 041 042 private static String[] emptyNames = { "", " " }; 043 private static String[] invalidNamespace = { ":a", "%:a" }; 044 private static String[] legalTableNames = { "foo", "with-dash_under.dot", "_under_start_ok", 045 "with-dash.with_underscore", "02-01-2012.my_table_01-02", "xyz._mytable_", "9_9_0.table_02", 046 "dot1.dot2.table", "new.-mytable", "with-dash.with.dot", "legal..t2", "legal..legal.t2", 047 "trailingdots..", "trailing.dots...", "ns:mytable", "ns:_mytable_", "ns:my_table_01-02" }; 048 private static String[] illegalTableNames = { ".dot_start_illegal", "-dash_start_illegal", 049 "spaces not ok", "-dash-.start_illegal", "new.table with space", "01 .table", "ns:-illegaldash", 050 "new:.illegaldot", "new:illegalcolon1:", "new:illegalcolon1:2" }; 051 052 static class Names { 053 String ns; 054 byte[] nsb; 055 String tn; 056 byte[] tnb; 057 String nn; 058 byte[] nnb; 059 060 Names(String ns, String tn) { 061 this.ns = ns; 062 nsb = Bytes.toBytes(ns); 063 this.tn = tn; 064 tnb = Bytes.toBytes(tn); 065 nn = this.ns + ":" + this.tn; 066 nnb = Bytes.toBytes(nn); 067 } 068 069 @Override 070 public boolean equals(Object o) { 071 if (this == o) { 072 return true; 073 } 074 if (!(o instanceof Names)) { 075 return false; 076 } 077 Names names = (Names) o; 078 if (!ns.equals(names.ns)) { 079 return false; 080 } 081 if (!tn.equals(names.tn)) { 082 return false; 083 } 084 return true; 085 } 086 087 @Override 088 public int hashCode() { 089 int result = ns.hashCode(); 090 result = 31 * result + tn.hashCode(); 091 return result; 092 } 093 } 094 095 private static Names[] names = new Names[] { new Names("n1", "n1"), new Names("n2", "n2"), 096 new Names("table1", "table1"), new Names("table2", "table2"), new Names("table2", "table1"), 097 new Names("table1", "table2"), new Names("n1", "table1"), new Names("n1", "table1"), 098 new Names("n2", "table2"), new Names("n2", "table2") }; 099 100 @Test 101 public void testInvalidNamespace() { 102 for (String tn : invalidNamespace) { 103 assertThrows(IllegalArgumentException.class, 104 () -> TableName.isLegalFullyQualifiedTableName(Bytes.toBytes(tn))); 105 } 106 } 107 108 @Test 109 public void testEmptyNamespaceName() { 110 for (String nn : emptyNames) { 111 assertThrows(IllegalArgumentException.class, 112 () -> TableName.isLegalNamespaceName(Bytes.toBytes(nn))); 113 } 114 } 115 116 @Test 117 public void testEmptyTableName() { 118 for (String tn : emptyNames) { 119 assertThrows(IllegalArgumentException.class, 120 () -> TableName.isLegalFullyQualifiedTableName(Bytes.toBytes(tn))); 121 } 122 } 123 124 @Test 125 public void testLegalHTableNames() { 126 for (String tn : legalTableNames) { 127 TableName.isLegalFullyQualifiedTableName(Bytes.toBytes(tn)); 128 } 129 } 130 131 @Test 132 public void testIllegalHTableNames() { 133 for (String tn : illegalTableNames) { 134 assertThrows(IllegalArgumentException.class, 135 () -> TableName.isLegalFullyQualifiedTableName(Bytes.toBytes(tn))); 136 } 137 } 138 139 @Test 140 public void testValueOf() { 141 Map<String, TableName> inCache = new HashMap<>(); 142 // fill cache 143 for (Names name : names) { 144 inCache.put(name.nn, TableName.valueOf(name.ns, name.tn)); 145 } 146 for (Names name : names) { 147 assertSame(inCache.get(name.nn), validateNames(TableName.valueOf(name.ns, name.tn), name)); 148 assertSame(inCache.get(name.nn), validateNames(TableName.valueOf(name.nsb, name.tnb), name)); 149 assertSame(inCache.get(name.nn), validateNames(TableName.valueOf(name.nn), name)); 150 assertSame(inCache.get(name.nn), validateNames(TableName.valueOf(name.nnb), name)); 151 assertSame(inCache.get(name.nn), validateNames( 152 TableName.valueOf(ByteBuffer.wrap(name.nsb), ByteBuffer.wrap(name.tnb)), name)); 153 } 154 } 155 156 private TableName validateNames(TableName expected, Names names) { 157 assertEquals(expected.getNameAsString(), names.nn); 158 assertArrayEquals(expected.getName(), names.nnb); 159 assertEquals(expected.getQualifierAsString(), names.tn); 160 assertArrayEquals(expected.getQualifier(), names.tnb); 161 assertEquals(expected.getNamespaceAsString(), names.ns); 162 assertArrayEquals(expected.getNamespace(), names.nsb); 163 return expected; 164 } 165 166 @Test 167 public void testValidMetaTableSuffix() { 168 String[] validSuffixes = { "REPL1", "123", "123abc" }; 169 for (String suffix : validSuffixes) { 170 Configuration conf = HBaseConfiguration.create(); 171 conf.set(HConstants.HBASE_META_TABLE_SUFFIX, suffix); 172 TableName metaTableName = TableName.initializeHbaseMetaTableName(conf); 173 assertEquals("hbase:meta_" + suffix, metaTableName.getNameAsString()); 174 } 175 } 176 177 @Test 178 public void testInvalidMetaTableSuffix() { 179 String[] invalidSuffixes = { "test_1", "test-1", "test.1", "test 1", "_test", "-test", ".test", 180 "has!special", "has:colon", " " }; 181 for (String suffix : invalidSuffixes) { 182 Configuration conf = HBaseConfiguration.create(); 183 conf.set(HConstants.HBASE_META_TABLE_SUFFIX, suffix); 184 assertThrows(IllegalArgumentException.class, 185 () -> TableName.initializeHbaseMetaTableName(conf), 186 "Expected IllegalArgumentException for suffix: " + suffix); 187 } 188 } 189}