1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.hadoop.hbase.regionserver.wal;
19
20 import java.io.IOException;
21 import org.apache.commons.logging.Log;
22 import org.apache.commons.logging.LogFactory;
23 import org.apache.hadoop.conf.Configuration;
24 import org.apache.hadoop.fs.FileSystem;
25 import org.apache.hadoop.fs.Path;
26 import org.apache.hadoop.hbase.HBaseTestingUtility;
27 import org.apache.hadoop.hbase.HConstants;
28 import org.apache.hadoop.hbase.TableName;
29 import org.apache.hadoop.hbase.client.Append;
30 import org.apache.hadoop.hbase.client.Durability;
31 import org.apache.hadoop.hbase.client.Increment;
32 import org.apache.hadoop.hbase.client.Put;
33 import org.apache.hadoop.hbase.exceptions.TimeoutIOException;
34 import org.apache.hadoop.hbase.regionserver.HRegion;
35 import org.apache.hadoop.hbase.regionserver.RegionServerServices;
36 import org.apache.hadoop.hbase.testclassification.MediumTests;
37 import org.apache.hadoop.hbase.testclassification.RegionServerTests;
38 import org.apache.hadoop.hbase.util.Bytes;
39 import org.apache.hadoop.hbase.wal.WAL;
40 import org.junit.After;
41 import org.junit.Before;
42 import org.junit.Rule;
43 import org.junit.Test;
44 import org.junit.experimental.categories.Category;
45 import org.junit.rules.TestName;
46 import org.mockito.Mockito;
47
48 import static org.junit.Assert.assertTrue;
49 import static org.junit.Assert.fail;
50 import static org.mockito.Mockito.mock;
51
52
53
54
55 @Category({MediumTests.class, RegionServerTests.class})
56 public class TestFSHLogTimedOutSync {
57 private static final Log LOG = LogFactory.getLog(TestFSHLogTimedOutSync.class);
58
59 @Rule public TestName name = new TestName();
60
61 private static final String COLUMN_FAMILY = "MyCF";
62 private static final byte [] COLUMN_FAMILY_BYTES = Bytes.toBytes(COLUMN_FAMILY);
63 private static final String COLUMN_QUALIFIER = "MyCQ";
64 private static final byte [] COLUMN_QUALIFIER_BYTES = Bytes.toBytes(COLUMN_QUALIFIER);
65 private static HBaseTestingUtility TEST_UTIL;
66 private static Configuration CONF ;
67 private String dir;
68
69
70 protected TableName tableName;
71
72 @Before
73 public void setup() throws IOException {
74 TEST_UTIL = HBaseTestingUtility.createLocalHTU();
75 CONF = TEST_UTIL.getConfiguration();
76
77 CONF.setFloat(HConstants.HFILE_BLOCK_CACHE_SIZE_KEY, 0f);
78 dir = TEST_UTIL.getDataTestDir("TestHRegion").toString();
79 tableName = TableName.valueOf(name.getMethodName());
80 }
81
82 @After
83 public void tearDown() throws Exception {
84 LOG.info("Cleaning test directory: " + TEST_UTIL.getDataTestDir());
85 TEST_UTIL.cleanupTestDir();
86 }
87
88
89 @Test(timeout=30000)
90 public void testRSAbortWhenSyncTimedOut() throws IOException {
91
92 class DodgyFSLog extends FSHLog {
93 volatile boolean throwSyncException = false;
94
95 public DodgyFSLog(FileSystem fs, Path root, String logDir, Configuration conf)
96 throws IOException {
97 super(fs, root, logDir, conf);
98 }
99
100 @Override
101 public void sync(long txid) throws IOException {
102 super.sync(txid);
103 if (throwSyncException) {
104 throw new TimeoutIOException("Exception");
105 }
106 }
107
108 @Override
109 public void sync(long txid, boolean force) throws IOException {
110 super.sync(txid, force);
111 if (throwSyncException) {
112 throw new TimeoutIOException("Exception");
113 }
114 }
115 }
116
117
118 RegionServerServices services = mock(RegionServerServices.class);
119 FileSystem fs = FileSystem.get(CONF);
120 Path rootDir = new Path(dir + getName());
121 DodgyFSLog dodgyWAL = new DodgyFSLog(fs, rootDir, getName(), CONF);
122 HRegion region = initHRegion(tableName, null, null, CONF, dodgyWAL);
123 region.setRegionServerServices(services);
124
125 byte[] row = Bytes.toBytes(getName());
126 byte[] value = Bytes.toBytes(getName());
127
128 try {
129 dodgyWAL.throwSyncException = true;
130 Put put = new Put(row);
131 put.addColumn(COLUMN_FAMILY_BYTES, COLUMN_QUALIFIER_BYTES, value);
132 region.put(put);
133 fail();
134 } catch (IOException ioe) {
135 assertTrue(ioe instanceof TimeoutIOException);
136 }
137
138 Mockito.verify(services, Mockito.times(1)).
139 abort(Mockito.anyString(), Mockito.<Throwable>anyObject());
140
141
142 try {
143 dodgyWAL.throwSyncException = true;
144 Append a = new Append(row);
145 a.setReturnResults(false);
146 a.add(COLUMN_FAMILY_BYTES, COLUMN_QUALIFIER_BYTES, value);
147 region.append(a, HConstants.NO_NONCE, HConstants.NO_NONCE);
148 fail();
149 } catch (IOException ioe) {
150 assertTrue(ioe instanceof TimeoutIOException);
151 }
152
153 Mockito.verify(services, Mockito.times(2)).
154 abort(Mockito.anyString(), Mockito.<Throwable>anyObject());
155
156
157 try {
158 dodgyWAL.throwSyncException = true;
159 final Increment inc = new Increment(row);
160 inc.addColumn(COLUMN_FAMILY_BYTES, Bytes.toBytes("qual2"), 1);
161 region.increment(inc, HConstants.NO_NONCE, HConstants.NO_NONCE);
162 fail();
163 } catch (IOException ioe) {
164 assertTrue(ioe instanceof TimeoutIOException);
165 }
166
167 Mockito.verify(services, Mockito.times(3)).
168 abort(Mockito.anyString(), Mockito.<Throwable>anyObject());
169 }
170
171 String getName() {
172 return name.getMethodName();
173 }
174
175
176
177
178
179 public HRegion initHRegion(TableName tableName, byte[] startKey, byte[] stopKey,
180 Configuration conf, WAL wal) throws IOException {
181 return TEST_UTIL.createLocalHRegion(tableName.getName(), startKey, stopKey,
182 getName(), conf, false, Durability.SYNC_WAL, wal, COLUMN_FAMILY_BYTES);
183 }
184 }