1/* Licensed to the Apache Software Foundation (ASF) under one or more
2 * contributor license agreements.  See the NOTICE file distributed with
3 * this work for additional information regarding copyright ownership.
4 * The ASF licenses this file to You under the Apache License, Version 2.0
5 * (the "License"); you may not use this file except in compliance with
6 * the License.  You may obtain a copy of the License at
7 *
8 *     http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package org.apache.harmony.nio.tests.java.nio.channels;
18
19import java.io.IOException;
20import java.nio.ByteBuffer;
21import java.nio.channels.ClosedChannelException;
22import java.nio.channels.Pipe;
23import java.nio.channels.SelectionKey;
24
25import junit.framework.TestCase;
26
27/**
28 * Tests for java.nio.channels.Pipe.SourceChannel
29 */
30public class SourceChannelTest extends TestCase {
31
32	private static final int BUFFER_SIZE = 5;
33
34	private static final String ISO8859_1 = "ISO8859-1";
35
36	private Pipe pipe;
37
38	private Pipe.SinkChannel sink;
39
40	private Pipe.SourceChannel source;
41
42	private ByteBuffer buffer;
43
44	private ByteBuffer positionedBuffer;
45
46	protected void setUp() throws Exception {
47		super.setUp();
48		pipe = Pipe.open();
49		sink = pipe.sink();
50		source = pipe.source();
51		buffer = ByteBuffer.wrap("bytes".getBytes(ISO8859_1));
52		positionedBuffer = ByteBuffer.wrap("12345bytes".getBytes(ISO8859_1));
53		positionedBuffer.position(BUFFER_SIZE);
54	}
55
56	/**
57	 * @tests java.nio.channels.Pipe.SourceChannel#validOps()
58	 */
59	public void test_validOps() {
60		assertEquals(SelectionKey.OP_READ, source.validOps());
61	}
62
63	/**
64	 * @tests java.nio.channels.Pipe.SourceChannel#read(ByteBuffer)
65	 */
66	public void test_read_LByteBuffer_DataAvailable() throws IOException {
67		// if anything can read, read method will not block
68		sink.write(ByteBuffer.allocate(1));
69		int count = source.read(ByteBuffer.allocate(10));
70		assertEquals(1, count);
71	}
72
73	/**
74	 * @tests java.nio.channels.Pipe.SourceChannel#read(ByteBuffer)
75	 */
76	public void test_read_LByteBuffer_Exception() throws IOException {
77		ByteBuffer nullBuf = null;
78		try {
79			source.read(nullBuf);
80            fail("should throw NullPointerException");
81		} catch (NullPointerException e) {
82			// expected
83		}
84	}
85
86	/**
87	 * @tests java.nio.channels.Pipe.SourceChannel#read(ByteBuffer)
88	 */
89	public void test_read_LByteBuffer_SinkClosed() throws IOException {
90		ByteBuffer readBuf = ByteBuffer.allocate(BUFFER_SIZE);
91		sink.write(buffer);
92		sink.close();
93		long count = source.read(readBuf);
94		assertEquals(BUFFER_SIZE, count);
95		// readBuf is full, read 0 byte expected
96		count = source.read(readBuf);
97		assertEquals(0, count);
98		// readBuf is not null, -1 is expected
99		readBuf.position(0);
100		count = source.read(readBuf);
101		assertEquals(-1, count);
102	}
103
104	/**
105	 * @tests java.nio.channels.Pipe.SourceChannel#read(ByteBuffer)
106	 */
107	public void test_read_LByteBuffer_SourceClosed() throws IOException {
108		ByteBuffer readBuf = ByteBuffer.allocate(BUFFER_SIZE);
109		source.close();
110		try {
111			source.read(readBuf);
112            fail("should throw ClosedChannelException");
113		} catch (ClosedChannelException e) {
114			// expected
115		}
116		readBuf.position(BUFFER_SIZE);
117		try {
118			// readBuf is full
119			source.read(readBuf);
120            fail("should throw ClosedChannelException");
121		} catch (ClosedChannelException e) {
122			// expected
123		}
124
125		ByteBuffer nullBuf = null;
126		try {
127			source.read(nullBuf);
128            fail("should throw NullPointerException");
129		} catch (NullPointerException e) {
130			// expected
131		}
132
133        ByteBuffer[] bufArray = null;
134        try {
135            source.read(bufArray);
136            fail("should throw NullPointerException");
137        } catch (NullPointerException e) {
138            // expected
139        }
140
141        ByteBuffer[] nullBufArray = {nullBuf};
142        try {
143            source.read(nullBufArray);
144            fail("should throw ClosedChannelException");
145        } catch (ClosedChannelException e) {
146            // expected
147        }
148	}
149
150	/**
151     * @tests java.nio.channels.Pipe.SourceChannel#read(ByteBuffer[])
152     */
153    public void test_read_$LByteBuffer() throws IOException {
154        ByteBuffer[] bufArray = { buffer, positionedBuffer };
155        boolean[] sinkBlockingMode = { true, true, false, false };
156        boolean[] sourceBlockingMode = { true, false, true, false };
157        for (int i = 0; i < sinkBlockingMode.length; ++i) {
158            // open new pipe everytime, will be closed in finally block
159            pipe = Pipe.open();
160            sink = pipe.sink();
161            source = pipe.source();
162            sink.configureBlocking(sinkBlockingMode[i]);
163            source.configureBlocking(sourceBlockingMode[i]);
164            buffer.position(0);
165            positionedBuffer.position(BUFFER_SIZE);
166            try {
167                long writeCount = sink.write(bufArray);
168                assertEquals(10, writeCount);
169                // invoke close to ensure all data will be sent out
170                sink.close();
171                // read until EOF is meet or readBufArray is full.
172                ByteBuffer[] readBufArray = { ByteBuffer.allocate(BUFFER_SIZE),
173                        ByteBuffer.allocate(BUFFER_SIZE) };
174                long totalCount = 0;
175                do {
176                    long count = source.read(readBufArray);
177                    if (count < 0) {
178                        break;
179                    }
180                    if (0 == count && BUFFER_SIZE == readBufArray[1].position()) {
181                        // source.read returns 0 because readBufArray is full
182                        break;
183                    }
184                    totalCount += count;
185                } while (totalCount <= 10);
186                // assert read result
187                for (ByteBuffer readBuf : readBufArray) {
188                    // RI may fail because of its bug implementation
189                    assertEquals(BUFFER_SIZE, readBuf.position());
190                    assertEquals("bytes",
191                            new String(readBuf.array(), ISO8859_1));
192                }
193            } finally {
194                // close pipe everytime
195                sink.close();
196                source.close();
197            }
198        }
199    }
200
201	/**
202	 * @tests java.nio.channels.Pipe.SourceChannel#read(ByteBuffer)
203	 */
204	public void test_read_$LByteBuffer_Exception() throws IOException {
205		ByteBuffer[] nullBufArrayRef = null;
206		try {
207			source.read(nullBufArrayRef);
208			fail("should throw NullPointerException");
209		} catch (NullPointerException e) {
210			// expected
211		}
212
213		// ByteBuffer array contains null element
214		ByteBuffer nullBuf = null;
215		ByteBuffer[] nullBufArray1 = { nullBuf };
216		try {
217			source.read(nullBufArray1);
218			fail("should throw NullPointerException");
219		} catch (NullPointerException e) {
220			// expected
221		}
222
223		ByteBuffer[] nullBufArray2 = { buffer, nullBuf };
224		try {
225			source.read(nullBufArray2);
226			fail("should throw NullPointerException");
227		} catch (NullPointerException e) {
228			// expected
229		}
230	}
231
232	/**
233	 * @tests java.nio.channels.Pipe.SourceChannel#read(ByteBuffer)
234	 */
235	public void test_read_$LByteBuffer_SinkClosed() throws IOException {
236		ByteBuffer readBuf = ByteBuffer.allocate(BUFFER_SIZE);
237		ByteBuffer[] readBufArray = { readBuf };
238		sink.write(buffer);
239		sink.close();
240		long count = source.read(readBufArray);
241		assertEquals(BUFFER_SIZE, count);
242		// readBuf is full, read 0 byte expected
243		count = source.read(readBufArray);
244		assertEquals(0, count);
245		// readBuf is not null, -1 is expected
246		readBuf.position(0);
247        assertTrue(readBuf.hasRemaining());
248		count = source.read(readBufArray);
249		assertEquals(-1, count);
250	}
251
252	/**
253	 * @tests java.nio.channels.Pipe.SourceChannel#read(ByteBuffer)
254	 */
255	public void test_read_$LByteBuffer_SourceClosed() throws IOException {
256		ByteBuffer readBuf = ByteBuffer.allocate(BUFFER_SIZE);
257		ByteBuffer[] readBufArray = { readBuf };
258		source.close();
259		try {
260			source.read(readBufArray);
261            fail("should throw ClosedChannelException");
262		} catch (ClosedChannelException e) {
263			// expected
264		}
265		readBuf.position(BUFFER_SIZE);
266		try {
267			// readBuf is full
268			source.read(readBufArray);
269            fail("should throw ClosedChannelException");
270		} catch (ClosedChannelException e) {
271			// expected
272		}
273
274		ByteBuffer[] nullBufArrayRef = null;
275		try {
276			source.read(nullBufArrayRef);
277			fail("should throw NullPointerException");
278		} catch (NullPointerException e) {
279			// expected
280		}
281
282		// ByteBuffer array contains null element
283		ByteBuffer nullBuf = null;
284		ByteBuffer[] nullBufArray1 = { nullBuf };
285		try {
286			source.read(nullBufArray1);
287			fail("should throw ClosedChannelException");
288		} catch (ClosedChannelException e) {
289			// expected
290		}
291	}
292
293	/**
294     * @tests java.nio.channels.Pipe.SourceChannel#read(ByteBuffer[], int, int)
295     */
296    public void test_read_$LByteBufferII() throws IOException {
297        ByteBuffer[] bufArray = { buffer, positionedBuffer };
298        boolean[] sinkBlockingMode = { true, true, false, false };
299        boolean[] sourceBlockingMode = { true, false, true, false };
300        for (int i = 0; i < sinkBlockingMode.length; ++i) {
301            Pipe pipe = Pipe.open();
302            sink = pipe.sink();
303            source = pipe.source();
304
305            sink.configureBlocking(sinkBlockingMode[i]);
306            source.configureBlocking(sourceBlockingMode[i]);
307
308            buffer.position(0);
309            positionedBuffer.position(BUFFER_SIZE);
310            try {
311                sink.write(bufArray);
312                // invoke close to ensure all data will be sent out
313                sink.close();
314                // read until EOF is meet or readBufArray is full.
315                ByteBuffer[] readBufArray = { ByteBuffer.allocate(BUFFER_SIZE),
316                        ByteBuffer.allocate(BUFFER_SIZE) };
317                long totalCount = 0;
318                do {
319                    long count = source.read(readBufArray, 0, 2);
320                    if (count < 0) {
321                        break;
322                    }
323                    if (0 == count && BUFFER_SIZE == readBufArray[1].position()) {
324                        // source.read returns 0 because readBufArray is full
325                        break;
326                    }
327                    totalCount += count;
328                } while (totalCount != 10);
329
330                // assert read result
331                for (ByteBuffer readBuf : readBufArray) {
332                    // RI may fail because of its bug implementation
333                    assertEquals(BUFFER_SIZE, readBuf.position());
334                    assertEquals("bytes",
335                            new String(readBuf.array(), ISO8859_1));
336                }
337            } finally {
338                sink.close();
339                source.close();
340            }
341        }
342    }
343
344	/**
345	 * @tests java.nio.channels.Pipe.SourceChannel#read(ByteBuffer)
346	 */
347	public void test_read_$LByteBufferII_Exception() throws IOException {
348
349		ByteBuffer[] nullBufArrayRef = null;
350		try {
351			source.read(nullBufArrayRef, 0, 1);
352			fail("should throw NullPointerException");
353		} catch (NullPointerException e) {
354			// expected
355		}
356
357		try {
358			source.read(nullBufArrayRef, 0, -1);
359			fail("should throw IndexOutOfBoundsException");
360		} catch (IndexOutOfBoundsException e) {
361			// expected
362		}
363
364		// ByteBuffer array contains null element
365		ByteBuffer nullBuf = null;
366		ByteBuffer[] nullBufArray1 = { nullBuf };
367		try {
368			source.read(nullBufArray1, 0, 1);
369			fail("should throw NullPointerException");
370		} catch (NullPointerException e) {
371			// expected
372		}
373		try {
374			source.read(nullBufArray1, 0, -1);
375			fail("should throw IndexOutOfBoundsException");
376		} catch (IndexOutOfBoundsException e) {
377			// expected
378		}
379		try {
380			source.read(nullBufArray1, -1, 0);
381			fail("should throw IndexOutOfBoundsException");
382		} catch (IndexOutOfBoundsException e) {
383			// expected
384		}
385		try {
386			source.read(nullBufArray1, -1, 1);
387			fail("should throw IndexOutOfBoundsException");
388		} catch (IndexOutOfBoundsException e) {
389			// expected
390		}
391
392		ByteBuffer[] nullBufArray2 = { buffer, nullBuf };
393
394		try {
395			source.read(nullBufArray1, 1, -1);
396			fail("should throw IndexOutOfBoundsException");
397		} catch (IndexOutOfBoundsException e) {
398			// expected
399		}
400
401		try {
402			source.read(nullBufArray2, 0, 3);
403			fail("should throw IndexOutOfBoundsException");
404		} catch (IndexOutOfBoundsException e) {
405			// expected
406		}
407
408		try {
409			source.read(nullBufArray2, 0, 2);
410			fail("should throw NullPointerException");
411		} catch (NullPointerException e) {
412			// expected
413		}
414	}
415
416	/**
417	 * @tests java.nio.channels.Pipe.SourceChannel#read(ByteBuffer)
418	 */
419	public void test_read_$LByteBufferII_SinkClosed() throws IOException {
420		ByteBuffer readBuf = ByteBuffer.allocate(BUFFER_SIZE);
421		ByteBuffer[] readBufArray = { readBuf };
422		sink.write(buffer);
423		sink.close();
424		long count = source.read(readBufArray, 0, 1);
425		assertEquals(BUFFER_SIZE, count);
426		// readBuf is full, read 0 byte expected
427		count = source.read(readBufArray);
428		assertEquals(0, count);
429		// readBuf is not null, -1 is expected
430		readBuf.position(0);
431		count = source.read(readBufArray, 0, 1);
432		assertEquals(-1, count);
433	}
434
435	/**
436	 * @tests java.nio.channels.Pipe.SourceChannel#read(ByteBuffer)
437	 */
438	public void test_read_$LByteBufferII_SourceClosed() throws IOException {
439		ByteBuffer readBuf = ByteBuffer.allocate(BUFFER_SIZE);
440		ByteBuffer[] readBufArray = { readBuf };
441		source.close();
442		try {
443			source.read(readBufArray, 0, 1);
444			fail("should throw ClosedChannelException");
445		} catch (ClosedChannelException e) {
446			// expected
447		}
448		readBuf.position(BUFFER_SIZE);
449		try {
450			// readBuf is full
451			source.read(readBufArray, 0, 1);
452			fail("should throw ClosedChannelException");
453		} catch (ClosedChannelException e) {
454			// expected
455		}
456
457		ByteBuffer[] nullBufArrayRef = null;
458		try {
459			source.read(nullBufArrayRef, 0, 1);
460			fail("should throw NullPointerException");
461		} catch (NullPointerException e) {
462			// expected
463		}
464
465		try {
466			source.read(nullBufArrayRef, 0, -1);
467			fail("should throw IndexOutOfBoundsException");
468		} catch (IndexOutOfBoundsException e) {
469			// expected
470		}
471
472		// ByteBuffer array contains null element
473		ByteBuffer nullBuf = null;
474		ByteBuffer[] nullBufArray1 = { nullBuf };
475		try {
476			source.read(nullBufArray1, 0, 1);
477			fail("should throw ClosedChannelException");
478		} catch (ClosedChannelException e) {
479			// expected
480		}
481		try {
482			source.read(nullBufArray1, 0, -1);
483			fail("should throw IndexOutOfBoundsException");
484		} catch (IndexOutOfBoundsException e) {
485			// expected
486		}
487		try {
488			source.read(nullBufArray1, -1, 0);
489			fail("should throw IndexOutOfBoundsException");
490		} catch (IndexOutOfBoundsException e) {
491			// expected
492		}
493		try {
494			source.read(nullBufArray1, -1, 1);
495			fail("should throw IndexOutOfBoundsException");
496		} catch (IndexOutOfBoundsException e) {
497			// expected
498		}
499
500		ByteBuffer[] nullBufArray2 = { buffer, nullBuf };
501
502		try {
503			source.read(nullBufArray1, 1, -1);
504			fail("should throw IndexOutOfBoundsException");
505		} catch (IndexOutOfBoundsException e) {
506			// expected
507		}
508
509		try {
510			source.read(nullBufArray2, 0, 3);
511			fail("should throw IndexOutOfBoundsException");
512		} catch (IndexOutOfBoundsException e) {
513			// expected
514		}
515
516		try {
517			source.read(nullBufArray2, 0, 2);
518			fail("should throw ClosedChannelException");
519		} catch (ClosedChannelException e) {
520			// expected
521		}
522	}
523
524	/**
525	 * @tests java.nio.channels.Pipe.SourceChannel#close()
526	 */
527	public void test_close() throws IOException {
528		sink.close();
529		assertFalse(sink.isOpen());
530	}
531
532}
533