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.master.region;
019
020import static org.junit.Assert.assertArrayEquals;
021import static org.junit.Assert.assertEquals;
022import static org.junit.Assert.assertFalse;
023import static org.junit.Assert.assertNull;
024import static org.junit.Assert.assertTrue;
025
026import java.io.IOException;
027import org.apache.hadoop.fs.Path;
028import org.apache.hadoop.hbase.HBaseClassTestRule;
029import org.apache.hadoop.hbase.client.Get;
030import org.apache.hadoop.hbase.client.Put;
031import org.apache.hadoop.hbase.client.TableDescriptor;
032import org.apache.hadoop.hbase.regionserver.HRegion.FlushResult;
033import org.apache.hadoop.hbase.regionserver.HRegionFileSystem;
034import org.apache.hadoop.hbase.regionserver.storefiletracker.StoreFileTrackerFactory;
035import org.apache.hadoop.hbase.testclassification.MasterTests;
036import org.apache.hadoop.hbase.testclassification.MediumTests;
037import org.apache.hadoop.hbase.util.Bytes;
038import org.apache.hadoop.hbase.util.CommonFSUtils;
039import org.apache.hadoop.hbase.util.FSTableDescriptors;
040import org.junit.ClassRule;
041import org.junit.Test;
042import org.junit.experimental.categories.Category;
043
044@Category({ MasterTests.class, MediumTests.class })
045public class TestMasterRegionInitialize extends MasterRegionTestBase {
046
047  @ClassRule
048  public static final HBaseClassTestRule CLASS_RULE =
049    HBaseClassTestRule.forClass(TestMasterRegionInitialize.class);
050
051  @Test
052  public void testUpgrade() throws IOException {
053    Path rootDir = new Path(htu.getDataTestDir(), REGION_DIR_NAME);
054    Path tableDir =
055      CommonFSUtils.getTableDir(rootDir, region.region.getTableDescriptor().getTableName());
056    Path initializingFlag = new Path(tableDir, MasterRegion.INITIALIZING_FLAG);
057    Path initializedFlag = new Path(tableDir, MasterRegion.INITIALIZED_FLAG);
058    HRegionFileSystem hfs = region.region.getRegionFileSystem();
059    assertFalse(hfs.getFileSystem().exists(initializingFlag));
060    assertTrue(hfs.getFileSystem().exists(initializedFlag));
061    byte[] row = Bytes.toBytes("row");
062    byte[] cf = CF1;
063    byte[] cq = Bytes.toBytes("qual");
064    byte[] value = Bytes.toBytes("value");
065    region.update(r -> r.put(new Put(row).addColumn(cf, cq, value)));
066    assertEquals(FlushResult.Result.FLUSHED_NO_COMPACTION_NEEDED, region.flush(true).getResult());
067    // delete initialized flag to simulate old implementation
068    hfs.getFileSystem().delete(initializedFlag, true);
069    FSTableDescriptors.deleteTableDescriptors(hfs.getFileSystem(), tableDir);
070    assertNull(FSTableDescriptors.getTableDescriptorFromFs(hfs.getFileSystem(), tableDir));
071    // reopen, with new file tracker
072    region.close(false);
073    htu.getConfiguration().set(StoreFileTrackerFactory.TRACKER_IMPL,
074      StoreFileTrackerFactory.Trackers.FILE.name());
075    createMasterRegion();
076
077    // make sure we successfully upgrade to new implementation without data loss
078    hfs = region.region.getRegionFileSystem();
079    assertFalse(hfs.getFileSystem().exists(initializingFlag));
080    assertTrue(hfs.getFileSystem().exists(initializedFlag));
081    TableDescriptor td = FSTableDescriptors.getTableDescriptorFromFs(hfs.getFileSystem(), tableDir);
082    assertEquals(StoreFileTrackerFactory.Trackers.FILE.name(),
083      td.getValue(StoreFileTrackerFactory.TRACKER_IMPL));
084    assertArrayEquals(value, region.get(new Get(row)).getValue(cf, cq));
085  }
086
087  @Test
088  public void testInitializingCleanup() throws IOException {
089    Path rootDir = new Path(htu.getDataTestDir(), REGION_DIR_NAME);
090    Path tableDir =
091      CommonFSUtils.getTableDir(rootDir, region.region.getTableDescriptor().getTableName());
092    Path initializingFlag = new Path(tableDir, MasterRegion.INITIALIZING_FLAG);
093    Path initializedFlag = new Path(tableDir, MasterRegion.INITIALIZED_FLAG);
094    HRegionFileSystem hfs = region.region.getRegionFileSystem();
095    assertFalse(hfs.getFileSystem().exists(initializingFlag));
096    assertTrue(hfs.getFileSystem().exists(initializedFlag));
097    byte[] row = Bytes.toBytes("row");
098    byte[] cf = CF1;
099    byte[] cq = Bytes.toBytes("qual");
100    byte[] value = Bytes.toBytes("value");
101    region.update(r -> r.put(new Put(row).addColumn(cf, cq, value)));
102    // delete initialized flag and touch a initializing flag, to simulate initializing in progress
103    hfs.getFileSystem().delete(initializedFlag, true);
104    if (!hfs.getFileSystem().mkdirs(initializingFlag)) {
105      throw new IOException("can not touch " + initializedFlag);
106    }
107
108    region.close(false);
109    createMasterRegion();
110    hfs = region.region.getRegionFileSystem();
111    assertFalse(hfs.getFileSystem().exists(initializingFlag));
112    assertTrue(hfs.getFileSystem().exists(initializedFlag));
113
114    // but the data should have been cleaned up
115    assertTrue(region.get(new Get(row)).isEmpty());
116  }
117}