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