1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.hadoop.hbase.ipc;
19
20 import static org.junit.Assert.*;
21
22 import java.io.File;
23 import java.io.FileOutputStream;
24 import java.io.IOException;
25 import java.nio.ByteBuffer;
26 import java.nio.channels.FileChannel;
27
28 import org.apache.hadoop.hbase.testclassification.SmallTests;
29 import org.apache.hadoop.hbase.util.Bytes;
30 import org.junit.After;
31 import org.junit.Before;
32 import org.junit.Test;
33 import org.junit.experimental.categories.Category;
34 import org.mockito.Mockito;
35
36 import com.google.common.base.Charsets;
37 import com.google.common.io.Files;
38
39 @Category(SmallTests.class)
40 public class TestBufferChain {
41 private File tmpFile;
42
43 private static final byte[][] HELLO_WORLD_CHUNKS = new byte[][] {
44 "hello".getBytes(Charsets.UTF_8),
45 " ".getBytes(Charsets.UTF_8),
46 "world".getBytes(Charsets.UTF_8)
47 };
48
49 @Before
50 public void setup() throws IOException {
51 tmpFile = File.createTempFile("TestBufferChain", "txt");
52 }
53
54 @After
55 public void teardown() {
56 tmpFile.delete();
57 }
58
59 @Test
60 public void testGetBackBytesWePutIn() {
61 ByteBuffer[] bufs = wrapArrays(HELLO_WORLD_CHUNKS);
62 BufferChain chain = new BufferChain(bufs);
63 assertTrue(Bytes.equals(Bytes.toBytes("hello world"), chain.getBytes()));
64 }
65
66 @Test
67 public void testChainChunkBiggerThanWholeArray() throws IOException {
68 ByteBuffer[] bufs = wrapArrays(HELLO_WORLD_CHUNKS);
69 BufferChain chain = new BufferChain(bufs);
70 writeAndVerify(chain, "hello world", 8192);
71 assertNoRemaining(bufs);
72 }
73
74 @Test
75 public void testChainChunkBiggerThanSomeArrays() throws IOException {
76 ByteBuffer[] bufs = wrapArrays(HELLO_WORLD_CHUNKS);
77 BufferChain chain = new BufferChain(bufs);
78 writeAndVerify(chain, "hello world", 3);
79 assertNoRemaining(bufs);
80 }
81
82 @Test
83 public void testLimitOffset() throws IOException {
84 ByteBuffer[] bufs = new ByteBuffer[] {
85 stringBuf("XXXhelloYYY", 3, 5),
86 stringBuf(" ", 0, 1),
87 stringBuf("XXXXworldY", 4, 5) };
88 BufferChain chain = new BufferChain(bufs);
89 writeAndVerify(chain , "hello world", 3);
90 assertNoRemaining(bufs);
91 }
92
93 @Test
94 public void testWithSpy() throws IOException {
95 ByteBuffer[] bufs = new ByteBuffer[] {
96 stringBuf("XXXhelloYYY", 3, 5),
97 stringBuf(" ", 0, 1),
98 stringBuf("XXXXworldY", 4, 5) };
99 BufferChain chain = new BufferChain(bufs);
100 FileOutputStream fos = new FileOutputStream(tmpFile);
101 FileChannel ch = Mockito.spy(fos.getChannel());
102 try {
103 chain.write(ch, 2);
104 assertEquals("he", Files.toString(tmpFile, Charsets.UTF_8));
105 chain.write(ch, 2);
106 assertEquals("hell", Files.toString(tmpFile, Charsets.UTF_8));
107 chain.write(ch, 3);
108 assertEquals("hello w", Files.toString(tmpFile, Charsets.UTF_8));
109 chain.write(ch, 8);
110 assertEquals("hello world", Files.toString(tmpFile, Charsets.UTF_8));
111 } finally {
112 ch.close();
113 fos.close();
114 }
115 }
116
117 private ByteBuffer stringBuf(String string, int position, int length) {
118 ByteBuffer buf = ByteBuffer.wrap(string.getBytes(Charsets.UTF_8));
119 buf.position(position);
120 buf.limit(position + length);
121 assertTrue(buf.hasRemaining());
122 return buf;
123 }
124
125 private void assertNoRemaining(ByteBuffer[] bufs) {
126 for (ByteBuffer buf : bufs) {
127 assertFalse(buf.hasRemaining());
128 }
129 }
130
131 private ByteBuffer[] wrapArrays(byte[][] arrays) {
132 ByteBuffer[] ret = new ByteBuffer[arrays.length];
133 for (int i = 0; i < arrays.length; i++) {
134 ret[i] = ByteBuffer.wrap(arrays[i]);
135 }
136 return ret;
137 }
138
139 private void writeAndVerify(BufferChain chain, String string, int chunkSize)
140 throws IOException {
141 FileOutputStream fos = new FileOutputStream(tmpFile);
142 FileChannel ch = fos.getChannel();
143 try {
144 long remaining = string.length();
145 while (chain.hasRemaining()) {
146 long n = chain.write(ch, chunkSize);
147 assertTrue(n == chunkSize || n == remaining);
148 remaining -= n;
149 }
150 assertEquals(0, remaining);
151 } finally {
152 fos.close();
153 }
154 assertFalse(chain.hasRemaining());
155 assertEquals(string, Files.toString(tmpFile, Charsets.UTF_8));
156 }
157 }