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.regionserver;
019
020import static junit.framework.TestCase.assertTrue;
021import static org.junit.Assert.assertEquals;
022import static org.junit.Assert.assertFalse;
023
024import java.io.FileNotFoundException;
025import java.io.IOException;
026import org.apache.hadoop.fs.FileSystem;
027import org.apache.hadoop.fs.Path;
028import org.apache.hadoop.hbase.HBaseClassTestRule;
029import org.apache.hadoop.hbase.HBaseTestingUtil;
030import org.apache.hadoop.hbase.HConstants;
031import org.apache.hadoop.hbase.TableName;
032import org.apache.hadoop.hbase.client.ColumnFamilyDescriptorBuilder;
033import org.apache.hadoop.hbase.client.RegionInfo;
034import org.apache.hadoop.hbase.client.RegionInfoBuilder;
035import org.apache.hadoop.hbase.io.HFileLink;
036import org.apache.hadoop.hbase.io.Reference;
037import org.apache.hadoop.hbase.io.hfile.ReaderContext;
038import org.apache.hadoop.hbase.io.hfile.ReaderContext.ReaderType;
039import org.apache.hadoop.hbase.regionserver.storefiletracker.StoreFileTrackerForTest;
040import org.apache.hadoop.hbase.testclassification.RegionServerTests;
041import org.apache.hadoop.hbase.testclassification.SmallTests;
042import org.junit.ClassRule;
043import org.junit.Test;
044import org.junit.experimental.categories.Category;
045
046/**
047 * Test HStoreFile
048 */
049@Category({ RegionServerTests.class, SmallTests.class })
050public class TestStoreFileInfo {
051
052  @ClassRule
053  public static final HBaseClassTestRule CLASS_RULE =
054    HBaseClassTestRule.forClass(TestStoreFileInfo.class);
055
056  private static final HBaseTestingUtil TEST_UTIL = new HBaseTestingUtil();
057
058  /**
059   * Validate that we can handle valid tables with '.', '_', and '-' chars.
060   */
061  @Test
062  public void testStoreFileNames() {
063    String[] legalHFileLink = { "MyTable_02=abc012-def345", "MyTable_02.300=abc012-def345",
064      "MyTable_02-400=abc012-def345", "MyTable_02-400.200=abc012-def345",
065      "MyTable_02=abc012-def345_SeqId_1_", "MyTable_02=abc012-def345_SeqId_20_" };
066    for (String name : legalHFileLink) {
067      assertTrue("should be a valid link: " + name, HFileLink.isHFileLink(name));
068      assertTrue("should be a valid StoreFile" + name, StoreFileInfo.validateStoreFileName(name));
069      assertFalse("should not be a valid reference: " + name, StoreFileInfo.isReference(name));
070
071      String refName = name + ".6789";
072      assertTrue("should be a valid link reference: " + refName,
073        StoreFileInfo.isReference(refName));
074      assertTrue("should be a valid StoreFile" + refName,
075        StoreFileInfo.validateStoreFileName(refName));
076    }
077
078    String[] illegalHFileLink = { ".MyTable_02=abc012-def345", "-MyTable_02.300=abc012-def345",
079      "MyTable_02-400=abc0_12-def345", "MyTable_02-400.200=abc012-def345...." };
080    for (String name : illegalHFileLink) {
081      assertFalse("should not be a valid link: " + name, HFileLink.isHFileLink(name));
082    }
083  }
084
085  @Test
086  public void testEqualsWithLink() throws IOException {
087    Path origin = new Path("/origin");
088    Path tmp = TEST_UTIL.getDataTestDir();
089    Path mob = new Path("/mob");
090    Path archive = new Path("/archive");
091    HFileLink link1 = new HFileLink(new Path(origin, "f1"), new Path(tmp, "f1"),
092      new Path(mob, "f1"), new Path(archive, "f1"));
093    HFileLink link2 = new HFileLink(new Path(origin, "f1"), new Path(tmp, "f1"),
094      new Path(mob, "f1"), new Path(archive, "f1"));
095
096    StoreFileInfo info1 =
097      new StoreFileInfo(TEST_UTIL.getConfiguration(), TEST_UTIL.getTestFileSystem(), null, link1);
098    StoreFileInfo info2 =
099      new StoreFileInfo(TEST_UTIL.getConfiguration(), TEST_UTIL.getTestFileSystem(), null, link2);
100
101    assertEquals(info1, info2);
102    assertEquals(info1.hashCode(), info2.hashCode());
103  }
104
105  @Test
106  public void testOpenErrorMessageReference() throws IOException {
107    // Test file link exception
108    // Try to open nonsense hfilelink. Make sure exception is from HFileLink.
109    Path p = new Path(TEST_UTIL.getDataTestDirOnTestFS(), "4567.abcd");
110    FileSystem fs = FileSystem.get(TEST_UTIL.getConfiguration());
111    fs.mkdirs(p.getParent());
112    Reference r = Reference.createBottomReference(HConstants.EMPTY_START_ROW);
113    RegionInfo regionInfo = RegionInfoBuilder.newBuilder(TableName.valueOf("table1")).build();
114    StoreContext storeContext = StoreContext.getBuilder()
115      .withRegionFileSystem(HRegionFileSystem.create(TEST_UTIL.getConfiguration(), fs,
116        TEST_UTIL.getDataTestDirOnTestFS(), regionInfo))
117      .withColumnFamilyDescriptor(
118        ColumnFamilyDescriptorBuilder.newBuilder("cf1".getBytes()).build())
119      .build();
120    StoreFileTrackerForTest storeFileTrackerForTest =
121      new StoreFileTrackerForTest(TEST_UTIL.getConfiguration(), true, storeContext);
122    storeFileTrackerForTest.createReference(r, p);
123    StoreFileInfo sfi = storeFileTrackerForTest.getStoreFileInfo(p, true);
124    try {
125      ReaderContext context = sfi.createReaderContext(false, 1000, ReaderType.PREAD);
126      sfi.createReader(context, null);
127      throw new IllegalStateException();
128    } catch (FileNotFoundException fnfe) {
129      assertTrue(fnfe.getMessage().contains("->"));
130    }
131  }
132}