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.TableNotEnabledException;
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.DisableTableState;
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 TestDisableTableProcedure {
47 private static final Log LOG = LogFactory.getLog(TestDisableTableProcedure.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 testDisableTable() throws Exception {
86 final TableName tableName = TableName.valueOf("testDisableTable");
87 final ProcedureExecutor<MasterProcedureEnv> procExec = getMasterProcedureExecutor();
88
89 MasterProcedureTestingUtility.createTable(procExec, tableName, null, "f1", "f2");
90
91
92 long procId = procExec.submitProcedure(
93 new DisableTableProcedure(procExec.getEnvironment(), tableName, false));
94
95 ProcedureTestingUtility.waitProcedure(procExec, procId);
96 ProcedureTestingUtility.assertProcNotFailed(procExec, procId);
97 MasterProcedureTestingUtility.validateTableIsDisabled(UTIL.getHBaseCluster().getMaster(),
98 tableName);
99 }
100
101 @Test(timeout = 60000)
102 public void testDisableTableMultipleTimes() throws Exception {
103 final TableName tableName = TableName.valueOf("testDisableTableMultipleTimes");
104 final ProcedureExecutor<MasterProcedureEnv> procExec = getMasterProcedureExecutor();
105
106 MasterProcedureTestingUtility.createTable(procExec, tableName, null, "f1", "f2");
107
108
109 long procId1 = procExec.submitProcedure(new DisableTableProcedure(
110 procExec.getEnvironment(), tableName, false));
111
112 ProcedureTestingUtility.waitProcedure(procExec, procId1);
113 ProcedureTestingUtility.assertProcNotFailed(procExec, procId1);
114 MasterProcedureTestingUtility.validateTableIsDisabled(UTIL.getHBaseCluster().getMaster(),
115 tableName);
116
117
118 long procId2 = procExec.submitProcedure(new DisableTableProcedure(
119 procExec.getEnvironment(), tableName, false));
120
121 ProcedureTestingUtility.waitProcedure(procExec, procId2);
122 ProcedureInfo result = procExec.getResult(procId2);
123 assertTrue(result.isFailed());
124 LOG.debug("Disable failed with exception: " + result.getExceptionFullMessage());
125 assertTrue(
126 ProcedureTestingUtility.getExceptionCause(result) instanceof TableNotEnabledException);
127
128
129 try {
130 final ProcedurePrepareLatch prepareLatch = new ProcedurePrepareLatch.CompatibilityLatch();
131
132 long procId3 = procExec.submitProcedure(new DisableTableProcedure(
133 procExec.getEnvironment(), tableName, false, prepareLatch));
134 prepareLatch.await();
135 Assert.fail("Disable should throw exception through latch.");
136 } catch (TableNotEnabledException tnee) {
137
138 LOG.debug("Disable failed with expected exception.");
139 }
140
141
142 long procId4 = procExec.submitProcedure(new DisableTableProcedure(
143 procExec.getEnvironment(), tableName, true));
144
145 ProcedureTestingUtility.waitProcedure(procExec, procId4);
146 ProcedureTestingUtility.assertProcNotFailed(procExec, procId4);
147 MasterProcedureTestingUtility.validateTableIsDisabled(UTIL.getHBaseCluster().getMaster(),
148 tableName);
149 }
150
151 @Test(timeout=60000)
152 public void testRecoveryAndDoubleExecution() throws Exception {
153 final TableName tableName = TableName.valueOf("testRecoveryAndDoubleExecution");
154 final ProcedureExecutor<MasterProcedureEnv> procExec = getMasterProcedureExecutor();
155
156 final byte[][] splitKeys = new byte[][] {
157 Bytes.toBytes("a"), Bytes.toBytes("b"), Bytes.toBytes("c")
158 };
159 MasterProcedureTestingUtility.createTable(procExec, tableName, splitKeys, "f1", "f2");
160
161 ProcedureTestingUtility.setKillAndToggleBeforeStoreUpdate(procExec, true);
162
163
164 long procId =
165 procExec.submitProcedure(new DisableTableProcedure(procExec.getEnvironment(), tableName,
166 false));
167
168
169 int numberOfSteps = DisableTableState.values().length;
170 MasterProcedureTestingUtility.testRecoveryAndDoubleExecution(
171 procExec,
172 procId,
173 numberOfSteps,
174 DisableTableState.values());
175 MasterProcedureTestingUtility.validateTableIsDisabled(UTIL.getHBaseCluster().getMaster(),
176 tableName);
177 }
178
179 private ProcedureExecutor<MasterProcedureEnv> getMasterProcedureExecutor() {
180 return UTIL.getHBaseCluster().getMaster().getMasterProcedureExecutor();
181 }
182 }