View Javadoc

1   /*
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
9    *
10   *     http://www.apache.org/licenses/LICENSE-2.0
11   *
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.
17   */
18  package org.apache.hadoop.hbase.io.hfile;
19  
20  import static org.junit.Assert.*;
21  import static org.mockito.Mockito.*;
22  
23  import java.io.IOException;
24  
25  import org.apache.hadoop.fs.FSDataInputStream;
26  import org.apache.hadoop.hbase.testclassification.SmallTests;
27  import org.junit.Rule;
28  import org.junit.Test;
29  import org.junit.experimental.categories.Category;
30  import org.junit.rules.ExpectedException;
31  
32  /**
33   * Unit test suite covering HFileBlock positional read logic.
34   */
35  @Category({SmallTests.class})
36  public class TestHFileBlockPositionalRead {
37  
38    @Rule
39    public ExpectedException exception = ExpectedException.none();
40  
41    @Test
42    public void testPositionalReadNoExtra() throws IOException {
43      long position = 0;
44      int bufOffset = 0;
45      int necessaryLen = 10;
46      int extraLen = 0;
47      int totalLen = necessaryLen + extraLen;
48      byte[] buf = new byte[totalLen];
49      FSDataInputStream in = mock(FSDataInputStream.class);
50      when(in.read(position, buf, bufOffset, totalLen)).thenReturn(totalLen);
51      boolean ret = HFileBlock.positionalReadWithExtra(in, position, buf,
52          bufOffset, necessaryLen, extraLen);
53      assertFalse("Expect false return when no extra bytes requested", ret);
54      verify(in).read(position, buf, bufOffset, totalLen);
55      verifyNoMoreInteractions(in);
56    }
57  
58    @Test
59    public void testPositionalReadShortReadOfNecessaryBytes() throws IOException {
60      long position = 0;
61      int bufOffset = 0;
62      int necessaryLen = 10;
63      int extraLen = 0;
64      int totalLen = necessaryLen + extraLen;
65      byte[] buf = new byte[totalLen];
66      FSDataInputStream in = mock(FSDataInputStream.class);
67      when(in.read(position, buf, bufOffset, totalLen)).thenReturn(5);
68      when(in.read(5, buf, 5, 5)).thenReturn(5);
69      boolean ret = HFileBlock.positionalReadWithExtra(in, position, buf,
70          bufOffset, necessaryLen, extraLen);
71      assertFalse("Expect false return when no extra bytes requested", ret);
72      verify(in).read(position, buf, bufOffset, totalLen);
73      verify(in).read(5, buf, 5, 5);
74      verifyNoMoreInteractions(in);
75    }
76  
77    @Test
78    public void testPositionalReadExtraSucceeded() throws IOException {
79      long position = 0;
80      int bufOffset = 0;
81      int necessaryLen = 10;
82      int extraLen = 5;
83      int totalLen = necessaryLen + extraLen;
84      byte[] buf = new byte[totalLen];
85      FSDataInputStream in = mock(FSDataInputStream.class);
86      when(in.read(position, buf, bufOffset, totalLen)).thenReturn(totalLen);
87      boolean ret = HFileBlock.positionalReadWithExtra(in, position, buf,
88          bufOffset, necessaryLen, extraLen);
89      assertTrue("Expect true return when reading extra bytes succeeds", ret);
90      verify(in).read(position, buf, bufOffset, totalLen);
91      verifyNoMoreInteractions(in);
92    }
93  
94    @Test
95    public void testPositionalReadExtraFailed() throws IOException {
96      long position = 0;
97      int bufOffset = 0;
98      int necessaryLen = 10;
99      int extraLen = 5;
100     int totalLen = necessaryLen + extraLen;
101     byte[] buf = new byte[totalLen];
102     FSDataInputStream in = mock(FSDataInputStream.class);
103     when(in.read(position, buf, bufOffset, totalLen)).thenReturn(necessaryLen);
104     boolean ret = HFileBlock.positionalReadWithExtra(in, position, buf,
105         bufOffset, necessaryLen, extraLen);
106     assertFalse("Expect false return when reading extra bytes fails", ret);
107     verify(in).read(position, buf, bufOffset, totalLen);
108     verifyNoMoreInteractions(in);
109   }
110 
111   @Test
112   public void testPositionalReadShortReadCompletesNecessaryAndExtraBytes()
113       throws IOException {
114     long position = 0;
115     int bufOffset = 0;
116     int necessaryLen = 10;
117     int extraLen = 5;
118     int totalLen = necessaryLen + extraLen;
119     byte[] buf = new byte[totalLen];
120     FSDataInputStream in = mock(FSDataInputStream.class);
121     when(in.read(position, buf, bufOffset, totalLen)).thenReturn(5);
122     when(in.read(5, buf, 5, 10)).thenReturn(10);
123     boolean ret = HFileBlock.positionalReadWithExtra(in, position, buf,
124         bufOffset, necessaryLen, extraLen);
125     assertTrue("Expect true return when reading extra bytes succeeds", ret);
126     verify(in).read(position, buf, bufOffset, totalLen);
127     verify(in).read(5, buf, 5, 10);
128     verifyNoMoreInteractions(in);
129   }
130 
131   @Test
132   public void testPositionalReadPrematureEOF() throws IOException {
133     long position = 0;
134     int bufOffset = 0;
135     int necessaryLen = 10;
136     int extraLen = 0;
137     int totalLen = necessaryLen + extraLen;
138     byte[] buf = new byte[totalLen];
139     FSDataInputStream in = mock(FSDataInputStream.class);
140     when(in.read(position, buf, bufOffset, totalLen)).thenReturn(9);
141     when(in.read(position, buf, bufOffset, totalLen)).thenReturn(-1);
142     exception.expect(IOException.class);
143     exception.expectMessage("EOF");
144     HFileBlock.positionalReadWithExtra(in, position, buf, bufOffset,
145         necessaryLen, extraLen);
146   }
147 }