1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.hadoop.hbase.coprocessor;
21
22 import static org.junit.Assert.fail;
23
24 import java.io.IOException;
25
26 import org.apache.commons.logging.Log;
27 import org.apache.commons.logging.LogFactory;
28 import org.apache.hadoop.conf.Configuration;
29 import org.apache.hadoop.hbase.CoprocessorEnvironment;
30 import org.apache.hadoop.hbase.HBaseTestingUtility;
31 import org.apache.hadoop.hbase.HConstants;
32 import org.apache.hadoop.hbase.MiniHBaseCluster;
33 import org.apache.hadoop.hbase.TableName;
34 import org.apache.hadoop.hbase.Waiter.Predicate;
35 import org.apache.hadoop.hbase.client.Durability;
36 import org.apache.hadoop.hbase.client.HTable;
37 import org.apache.hadoop.hbase.client.Put;
38 import org.apache.hadoop.hbase.regionserver.HRegionServer;
39 import org.apache.hadoop.hbase.regionserver.wal.WALEdit;
40 import org.apache.hadoop.hbase.testclassification.MediumTests;
41 import org.apache.hadoop.hbase.util.Bytes;
42 import org.junit.Assert;
43 import org.junit.Test;
44 import org.junit.experimental.categories.Category;
45
46
47
48
49
50
51
52 @Category(MediumTests.class)
53 public class TestRegionServerCoprocessorExceptionWithAbort {
54 private static final Log LOG = LogFactory.getLog(
55 TestRegionServerCoprocessorExceptionWithAbort.class);
56 private static final HBaseTestingUtility TEST_UTIL = new HBaseTestingUtility();
57 private static final TableName TABLE_NAME = TableName.valueOf("observed_table");
58
59 @Test(timeout=60000)
60 public void testExceptionDuringInitialization() throws Exception {
61 Configuration conf = TEST_UTIL.getConfiguration();
62 conf.setInt(HConstants.HBASE_CLIENT_RETRIES_NUMBER, 2);
63 conf.setBoolean(CoprocessorHost.ABORT_ON_ERROR_KEY, true);
64 conf.set(CoprocessorHost.REGION_COPROCESSOR_CONF_KEY, "");
65 TEST_UTIL.startMiniCluster(2);
66 try {
67 MiniHBaseCluster cluster = TEST_UTIL.getHBaseCluster();
68
69
70 final HRegionServer regionServer = cluster.getRegionServer(0);
71 conf.set(CoprocessorHost.REGION_COPROCESSOR_CONF_KEY,
72 FailedInitializationObserver.class.getName());
73 regionServer.getRegionServerCoprocessorHost().loadSystemCoprocessors(conf,
74 CoprocessorHost.REGION_COPROCESSOR_CONF_KEY);
75 TEST_UTIL.waitFor(10000, 1000, new Predicate<Exception>() {
76 @Override
77 public boolean evaluate() throws Exception {
78 return regionServer.isAborted();
79 }
80 });
81 } finally {
82 TEST_UTIL.shutdownMiniCluster();
83 }
84 }
85
86 @Test(timeout=60000)
87 public void testExceptionFromCoprocessorDuringPut() throws Exception {
88
89 Configuration conf = TEST_UTIL.getConfiguration();
90 conf.setInt(HConstants.HBASE_CLIENT_RETRIES_NUMBER, 2);
91 conf.set(CoprocessorHost.REGION_COPROCESSOR_CONF_KEY, BuggyRegionObserver.class.getName());
92 conf.setBoolean(CoprocessorHost.ABORT_ON_ERROR_KEY, true);
93 TEST_UTIL.startMiniCluster(2);
94 try {
95
96
97
98 final byte[] TEST_FAMILY = Bytes.toBytes("aaa");
99
100 HTable table = TEST_UTIL.createMultiRegionTable(TABLE_NAME, TEST_FAMILY);
101 TEST_UTIL.waitUntilAllRegionsAssigned(TABLE_NAME);
102
103
104 final HRegionServer regionServer = TEST_UTIL.getRSForFirstRegionInTable(TABLE_NAME);
105
106 try {
107 final byte[] ROW = Bytes.toBytes("aaa");
108 Put put = new Put(ROW);
109 put.add(TEST_FAMILY, ROW, ROW);
110 table.put(put);
111 table.flushCommits();
112 } catch (IOException e) {
113
114
115
116 }
117
118
119
120 boolean aborted = false;
121 for (int i = 0; i < 10; i++) {
122 aborted = regionServer.isAborted();
123 if (aborted) {
124 break;
125 }
126 try {
127 Thread.sleep(1000);
128 } catch (InterruptedException e) {
129 fail("InterruptedException while waiting for regionserver " +
130 "zk node to be deleted.");
131 }
132 }
133 Assert.assertTrue("The region server should have aborted", aborted);
134 table.close();
135 } finally {
136 TEST_UTIL.shutdownMiniCluster();
137 }
138 }
139
140 public static class FailedInitializationObserver extends SimpleRegionObserver {
141 @SuppressWarnings("null")
142 @Override
143 public void start(CoprocessorEnvironment e) throws IOException {
144
145 Integer i = null;
146 i = i + 1;
147 }
148 }
149
150 public static class BuggyRegionObserver extends SimpleRegionObserver {
151 @SuppressWarnings("null")
152 @Override
153 public void prePut(final ObserverContext<RegionCoprocessorEnvironment> c,
154 final Put put, final WALEdit edit,
155 final Durability durability) {
156 String tableName =
157 c.getEnvironment().getRegion().getRegionInfo().getTable().getNameAsString();
158 if (tableName.equals("observed_table")) {
159
160 Integer i = null;
161 i = i + 1;
162 }
163 }
164 }
165 }