2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
18 package org
.apache
.hadoop
.hbase
.wal
;
20 import static org
.junit
.Assert
.assertEquals
;
21 import static org
.junit
.Assert
.assertNotNull
;
22 import static org
.junit
.Assert
.assertNotSame
;
23 import static org
.junit
.Assert
.assertNull
;
24 import static org
.junit
.Assert
.assertTrue
;
26 import java
.io
.IOException
;
27 import java
.util
.NavigableSet
;
28 import org
.apache
.hadoop
.conf
.Configuration
;
29 import org
.apache
.hadoop
.fs
.FSDataOutputStream
;
30 import org
.apache
.hadoop
.fs
.FileSystem
;
31 import org
.apache
.hadoop
.fs
.Path
;
32 import org
.apache
.hadoop
.hbase
.HBaseClassTestRule
;
33 import org
.apache
.hadoop
.hbase
.HBaseTestingUtility
;
34 import org
.apache
.hadoop
.hbase
.HConstants
;
35 import org
.apache
.hadoop
.hbase
.KeyValueTestUtil
;
36 import org
.apache
.hadoop
.hbase
.ServerName
;
37 import org
.apache
.hadoop
.hbase
.TableName
;
38 import org
.apache
.hadoop
.hbase
.testclassification
.RegionServerTests
;
39 import org
.apache
.hadoop
.hbase
.testclassification
.SmallTests
;
40 import org
.apache
.hadoop
.hbase
.util
.Bytes
;
41 import org
.apache
.hadoop
.hbase
.util
.FSUtils
;
42 import org
.apache
.hadoop
.hbase
.wal
.WALSplitter
.EntryBuffers
;
43 import org
.apache
.hadoop
.hbase
.wal
.WALSplitter
.PipelineController
;
44 import org
.apache
.hadoop
.hbase
.wal
.WALSplitter
.RegionEntryBuffer
;
45 import org
.junit
.ClassRule
;
46 import org
.junit
.Test
;
47 import org
.junit
.experimental
.categories
.Category
;
50 * Simple testing of a few WAL methods.
52 @Category({RegionServerTests
.class, SmallTests
.class})
53 public class TestWALMethods
{
56 public static final HBaseClassTestRule CLASS_RULE
=
57 HBaseClassTestRule
.forClass(TestWALMethods
.class);
59 private static final byte[] TEST_REGION
= Bytes
.toBytes("test_region");
60 private static final TableName TEST_TABLE
=
61 TableName
.valueOf("test_table");
63 private final HBaseTestingUtility util
= new HBaseTestingUtility();
66 public void testServerNameFromWAL() throws Exception
{
67 Path walPath
= new Path("/hbase/WALs/regionserver-2.example.com,22101,1487767381290",
68 "regionserver-2.example.com%2C22101%2C1487767381290.null0.1487785392316");
69 ServerName name
= AbstractFSWALProvider
.getServerNameFromWALDirectoryName(walPath
);
70 assertEquals(ServerName
.valueOf("regionserver-2.example.com", 22101, 1487767381290L), name
);
74 public void testServerNameFromTestWAL() throws Exception
{
75 Path walPath
= new Path(
76 "/user/example/test-data/12ff1404-68c6-4715-a4b9-775e763842bc/WALs/TestWALRecordReader",
77 "TestWALRecordReader.default.1487787939118");
78 ServerName name
= AbstractFSWALProvider
.getServerNameFromWALDirectoryName(walPath
);
83 * Assert that getSplitEditFilesSorted returns files in expected order and
84 * that it skips moved-aside files.
87 @Test public void testGetSplitEditFilesSorted() throws IOException
{
88 FileSystem fs
= FileSystem
.get(util
.getConfiguration());
89 Path regiondir
= util
.getDataTestDir("regiondir");
90 fs
.delete(regiondir
, true);
92 Path recoverededits
= WALSplitter
.getRegionDirRecoveredEditsDir(regiondir
);
93 String first
= WALSplitter
.formatRecoveredEditsFileName(-1);
94 createFile(fs
, recoverededits
, first
);
95 createFile(fs
, recoverededits
, WALSplitter
.formatRecoveredEditsFileName(0));
96 createFile(fs
, recoverededits
, WALSplitter
.formatRecoveredEditsFileName(1));
97 createFile(fs
, recoverededits
, WALSplitter
98 .formatRecoveredEditsFileName(11));
99 createFile(fs
, recoverededits
, WALSplitter
.formatRecoveredEditsFileName(2));
100 createFile(fs
, recoverededits
, WALSplitter
101 .formatRecoveredEditsFileName(50));
102 String last
= WALSplitter
.formatRecoveredEditsFileName(Long
.MAX_VALUE
);
103 createFile(fs
, recoverededits
, last
);
104 createFile(fs
, recoverededits
,
105 Long
.toString(Long
.MAX_VALUE
) + "." + System
.currentTimeMillis());
107 final Configuration walConf
= new Configuration(util
.getConfiguration());
108 FSUtils
.setRootDir(walConf
, regiondir
);
109 (new WALFactory(walConf
, "dummyLogName")).getWAL(null);
111 NavigableSet
<Path
> files
= WALSplitter
.getSplitEditFilesSorted(fs
, regiondir
);
112 assertEquals(7, files
.size());
113 assertEquals(files
.pollFirst().getName(), first
);
114 assertEquals(files
.pollLast().getName(), last
);
115 assertEquals(files
.pollFirst().getName(),
117 .formatRecoveredEditsFileName(0));
118 assertEquals(files
.pollFirst().getName(),
120 .formatRecoveredEditsFileName(1));
121 assertEquals(files
.pollFirst().getName(),
123 .formatRecoveredEditsFileName(2));
124 assertEquals(files
.pollFirst().getName(),
126 .formatRecoveredEditsFileName(11));
129 private void createFile(final FileSystem fs
, final Path testdir
,
132 FSDataOutputStream fdos
= fs
.create(new Path(testdir
, name
), true);
137 public void testRegionEntryBuffer() throws Exception
{
138 WALSplitter
.RegionEntryBuffer reb
= new WALSplitter
.RegionEntryBuffer(
139 TEST_TABLE
, TEST_REGION
);
140 assertEquals(0, reb
.heapSize());
142 reb
.appendEntry(createTestLogEntry(1));
143 assertTrue(reb
.heapSize() > 0);
147 public void testEntrySink() throws Exception
{
148 EntryBuffers sink
= new EntryBuffers(new PipelineController(), 1*1024*1024);
149 for (int i
= 0; i
< 1000; i
++) {
150 WAL
.Entry entry
= createTestLogEntry(i
);
151 sink
.appendEntry(entry
);
154 assertTrue(sink
.totalBuffered
> 0);
155 long amountInChunk
= sink
.totalBuffered
;
157 RegionEntryBuffer chunk
= sink
.getChunkToWrite();
158 assertEquals(chunk
.heapSize(), amountInChunk
);
160 // Make sure it got marked that a thread is "working on this"
161 assertTrue(sink
.isRegionCurrentlyWriting(TEST_REGION
));
163 // Insert some more entries
164 for (int i
= 0; i
< 500; i
++) {
165 WAL
.Entry entry
= createTestLogEntry(i
);
166 sink
.appendEntry(entry
);
168 // Asking for another chunk shouldn't work since the first one
170 assertNull(sink
.getChunkToWrite());
172 // If we say we're done writing the first chunk, then we should be able
174 sink
.doneWriting(chunk
);
176 RegionEntryBuffer chunk2
= sink
.getChunkToWrite();
177 assertNotNull(chunk2
);
178 assertNotSame(chunk
, chunk2
);
179 long amountInChunk2
= sink
.totalBuffered
;
180 // The second chunk had fewer rows than the first
181 assertTrue(amountInChunk2
< amountInChunk
);
183 sink
.doneWriting(chunk2
);
184 assertEquals(0, sink
.totalBuffered
);
187 private WAL
.Entry
createTestLogEntry(int i
) {
191 WALEdit edit
= new WALEdit();
192 edit
.add(KeyValueTestUtil
.create("row", "fam", "qual", 1234, "val"));
193 WALKeyImpl key
= new WALKeyImpl(TEST_REGION
, TEST_TABLE
, seq
, now
,
194 HConstants
.DEFAULT_CLUSTER_ID
);
195 WAL
.Entry entry
= new WAL
.Entry(key
, edit
);