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