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 java.util.Random;
22 import java.util.List;
23
24 import org.apache.commons.logging.Log;
25 import org.apache.commons.logging.LogFactory;
26 import org.apache.hadoop.conf.Configuration;
27 import org.apache.hadoop.hbase.HBaseTestingUtility;
28 import org.apache.hadoop.hbase.HConstants;
29 import org.apache.hadoop.hbase.HRegionInfo;
30 import org.apache.hadoop.hbase.HTableDescriptor;
31 import org.apache.hadoop.hbase.ProcedureInfo;
32 import org.apache.hadoop.hbase.TableName;
33 import org.apache.hadoop.hbase.procedure2.ProcedureExecutor;
34 import org.apache.hadoop.hbase.procedure2.ProcedureTestingUtility;
35 import org.apache.hadoop.hbase.protobuf.generated.ProcedureProtos.ProcedureState;
36 import org.apache.hadoop.hbase.testclassification.MediumTests;
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.*;
45
46 @Category(MediumTests.class)
47 public class TestProcedureAdmin {
48 private static final Log LOG = LogFactory.getLog(TestProcedureAdmin.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)
95 public void testAbortProcedureSuccess() throws Exception {
96 final TableName tableName = TableName.valueOf("testAbortProcedureSuccess");
97 final ProcedureExecutor<MasterProcedureEnv> procExec = getMasterProcedureExecutor();
98
99 MasterProcedureTestingUtility.createTable(procExec, tableName, null, "f");
100 ProcedureTestingUtility.waitNoProcedureRunning(procExec);
101 ProcedureTestingUtility.setKillAndToggleBeforeStoreUpdate(procExec, true);
102
103 long procId = procExec.submitProcedure(
104 new DisableTableProcedure(procExec.getEnvironment(), tableName, false), nonceGroup, nonce);
105
106 boolean abortResult = procExec.abort(procId, true);
107 assertTrue(abortResult);
108
109 ProcedureTestingUtility.setKillAndToggleBeforeStoreUpdate(procExec, false);
110 ProcedureTestingUtility.restart(procExec);
111 ProcedureTestingUtility.waitNoProcedureRunning(procExec);
112
113 MasterProcedureTestingUtility.validateTableIsEnabled(
114 UTIL.getHBaseCluster().getMaster(),
115 tableName);
116 }
117
118 @Test(timeout=60000)
119 public void testAbortProcedureFailure() throws Exception {
120 final TableName tableName = TableName.valueOf("testAbortProcedureFailure");
121 final ProcedureExecutor<MasterProcedureEnv> procExec = getMasterProcedureExecutor();
122
123 HRegionInfo[] regions =
124 MasterProcedureTestingUtility.createTable(procExec, tableName, null, "f");
125 UTIL.getHBaseAdmin().disableTable(tableName);
126 ProcedureTestingUtility.waitNoProcedureRunning(procExec);
127 ProcedureTestingUtility.setKillAndToggleBeforeStoreUpdate(procExec, true);
128
129 long procId = procExec.submitProcedure(
130 new DeleteTableProcedure(procExec.getEnvironment(), tableName), nonceGroup, nonce);
131
132 boolean abortResult = procExec.abort(procId, true);
133 assertFalse(abortResult);
134
135 ProcedureTestingUtility.setKillAndToggleBeforeStoreUpdate(procExec, false);
136 ProcedureTestingUtility.restart(procExec);
137 ProcedureTestingUtility.waitNoProcedureRunning(procExec);
138 ProcedureTestingUtility.assertProcNotFailed(procExec, procId);
139
140 MasterProcedureTestingUtility.validateTableDeletion(
141 UTIL.getHBaseCluster().getMaster(), tableName, regions, "f");
142 }
143
144 @Test(timeout=60000)
145 public void testAbortProcedureInterruptedNotAllowed() throws Exception {
146 final TableName tableName = TableName.valueOf("testAbortProcedureInterruptedNotAllowed");
147 final ProcedureExecutor<MasterProcedureEnv> procExec = getMasterProcedureExecutor();
148
149 HRegionInfo[] regions =
150 MasterProcedureTestingUtility.createTable(procExec, tableName, null, "f");
151 ProcedureTestingUtility.waitNoProcedureRunning(procExec);
152 ProcedureTestingUtility.setKillAndToggleBeforeStoreUpdate(procExec, true);
153
154 long procId = procExec.submitProcedure(
155 new DisableTableProcedure(procExec.getEnvironment(), tableName, true), nonceGroup, nonce);
156
157 ProcedureTestingUtility.waitProcedure(procExec, procId);
158
159
160 boolean abortResult = procExec.abort(procId, false);
161 assertFalse(abortResult);
162
163 ProcedureTestingUtility.setKillAndToggleBeforeStoreUpdate(procExec, false);
164 ProcedureTestingUtility.restart(procExec);
165 ProcedureTestingUtility.waitNoProcedureRunning(procExec);
166 ProcedureTestingUtility.assertProcNotFailed(procExec, procId);
167
168 MasterProcedureTestingUtility.validateTableIsDisabled(
169 UTIL.getHBaseCluster().getMaster(), tableName);
170 }
171
172 @Test(timeout=60000)
173 public void testAbortNonExistProcedure() throws Exception {
174 final ProcedureExecutor<MasterProcedureEnv> procExec = getMasterProcedureExecutor();
175 Random randomGenerator = new Random();
176 long procId;
177
178 do {
179 procId = randomGenerator.nextLong();
180 } while (procExec.getResult(procId) != null);
181
182 boolean abortResult = procExec.abort(procId, true);
183 assertFalse(abortResult);
184 }
185
186 @Test(timeout=60000)
187 public void testListProcedure() throws Exception {
188 final TableName tableName = TableName.valueOf("testListProcedure");
189 final ProcedureExecutor<MasterProcedureEnv> procExec = getMasterProcedureExecutor();
190
191 MasterProcedureTestingUtility.createTable(procExec, tableName, null, "f");
192 ProcedureTestingUtility.waitNoProcedureRunning(procExec);
193 ProcedureTestingUtility.setKillAndToggleBeforeStoreUpdate(procExec, true);
194
195 long procId = procExec.submitProcedure(
196 new DisableTableProcedure(procExec.getEnvironment(), tableName, false), nonceGroup, nonce);
197
198 List<ProcedureInfo> listProcedures = procExec.listProcedures();
199 assertTrue(listProcedures.size() >= 1);
200 boolean found = false;
201 for (ProcedureInfo procInfo: listProcedures) {
202 if (procInfo.getProcId() == procId) {
203 assertTrue(procInfo.getProcState() == ProcedureState.RUNNABLE);
204 found = true;
205 } else {
206 assertTrue(procInfo.getProcState() == ProcedureState.FINISHED);
207 }
208 }
209 assertTrue(found);
210
211 ProcedureTestingUtility.setKillAndToggleBeforeStoreUpdate(procExec, false);
212 ProcedureTestingUtility.restart(procExec);
213 ProcedureTestingUtility.waitNoProcedureRunning(procExec);
214 ProcedureTestingUtility.assertProcNotFailed(procExec, procId);
215 listProcedures = procExec.listProcedures();
216 for (ProcedureInfo procInfo: listProcedures) {
217 assertTrue(procInfo.getProcState() == ProcedureState.FINISHED);
218 }
219 }
220
221 private ProcedureExecutor<MasterProcedureEnv> getMasterProcedureExecutor() {
222 return UTIL.getHBaseCluster().getMaster().getMasterProcedureExecutor();
223 }
224 }