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