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 static org.junit.Assert.assertNotNull;
22 import static org.junit.Assert.assertNull;
23 import static org.junit.Assert.assertTrue;
24
25 import java.io.IOException;
26
27 import org.apache.commons.logging.Log;
28 import org.apache.commons.logging.LogFactory;
29 import org.apache.hadoop.conf.Configuration;
30 import org.apache.hadoop.hbase.HBaseTestingUtility;
31 import org.apache.hadoop.hbase.HTableDescriptor;
32 import org.apache.hadoop.hbase.NamespaceDescriptor;
33 import org.apache.hadoop.hbase.NamespaceNotFoundException;
34 import org.apache.hadoop.hbase.ProcedureInfo;
35 import org.apache.hadoop.hbase.TableName;
36 import org.apache.hadoop.hbase.constraint.ConstraintException;
37 import org.apache.hadoop.hbase.procedure2.ProcedureExecutor;
38 import org.apache.hadoop.hbase.procedure2.ProcedureTestingUtility;
39 import org.apache.hadoop.hbase.protobuf.generated.MasterProcedureProtos.DeleteNamespaceState;
40 import org.apache.hadoop.hbase.testclassification.MediumTests;
41 import org.junit.After;
42 import org.junit.AfterClass;
43 import org.junit.Before;
44 import org.junit.BeforeClass;
45 import org.junit.Test;
46 import org.junit.experimental.categories.Category;
47
48 @Category(MediumTests.class)
49 public class TestDeleteNamespaceProcedure {
50 private static final Log LOG = LogFactory.getLog(TestDeleteNamespaceProcedure.class);
51
52 protected static final HBaseTestingUtility UTIL = new HBaseTestingUtility();
53
54 private static void setupConf(Configuration conf) {
55 conf.setInt(MasterProcedureConstants.MASTER_PROCEDURE_THREADS, 1);
56 }
57
58 @BeforeClass
59 public static void setupCluster() throws Exception {
60 setupConf(UTIL.getConfiguration());
61 UTIL.startMiniCluster(1);
62 }
63
64 @AfterClass
65 public static void cleanupTest() throws Exception {
66 try {
67 UTIL.shutdownMiniCluster();
68 } catch (Exception e) {
69 LOG.warn("failure shutting down cluster", e);
70 }
71 }
72
73 @Before
74 public void setup() throws Exception {
75 ProcedureTestingUtility.setKillAndToggleBeforeStoreUpdate(getMasterProcedureExecutor(), false);
76 }
77
78 @After
79 public void tearDown() throws Exception {
80 ProcedureTestingUtility.setKillAndToggleBeforeStoreUpdate(getMasterProcedureExecutor(), false);
81 for (HTableDescriptor htd: UTIL.getHBaseAdmin().listTables()) {
82 LOG.info("Tear down, remove table=" + htd.getTableName());
83 UTIL.deleteTable(htd.getTableName());
84 }
85 }
86
87 @Test(timeout = 60000)
88 public void testDeleteNamespace() throws Exception {
89 final String namespaceName = "testDeleteNamespace";
90 final ProcedureExecutor<MasterProcedureEnv> procExec = getMasterProcedureExecutor();
91
92 createNamespaceForTesting(namespaceName);
93
94 long procId = procExec.submitProcedure(
95 new DeleteNamespaceProcedure(procExec.getEnvironment(), namespaceName));
96
97 ProcedureTestingUtility.waitProcedure(procExec, procId);
98 ProcedureTestingUtility.assertProcNotFailed(procExec, procId);
99
100 validateNamespaceNotExist(namespaceName);
101 }
102
103 @Test(timeout=60000)
104 public void testDeleteNonExistNamespace() throws Exception {
105 final String namespaceName = "testDeleteNonExistNamespace";
106 final ProcedureExecutor<MasterProcedureEnv> procExec = getMasterProcedureExecutor();
107
108 validateNamespaceNotExist(namespaceName);
109
110 long procId = procExec.submitProcedure(
111 new DeleteNamespaceProcedure(procExec.getEnvironment(), namespaceName));
112
113 ProcedureTestingUtility.waitProcedure(procExec, procId);
114
115 ProcedureInfo result = procExec.getResult(procId);
116 assertTrue(result.isFailed());
117 LOG.debug("Delete namespace failed with exception: " + result.getExceptionFullMessage());
118 assertTrue(
119 ProcedureTestingUtility.getExceptionCause(result) instanceof NamespaceNotFoundException);
120 }
121
122 @Test(timeout=60000)
123 public void testDeleteSystemNamespace() throws Exception {
124 final String namespaceName = NamespaceDescriptor.SYSTEM_NAMESPACE.getName();
125 final ProcedureExecutor<MasterProcedureEnv> procExec = getMasterProcedureExecutor();
126
127 long procId = procExec.submitProcedure(
128 new DeleteNamespaceProcedure(procExec.getEnvironment(), namespaceName));
129
130 ProcedureTestingUtility.waitProcedure(procExec, procId);
131 ProcedureInfo result = procExec.getResult(procId);
132 assertTrue(result.isFailed());
133 LOG.debug("Delete namespace failed with exception: " + result.getExceptionFullMessage());
134 assertTrue(ProcedureTestingUtility.getExceptionCause(result) instanceof ConstraintException);
135 }
136
137 @Test(timeout=60000)
138 public void testDeleteNonEmptyNamespace() throws Exception {
139 final String namespaceName = "testDeleteNonExistNamespace";
140 final TableName tableName = TableName.valueOf("testDeleteNonExistNamespace:t1");
141 final ProcedureExecutor<MasterProcedureEnv> procExec = getMasterProcedureExecutor();
142
143 createNamespaceForTesting(namespaceName);
144
145 MasterProcedureTestingUtility.createTable(procExec, tableName, null, "f1");
146
147 long procId = procExec.submitProcedure(
148 new DeleteNamespaceProcedure(procExec.getEnvironment(), namespaceName));
149
150 ProcedureTestingUtility.waitProcedure(procExec, procId);
151 ProcedureInfo result = procExec.getResult(procId);
152 assertTrue(result.isFailed());
153 LOG.debug("Delete namespace failed with exception: " + result.getExceptionFullMessage());
154 assertTrue(ProcedureTestingUtility.getExceptionCause(result) instanceof ConstraintException);
155 }
156
157 @Test(timeout = 60000)
158 public void testRecoveryAndDoubleExecution() throws Exception {
159 final String namespaceName = "testRecoveryAndDoubleExecution";
160 final ProcedureExecutor<MasterProcedureEnv> procExec = getMasterProcedureExecutor();
161
162 createNamespaceForTesting(namespaceName);
163
164 ProcedureTestingUtility.waitNoProcedureRunning(procExec);
165 ProcedureTestingUtility.setKillAndToggleBeforeStoreUpdate(procExec, true);
166
167
168 long procId = procExec.submitProcedure(
169 new DeleteNamespaceProcedure(procExec.getEnvironment(), namespaceName));
170
171 int numberOfSteps = DeleteNamespaceState.values().length;
172 MasterProcedureTestingUtility.testRecoveryAndDoubleExecution(
173 procExec,
174 procId,
175 numberOfSteps,
176 DeleteNamespaceState.values());
177
178
179 ProcedureTestingUtility.assertProcNotFailed(procExec, procId);
180 validateNamespaceNotExist(namespaceName);
181 }
182
183 @Test(timeout = 60000)
184 public void testRollbackAndDoubleExecution() throws Exception {
185 final String namespaceName = "testRollbackAndDoubleExecution";
186 final ProcedureExecutor<MasterProcedureEnv> procExec = getMasterProcedureExecutor();
187
188 createNamespaceForTesting(namespaceName);
189
190 ProcedureTestingUtility.waitNoProcedureRunning(procExec);
191 ProcedureTestingUtility.setKillAndToggleBeforeStoreUpdate(procExec, true);
192
193
194 long procId = procExec.submitProcedure(
195 new DeleteNamespaceProcedure(procExec.getEnvironment(), namespaceName));
196
197 int numberOfSteps = DeleteNamespaceState.values().length - 2;
198 MasterProcedureTestingUtility.testRollbackAndDoubleExecution(
199 procExec,
200 procId,
201 numberOfSteps,
202 DeleteNamespaceState.values());
203
204
205 NamespaceDescriptor createdNsDescriptor=
206 UTIL.getHBaseAdmin().getNamespaceDescriptor(namespaceName);
207 assertNotNull(createdNsDescriptor);
208 }
209
210 private ProcedureExecutor<MasterProcedureEnv> getMasterProcedureExecutor() {
211 return UTIL.getHBaseCluster().getMaster().getMasterProcedureExecutor();
212 }
213
214 private void createNamespaceForTesting(final String namespaceName) throws Exception {
215 final NamespaceDescriptor nsd = NamespaceDescriptor.create(namespaceName).build();
216 final ProcedureExecutor<MasterProcedureEnv> procExec = getMasterProcedureExecutor();
217
218 long procId = procExec.submitProcedure(
219 new CreateNamespaceProcedure(procExec.getEnvironment(), nsd));
220
221 ProcedureTestingUtility.waitProcedure(procExec, procId);
222 ProcedureTestingUtility.assertProcNotFailed(procExec, procId);
223 }
224
225 public static void validateNamespaceNotExist(final String nsName) throws IOException {
226 try {
227 NamespaceDescriptor nsDescriptor = UTIL.getHBaseAdmin().getNamespaceDescriptor(nsName);
228 assertNull(nsDescriptor);
229 } catch (NamespaceNotFoundException nsnfe) {
230
231 }
232 }
233 }