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