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