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 static void setupConf(Configuration conf) {
53 conf.setInt(MasterProcedureConstants.MASTER_PROCEDURE_THREADS, 1);
54 }
55
56 @BeforeClass
57 public static void setupCluster() throws Exception {
58 setupConf(UTIL.getConfiguration());
59 UTIL.startMiniCluster(1);
60 }
61
62 @AfterClass
63 public static void cleanupTest() throws Exception {
64 try {
65 UTIL.shutdownMiniCluster();
66 } catch (Exception e) {
67 LOG.warn("failure shutting down cluster", e);
68 }
69 }
70
71 @Before
72 public void setup() throws Exception {
73 final ProcedureExecutor<MasterProcedureEnv> procExec = getMasterProcedureExecutor();
74 ProcedureTestingUtility.setKillAndToggleBeforeStoreUpdate(procExec, false);
75 assertTrue("expected executor to be running", procExec.isRunning());
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 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 boolean abortResult = procExec.abort(procId, true);
100 assertTrue(abortResult);
101
102 ProcedureTestingUtility.setKillAndToggleBeforeStoreUpdate(procExec, false);
103 ProcedureTestingUtility.restart(procExec);
104 ProcedureTestingUtility.waitNoProcedureRunning(procExec);
105
106 MasterProcedureTestingUtility.validateTableIsEnabled(
107 UTIL.getHBaseCluster().getMaster(),
108 tableName);
109 }
110
111 @Test(timeout=60000)
112 public void testAbortProcedureFailure() throws Exception {
113 final TableName tableName = TableName.valueOf("testAbortProcedureFailure");
114 final ProcedureExecutor<MasterProcedureEnv> procExec = getMasterProcedureExecutor();
115
116 HRegionInfo[] regions =
117 MasterProcedureTestingUtility.createTable(procExec, tableName, null, "f");
118 UTIL.getHBaseAdmin().disableTable(tableName);
119 ProcedureTestingUtility.waitNoProcedureRunning(procExec);
120 ProcedureTestingUtility.setKillAndToggleBeforeStoreUpdate(procExec, true);
121
122 long procId = procExec.submitProcedure(
123 new DeleteTableProcedure(procExec.getEnvironment(), tableName));
124
125 boolean abortResult = procExec.abort(procId, true);
126 assertFalse(abortResult);
127
128 ProcedureTestingUtility.setKillAndToggleBeforeStoreUpdate(procExec, false);
129 ProcedureTestingUtility.restart(procExec);
130 ProcedureTestingUtility.waitNoProcedureRunning(procExec);
131 ProcedureTestingUtility.assertProcNotFailed(procExec, procId);
132
133 MasterProcedureTestingUtility.validateTableDeletion(
134 UTIL.getHBaseCluster().getMaster(), tableName, regions, "f");
135 }
136
137 @Test(timeout=60000)
138 public void testAbortProcedureInterruptedNotAllowed() throws Exception {
139 final TableName tableName = TableName.valueOf("testAbortProcedureInterruptedNotAllowed");
140 final ProcedureExecutor<MasterProcedureEnv> procExec = getMasterProcedureExecutor();
141
142 HRegionInfo[] regions =
143 MasterProcedureTestingUtility.createTable(procExec, tableName, null, "f");
144 ProcedureTestingUtility.waitNoProcedureRunning(procExec);
145 ProcedureTestingUtility.setKillAndToggleBeforeStoreUpdate(procExec, true);
146
147 long procId = procExec.submitProcedure(
148 new DisableTableProcedure(procExec.getEnvironment(), tableName, true));
149
150 ProcedureTestingUtility.waitProcedure(procExec, procId);
151
152
153 boolean abortResult = procExec.abort(procId, false);
154 assertFalse(abortResult);
155
156 ProcedureTestingUtility.setKillAndToggleBeforeStoreUpdate(procExec, false);
157 ProcedureTestingUtility.restart(procExec);
158 ProcedureTestingUtility.waitNoProcedureRunning(procExec);
159 ProcedureTestingUtility.assertProcNotFailed(procExec, procId);
160
161 MasterProcedureTestingUtility.validateTableIsDisabled(
162 UTIL.getHBaseCluster().getMaster(), tableName);
163 }
164
165 @Test(timeout=60000)
166 public void testAbortNonExistProcedure() throws Exception {
167 final ProcedureExecutor<MasterProcedureEnv> procExec = getMasterProcedureExecutor();
168 Random randomGenerator = new Random();
169 long procId;
170
171 do {
172 procId = randomGenerator.nextLong();
173 } while (procExec.getResult(procId) != null);
174
175 boolean abortResult = procExec.abort(procId, true);
176 assertFalse(abortResult);
177 }
178
179 @Test(timeout=60000)
180 public void testListProcedure() throws Exception {
181 final TableName tableName = TableName.valueOf("testListProcedure");
182 final ProcedureExecutor<MasterProcedureEnv> procExec = getMasterProcedureExecutor();
183
184 MasterProcedureTestingUtility.createTable(procExec, tableName, null, "f");
185 ProcedureTestingUtility.waitNoProcedureRunning(procExec);
186 ProcedureTestingUtility.setKillAndToggleBeforeStoreUpdate(procExec, true);
187
188 long procId = procExec.submitProcedure(
189 new DisableTableProcedure(procExec.getEnvironment(), tableName, false));
190
191 List<ProcedureInfo> listProcedures = procExec.listProcedures();
192 assertTrue(listProcedures.size() >= 1);
193 boolean found = false;
194 for (ProcedureInfo procInfo: listProcedures) {
195 if (procInfo.getProcId() == procId) {
196 assertTrue(procInfo.getProcState() == ProcedureState.RUNNABLE);
197 found = true;
198 } else {
199 assertTrue(procInfo.getProcState() == ProcedureState.FINISHED);
200 }
201 }
202 assertTrue(found);
203
204 ProcedureTestingUtility.setKillAndToggleBeforeStoreUpdate(procExec, false);
205 ProcedureTestingUtility.restart(procExec);
206 ProcedureTestingUtility.waitNoProcedureRunning(procExec);
207 ProcedureTestingUtility.assertProcNotFailed(procExec, procId);
208 listProcedures = procExec.listProcedures();
209 for (ProcedureInfo procInfo: listProcedures) {
210 assertTrue(procInfo.getProcState() == ProcedureState.FINISHED);
211 }
212 }
213
214 private ProcedureExecutor<MasterProcedureEnv> getMasterProcedureExecutor() {
215 return UTIL.getHBaseCluster().getMaster().getMasterProcedureExecutor();
216 }
217 }