1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28 package org.apache.http.impl.nio.codecs;
29
30 import java.io.File;
31 import java.io.IOException;
32 import java.io.RandomAccessFile;
33 import java.nio.ByteBuffer;
34 import java.nio.channels.FileChannel;
35 import java.nio.channels.ReadableByteChannel;
36
37 import org.apache.http.Consts;
38 import org.apache.http.ReadableByteChannelMock;
39 import org.apache.http.impl.io.HttpTransportMetricsImpl;
40 import org.apache.http.impl.nio.reactor.SessionInputBufferImpl;
41 import org.apache.http.nio.reactor.SessionInputBuffer;
42 import org.apache.http.util.EncodingUtils;
43 import org.junit.After;
44 import org.junit.Assert;
45 import org.junit.Test;
46
47
48
49
50 public class TestIdentityDecoder {
51
52 private File tmpfile;
53
54 protected File createTempFile() throws IOException {
55 this.tmpfile = File.createTempFile("testFile", ".txt");
56 return this.tmpfile;
57 }
58
59 @After
60 public void deleteTempFile() {
61 if (this.tmpfile != null && this.tmpfile.exists()) {
62 this.tmpfile.delete();
63 }
64 }
65
66 @Test
67 public void testBasicDecoding() throws Exception {
68 final ReadableByteChannel channel = new ReadableByteChannelMock(
69 new String[] {"stuff;", "more stuff"}, Consts.ASCII);
70
71 final SessionInputBuffer inbuf = new SessionInputBufferImpl(1024, 256, Consts.ASCII);
72 final HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
73 final IdentityDecoder decoder = new IdentityDecoder(channel, inbuf, metrics);
74
75 final ByteBuffer dst = ByteBuffer.allocate(1024);
76
77 int bytesRead = decoder.read(dst);
78 Assert.assertEquals(6, bytesRead);
79 Assert.assertEquals("stuff;", CodecTestUtils.convert(dst));
80 Assert.assertFalse(decoder.isCompleted());
81 Assert.assertEquals(6, metrics.getBytesTransferred());
82
83 dst.clear();
84 bytesRead = decoder.read(dst);
85 Assert.assertEquals(10, bytesRead);
86 Assert.assertEquals("more stuff", CodecTestUtils.convert(dst));
87 Assert.assertFalse(decoder.isCompleted());
88 Assert.assertEquals(16, metrics.getBytesTransferred());
89
90 dst.clear();
91 bytesRead = decoder.read(dst);
92 Assert.assertEquals(-1, bytesRead);
93 Assert.assertTrue(decoder.isCompleted());
94 Assert.assertEquals(16, metrics.getBytesTransferred());
95
96 dst.clear();
97 bytesRead = decoder.read(dst);
98 Assert.assertEquals(-1, bytesRead);
99 Assert.assertTrue(decoder.isCompleted());
100 Assert.assertEquals(16, metrics.getBytesTransferred());
101
102 Assert.assertEquals("[identity; completed: true]", decoder.toString());
103 }
104
105 @Test
106 public void testDecodingFromSessionBuffer() throws Exception {
107 final ReadableByteChannel channel = new ReadableByteChannelMock(
108 new String[] {"stuff;", "more stuff"}, Consts.ASCII);
109
110 final SessionInputBuffer inbuf = new SessionInputBufferImpl(1024, 256, Consts.ASCII);
111 final HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
112
113 inbuf.fill(channel);
114
115 Assert.assertEquals(6, inbuf.length());
116
117 final IdentityDecoder decoder = new IdentityDecoder(channel, inbuf, metrics);
118
119 final ByteBuffer dst = ByteBuffer.allocate(1024);
120
121 int bytesRead = decoder.read(dst);
122 Assert.assertEquals(6, bytesRead);
123 Assert.assertEquals("stuff;", CodecTestUtils.convert(dst));
124 Assert.assertFalse(decoder.isCompleted());
125 Assert.assertEquals(0, metrics.getBytesTransferred());
126
127 dst.clear();
128 bytesRead = decoder.read(dst);
129 Assert.assertEquals(10, bytesRead);
130 Assert.assertEquals("more stuff", CodecTestUtils.convert(dst));
131 Assert.assertFalse(decoder.isCompleted());
132 Assert.assertEquals(10, metrics.getBytesTransferred());
133
134 dst.clear();
135 bytesRead = decoder.read(dst);
136 Assert.assertEquals(-1, bytesRead);
137 Assert.assertTrue(decoder.isCompleted());
138 Assert.assertEquals(10, metrics.getBytesTransferred());
139
140 dst.clear();
141 bytesRead = decoder.read(dst);
142 Assert.assertEquals(-1, bytesRead);
143 Assert.assertTrue(decoder.isCompleted());
144 Assert.assertEquals(10, metrics.getBytesTransferred());
145
146 }
147
148 @Test
149 public void testBasicDecodingFile() throws Exception {
150 final ReadableByteChannel channel = new ReadableByteChannelMock(
151 new String[] {"stuff; ", "more stuff; ", "a lot more stuff!"}, Consts.ASCII);
152
153 final SessionInputBuffer inbuf = new SessionInputBufferImpl(1024, 256, Consts.ASCII);
154 final HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
155 final IdentityDecoder decoder = new IdentityDecoder(
156 channel, inbuf, metrics);
157
158 createTempFile();
159 final RandomAccessFile testfile = new RandomAccessFile(this.tmpfile, "rw");
160 try {
161 final FileChannel fchannel = testfile.getChannel();
162 long pos = 0;
163 while (!decoder.isCompleted()) {
164 final long bytesRead = decoder.transfer(fchannel, pos, 10);
165 if (bytesRead > 0) {
166 pos += bytesRead;
167 }
168 }
169
170 Assert.assertEquals(testfile.length(), metrics.getBytesTransferred());
171 } finally {
172 testfile.close();
173 }
174 Assert.assertEquals("stuff; more stuff; a lot more stuff!",
175 CodecTestUtils.readFromFile(this.tmpfile));
176 }
177
178 @Test
179 public void testDecodingFileWithBufferedSessionData() throws Exception {
180 final ReadableByteChannel channel = new ReadableByteChannelMock(
181 new String[] {"stuff; ", "more stuff; ", "a lot more stuff!"}, Consts.ASCII);
182
183 final SessionInputBuffer inbuf = new SessionInputBufferImpl(1024, 256, Consts.ASCII);
184 final HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
185 final IdentityDecoder decoder = new IdentityDecoder(
186 channel, inbuf, metrics);
187
188 final int i = inbuf.fill(channel);
189 Assert.assertEquals(7, i);
190
191 createTempFile();
192 final RandomAccessFile testfile = new RandomAccessFile(this.tmpfile, "rw");
193 try {
194 final FileChannel fchannel = testfile.getChannel();
195 long pos = 0;
196 while (!decoder.isCompleted()) {
197 final long bytesRead = decoder.transfer(fchannel, pos, 10);
198 if (bytesRead > 0) {
199 pos += bytesRead;
200 }
201 }
202
203
204 Assert.assertEquals(testfile.length() - 7, metrics.getBytesTransferred());
205 } finally {
206 testfile.close();
207 }
208 Assert.assertEquals("stuff; more stuff; a lot more stuff!",
209 CodecTestUtils.readFromFile(this.tmpfile));
210 }
211
212 @Test
213 public void testDecodingFileWithOffsetAndBufferedSessionData() throws Exception {
214 final ReadableByteChannel channel = new ReadableByteChannelMock(
215 new String[] {"stuff; ", "more stuff; ", "a lot more stuff!"}, Consts.ASCII);
216
217 final SessionInputBuffer inbuf = new SessionInputBufferImpl(1024, 256, Consts.ASCII);
218 final HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
219 final IdentityDecoder decoder = new IdentityDecoder(
220 channel, inbuf, metrics);
221
222 final int i = inbuf.fill(channel);
223 Assert.assertEquals(7, i);
224
225 final byte[] beginning = EncodingUtils.getAsciiBytes("beginning; ");
226
227 createTempFile();
228 RandomAccessFile testfile = new RandomAccessFile(this.tmpfile, "rw");
229 try {
230 testfile.write(beginning);
231 } finally {
232 testfile.close();
233 }
234
235 testfile = new RandomAccessFile(this.tmpfile, "rw");
236 try {
237 final FileChannel fchannel = testfile.getChannel();
238 long pos = beginning.length;
239 while (!decoder.isCompleted()) {
240 if(testfile.length() < pos) {
241 testfile.setLength(pos);
242 }
243 final long bytesRead = decoder.transfer(fchannel, pos, 10);
244 if (bytesRead > 0) {
245 pos += bytesRead;
246 }
247 }
248
249
250 Assert.assertEquals(testfile.length() - 7 - beginning.length, metrics.getBytesTransferred());
251 } finally {
252 testfile.close();
253 }
254
255 Assert.assertEquals("beginning; stuff; more stuff; a lot more stuff!",
256 CodecTestUtils.readFromFile(this.tmpfile));
257 }
258
259 @Test
260 public void testDecodingFileWithLimit() throws Exception {
261 final ReadableByteChannel channel = new ReadableByteChannelMock(
262 new String[] {"stuff; more stuff; ", "a lot more stuff!"}, Consts.ASCII);
263
264 final SessionInputBuffer inbuf = new SessionInputBufferImpl(1024, 256, Consts.ASCII);
265 final HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
266 final IdentityDecoder decoder = new IdentityDecoder(
267 channel, inbuf, metrics);
268
269 final int i = inbuf.fill(channel);
270 Assert.assertEquals(19, i);
271
272 createTempFile();
273 final RandomAccessFile testfile = new RandomAccessFile(this.tmpfile, "rw");
274 try {
275 final FileChannel fchannel = testfile.getChannel();
276 long pos = 0;
277
278
279 long bytesRead = decoder.transfer(fchannel, pos, 1);
280 Assert.assertEquals(1, bytesRead);
281 Assert.assertFalse(decoder.isCompleted());
282 Assert.assertEquals(0, metrics.getBytesTransferred());
283 pos += bytesRead;
284
285 bytesRead = decoder.transfer(fchannel, pos, 2);
286 Assert.assertEquals(2, bytesRead);
287 Assert.assertFalse(decoder.isCompleted());
288 Assert.assertEquals(0, metrics.getBytesTransferred());
289 pos += bytesRead;
290
291 bytesRead = decoder.transfer(fchannel, pos, 17);
292 Assert.assertEquals(16, bytesRead);
293 Assert.assertFalse(decoder.isCompleted());
294 Assert.assertEquals(0, metrics.getBytesTransferred());
295 pos += bytesRead;
296
297
298 bytesRead = decoder.transfer(fchannel, pos, 1);
299 Assert.assertEquals(1, bytesRead);
300 Assert.assertFalse(decoder.isCompleted());
301 Assert.assertEquals(1, metrics.getBytesTransferred());
302 pos += bytesRead;
303
304 bytesRead = decoder.transfer(fchannel, pos, 2);
305 Assert.assertEquals(2, bytesRead);
306 Assert.assertFalse(decoder.isCompleted());
307 Assert.assertEquals(3, metrics.getBytesTransferred());
308 pos += bytesRead;
309
310 bytesRead = decoder.transfer(fchannel, pos, 15);
311 Assert.assertEquals(14, bytesRead);
312 Assert.assertFalse(decoder.isCompleted());
313 Assert.assertEquals(17, metrics.getBytesTransferred());
314 pos += bytesRead;
315
316 bytesRead = decoder.transfer(fchannel, pos, 1);
317 Assert.assertEquals(-1, bytesRead);
318 Assert.assertTrue(decoder.isCompleted());
319 Assert.assertEquals(17, metrics.getBytesTransferred());
320 } finally {
321 testfile.close();
322 }
323 Assert.assertEquals("stuff; more stuff; a lot more stuff!",
324 CodecTestUtils.readFromFile(this.tmpfile));
325 }
326
327 @Test
328 public void testWriteBeyondFileSize() throws Exception {
329 final ReadableByteChannel channel = new ReadableByteChannelMock(
330 new String[] {"a"}, Consts.ASCII);
331
332 final SessionInputBuffer inbuf = new SessionInputBufferImpl(1024, 256, Consts.ASCII);
333 final HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
334 final IdentityDecoder decoder = new IdentityDecoder(
335 channel, inbuf, metrics);
336
337 createTempFile();
338 final RandomAccessFile testfile = new RandomAccessFile(this.tmpfile, "rw");
339 try {
340 Assert.assertEquals(0, testfile.length());
341 final FileChannel fchannel = testfile.getChannel();
342 try {
343 decoder.transfer(fchannel, 5, 10);
344 Assert.fail("expected IOException");
345 } catch(final IOException iox) {}
346 } finally {
347 testfile.close();
348 }
349 }
350
351 @Test
352 public void testInvalidConstructor() {
353 final ReadableByteChannel channel = new ReadableByteChannelMock(
354 new String[] {"stuff;", "more stuff"}, Consts.ASCII);
355
356 final SessionInputBuffer inbuf = new SessionInputBufferImpl(1024, 256, Consts.ASCII);
357 try {
358 new IdentityDecoder(null, null, null);
359 Assert.fail("IllegalArgumentException should have been thrown");
360 } catch (final IllegalArgumentException ex) {
361
362 }
363 try {
364 new IdentityDecoder(channel, null, null);
365 Assert.fail("IllegalArgumentException should have been thrown");
366 } catch (final IllegalArgumentException ex) {
367
368 }
369 try {
370 new IdentityDecoder(channel, inbuf, null);
371 Assert.fail("IllegalArgumentException should have been thrown");
372 } catch (final IllegalArgumentException ex) {
373
374 }
375 }
376
377 @Test
378 public void testInvalidInput() throws Exception {
379 final String s = "stuff";
380 final ReadableByteChannel channel = new ReadableByteChannelMock(
381 new String[] {s}, Consts.ASCII);
382
383 final SessionInputBuffer inbuf = new SessionInputBufferImpl(1024, 256, Consts.ASCII);
384 final HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
385 final IdentityDecoder decoder = new IdentityDecoder(channel, inbuf, metrics);
386
387 try {
388 decoder.read(null);
389 Assert.fail("IllegalArgumentException should have been thrown");
390 } catch (final IllegalArgumentException ex) {
391
392 }
393 }
394
395 }