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 instanceof Names)) {
077        return false;
078      }
079      Names names = (Names) o;
080      if (!ns.equals(names.ns)) {
081        return false;
082      }
083      if (!tn.equals(names.tn)) {
084        return false;
085      }
086      return true;
087    }
088
089    @Override
090    public int hashCode() {
091      int result = ns.hashCode();
092      result = 31 * result + tn.hashCode();
093      return result;
094    }
095  }
096
097  private static Names[] names = new Names[] { new Names("n1", "n1"), new Names("n2", "n2"),
098    new Names("table1", "table1"), new Names("table2", "table2"), new Names("table2", "table1"),
099    new Names("table1", "table2"), new Names("n1", "table1"), new Names("n1", "table1"),
100    new Names("n2", "table2"), new Names("n2", "table2") };
101
102  @Test
103  public void testInvalidNamespace() {
104    for (String tn : invalidNamespace) {
105      assertThrows(IllegalArgumentException.class,
106        () -> TableName.isLegalFullyQualifiedTableName(Bytes.toBytes(tn)));
107    }
108  }
109
110  @Test
111  public void testEmptyNamespaceName() {
112    for (String nn : emptyNames) {
113      assertThrows(IllegalArgumentException.class,
114        () -> TableName.isLegalNamespaceName(Bytes.toBytes(nn)));
115    }
116  }
117
118  @Test
119  public void testEmptyTableName() {
120    for (String tn : emptyNames) {
121      assertThrows(IllegalArgumentException.class,
122        () -> TableName.isLegalFullyQualifiedTableName(Bytes.toBytes(tn)));
123    }
124  }
125
126  @Test
127  public void testLegalHTableNames() {
128    for (String tn : legalTableNames) {
129      TableName.isLegalFullyQualifiedTableName(Bytes.toBytes(tn));
130    }
131  }
132
133  @Test
134  public void testIllegalHTableNames() {
135    for (String tn : illegalTableNames) {
136      assertThrows(IllegalArgumentException.class,
137        () -> TableName.isLegalFullyQualifiedTableName(Bytes.toBytes(tn)));
138    }
139  }
140
141  @Test
142  public void testValueOf() {
143    Map<String, TableName> inCache = new HashMap<>();
144    // fill cache
145    for (Names name : names) {
146      inCache.put(name.nn, TableName.valueOf(name.ns, name.tn));
147    }
148    for (Names name : names) {
149      assertSame(inCache.get(name.nn), validateNames(TableName.valueOf(name.ns, name.tn), name));
150      assertSame(inCache.get(name.nn), validateNames(TableName.valueOf(name.nsb, name.tnb), name));
151      assertSame(inCache.get(name.nn), validateNames(TableName.valueOf(name.nn), name));
152      assertSame(inCache.get(name.nn), validateNames(TableName.valueOf(name.nnb), name));
153      assertSame(inCache.get(name.nn), validateNames(
154        TableName.valueOf(ByteBuffer.wrap(name.nsb), ByteBuffer.wrap(name.tnb)), name));
155    }
156  }
157
158  private TableName validateNames(TableName expected, Names names) {
159    assertEquals(expected.getNameAsString(), names.nn);
160    assertArrayEquals(expected.getName(), names.nnb);
161    assertEquals(expected.getQualifierAsString(), names.tn);
162    assertArrayEquals(expected.getQualifier(), names.tnb);
163    assertEquals(expected.getNamespaceAsString(), names.ns);
164    assertArrayEquals(expected.getNamespace(), names.nsb);
165    return expected;
166  }
167}