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.fs.PathFilter;
32  import org.apache.hadoop.hbase.HConstants;
33  import org.apache.hadoop.hbase.TableName;
34  import org.apache.hadoop.hbase.HBaseTestingUtility;
35  import org.apache.hadoop.hbase.HColumnDescriptor;
36  import org.apache.hadoop.hbase.HTableDescriptor;
37  import org.apache.hadoop.hbase.testclassification.LargeTests;
38  import org.apache.hadoop.hbase.client.Admin;
39  import org.apache.hadoop.hbase.client.HTable;
40  import org.apache.hadoop.hbase.util.Bytes;
41  import org.apache.hadoop.hbase.util.FSUtils;
42  import org.apache.hadoop.hbase.wal.WALSplitter;
43  import org.junit.AfterClass;
44  import org.junit.Before;
45  import org.junit.BeforeClass;
46  import org.junit.Test;
47  import org.junit.experimental.categories.Category;
48  
49  @Category(LargeTests.class)
50  public class TestTableDeleteFamilyHandler {
51  
52    private static final HBaseTestingUtility TEST_UTIL = new HBaseTestingUtility();
53    private static final TableName TABLENAME =
54        TableName.valueOf("column_family_handlers");
55    private static final byte[][] FAMILIES = new byte[][] { Bytes.toBytes("cf1"),
56        Bytes.toBytes("cf2"), Bytes.toBytes("cf3") };
57  
58    /**
59     * Start up a mini cluster and put a small table of empty regions into it.
60     * 
61     * @throws Exception
62     */
63    @BeforeClass
64    public static void beforeAllTests() throws Exception {
65  
66      TEST_UTIL.getConfiguration().setBoolean("dfs.support.append", true);
67      TEST_UTIL.startMiniCluster(2);
68  
69      // Create a table of three families. This will assign a region.
70      TEST_UTIL.createTable(TABLENAME, FAMILIES);
71      HTable t = new HTable(TEST_UTIL.getConfiguration(), TABLENAME);
72      while(TEST_UTIL.getMiniHBaseCluster().getMaster().getAssignmentManager()
73          .getRegionStates().getRegionsInTransition().size() > 0) {
74        Thread.sleep(100);
75      }
76      // Create multiple regions in all the three column families
77      while(TEST_UTIL.getMiniHBaseCluster().getMaster().getAssignmentManager()
78          .getRegionStates().getRegionsInTransition().size() > 0) {
79        Thread.sleep(100);
80      }
81      // Load the table with data for all families
82      TEST_UTIL.loadTable(t, FAMILIES);
83  
84      TEST_UTIL.flush();
85  
86      t.close();
87    }
88  
89    @AfterClass
90    public static void afterAllTests() throws Exception {
91      TEST_UTIL.deleteTable(TABLENAME);
92      TEST_UTIL.shutdownMiniCluster();
93    }
94  
95    @Before
96    public void setup() throws IOException, InterruptedException {
97      TEST_UTIL.ensureSomeRegionServersAvailable(2);
98    }
99  
100   @Test
101   public void deleteColumnFamilyWithMultipleRegions() throws Exception {
102 
103     Admin admin = TEST_UTIL.getHBaseAdmin();
104     HTableDescriptor beforehtd = admin.getTableDescriptor(TABLENAME);
105 
106     FileSystem fs = TEST_UTIL.getDFSCluster().getFileSystem();
107 
108     // 1 - Check if table exists in descriptor
109     assertTrue(admin.isTableAvailable(TABLENAME));
110 
111     // 2 - Check if all three families exist in descriptor
112     assertEquals(3, beforehtd.getColumnFamilies().length);
113     HColumnDescriptor[] families = beforehtd.getColumnFamilies();
114     for (int i = 0; i < families.length; i++) {
115 
116       assertTrue(families[i].getNameAsString().equals("cf" + (i + 1)));
117     }
118 
119     // 3 - Check if table exists in FS
120     Path tableDir = FSUtils.getTableDir(TEST_UTIL.getDefaultRootDirPath(), TABLENAME);
121     assertTrue(fs.exists(tableDir));
122 
123     // 4 - Check if all the 3 column families exist in FS
124     FileStatus[] fileStatus = fs.listStatus(tableDir);
125     for (int i = 0; i < fileStatus.length; i++) {
126       if (fileStatus[i].isDirectory() == true) {
127         FileStatus[] cf = fs.listStatus(fileStatus[i].getPath(), new PathFilter() {
128           @Override
129           public boolean accept(Path p) {
130             if (p.getName().contains(HConstants.RECOVERED_EDITS_DIR)) {
131               return false;
132             }
133             return true;
134           }
135         });
136         int k = 1;
137         for (int j = 0; j < cf.length; j++) {
138           if (cf[j].isDirectory() == true
139               && cf[j].getPath().getName().startsWith(".") == false) {
140             assertEquals(cf[j].getPath().getName(), "cf" + k);
141             k++;
142           }
143         }
144       }
145     }
146 
147     // TEST - Disable and delete the column family
148     admin.disableTable(TABLENAME);
149     admin.deleteColumn(TABLENAME, Bytes.toBytes("cf2"));
150 
151     // 5 - Check if only 2 column families exist in the descriptor
152     HTableDescriptor afterhtd = admin.getTableDescriptor(TABLENAME);
153     assertEquals(2, afterhtd.getColumnFamilies().length);
154     HColumnDescriptor[] newFamilies = afterhtd.getColumnFamilies();
155     assertTrue(newFamilies[0].getNameAsString().equals("cf1"));
156     assertTrue(newFamilies[1].getNameAsString().equals("cf3"));
157 
158     // 6 - Check if the second column family is gone from the FS
159     fileStatus = fs.listStatus(tableDir);
160     for (int i = 0; i < fileStatus.length; i++) {
161       if (fileStatus[i].isDirectory() == true) {
162         FileStatus[] cf = fs.listStatus(fileStatus[i].getPath(), new PathFilter() {
163           @Override
164           public boolean accept(Path p) {
165             if (WALSplitter.isSequenceIdFile(p)) {
166               return false;
167             }
168             return true;
169           }
170         });
171         for (int j = 0; j < cf.length; j++) {
172           if (cf[j].isDirectory() == true) {
173             assertFalse(cf[j].getPath().getName().equals("cf2"));
174           }
175         }
176       }
177     }
178   }
179 
180 }