View Javadoc

1   /**
2    * Copyright The Apache Software Foundation
3    *
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *     http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing, software
15   * distributed under the License is distributed on an "AS IS" BASIS,
16   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17   * See the License for the specific language governing permissions and
18   * limitations under the License.
19   */
20  package org.apache.hadoop.hbase.master.handler;
21  
22  import static org.junit.Assert.assertEquals;
23  import static org.junit.Assert.assertFalse;
24  import static org.junit.Assert.assertTrue;
25  
26  import java.io.IOException;
27  
28  import org.apache.hadoop.fs.FileStatus;
29  import org.apache.hadoop.fs.FileSystem;
30  import org.apache.hadoop.fs.Path;
31  import org.apache.hadoop.hbase.TableName;
32  import org.apache.hadoop.hbase.HBaseTestingUtility;
33  import org.apache.hadoop.hbase.HColumnDescriptor;
34  import org.apache.hadoop.hbase.HTableDescriptor;
35  import org.apache.hadoop.hbase.LargeTests;
36  import org.apache.hadoop.hbase.client.HBaseAdmin;
37  import org.apache.hadoop.hbase.client.HTable;
38  import org.apache.hadoop.hbase.util.Bytes;
39  import org.apache.hadoop.hbase.util.FSUtils;
40  import org.junit.AfterClass;
41  import org.junit.Before;
42  import org.junit.BeforeClass;
43  import org.junit.Test;
44  import org.junit.experimental.categories.Category;
45  
46  @Category(LargeTests.class)
47  public class TestTableDeleteFamilyHandler {
48  
49    private static final HBaseTestingUtility TEST_UTIL = new HBaseTestingUtility();
50    private static final TableName TABLENAME =
51        TableName.valueOf("column_family_handlers");
52    private static final byte[][] FAMILIES = new byte[][] { Bytes.toBytes("cf1"),
53        Bytes.toBytes("cf2"), Bytes.toBytes("cf3") };
54  
55    /**
56     * Start up a mini cluster and put a small table of empty regions into it.
57     * 
58     * @throws Exception
59     */
60    @BeforeClass
61    public static void beforeAllTests() throws Exception {
62  
63      TEST_UTIL.getConfiguration().setBoolean("dfs.support.append", true);
64      TEST_UTIL.startMiniCluster(2);
65  
66      // Create a table of three families. This will assign a region.
67      TEST_UTIL.createTable(TABLENAME, FAMILIES);
68      HTable t = new HTable(TEST_UTIL.getConfiguration(), TABLENAME);
69      while(TEST_UTIL.getMiniHBaseCluster().getMaster().getAssignmentManager()
70          .getRegionStates().getRegionsInTransition().size() > 0) {
71        Thread.sleep(100);
72      }
73      // Create multiple regions in all the three column families
74      while(TEST_UTIL.getMiniHBaseCluster().getMaster().getAssignmentManager()
75          .getRegionStates().getRegionsInTransition().size() > 0) {
76        Thread.sleep(100);
77      }
78      // Load the table with data for all families
79      TEST_UTIL.loadTable(t, FAMILIES);
80  
81      TEST_UTIL.flush();
82  
83      t.close();
84    }
85  
86    @AfterClass
87    public static void afterAllTests() throws Exception {
88      TEST_UTIL.deleteTable(TABLENAME);
89      TEST_UTIL.shutdownMiniCluster();
90    }
91  
92    @Before
93    public void setup() throws IOException, InterruptedException {
94      TEST_UTIL.ensureSomeRegionServersAvailable(2);
95    }
96  
97    @Test
98    public void deleteColumnFamilyWithMultipleRegions() throws Exception {
99  
100     HBaseAdmin admin = TEST_UTIL.getHBaseAdmin();
101     HTableDescriptor beforehtd = admin.getTableDescriptor(TABLENAME);
102 
103     FileSystem fs = TEST_UTIL.getDFSCluster().getFileSystem();
104 
105     // 1 - Check if table exists in descriptor
106     assertTrue(admin.isTableAvailable(TABLENAME));
107 
108     // 2 - Check if all three families exist in descriptor
109     assertEquals(3, beforehtd.getColumnFamilies().length);
110     HColumnDescriptor[] families = beforehtd.getColumnFamilies();
111     for (int i = 0; i < families.length; i++) {
112 
113       assertTrue(families[i].getNameAsString().equals("cf" + (i + 1)));
114     }
115 
116     // 3 - Check if table exists in FS
117     Path tableDir = FSUtils.getTableDir(TEST_UTIL.getDefaultRootDirPath(), TABLENAME);
118     assertTrue(fs.exists(tableDir));
119 
120     // 4 - Check if all the 3 column families exist in FS
121     FileStatus[] fileStatus = fs.listStatus(tableDir);
122     for (int i = 0; i < fileStatus.length; i++) {
123       if (fileStatus[i].isDir() == true) {
124         FileStatus[] cf = fs.listStatus(fileStatus[i].getPath());
125         int k = 1;
126         for (int j = 0; j < cf.length; j++) {
127           if (cf[j].isDir() == true
128               && cf[j].getPath().getName().startsWith(".") == false) {
129             assertEquals(cf[j].getPath().getName(), "cf" + k);
130             k++;
131           }
132         }
133       }
134     }
135 
136     // TEST - Disable and delete the column family
137     admin.disableTable(TABLENAME);
138     admin.deleteColumn(TABLENAME.getName(), "cf2");
139 
140     // 5 - Check if only 2 column families exist in the descriptor
141     HTableDescriptor afterhtd = admin.getTableDescriptor(TABLENAME);
142     assertEquals(2, afterhtd.getColumnFamilies().length);
143     HColumnDescriptor[] newFamilies = afterhtd.getColumnFamilies();
144     assertTrue(newFamilies[0].getNameAsString().equals("cf1"));
145     assertTrue(newFamilies[1].getNameAsString().equals("cf3"));
146 
147     // 6 - Check if the second column family is gone from the FS
148     fileStatus = fs.listStatus(tableDir);
149     for (int i = 0; i < fileStatus.length; i++) {
150       if (fileStatus[i].isDir() == true) {
151         FileStatus[] cf = fs.listStatus(fileStatus[i].getPath());
152         for (int j = 0; j < cf.length; j++) {
153           if (cf[j].isDir() == true) {
154             assertFalse(cf[j].getPath().getName().equals("cf2"));
155           }
156         }
157       }
158     }
159   }
160 
161 }