HBASE-15865 Move TestTableDeleteFamilyHandler and TestTableDescriptorModification handler tests to procedure
Project: http://git-wip-us.apache.org/repos/asf/hbase/repo Commit: http://git-wip-us.apache.org/repos/asf/hbase/commit/07b8f79f Tree: http://git-wip-us.apache.org/repos/asf/hbase/tree/07b8f79f Diff: http://git-wip-us.apache.org/repos/asf/hbase/diff/07b8f79f Branch: refs/heads/branch-1.3 Commit: 07b8f79f7f5ec7698bf510be3d05346b5ea91450 Parents: f9aff84 Author: Matteo Bertozzi <matteo.berto...@cloudera.com> Authored: Fri May 20 07:03:11 2016 -0700 Committer: Matteo Bertozzi <matteo.berto...@cloudera.com> Committed: Fri May 20 07:16:11 2016 -0700 ---------------------------------------------------------------------- .../handler/TestTableDeleteFamilyHandler.java | 272 ----------------- .../TestTableDescriptorModification.java | 289 ------------------- ...stDeleteColumnFamilyProcedureFromClient.java | 269 +++++++++++++++++ ...stTableDescriptorModificationFromClient.java | 289 +++++++++++++++++++ 4 files changed, 558 insertions(+), 561 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/hbase/blob/07b8f79f/hbase-server/src/test/java/org/apache/hadoop/hbase/master/handler/TestTableDeleteFamilyHandler.java ---------------------------------------------------------------------- diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/master/handler/TestTableDeleteFamilyHandler.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/master/handler/TestTableDeleteFamilyHandler.java deleted file mode 100644 index a730deb..0000000 --- a/hbase-server/src/test/java/org/apache/hadoop/hbase/master/handler/TestTableDeleteFamilyHandler.java +++ /dev/null @@ -1,272 +0,0 @@ -/** - * Copyright 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.handler; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; - -import java.io.IOException; - -import org.apache.hadoop.fs.FileStatus; -import org.apache.hadoop.fs.FileSystem; -import org.apache.hadoop.fs.Path; -import org.apache.hadoop.fs.PathFilter; -import org.apache.hadoop.hbase.HBaseTestingUtility; -import org.apache.hadoop.hbase.HColumnDescriptor; -import org.apache.hadoop.hbase.HConstants; -import org.apache.hadoop.hbase.HTableDescriptor; -import org.apache.hadoop.hbase.testclassification.LargeTests; -import org.apache.hadoop.hbase.client.Admin; -import org.apache.hadoop.hbase.client.HTable; -import org.apache.hadoop.hbase.InvalidFamilyOperationException; -import org.apache.hadoop.hbase.TableName; -import org.apache.hadoop.hbase.client.Admin; -import org.apache.hadoop.hbase.client.Table; -import org.apache.hadoop.hbase.testclassification.LargeTests; -import org.apache.hadoop.hbase.util.Bytes; -import org.apache.hadoop.hbase.util.FSUtils; -import org.apache.hadoop.hbase.wal.WALSplitter; -import org.junit.After; -import org.junit.AfterClass; -import org.junit.Assert; -import org.junit.Before; -import org.junit.BeforeClass; -import org.junit.Test; -import org.junit.experimental.categories.Category; - -@Category(LargeTests.class) -public class TestTableDeleteFamilyHandler { - - private static final HBaseTestingUtility TEST_UTIL = new HBaseTestingUtility(); - private static final TableName TABLENAME = - TableName.valueOf("column_family_handlers"); - private static final byte[][] FAMILIES = new byte[][] { Bytes.toBytes("cf1"), - Bytes.toBytes("cf2"), Bytes.toBytes("cf3") }; - - /** - * Start up a mini cluster and put a small table of empty regions into it. - * - * @throws Exception - */ - @BeforeClass - public static void beforeAllTests() throws Exception { - TEST_UTIL.getConfiguration().setBoolean("dfs.support.append", true); - TEST_UTIL.startMiniCluster(2); - } - - @AfterClass - public static void afterAllTests() throws Exception { - TEST_UTIL.shutdownMiniCluster(); - } - - @Before - public void setup() throws IOException, InterruptedException { - // Create a table of three families. This will assign a region. - TEST_UTIL.createTable(TABLENAME, FAMILIES); - - HTable t = new HTable(TEST_UTIL.getConfiguration(), TABLENAME); - TEST_UTIL.waitUntilNoRegionsInTransition(); - - // Load the table with data for all families - TEST_UTIL.loadTable(t, FAMILIES); - - TEST_UTIL.flush(); - - t.close(); - - TEST_UTIL.ensureSomeRegionServersAvailable(2); - } - - @After - public void cleanup() throws Exception { - TEST_UTIL.deleteTable(TABLENAME); - } - - @Test - public void deleteColumnFamilyWithMultipleRegions() throws Exception { - Admin admin = TEST_UTIL.getHBaseAdmin(); - HTableDescriptor beforehtd = admin.getTableDescriptor(TABLENAME); - - FileSystem fs = TEST_UTIL.getDFSCluster().getFileSystem(); - - // 1 - Check if table exists in descriptor - assertTrue(admin.isTableAvailable(TABLENAME)); - - // 2 - Check if all three families exist in descriptor - assertEquals(3, beforehtd.getColumnFamilies().length); - HColumnDescriptor[] families = beforehtd.getColumnFamilies(); - for (int i = 0; i < families.length; i++) { - assertTrue(families[i].getNameAsString().equals("cf" + (i + 1))); - } - - // 3 - Check if table exists in FS - Path tableDir = FSUtils.getTableDir(TEST_UTIL.getDefaultRootDirPath(), TABLENAME); - assertTrue(fs.exists(tableDir)); - - // 4 - Check if all the 3 column families exist in FS - FileStatus[] fileStatus = fs.listStatus(tableDir); - for (int i = 0; i < fileStatus.length; i++) { - if (fileStatus[i].isDirectory() == true) { - FileStatus[] cf = fs.listStatus(fileStatus[i].getPath(), new PathFilter() { - @Override - public boolean accept(Path p) { - if (p.getName().contains(HConstants.RECOVERED_EDITS_DIR)) { - return false; - } - return true; - } - }); - int k = 1; - for (int j = 0; j < cf.length; j++) { - if (cf[j].isDirectory() == true - && cf[j].getPath().getName().startsWith(".") == false) { - assertEquals(cf[j].getPath().getName(), "cf" + k); - k++; - } - } - } - } - - // TEST - Disable and delete the column family - admin.disableTable(TABLENAME); - admin.deleteColumn(TABLENAME, Bytes.toBytes("cf2")); - - // 5 - Check if only 2 column families exist in the descriptor - HTableDescriptor afterhtd = admin.getTableDescriptor(TABLENAME); - assertEquals(2, afterhtd.getColumnFamilies().length); - HColumnDescriptor[] newFamilies = afterhtd.getColumnFamilies(); - assertTrue(newFamilies[0].getNameAsString().equals("cf1")); - assertTrue(newFamilies[1].getNameAsString().equals("cf3")); - - // 6 - Check if the second column family is gone from the FS - fileStatus = fs.listStatus(tableDir); - for (int i = 0; i < fileStatus.length; i++) { - if (fileStatus[i].isDirectory() == true) { - FileStatus[] cf = fs.listStatus(fileStatus[i].getPath(), new PathFilter() { - @Override - public boolean accept(Path p) { - if (WALSplitter.isSequenceIdFile(p)) { - return false; - } - return true; - } - }); - for (int j = 0; j < cf.length; j++) { - if (cf[j].isDirectory() == true) { - assertFalse(cf[j].getPath().getName().equals("cf2")); - } - } - } - } - } - - @Test - public void deleteColumnFamilyTwice() throws Exception { - - Admin admin = TEST_UTIL.getHBaseAdmin(); - HTableDescriptor beforehtd = admin.getTableDescriptor(TABLENAME); - String cfToDelete = "cf1"; - - FileSystem fs = TEST_UTIL.getDFSCluster().getFileSystem(); - - // 1 - Check if table exists in descriptor - assertTrue(admin.isTableAvailable(TABLENAME)); - - // 2 - Check if all the target column family exist in descriptor - HColumnDescriptor[] families = beforehtd.getColumnFamilies(); - Boolean foundCF = false; - int i; - for (i = 0; i < families.length; i++) { - if (families[i].getNameAsString().equals(cfToDelete)) { - foundCF = true; - break; - } - } - assertTrue(foundCF); - - // 3 - Check if table exists in FS - Path tableDir = FSUtils.getTableDir(TEST_UTIL.getDefaultRootDirPath(), TABLENAME); - assertTrue(fs.exists(tableDir)); - - // 4 - Check if all the target column family exist in FS - FileStatus[] fileStatus = fs.listStatus(tableDir); - foundCF = false; - for (i = 0; i < fileStatus.length; i++) { - if (fileStatus[i].isDirectory() == true) { - FileStatus[] cf = fs.listStatus(fileStatus[i].getPath(), new PathFilter() { - @Override - public boolean accept(Path p) { - if (p.getName().contains(HConstants.RECOVERED_EDITS_DIR)) { - return false; - } - return true; - } - }); - for (int j = 0; j < cf.length; j++) { - if (cf[j].isDirectory() == true && cf[j].getPath().getName().equals(cfToDelete)) { - foundCF = true; - break; - } - } - } - if (foundCF) { - break; - } - } - assertTrue(foundCF); - - // TEST - Disable and delete the column family - if (admin.isTableEnabled(TABLENAME)) { - admin.disableTable(TABLENAME); - } - admin.deleteColumn(TABLENAME, Bytes.toBytes(cfToDelete)); - - // 5 - Check if the target column family is gone from the FS - fileStatus = fs.listStatus(tableDir); - for (i = 0; i < fileStatus.length; i++) { - if (fileStatus[i].isDirectory() == true) { - FileStatus[] cf = fs.listStatus(fileStatus[i].getPath(), new PathFilter() { - @Override - public boolean accept(Path p) { - if (WALSplitter.isSequenceIdFile(p)) { - return false; - } - return true; - } - }); - for (int j = 0; j < cf.length; j++) { - if (cf[j].isDirectory() == true) { - assertFalse(cf[j].getPath().getName().equals(cfToDelete)); - } - } - } - } - - try { - // Test: delete again - admin.deleteColumn(TABLENAME, Bytes.toBytes(cfToDelete)); - Assert.fail("Delete a non-exist column family should fail"); - } catch (InvalidFamilyOperationException e) { - // Expected. - } - } - -} http://git-wip-us.apache.org/repos/asf/hbase/blob/07b8f79f/hbase-server/src/test/java/org/apache/hadoop/hbase/master/handler/TestTableDescriptorModification.java ---------------------------------------------------------------------- diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/master/handler/TestTableDescriptorModification.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/master/handler/TestTableDescriptorModification.java deleted file mode 100644 index 47f2b8f..0000000 --- a/hbase-server/src/test/java/org/apache/hadoop/hbase/master/handler/TestTableDescriptorModification.java +++ /dev/null @@ -1,289 +0,0 @@ -/** - * Copyright 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.handler; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; - -import java.io.IOException; -import java.util.Set; - -import org.apache.hadoop.fs.Path; -import org.apache.hadoop.hbase.HBaseTestingUtility; -import org.apache.hadoop.hbase.HColumnDescriptor; -import org.apache.hadoop.hbase.HTableDescriptor; -import org.apache.hadoop.hbase.testclassification.LargeTests; -import org.apache.hadoop.hbase.InvalidFamilyOperationException; -import org.apache.hadoop.hbase.TableName; -import org.apache.hadoop.hbase.client.Admin; -import org.apache.hadoop.hbase.master.MasterFileSystem; -import org.apache.hadoop.hbase.util.Bytes; -import org.apache.hadoop.hbase.util.FSTableDescriptors; -import org.apache.hadoop.hbase.util.FSUtils; -import org.junit.AfterClass; -import org.junit.Assert; -import org.junit.Before; -import org.junit.BeforeClass; -import org.junit.Rule; -import org.junit.Test; -import org.junit.experimental.categories.Category; -import org.junit.rules.TestName; - -/** - * Verify that the HTableDescriptor is updated after - * addColumn(), deleteColumn() and modifyTable() operations. - */ -@Category(LargeTests.class) -public class TestTableDescriptorModification { - - @Rule public TestName name = new TestName(); - private static final HBaseTestingUtility TEST_UTIL = new HBaseTestingUtility(); - private static TableName TABLE_NAME = null; - private static final byte[] FAMILY_0 = Bytes.toBytes("cf0"); - private static final byte[] FAMILY_1 = Bytes.toBytes("cf1"); - - /** - * Start up a mini cluster and put a small table of empty regions into it. - * - * @throws Exception - */ - @BeforeClass - public static void beforeAllTests() throws Exception { - TEST_UTIL.startMiniCluster(1); - } - - @Before - public void setup() { - TABLE_NAME = TableName.valueOf(name.getMethodName()); - - } - - @AfterClass - public static void afterAllTests() throws Exception { - TEST_UTIL.shutdownMiniCluster(); - } - - @Test - public void testModifyTable() throws IOException { - Admin admin = TEST_UTIL.getHBaseAdmin(); - // Create a table with one family - HTableDescriptor baseHtd = new HTableDescriptor(TABLE_NAME); - baseHtd.addFamily(new HColumnDescriptor(FAMILY_0)); - admin.createTable(baseHtd); - admin.disableTable(TABLE_NAME); - try { - // Verify the table descriptor - verifyTableDescriptor(TABLE_NAME, FAMILY_0); - - // Modify the table adding another family and verify the descriptor - HTableDescriptor modifiedHtd = new HTableDescriptor(TABLE_NAME); - modifiedHtd.addFamily(new HColumnDescriptor(FAMILY_0)); - modifiedHtd.addFamily(new HColumnDescriptor(FAMILY_1)); - admin.modifyTable(TABLE_NAME, modifiedHtd); - verifyTableDescriptor(TABLE_NAME, FAMILY_0, FAMILY_1); - } finally { - admin.deleteTable(TABLE_NAME); - } - } - - @Test - public void testAddColumn() throws IOException { - Admin admin = TEST_UTIL.getHBaseAdmin(); - // Create a table with two families - HTableDescriptor baseHtd = new HTableDescriptor(TABLE_NAME); - baseHtd.addFamily(new HColumnDescriptor(FAMILY_0)); - admin.createTable(baseHtd); - admin.disableTable(TABLE_NAME); - try { - // Verify the table descriptor - verifyTableDescriptor(TABLE_NAME, FAMILY_0); - - // Modify the table removing one family and verify the descriptor - admin.addColumn(TABLE_NAME, new HColumnDescriptor(FAMILY_1)); - verifyTableDescriptor(TABLE_NAME, FAMILY_0, FAMILY_1); - } finally { - admin.deleteTable(TABLE_NAME); - } - } - - @Test - public void testAddSameColumnFamilyTwice() throws IOException { - Admin admin = TEST_UTIL.getHBaseAdmin(); - // Create a table with one families - HTableDescriptor baseHtd = new HTableDescriptor(TABLE_NAME); - baseHtd.addFamily(new HColumnDescriptor(FAMILY_0)); - admin.createTable(baseHtd); - admin.disableTable(TABLE_NAME); - try { - // Verify the table descriptor - verifyTableDescriptor(TABLE_NAME, FAMILY_0); - - // Modify the table removing one family and verify the descriptor - admin.addColumn(TABLE_NAME, new HColumnDescriptor(FAMILY_1)); - verifyTableDescriptor(TABLE_NAME, FAMILY_0, FAMILY_1); - - try { - // Add same column family again - expect failure - admin.addColumn(TABLE_NAME, new HColumnDescriptor(FAMILY_1)); - Assert.fail("Delete a non-exist column family should fail"); - } catch (InvalidFamilyOperationException e) { - // Expected. - } - - } finally { - admin.deleteTable(TABLE_NAME); - } - } - - @Test - public void testModifyColumnFamily() throws IOException { - Admin admin = TEST_UTIL.getHBaseAdmin(); - - HColumnDescriptor cfDescriptor = new HColumnDescriptor(FAMILY_0); - int blockSize = cfDescriptor.getBlocksize(); - // Create a table with one families - HTableDescriptor baseHtd = new HTableDescriptor(TABLE_NAME); - baseHtd.addFamily(cfDescriptor); - admin.createTable(baseHtd); - admin.disableTable(TABLE_NAME); - try { - // Verify the table descriptor - verifyTableDescriptor(TABLE_NAME, FAMILY_0); - - int newBlockSize = 2 * blockSize; - cfDescriptor.setBlocksize(newBlockSize); - - // Modify colymn family - admin.modifyColumn(TABLE_NAME, cfDescriptor); - - HTableDescriptor htd = admin.getTableDescriptor(TABLE_NAME); - HColumnDescriptor hcfd = htd.getFamily(FAMILY_0); - assertTrue(hcfd.getBlocksize() == newBlockSize); - } finally { - admin.deleteTable(TABLE_NAME); - } - } - - @Test - public void testModifyNonExistingColumnFamily() throws IOException { - Admin admin = TEST_UTIL.getHBaseAdmin(); - - HColumnDescriptor cfDescriptor = new HColumnDescriptor(FAMILY_1); - int blockSize = cfDescriptor.getBlocksize(); - // Create a table with one families - HTableDescriptor baseHtd = new HTableDescriptor(TABLE_NAME); - baseHtd.addFamily(new HColumnDescriptor(FAMILY_0)); - admin.createTable(baseHtd); - admin.disableTable(TABLE_NAME); - try { - // Verify the table descriptor - verifyTableDescriptor(TABLE_NAME, FAMILY_0); - - int newBlockSize = 2 * blockSize; - cfDescriptor.setBlocksize(newBlockSize); - - // Modify a column family that is not in the table. - try { - admin.modifyColumn(TABLE_NAME, cfDescriptor); - Assert.fail("Modify a non-exist column family should fail"); - } catch (InvalidFamilyOperationException e) { - // Expected. - } - - } finally { - admin.deleteTable(TABLE_NAME); - } - } - - @Test - public void testDeleteColumn() throws IOException { - Admin admin = TEST_UTIL.getHBaseAdmin(); - // Create a table with two families - HTableDescriptor baseHtd = new HTableDescriptor(TABLE_NAME); - baseHtd.addFamily(new HColumnDescriptor(FAMILY_0)); - baseHtd.addFamily(new HColumnDescriptor(FAMILY_1)); - admin.createTable(baseHtd); - admin.disableTable(TABLE_NAME); - try { - // Verify the table descriptor - verifyTableDescriptor(TABLE_NAME, FAMILY_0, FAMILY_1); - - // Modify the table removing one family and verify the descriptor - admin.deleteColumn(TABLE_NAME, FAMILY_1); - verifyTableDescriptor(TABLE_NAME, FAMILY_0); - } finally { - admin.deleteTable(TABLE_NAME); - } - } - - @Test - public void testDeleteSameColumnFamilyTwice() throws IOException { - Admin admin = TEST_UTIL.getHBaseAdmin(); - // Create a table with two families - HTableDescriptor baseHtd = new HTableDescriptor(TABLE_NAME); - baseHtd.addFamily(new HColumnDescriptor(FAMILY_0)); - baseHtd.addFamily(new HColumnDescriptor(FAMILY_1)); - admin.createTable(baseHtd); - admin.disableTable(TABLE_NAME); - try { - // Verify the table descriptor - verifyTableDescriptor(TABLE_NAME, FAMILY_0, FAMILY_1); - - // Modify the table removing one family and verify the descriptor - admin.deleteColumn(TABLE_NAME, FAMILY_1); - verifyTableDescriptor(TABLE_NAME, FAMILY_0); - - try { - // Delete again - expect failure - admin.deleteColumn(TABLE_NAME, FAMILY_1); - Assert.fail("Delete a non-exist column family should fail"); - } catch (Exception e) { - // Expected. - } - } finally { - admin.deleteTable(TABLE_NAME); - } - } - - private void verifyTableDescriptor(final TableName tableName, - final byte[]... families) throws IOException { - Admin admin = TEST_UTIL.getHBaseAdmin(); - - // Verify descriptor from master - HTableDescriptor htd = admin.getTableDescriptor(tableName); - verifyTableDescriptor(htd, tableName, families); - - // Verify descriptor from HDFS - MasterFileSystem mfs = TEST_UTIL.getMiniHBaseCluster().getMaster().getMasterFileSystem(); - Path tableDir = FSUtils.getTableDir(mfs.getRootDir(), tableName); - htd = FSTableDescriptors.getTableDescriptorFromFs(mfs.getFileSystem(), tableDir); - verifyTableDescriptor(htd, tableName, families); - } - - private void verifyTableDescriptor(final HTableDescriptor htd, - final TableName tableName, final byte[]... families) { - Set<byte[]> htdFamilies = htd.getFamiliesKeys(); - assertEquals(tableName, htd.getTableName()); - assertEquals(families.length, htdFamilies.size()); - for (byte[] familyName: families) { - assertTrue("Expected family " + Bytes.toString(familyName), htdFamilies.contains(familyName)); - } - } -} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/hbase/blob/07b8f79f/hbase-server/src/test/java/org/apache/hadoop/hbase/master/procedure/TestDeleteColumnFamilyProcedureFromClient.java ---------------------------------------------------------------------- diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/master/procedure/TestDeleteColumnFamilyProcedureFromClient.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/master/procedure/TestDeleteColumnFamilyProcedureFromClient.java new file mode 100644 index 0000000..1fddc25 --- /dev/null +++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/master/procedure/TestDeleteColumnFamilyProcedureFromClient.java @@ -0,0 +1,269 @@ +/** + * Copyright 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.procedure; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import java.io.IOException; + +import org.apache.hadoop.fs.FileStatus; +import org.apache.hadoop.fs.FileSystem; +import org.apache.hadoop.fs.Path; +import org.apache.hadoop.fs.PathFilter; +import org.apache.hadoop.hbase.HBaseTestingUtility; +import org.apache.hadoop.hbase.HColumnDescriptor; +import org.apache.hadoop.hbase.HConstants; +import org.apache.hadoop.hbase.HTableDescriptor; +import org.apache.hadoop.hbase.testclassification.LargeTests; +import org.apache.hadoop.hbase.client.Admin; +import org.apache.hadoop.hbase.client.HTable; +import org.apache.hadoop.hbase.InvalidFamilyOperationException; +import org.apache.hadoop.hbase.TableName; +import org.apache.hadoop.hbase.client.Admin; +import org.apache.hadoop.hbase.client.Table; +import org.apache.hadoop.hbase.testclassification.LargeTests; +import org.apache.hadoop.hbase.util.Bytes; +import org.apache.hadoop.hbase.util.FSUtils; +import org.apache.hadoop.hbase.wal.WALSplitter; +import org.junit.After; +import org.junit.AfterClass; +import org.junit.Assert; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; +import org.junit.experimental.categories.Category; + +@Category(LargeTests.class) +public class TestDeleteColumnFamilyProcedureFromClient { + private static final HBaseTestingUtility TEST_UTIL = new HBaseTestingUtility(); + + private static final TableName TABLENAME = + TableName.valueOf("column_family_handlers"); + private static final byte[][] FAMILIES = new byte[][] { Bytes.toBytes("cf1"), + Bytes.toBytes("cf2"), Bytes.toBytes("cf3") }; + + /** + * Start up a mini cluster and put a small table of empty regions into it. + * + * @throws Exception + */ + @BeforeClass + public static void beforeAllTests() throws Exception { + TEST_UTIL.getConfiguration().setBoolean("dfs.support.append", true); + TEST_UTIL.startMiniCluster(2); + } + + @AfterClass + public static void afterAllTests() throws Exception { + TEST_UTIL.shutdownMiniCluster(); + } + + @Before + public void setup() throws IOException, InterruptedException { + // Create a table of three families. This will assign a region. + TEST_UTIL.createTable(TABLENAME, FAMILIES); + + HTable t = new HTable(TEST_UTIL.getConfiguration(), TABLENAME); + TEST_UTIL.waitUntilNoRegionsInTransition(); + + // Load the table with data for all families + TEST_UTIL.loadTable(t, FAMILIES); + + TEST_UTIL.flush(); + + t.close(); + + TEST_UTIL.ensureSomeRegionServersAvailable(2); + } + + @After + public void cleanup() throws Exception { + TEST_UTIL.deleteTable(TABLENAME); + } + + @Test + public void deleteColumnFamilyWithMultipleRegions() throws Exception { + Admin admin = TEST_UTIL.getHBaseAdmin(); + HTableDescriptor beforehtd = admin.getTableDescriptor(TABLENAME); + + FileSystem fs = TEST_UTIL.getDFSCluster().getFileSystem(); + + // 1 - Check if table exists in descriptor + assertTrue(admin.isTableAvailable(TABLENAME)); + + // 2 - Check if all three families exist in descriptor + assertEquals(3, beforehtd.getColumnFamilies().length); + HColumnDescriptor[] families = beforehtd.getColumnFamilies(); + for (int i = 0; i < families.length; i++) { + assertTrue(families[i].getNameAsString().equals("cf" + (i + 1))); + } + + // 3 - Check if table exists in FS + Path tableDir = FSUtils.getTableDir(TEST_UTIL.getDefaultRootDirPath(), TABLENAME); + assertTrue(fs.exists(tableDir)); + + // 4 - Check if all the 3 column families exist in FS + FileStatus[] fileStatus = fs.listStatus(tableDir); + for (int i = 0; i < fileStatus.length; i++) { + if (fileStatus[i].isDirectory() == true) { + FileStatus[] cf = fs.listStatus(fileStatus[i].getPath(), new PathFilter() { + @Override + public boolean accept(Path p) { + if (p.getName().contains(HConstants.RECOVERED_EDITS_DIR)) { + return false; + } + return true; + } + }); + int k = 1; + for (int j = 0; j < cf.length; j++) { + if (cf[j].isDirectory() == true + && cf[j].getPath().getName().startsWith(".") == false) { + assertEquals(cf[j].getPath().getName(), "cf" + k); + k++; + } + } + } + } + + // TEST - Disable and delete the column family + admin.disableTable(TABLENAME); + admin.deleteColumn(TABLENAME, Bytes.toBytes("cf2")); + + // 5 - Check if only 2 column families exist in the descriptor + HTableDescriptor afterhtd = admin.getTableDescriptor(TABLENAME); + assertEquals(2, afterhtd.getColumnFamilies().length); + HColumnDescriptor[] newFamilies = afterhtd.getColumnFamilies(); + assertTrue(newFamilies[0].getNameAsString().equals("cf1")); + assertTrue(newFamilies[1].getNameAsString().equals("cf3")); + + // 6 - Check if the second column family is gone from the FS + fileStatus = fs.listStatus(tableDir); + for (int i = 0; i < fileStatus.length; i++) { + if (fileStatus[i].isDirectory() == true) { + FileStatus[] cf = fs.listStatus(fileStatus[i].getPath(), new PathFilter() { + @Override + public boolean accept(Path p) { + if (WALSplitter.isSequenceIdFile(p)) { + return false; + } + return true; + } + }); + for (int j = 0; j < cf.length; j++) { + if (cf[j].isDirectory() == true) { + assertFalse(cf[j].getPath().getName().equals("cf2")); + } + } + } + } + } + + @Test + public void deleteColumnFamilyTwice() throws Exception { + Admin admin = TEST_UTIL.getHBaseAdmin(); + HTableDescriptor beforehtd = admin.getTableDescriptor(TABLENAME); + String cfToDelete = "cf1"; + + FileSystem fs = TEST_UTIL.getDFSCluster().getFileSystem(); + + // 1 - Check if table exists in descriptor + assertTrue(admin.isTableAvailable(TABLENAME)); + + // 2 - Check if all the target column family exist in descriptor + HColumnDescriptor[] families = beforehtd.getColumnFamilies(); + Boolean foundCF = false; + for (int i = 0; i < families.length; i++) { + if (families[i].getNameAsString().equals(cfToDelete)) { + foundCF = true; + break; + } + } + assertTrue(foundCF); + + // 3 - Check if table exists in FS + Path tableDir = FSUtils.getTableDir(TEST_UTIL.getDefaultRootDirPath(), TABLENAME); + assertTrue(fs.exists(tableDir)); + + // 4 - Check if all the target column family exist in FS + FileStatus[] fileStatus = fs.listStatus(tableDir); + foundCF = false; + for (int i = 0; i < fileStatus.length; i++) { + if (fileStatus[i].isDirectory() == true) { + FileStatus[] cf = fs.listStatus(fileStatus[i].getPath(), new PathFilter() { + @Override + public boolean accept(Path p) { + if (p.getName().contains(HConstants.RECOVERED_EDITS_DIR)) { + return false; + } + return true; + } + }); + for (int j = 0; j < cf.length; j++) { + if (cf[j].isDirectory() == true && cf[j].getPath().getName().equals(cfToDelete)) { + foundCF = true; + break; + } + } + } + if (foundCF) { + break; + } + } + assertTrue(foundCF); + + // TEST - Disable and delete the column family + if (admin.isTableEnabled(TABLENAME)) { + admin.disableTable(TABLENAME); + } + admin.deleteColumn(TABLENAME, Bytes.toBytes(cfToDelete)); + + // 5 - Check if the target column family is gone from the FS + fileStatus = fs.listStatus(tableDir); + for (int i = 0; i < fileStatus.length; i++) { + if (fileStatus[i].isDirectory() == true) { + FileStatus[] cf = fs.listStatus(fileStatus[i].getPath(), new PathFilter() { + @Override + public boolean accept(Path p) { + if (WALSplitter.isSequenceIdFile(p)) { + return false; + } + return true; + } + }); + for (int j = 0; j < cf.length; j++) { + if (cf[j].isDirectory() == true) { + assertFalse(cf[j].getPath().getName().equals(cfToDelete)); + } + } + } + } + + try { + // Test: delete again + admin.deleteColumn(TABLENAME, Bytes.toBytes(cfToDelete)); + Assert.fail("Delete a non-exist column family should fail"); + } catch (InvalidFamilyOperationException e) { + // Expected. + } + } +} http://git-wip-us.apache.org/repos/asf/hbase/blob/07b8f79f/hbase-server/src/test/java/org/apache/hadoop/hbase/master/procedure/TestTableDescriptorModificationFromClient.java ---------------------------------------------------------------------- diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/master/procedure/TestTableDescriptorModificationFromClient.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/master/procedure/TestTableDescriptorModificationFromClient.java new file mode 100644 index 0000000..0b5e83f --- /dev/null +++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/master/procedure/TestTableDescriptorModificationFromClient.java @@ -0,0 +1,289 @@ +/** + * Copyright 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.procedure; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import java.io.IOException; +import java.util.Set; + +import org.apache.hadoop.fs.Path; +import org.apache.hadoop.hbase.HBaseTestingUtility; +import org.apache.hadoop.hbase.HColumnDescriptor; +import org.apache.hadoop.hbase.HTableDescriptor; +import org.apache.hadoop.hbase.testclassification.LargeTests; +import org.apache.hadoop.hbase.InvalidFamilyOperationException; +import org.apache.hadoop.hbase.TableName; +import org.apache.hadoop.hbase.client.Admin; +import org.apache.hadoop.hbase.master.MasterFileSystem; +import org.apache.hadoop.hbase.util.Bytes; +import org.apache.hadoop.hbase.util.FSTableDescriptors; +import org.apache.hadoop.hbase.util.FSUtils; +import org.junit.AfterClass; +import org.junit.Assert; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Rule; +import org.junit.Test; +import org.junit.experimental.categories.Category; +import org.junit.rules.TestName; + +/** + * Verify that the HTableDescriptor is updated after + * addColumn(), deleteColumn() and modifyTable() operations. + */ +@Category(LargeTests.class) +public class TestTableDescriptorModificationFromClient { + + @Rule public TestName name = new TestName(); + private static final HBaseTestingUtility TEST_UTIL = new HBaseTestingUtility(); + private static TableName TABLE_NAME = null; + private static final byte[] FAMILY_0 = Bytes.toBytes("cf0"); + private static final byte[] FAMILY_1 = Bytes.toBytes("cf1"); + + /** + * Start up a mini cluster and put a small table of empty regions into it. + * + * @throws Exception + */ + @BeforeClass + public static void beforeAllTests() throws Exception { + TEST_UTIL.startMiniCluster(1); + } + + @Before + public void setup() { + TABLE_NAME = TableName.valueOf(name.getMethodName()); + + } + + @AfterClass + public static void afterAllTests() throws Exception { + TEST_UTIL.shutdownMiniCluster(); + } + + @Test + public void testModifyTable() throws IOException { + Admin admin = TEST_UTIL.getHBaseAdmin(); + // Create a table with one family + HTableDescriptor baseHtd = new HTableDescriptor(TABLE_NAME); + baseHtd.addFamily(new HColumnDescriptor(FAMILY_0)); + admin.createTable(baseHtd); + admin.disableTable(TABLE_NAME); + try { + // Verify the table descriptor + verifyTableDescriptor(TABLE_NAME, FAMILY_0); + + // Modify the table adding another family and verify the descriptor + HTableDescriptor modifiedHtd = new HTableDescriptor(TABLE_NAME); + modifiedHtd.addFamily(new HColumnDescriptor(FAMILY_0)); + modifiedHtd.addFamily(new HColumnDescriptor(FAMILY_1)); + admin.modifyTable(TABLE_NAME, modifiedHtd); + verifyTableDescriptor(TABLE_NAME, FAMILY_0, FAMILY_1); + } finally { + admin.deleteTable(TABLE_NAME); + } + } + + @Test + public void testAddColumn() throws IOException { + Admin admin = TEST_UTIL.getHBaseAdmin(); + // Create a table with two families + HTableDescriptor baseHtd = new HTableDescriptor(TABLE_NAME); + baseHtd.addFamily(new HColumnDescriptor(FAMILY_0)); + admin.createTable(baseHtd); + admin.disableTable(TABLE_NAME); + try { + // Verify the table descriptor + verifyTableDescriptor(TABLE_NAME, FAMILY_0); + + // Modify the table removing one family and verify the descriptor + admin.addColumn(TABLE_NAME, new HColumnDescriptor(FAMILY_1)); + verifyTableDescriptor(TABLE_NAME, FAMILY_0, FAMILY_1); + } finally { + admin.deleteTable(TABLE_NAME); + } + } + + @Test + public void testAddSameColumnFamilyTwice() throws IOException { + Admin admin = TEST_UTIL.getHBaseAdmin(); + // Create a table with one families + HTableDescriptor baseHtd = new HTableDescriptor(TABLE_NAME); + baseHtd.addFamily(new HColumnDescriptor(FAMILY_0)); + admin.createTable(baseHtd); + admin.disableTable(TABLE_NAME); + try { + // Verify the table descriptor + verifyTableDescriptor(TABLE_NAME, FAMILY_0); + + // Modify the table removing one family and verify the descriptor + admin.addColumn(TABLE_NAME, new HColumnDescriptor(FAMILY_1)); + verifyTableDescriptor(TABLE_NAME, FAMILY_0, FAMILY_1); + + try { + // Add same column family again - expect failure + admin.addColumn(TABLE_NAME, new HColumnDescriptor(FAMILY_1)); + Assert.fail("Delete a non-exist column family should fail"); + } catch (InvalidFamilyOperationException e) { + // Expected. + } + + } finally { + admin.deleteTable(TABLE_NAME); + } + } + + @Test + public void testModifyColumnFamily() throws IOException { + Admin admin = TEST_UTIL.getHBaseAdmin(); + + HColumnDescriptor cfDescriptor = new HColumnDescriptor(FAMILY_0); + int blockSize = cfDescriptor.getBlocksize(); + // Create a table with one families + HTableDescriptor baseHtd = new HTableDescriptor(TABLE_NAME); + baseHtd.addFamily(cfDescriptor); + admin.createTable(baseHtd); + admin.disableTable(TABLE_NAME); + try { + // Verify the table descriptor + verifyTableDescriptor(TABLE_NAME, FAMILY_0); + + int newBlockSize = 2 * blockSize; + cfDescriptor.setBlocksize(newBlockSize); + + // Modify colymn family + admin.modifyColumn(TABLE_NAME, cfDescriptor); + + HTableDescriptor htd = admin.getTableDescriptor(TABLE_NAME); + HColumnDescriptor hcfd = htd.getFamily(FAMILY_0); + assertTrue(hcfd.getBlocksize() == newBlockSize); + } finally { + admin.deleteTable(TABLE_NAME); + } + } + + @Test + public void testModifyNonExistingColumnFamily() throws IOException { + Admin admin = TEST_UTIL.getHBaseAdmin(); + + HColumnDescriptor cfDescriptor = new HColumnDescriptor(FAMILY_1); + int blockSize = cfDescriptor.getBlocksize(); + // Create a table with one families + HTableDescriptor baseHtd = new HTableDescriptor(TABLE_NAME); + baseHtd.addFamily(new HColumnDescriptor(FAMILY_0)); + admin.createTable(baseHtd); + admin.disableTable(TABLE_NAME); + try { + // Verify the table descriptor + verifyTableDescriptor(TABLE_NAME, FAMILY_0); + + int newBlockSize = 2 * blockSize; + cfDescriptor.setBlocksize(newBlockSize); + + // Modify a column family that is not in the table. + try { + admin.modifyColumn(TABLE_NAME, cfDescriptor); + Assert.fail("Modify a non-exist column family should fail"); + } catch (InvalidFamilyOperationException e) { + // Expected. + } + + } finally { + admin.deleteTable(TABLE_NAME); + } + } + + @Test + public void testDeleteColumn() throws IOException { + Admin admin = TEST_UTIL.getHBaseAdmin(); + // Create a table with two families + HTableDescriptor baseHtd = new HTableDescriptor(TABLE_NAME); + baseHtd.addFamily(new HColumnDescriptor(FAMILY_0)); + baseHtd.addFamily(new HColumnDescriptor(FAMILY_1)); + admin.createTable(baseHtd); + admin.disableTable(TABLE_NAME); + try { + // Verify the table descriptor + verifyTableDescriptor(TABLE_NAME, FAMILY_0, FAMILY_1); + + // Modify the table removing one family and verify the descriptor + admin.deleteColumn(TABLE_NAME, FAMILY_1); + verifyTableDescriptor(TABLE_NAME, FAMILY_0); + } finally { + admin.deleteTable(TABLE_NAME); + } + } + + @Test + public void testDeleteSameColumnFamilyTwice() throws IOException { + Admin admin = TEST_UTIL.getHBaseAdmin(); + // Create a table with two families + HTableDescriptor baseHtd = new HTableDescriptor(TABLE_NAME); + baseHtd.addFamily(new HColumnDescriptor(FAMILY_0)); + baseHtd.addFamily(new HColumnDescriptor(FAMILY_1)); + admin.createTable(baseHtd); + admin.disableTable(TABLE_NAME); + try { + // Verify the table descriptor + verifyTableDescriptor(TABLE_NAME, FAMILY_0, FAMILY_1); + + // Modify the table removing one family and verify the descriptor + admin.deleteColumn(TABLE_NAME, FAMILY_1); + verifyTableDescriptor(TABLE_NAME, FAMILY_0); + + try { + // Delete again - expect failure + admin.deleteColumn(TABLE_NAME, FAMILY_1); + Assert.fail("Delete a non-exist column family should fail"); + } catch (Exception e) { + // Expected. + } + } finally { + admin.deleteTable(TABLE_NAME); + } + } + + private void verifyTableDescriptor(final TableName tableName, + final byte[]... families) throws IOException { + Admin admin = TEST_UTIL.getHBaseAdmin(); + + // Verify descriptor from master + HTableDescriptor htd = admin.getTableDescriptor(tableName); + verifyTableDescriptor(htd, tableName, families); + + // Verify descriptor from HDFS + MasterFileSystem mfs = TEST_UTIL.getMiniHBaseCluster().getMaster().getMasterFileSystem(); + Path tableDir = FSUtils.getTableDir(mfs.getRootDir(), tableName); + htd = FSTableDescriptors.getTableDescriptorFromFs(mfs.getFileSystem(), tableDir); + verifyTableDescriptor(htd, tableName, families); + } + + private void verifyTableDescriptor(final HTableDescriptor htd, + final TableName tableName, final byte[]... families) { + Set<byte[]> htdFamilies = htd.getFamiliesKeys(); + assertEquals(tableName, htd.getTableName()); + assertEquals(families.length, htdFamilies.size()); + for (byte[] familyName: families) { + assertTrue("Expected family " + Bytes.toString(familyName), htdFamilies.contains(familyName)); + } + } +}