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