1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.hadoop.hbase.procedure;
18
19 import static org.apache.hadoop.hbase.coprocessor.CoprocessorHost.MASTER_COPROCESSOR_CONF_KEY;
20 import static org.junit.Assert.fail;
21
22 import java.io.IOException;
23 import java.util.List;
24
25 import org.apache.commons.logging.Log;
26 import org.apache.commons.logging.LogFactory;
27 import org.apache.hadoop.conf.Configuration;
28 import org.apache.hadoop.hbase.HBaseTestingUtility;
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.coprocessor.BaseMasterObserver;
34 import org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment;
35 import org.apache.hadoop.hbase.coprocessor.ObserverContext;
36 import org.apache.hadoop.hbase.protobuf.generated.ProcedureProtos;
37 import org.apache.hadoop.hbase.security.AccessDeniedException;
38 import org.apache.hadoop.hbase.testclassification.MediumTests;
39 import org.apache.hadoop.hbase.util.Bytes;
40 import org.junit.After;
41 import org.junit.BeforeClass;
42 import org.junit.Test;
43 import org.junit.experimental.categories.Category;
44
45
46
47
48 @Category(MediumTests.class)
49 public class TestFailedProcCleanup {
50 private static final Log LOG = LogFactory.getLog(TestFailedProcCleanup.class);
51
52 protected static HBaseTestingUtility TEST_UTIL = new HBaseTestingUtility();
53 private static Configuration conf;
54 private static final TableName TABLE = TableName.valueOf("test");
55 private static final byte[] FAMILY = Bytes.toBytesBinary("f");
56 private static final int evictionDelay = 10 * 1000;
57
58 @BeforeClass
59 public static void setUpBeforeClass() {
60 conf = TEST_UTIL.getConfiguration();
61 conf.setInt("hbase.procedure.cleaner.evict.ttl", evictionDelay);
62 }
63
64 @After
65 public void tearDown() throws Exception {
66 TEST_UTIL.cleanupTestDir();
67 TEST_UTIL.cleanupDataTestDirOnTestFS();
68 TEST_UTIL.shutdownMiniCluster();
69 }
70
71 @Test
72 public void testFailCreateTable() throws Exception {
73 conf.set(MASTER_COPROCESSOR_CONF_KEY, CreateFailObserver.class.getName());
74 TEST_UTIL.startMiniCluster(3);
75 try {
76 TEST_UTIL.createTable(TABLE, FAMILY);
77 } catch (AccessDeniedException e) {
78 LOG.debug("Ignoring exception: ", e);
79 Thread.sleep(evictionDelay * 3);
80 }
81 List<ProcedureInfo> procedureInfos =
82 TEST_UTIL.getMiniHBaseCluster().getMaster().getMasterProcedureExecutor().listProcedures();
83 for (ProcedureInfo procedureInfo : procedureInfos) {
84 if (procedureInfo.getProcName().equals("CreateTableProcedure")
85 && procedureInfo.getProcState() == ProcedureProtos.ProcedureState.ROLLEDBACK) {
86 fail("Found procedure " + procedureInfo + " that hasn't been cleaned up");
87 }
88 }
89 }
90
91 @Test
92 public void testFailCreateTableHandler() throws Exception {
93 conf.set(MASTER_COPROCESSOR_CONF_KEY, CreateFailObserverHandler.class.getName());
94 TEST_UTIL.startMiniCluster(3);
95 try {
96 TEST_UTIL.createTable(TABLE, FAMILY);
97 } catch (AccessDeniedException e) {
98 LOG.debug("Ignoring exception: ", e);
99 Thread.sleep(evictionDelay * 3);
100 }
101 List<ProcedureInfo> procedureInfos =
102 TEST_UTIL.getMiniHBaseCluster().getMaster().getMasterProcedureExecutor().listProcedures();
103 for (ProcedureInfo procedureInfo : procedureInfos) {
104 if (procedureInfo.getProcName().equals("CreateTableProcedure")
105 && procedureInfo.getProcState() == ProcedureProtos.ProcedureState.ROLLEDBACK) {
106 fail("Found procedure " + procedureInfo + " that hasn't been cleaned up");
107 }
108 }
109 }
110
111 public static class CreateFailObserver extends BaseMasterObserver {
112
113 @Override
114 public void preCreateTable(ObserverContext<MasterCoprocessorEnvironment> ctx,
115 HTableDescriptor desc, HRegionInfo[] regions) throws IOException {
116
117 if (desc.getTableName().equals(TABLE)) {
118 throw new AccessDeniedException("Don't allow creation of table");
119 }
120 }
121 }
122
123 public static class CreateFailObserverHandler extends BaseMasterObserver {
124
125 @Override
126 public void preCreateTableHandler(
127 final ObserverContext<MasterCoprocessorEnvironment> ctx,
128 HTableDescriptor desc, HRegionInfo[] regions) throws IOException {
129
130 if (desc.getTableName().equals(TABLE)) {
131 throw new AccessDeniedException("Don't allow creation of table");
132 }
133 }
134 }
135 }