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 import org.junit.After;
37 import org.junit.AfterClass;
38 import org.junit.Assert;
39 import org.junit.Before;
40 import org.junit.BeforeClass;
41 import org.junit.Test;
42 import org.junit.experimental.categories.Category;
43
44 @Category(MediumTests.class)
45 public class TestEnableTableProcedure {
46 private static final Log LOG = LogFactory.getLog(TestEnableTableProcedure.class);
47
48 protected static final HBaseTestingUtility UTIL = new HBaseTestingUtility();
49
50 private static void setupConf(Configuration conf) {
51 conf.setInt(MasterProcedureConstants.MASTER_PROCEDURE_THREADS, 1);
52 }
53
54 @BeforeClass
55 public static void setupCluster() throws Exception {
56 setupConf(UTIL.getConfiguration());
57 UTIL.startMiniCluster(1);
58 }
59
60 @AfterClass
61 public static void cleanupTest() throws Exception {
62 try {
63 UTIL.shutdownMiniCluster();
64 } catch (Exception e) {
65 LOG.warn("failure shutting down cluster", e);
66 }
67 }
68
69 @Before
70 public void setup() throws Exception {
71 ProcedureTestingUtility.setKillAndToggleBeforeStoreUpdate(getMasterProcedureExecutor(), false);
72 }
73
74 @After
75 public void tearDown() throws Exception {
76 ProcedureTestingUtility.setKillAndToggleBeforeStoreUpdate(getMasterProcedureExecutor(), false);
77 for (HTableDescriptor htd: UTIL.getHBaseAdmin().listTables()) {
78 LOG.info("Tear down, remove table=" + htd.getTableName());
79 UTIL.deleteTable(htd.getTableName());
80 }
81 }
82
83 @Test(timeout = 60000)
84 public void testEnableTable() throws Exception {
85 final TableName tableName = TableName.valueOf("testEnableTable");
86 final ProcedureExecutor<MasterProcedureEnv> procExec = getMasterProcedureExecutor();
87
88 MasterProcedureTestingUtility.createTable(procExec, tableName, null, "f1", "f2");
89 UTIL.getHBaseAdmin().disableTable(tableName);
90
91
92 long procId = procExec.submitProcedure(
93 new EnableTableProcedure(procExec.getEnvironment(), tableName, false));
94
95 ProcedureTestingUtility.waitProcedure(procExec, procId);
96 ProcedureTestingUtility.assertProcNotFailed(procExec, procId);
97 MasterProcedureTestingUtility.validateTableIsEnabled(UTIL.getHBaseCluster().getMaster(),
98 tableName);
99 }
100
101 @Test(timeout=60000, expected=TableNotDisabledException.class)
102 public void testEnableNonDisabledTable() throws Exception {
103 final TableName tableName = TableName.valueOf("testEnableNonExistingTable");
104 final ProcedureExecutor<MasterProcedureEnv> procExec = getMasterProcedureExecutor();
105
106 MasterProcedureTestingUtility.createTable(procExec, tableName, null, "f1", "f2");
107
108
109 long procId1 = procExec.submitProcedure(
110 new EnableTableProcedure(procExec.getEnvironment(), tableName, false));
111 ProcedureTestingUtility.waitProcedure(procExec, procId1);
112
113 ProcedureInfo result = procExec.getResult(procId1);
114 assertTrue(result.isFailed());
115 LOG.debug("Enable failed with exception: " + result.getExceptionFullMessage());
116 assertTrue(
117 ProcedureTestingUtility.getExceptionCause(result) instanceof TableNotDisabledException);
118
119
120 long procId2 = procExec.submitProcedure(
121 new EnableTableProcedure(procExec.getEnvironment(), tableName, true));
122
123 ProcedureTestingUtility.waitProcedure(procExec, procId2);
124 ProcedureTestingUtility.assertProcNotFailed(procExec, procId2);
125
126
127 final ProcedurePrepareLatch prepareLatch = new ProcedurePrepareLatch.CompatibilityLatch();
128 long procId3 = procExec.submitProcedure(
129 new EnableTableProcedure(procExec.getEnvironment(), tableName, false, prepareLatch));
130 prepareLatch.await();
131 Assert.fail("Enable should throw exception through latch.");
132 }
133
134 @Test(timeout = 60000)
135 public void testRecoveryAndDoubleExecution() throws Exception {
136 final TableName tableName = TableName.valueOf("testRecoveryAndDoubleExecution");
137 final ProcedureExecutor<MasterProcedureEnv> procExec = getMasterProcedureExecutor();
138
139 final byte[][] splitKeys = new byte[][] {
140 Bytes.toBytes("a"), Bytes.toBytes("b"), Bytes.toBytes("c")
141 };
142 MasterProcedureTestingUtility.createTable(procExec, tableName, splitKeys, "f1", "f2");
143 UTIL.getHBaseAdmin().disableTable(tableName);
144 ProcedureTestingUtility.waitNoProcedureRunning(procExec);
145 ProcedureTestingUtility.setKillAndToggleBeforeStoreUpdate(procExec, true);
146
147
148 long procId = procExec.submitProcedure(
149 new EnableTableProcedure(procExec.getEnvironment(), tableName, false));
150
151
152 int numberOfSteps = EnableTableState.values().length;
153 MasterProcedureTestingUtility.testRecoveryAndDoubleExecution(
154 procExec,
155 procId,
156 numberOfSteps,
157 EnableTableState.values());
158 MasterProcedureTestingUtility.validateTableIsEnabled(UTIL.getHBaseCluster().getMaster(),
159 tableName);
160 }
161
162 @Test(timeout = 60000)
163 public void testRollbackAndDoubleExecution() throws Exception {
164 final TableName tableName = TableName.valueOf("testRollbackAndDoubleExecution");
165 final ProcedureExecutor<MasterProcedureEnv> procExec = getMasterProcedureExecutor();
166
167 final byte[][] splitKeys = new byte[][] {
168 Bytes.toBytes("a"), Bytes.toBytes("b"), Bytes.toBytes("c")
169 };
170 MasterProcedureTestingUtility.createTable(procExec, tableName, splitKeys, "f1", "f2");
171 UTIL.getHBaseAdmin().disableTable(tableName);
172 ProcedureTestingUtility.waitNoProcedureRunning(procExec);
173 ProcedureTestingUtility.setKillAndToggleBeforeStoreUpdate(procExec, true);
174
175
176 long procId = procExec.submitProcedure(
177 new EnableTableProcedure(procExec.getEnvironment(), tableName, false));
178
179 int numberOfSteps = EnableTableState.values().length - 2;
180 MasterProcedureTestingUtility.testRollbackAndDoubleExecution(
181 procExec,
182 procId,
183 numberOfSteps,
184 EnableTableState.values());
185 MasterProcedureTestingUtility.validateTableIsDisabled(UTIL.getHBaseCluster().getMaster(),
186 tableName);
187 }
188
189 private ProcedureExecutor<MasterProcedureEnv> getMasterProcedureExecutor() {
190 return UTIL.getHBaseCluster().getMaster().getMasterProcedureExecutor();
191 }
192 }