1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.hadoop.hbase.master.procedure;
20
21 import org.apache.commons.logging.Log;
22 import org.apache.commons.logging.LogFactory;
23 import org.apache.hadoop.conf.Configuration;
24 import org.apache.hadoop.hbase.HBaseTestingUtility;
25 import org.apache.hadoop.hbase.HTableDescriptor;
26 import org.apache.hadoop.hbase.HRegionInfo;
27 import org.apache.hadoop.hbase.ProcedureInfo;
28 import org.apache.hadoop.hbase.TableName;
29 import org.apache.hadoop.hbase.TableNotDisabledException;
30 import org.apache.hadoop.hbase.TableNotFoundException;
31 import org.apache.hadoop.hbase.procedure2.ProcedureExecutor;
32 import org.apache.hadoop.hbase.procedure2.ProcedureTestingUtility;
33 import org.apache.hadoop.hbase.protobuf.generated.MasterProcedureProtos.DeleteTableState;
34 import org.apache.hadoop.hbase.testclassification.MediumTests;
35 import org.apache.hadoop.hbase.util.Bytes;
36 import org.junit.After;
37 import org.junit.AfterClass;
38 import org.junit.Before;
39 import org.junit.BeforeClass;
40 import org.junit.Test;
41 import org.junit.experimental.categories.Category;
42
43 import static org.junit.Assert.assertTrue;
44
45 @Category(MediumTests.class)
46 public class TestDeleteTableProcedure {
47 private static final Log LOG = LogFactory.getLog(TestDeleteTableProcedure.class);
48
49 protected static final HBaseTestingUtility UTIL = new HBaseTestingUtility();
50
51 private static void setupConf(Configuration conf) {
52 conf.setInt(MasterProcedureConstants.MASTER_PROCEDURE_THREADS, 1);
53 }
54
55 @BeforeClass
56 public static void setupCluster() throws Exception {
57 setupConf(UTIL.getConfiguration());
58 UTIL.startMiniCluster(1);
59 }
60
61 @AfterClass
62 public static void cleanupTest() throws Exception {
63 try {
64 UTIL.shutdownMiniCluster();
65 } catch (Exception e) {
66 LOG.warn("failure shutting down cluster", e);
67 }
68 }
69
70 @Before
71 public void setup() throws Exception {
72 final ProcedureExecutor<MasterProcedureEnv> procExec = getMasterProcedureExecutor();
73 ProcedureTestingUtility.setKillAndToggleBeforeStoreUpdate(procExec, false);
74 assertTrue("expected executor to be running", procExec.isRunning());
75 }
76
77 @After
78 public void tearDown() throws Exception {
79 ProcedureTestingUtility.setKillAndToggleBeforeStoreUpdate(getMasterProcedureExecutor(), false);
80 for (HTableDescriptor htd: UTIL.getHBaseAdmin().listTables()) {
81 LOG.info("Tear down, remove table=" + htd.getTableName());
82 UTIL.deleteTable(htd.getTableName());
83 }
84 }
85
86 @Test(timeout=60000, expected=TableNotFoundException.class)
87 public void testDeleteNotExistentTable() throws Exception {
88 final TableName tableName = TableName.valueOf("testDeleteNotExistentTable");
89
90 final ProcedureExecutor<MasterProcedureEnv> procExec = getMasterProcedureExecutor();
91 ProcedurePrepareLatch latch = new ProcedurePrepareLatch.CompatibilityLatch();
92 long procId = ProcedureTestingUtility.submitAndWait(procExec,
93 new DeleteTableProcedure(procExec.getEnvironment(), tableName, latch));
94 latch.await();
95 }
96
97 @Test(timeout=60000, expected=TableNotDisabledException.class)
98 public void testDeleteNotDisabledTable() throws Exception {
99 final TableName tableName = TableName.valueOf("testDeleteNotDisabledTable");
100
101 final ProcedureExecutor<MasterProcedureEnv> procExec = getMasterProcedureExecutor();
102 MasterProcedureTestingUtility.createTable(procExec, tableName, null, "f");
103
104 ProcedurePrepareLatch latch = new ProcedurePrepareLatch.CompatibilityLatch();
105 long procId = ProcedureTestingUtility.submitAndWait(procExec,
106 new DeleteTableProcedure(procExec.getEnvironment(), tableName, latch));
107 latch.await();
108 }
109
110 @Test(timeout=60000)
111 public void testDeleteDeletedTable() throws Exception {
112 final TableName tableName = TableName.valueOf("testDeleteDeletedTable");
113 final ProcedureExecutor<MasterProcedureEnv> procExec = getMasterProcedureExecutor();
114
115 HRegionInfo[] regions = MasterProcedureTestingUtility.createTable(
116 procExec, tableName, null, "f");
117 UTIL.getHBaseAdmin().disableTable(tableName);
118
119
120 long procId1 = procExec.submitProcedure(
121 new DeleteTableProcedure(procExec.getEnvironment(), tableName));
122
123 long procId2 = procExec.submitProcedure(
124 new DeleteTableProcedure(procExec.getEnvironment(), tableName));
125
126
127 ProcedureTestingUtility.waitProcedure(procExec, procId1);
128 ProcedureTestingUtility.waitProcedure(procExec, procId2);
129
130
131 ProcedureTestingUtility.assertProcNotFailed(procExec, procId1);
132 MasterProcedureTestingUtility.validateTableDeletion(
133 UTIL.getHBaseCluster().getMaster(), tableName, regions, "f");
134
135
136 ProcedureInfo result = procExec.getResult(procId2);
137 assertTrue(result.isFailed());
138 LOG.debug("Delete failed with exception: " + result.getExceptionFullMessage());
139 assertTrue(ProcedureTestingUtility.getExceptionCause(result) instanceof TableNotFoundException);
140 }
141
142 @Test(timeout=60000)
143 public void testSimpleDelete() throws Exception {
144 final TableName tableName = TableName.valueOf("testSimpleDelete");
145 final byte[][] splitKeys = null;
146 testSimpleDelete(tableName, splitKeys);
147 }
148
149 @Test(timeout=60000)
150 public void testSimpleDeleteWithSplits() throws Exception {
151 final TableName tableName = TableName.valueOf("testSimpleDeleteWithSplits");
152 final byte[][] splitKeys = new byte[][] {
153 Bytes.toBytes("a"), Bytes.toBytes("b"), Bytes.toBytes("c")
154 };
155 testSimpleDelete(tableName, splitKeys);
156 }
157
158 private void testSimpleDelete(final TableName tableName, byte[][] splitKeys) throws Exception {
159 HRegionInfo[] regions = MasterProcedureTestingUtility.createTable(
160 getMasterProcedureExecutor(), tableName, splitKeys, "f1", "f2");
161 UTIL.getHBaseAdmin().disableTable(tableName);
162
163
164 final ProcedureExecutor<MasterProcedureEnv> procExec = getMasterProcedureExecutor();
165 long procId = ProcedureTestingUtility.submitAndWait(procExec,
166 new DeleteTableProcedure(procExec.getEnvironment(), tableName));
167 ProcedureTestingUtility.assertProcNotFailed(procExec, procId);
168 MasterProcedureTestingUtility.validateTableDeletion(
169 UTIL.getHBaseCluster().getMaster(), tableName, regions, "f1", "f2");
170 }
171
172 @Test(timeout=60000)
173 public void testRecoveryAndDoubleExecution() throws Exception {
174 final TableName tableName = TableName.valueOf("testRecoveryAndDoubleExecution");
175
176
177 byte[][] splitKeys = null;
178 HRegionInfo[] regions = MasterProcedureTestingUtility.createTable(
179 getMasterProcedureExecutor(), tableName, splitKeys, "f1", "f2");
180 UTIL.getHBaseAdmin().disableTable(tableName);
181
182 final ProcedureExecutor<MasterProcedureEnv> procExec = getMasterProcedureExecutor();
183 ProcedureTestingUtility.waitNoProcedureRunning(procExec);
184 ProcedureTestingUtility.setKillAndToggleBeforeStoreUpdate(procExec, true);
185
186
187 long procId = procExec.submitProcedure(
188 new DeleteTableProcedure(procExec.getEnvironment(), tableName));
189
190
191
192
193 MasterProcedureTestingUtility.testRecoveryAndDoubleExecution(
194 procExec, procId, 6, DeleteTableState.values());
195
196 MasterProcedureTestingUtility.validateTableDeletion(
197 UTIL.getHBaseCluster().getMaster(), tableName, regions, "f1", "f2");
198 }
199
200 private ProcedureExecutor<MasterProcedureEnv> getMasterProcedureExecutor() {
201 return UTIL.getHBaseCluster().getMaster().getMasterProcedureExecutor();
202 }
203 }