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