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.assertTrue;
22
23 import org.apache.commons.logging.Log;
24 import org.apache.commons.logging.LogFactory;
25 import org.apache.hadoop.conf.Configuration;
26 import org.apache.hadoop.hbase.HBaseTestingUtility;
27 import org.apache.hadoop.hbase.HTableDescriptor;
28 import org.apache.hadoop.hbase.ProcedureInfo;
29 import org.apache.hadoop.hbase.TableName;
30 import org.apache.hadoop.hbase.TableNotDisabledException;
31 import org.apache.hadoop.hbase.procedure2.ProcedureExecutor;
32 import org.apache.hadoop.hbase.procedure2.ProcedureTestingUtility;
33 import org.apache.hadoop.hbase.protobuf.generated.MasterProcedureProtos.EnableTableState;
34 import org.apache.hadoop.hbase.testclassification.MediumTests;
35 import org.apache.hadoop.hbase.util.Bytes;
36
37 import org.junit.After;
38 import org.junit.AfterClass;
39 import org.junit.Assert;
40 import org.junit.Before;
41 import org.junit.BeforeClass;
42 import org.junit.Test;
43 import org.junit.experimental.categories.Category;
44
45 @Category(MediumTests.class)
46 public class TestEnableTableProcedure {
47 private static final Log LOG = LogFactory.getLog(TestEnableTableProcedure.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 ProcedureTestingUtility.setKillAndToggleBeforeStoreUpdate(getMasterProcedureExecutor(), false);
73 }
74
75 @After
76 public void tearDown() throws Exception {
77 ProcedureTestingUtility.setKillAndToggleBeforeStoreUpdate(getMasterProcedureExecutor(), false);
78 for (HTableDescriptor htd: UTIL.getHBaseAdmin().listTables()) {
79 LOG.info("Tear down, remove table=" + htd.getTableName());
80 UTIL.deleteTable(htd.getTableName());
81 }
82 }
83
84 @Test(timeout = 60000)
85 public void testEnableTable() throws Exception {
86 final TableName tableName = TableName.valueOf("testEnableTable");
87 final ProcedureExecutor<MasterProcedureEnv> procExec = getMasterProcedureExecutor();
88
89 MasterProcedureTestingUtility.createTable(procExec, tableName, null, "f1", "f2");
90 UTIL.getHBaseAdmin().disableTable(tableName);
91
92
93 long procId = procExec.submitProcedure(
94 new EnableTableProcedure(procExec.getEnvironment(), tableName, false));
95
96 ProcedureTestingUtility.waitProcedure(procExec, procId);
97 ProcedureTestingUtility.assertProcNotFailed(procExec, procId);
98 MasterProcedureTestingUtility.validateTableIsEnabled(UTIL.getHBaseCluster().getMaster(),
99 tableName);
100 }
101
102 @Test(timeout=60000, expected=TableNotDisabledException.class)
103 public void testEnableNonDisabledTable() throws Exception {
104 final TableName tableName = TableName.valueOf("testEnableNonExistingTable");
105 final ProcedureExecutor<MasterProcedureEnv> procExec = getMasterProcedureExecutor();
106
107 MasterProcedureTestingUtility.createTable(procExec, tableName, null, "f1", "f2");
108
109
110 long procId1 = procExec.submitProcedure(
111 new EnableTableProcedure(procExec.getEnvironment(), tableName, false));
112 ProcedureTestingUtility.waitProcedure(procExec, procId1);
113
114 ProcedureInfo result = procExec.getResult(procId1);
115 assertTrue(result.isFailed());
116 LOG.debug("Enable failed with exception: " + result.getExceptionFullMessage());
117 assertTrue(
118 ProcedureTestingUtility.getExceptionCause(result) instanceof TableNotDisabledException);
119
120
121 long procId2 = procExec.submitProcedure(
122 new EnableTableProcedure(procExec.getEnvironment(), tableName, true));
123
124 ProcedureTestingUtility.waitProcedure(procExec, procId2);
125 ProcedureTestingUtility.assertProcNotFailed(procExec, procId2);
126
127
128 final ProcedurePrepareLatch prepareLatch = new ProcedurePrepareLatch.CompatibilityLatch();
129 long procId3 = procExec.submitProcedure(
130 new EnableTableProcedure(procExec.getEnvironment(), tableName, false, prepareLatch));
131 prepareLatch.await();
132 Assert.fail("Enable should throw exception through latch.");
133 }
134
135 @Test(timeout = 60000)
136 public void testRecoveryAndDoubleExecution() throws Exception {
137 final TableName tableName = TableName.valueOf("testRecoveryAndDoubleExecution");
138 final ProcedureExecutor<MasterProcedureEnv> procExec = getMasterProcedureExecutor();
139
140 final byte[][] splitKeys = new byte[][] {
141 Bytes.toBytes("a"), Bytes.toBytes("b"), Bytes.toBytes("c")
142 };
143 MasterProcedureTestingUtility.createTable(procExec, tableName, splitKeys, "f1", "f2");
144 UTIL.getHBaseAdmin().disableTable(tableName);
145 ProcedureTestingUtility.waitNoProcedureRunning(procExec);
146 ProcedureTestingUtility.setKillAndToggleBeforeStoreUpdate(procExec, true);
147
148
149 long procId = procExec.submitProcedure(
150 new EnableTableProcedure(procExec.getEnvironment(), tableName, false));
151
152
153 int numberOfSteps = EnableTableState.values().length;
154 MasterProcedureTestingUtility.testRecoveryAndDoubleExecution(
155 procExec,
156 procId,
157 numberOfSteps,
158 EnableTableState.values());
159 MasterProcedureTestingUtility.validateTableIsEnabled(UTIL.getHBaseCluster().getMaster(),
160 tableName);
161 }
162
163 @Test(timeout = 60000)
164 public void testRollbackAndDoubleExecution() throws Exception {
165 final TableName tableName = TableName.valueOf("testRollbackAndDoubleExecution");
166 final ProcedureExecutor<MasterProcedureEnv> procExec = getMasterProcedureExecutor();
167
168 final byte[][] splitKeys = new byte[][] {
169 Bytes.toBytes("a"), Bytes.toBytes("b"), Bytes.toBytes("c")
170 };
171 MasterProcedureTestingUtility.createTable(procExec, tableName, splitKeys, "f1", "f2");
172 UTIL.getHBaseAdmin().disableTable(tableName);
173 ProcedureTestingUtility.waitNoProcedureRunning(procExec);
174 ProcedureTestingUtility.setKillAndToggleBeforeStoreUpdate(procExec, true);
175
176
177 long procId = procExec.submitProcedure(
178 new EnableTableProcedure(procExec.getEnvironment(), tableName, false));
179
180 int numberOfSteps = EnableTableState.values().length - 2;
181 MasterProcedureTestingUtility.testRollbackAndDoubleExecution(
182 procExec,
183 procId,
184 numberOfSteps,
185 EnableTableState.values());
186 MasterProcedureTestingUtility.validateTableIsDisabled(UTIL.getHBaseCluster().getMaster(),
187 tableName);
188 }
189
190 private ProcedureExecutor<MasterProcedureEnv> getMasterProcedureExecutor() {
191 return UTIL.getHBaseCluster().getMaster().getMasterProcedureExecutor();
192 }
193 }