blob: 5be8daada9d76e5535f4b42f853d432d015b6984 [file] [log] [blame]
/**
* Copyright 2010 The Apache Software Foundation
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.hadoop.hbase.master;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.hbase.HBaseTestingUtility;
import org.apache.hadoop.hbase.HColumnDescriptor;
import org.apache.hadoop.hbase.HConstants;
import org.apache.hadoop.hbase.HRegionInfo;
import org.apache.hadoop.hbase.HTableDescriptor;
import org.apache.hadoop.hbase.KeyValue;
import org.apache.hadoop.hbase.NotAllMetaRegionsOnlineException;
import org.apache.hadoop.hbase.Server;
import org.apache.hadoop.hbase.catalog.CatalogTracker;
import org.apache.hadoop.hbase.client.Result;
import org.apache.hadoop.hbase.executor.ExecutorService;
import org.apache.hadoop.hbase.io.Reference;
import org.apache.hadoop.hbase.ipc.HRegionInterface;
import org.apache.hadoop.hbase.regionserver.Store;
import org.apache.hadoop.hbase.util.Bytes;
import org.apache.hadoop.hbase.util.Writables;
import org.apache.hadoop.hbase.zookeeper.ZooKeeperWatcher;
import org.junit.Test;
import org.mockito.Mockito;
public class TestCatalogJanitor {
/**
* Pseudo server for below tests.
*/
class MockServer implements Server {
private final Configuration c;
private final CatalogTracker ct;
MockServer(final HBaseTestingUtility htu)
throws NotAllMetaRegionsOnlineException, IOException {
this.c = htu.getConfiguration();
// Set hbase.rootdir into test dir.
FileSystem fs = FileSystem.get(this.c);
Path rootdir =
fs.makeQualified(HBaseTestingUtility.getTestDir(HConstants.HBASE_DIR));
this.c.set(HConstants.HBASE_DIR, rootdir.toString());
this.ct = Mockito.mock(CatalogTracker.class);
HRegionInterface hri = Mockito.mock(HRegionInterface.class);
Mockito.when(ct.waitForMetaServerConnectionDefault()).thenReturn(hri);
}
@Override
public CatalogTracker getCatalogTracker() {
return this.ct;
}
@Override
public Configuration getConfiguration() {
return this.c;
}
@Override
public String getServerName() {
// TODO Auto-generated method stub
return null;
}
@Override
public ZooKeeperWatcher getZooKeeper() {
// TODO Auto-generated method stub
return null;
}
@Override
public void abort(String why, Throwable e) {
// TODO Auto-generated method stub
}
@Override
public boolean isStopped() {
// TODO Auto-generated method stub
return false;
}
@Override
public void stop(String why) {
// TODO Auto-generated method stub
}
}
/**
* Mock MasterServices for tests below.
*/
class MockMasterServices implements MasterServices {
private final MasterFileSystem mfs;
MockMasterServices(final Server server) throws IOException {
this.mfs = new MasterFileSystem(server, null);
}
@Override
public void checkTableModifiable(byte[] tableName) throws IOException {
// TODO Auto-generated method stub
}
@Override
public AssignmentManager getAssignmentManager() {
// TODO Auto-generated method stub
return null;
}
@Override
public ExecutorService getExecutorService() {
// TODO Auto-generated method stub
return null;
}
@Override
public MasterFileSystem getMasterFileSystem() {
return this.mfs;
}
@Override
public ServerManager getServerManager() {
// TODO Auto-generated method stub
return null;
}
}
@Test
public void testGetHRegionInfo() throws IOException {
assertNull(CatalogJanitor.getHRegionInfo(new Result()));
List<KeyValue> kvs = new ArrayList<KeyValue>();
Result r = new Result(kvs);
assertNull(CatalogJanitor.getHRegionInfo(r));
byte [] f = HConstants.CATALOG_FAMILY;
// Make a key value that doesn't have the expected qualifier.
kvs.add(new KeyValue(HConstants.EMPTY_BYTE_ARRAY, f,
HConstants.SERVER_QUALIFIER, f));
r = new Result(kvs);
assertNull(CatalogJanitor.getHRegionInfo(r));
// Make a key that does not have a regioninfo value.
kvs.add(new KeyValue(HConstants.EMPTY_BYTE_ARRAY, f,
HConstants.REGIONINFO_QUALIFIER, f));
HRegionInfo hri = CatalogJanitor.getHRegionInfo(new Result(kvs));
assertTrue(hri == null);
// OK, give it what it expects
kvs.clear();
kvs.add(new KeyValue(HConstants.EMPTY_BYTE_ARRAY, f,
HConstants.REGIONINFO_QUALIFIER,
Writables.getBytes(HRegionInfo.FIRST_META_REGIONINFO)));
hri = CatalogJanitor.getHRegionInfo(new Result(kvs));
assertNotNull(hri);
assertTrue(hri.equals(HRegionInfo.FIRST_META_REGIONINFO));
}
@Test
public void testCleanParent() throws IOException {
HBaseTestingUtility htu = new HBaseTestingUtility();
Server server = new MockServer(htu);
MasterServices services = new MockMasterServices(server);
CatalogJanitor janitor = new CatalogJanitor(server, services);
// Create regions.
HTableDescriptor htd = new HTableDescriptor("table");
htd.addFamily(new HColumnDescriptor("family"));
HRegionInfo parent =
new HRegionInfo(htd, Bytes.toBytes("aaa"), Bytes.toBytes("eee"));
HRegionInfo splita =
new HRegionInfo(htd, Bytes.toBytes("aaa"), Bytes.toBytes("ccc"));
HRegionInfo splitb =
new HRegionInfo(htd, Bytes.toBytes("ccc"), Bytes.toBytes("eee"));
// Test that when both daughter regions are in place, that we do not
// remove the parent.
List<KeyValue> kvs = new ArrayList<KeyValue>();
kvs.add(new KeyValue(parent.getRegionName(), HConstants.CATALOG_FAMILY,
HConstants.SPLITA_QUALIFIER, Writables.getBytes(splita)));
kvs.add(new KeyValue(parent.getRegionName(), HConstants.CATALOG_FAMILY,
HConstants.SPLITB_QUALIFIER, Writables.getBytes(splitb)));
Result r = new Result(kvs);
// Add a reference under splitA directory so we don't clear out the parent.
Path rootdir = services.getMasterFileSystem().getRootDir();
Path tabledir =
HTableDescriptor.getTableDir(rootdir, htd.getName());
Path storedir = Store.getStoreHomedir(tabledir, splita.getEncodedName(),
htd.getColumnFamilies()[0].getName());
Reference ref = new Reference(Bytes.toBytes("ccc"), Reference.Range.top);
long now = System.currentTimeMillis();
// Reference name has this format: StoreFile#REF_NAME_PARSER
Path p = new Path(storedir, Long.toString(now) + "." + parent.getEncodedName());
FileSystem fs = services.getMasterFileSystem().getFileSystem();
ref.write(fs, p);
assertFalse(janitor.cleanParent(parent, r));
// Remove the reference file and try again.
assertTrue(fs.delete(p, true));
assertTrue(janitor.cleanParent(parent, r));
}
}