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.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();
353		} catch (NullPointerException expected) {
354		}
355
356		try {
357			source.read(nullBufArrayRef, 0, -1);
358			fail();
359		} catch (NullPointerException expected) {
360		} catch (IndexOutOfBoundsException expected) {
361		}
362
363		try {
364			source.read(new ByteBuffer[0], 0, -1);
365			fail();
366		} catch (IndexOutOfBoundsException expected) {
367		}
368
369		try {
370			source.read(new ByteBuffer[0], -1, 0);
371			fail();
372		} catch (IndexOutOfBoundsException expected) {
373		}
374
375		// ByteBuffer array contains null element
376		ByteBuffer nullBuf = null;
377		ByteBuffer[] nullBufArray1 = { nullBuf };
378		try {
379			source.read(nullBufArray1, 0, 1);
380			fail("should throw NullPointerException");
381		} catch (NullPointerException e) {
382			// expected
383		}
384		try {
385			source.read(nullBufArray1, 0, -1);
386			fail("should throw IndexOutOfBoundsException");
387		} catch (IndexOutOfBoundsException e) {
388			// expected
389		}
390		try {
391			source.read(nullBufArray1, -1, 0);
392			fail("should throw IndexOutOfBoundsException");
393		} catch (IndexOutOfBoundsException e) {
394			// expected
395		}
396		try {
397			source.read(nullBufArray1, -1, 1);
398			fail("should throw IndexOutOfBoundsException");
399		} catch (IndexOutOfBoundsException e) {
400			// expected
401		}
402
403		ByteBuffer[] nullBufArray2 = { buffer, nullBuf };
404
405		try {
406			source.read(nullBufArray1, 1, -1);
407			fail("should throw IndexOutOfBoundsException");
408		} catch (IndexOutOfBoundsException e) {
409			// expected
410		}
411
412		try {
413			source.read(nullBufArray2, 0, 3);
414			fail("should throw IndexOutOfBoundsException");
415		} catch (IndexOutOfBoundsException e) {
416			// expected
417		}
418
419		try {
420			source.read(nullBufArray2, 0, 2);
421			fail("should throw NullPointerException");
422		} catch (NullPointerException e) {
423			// expected
424		}
425	}
426
427	/**
428	 * @tests java.nio.channels.Pipe.SourceChannel#read(ByteBuffer)
429	 */
430	public void test_read_$LByteBufferII_SinkClosed() throws IOException {
431		ByteBuffer readBuf = ByteBuffer.allocate(BUFFER_SIZE);
432		ByteBuffer[] readBufArray = { readBuf };
433		sink.write(buffer);
434		sink.close();
435		long count = source.read(readBufArray, 0, 1);
436		assertEquals(BUFFER_SIZE, count);
437		// readBuf is full, read 0 byte expected
438		count = source.read(readBufArray);
439		assertEquals(0, count);
440		// readBuf is not null, -1 is expected
441		readBuf.position(0);
442		count = source.read(readBufArray, 0, 1);
443		assertEquals(-1, count);
444	}
445
446	/**
447	 * @tests java.nio.channels.Pipe.SourceChannel#read(ByteBuffer)
448	 */
449	public void test_read_$LByteBufferII_SourceClosed() throws IOException {
450		ByteBuffer readBuf = ByteBuffer.allocate(BUFFER_SIZE);
451		ByteBuffer[] readBufArray = { readBuf };
452		source.close();
453		try {
454			source.read(readBufArray, 0, 1);
455			fail("should throw ClosedChannelException");
456		} catch (ClosedChannelException e) {
457			// expected
458		}
459		readBuf.position(BUFFER_SIZE);
460		try {
461			// readBuf is full
462			source.read(readBufArray, 0, 1);
463			fail("should throw ClosedChannelException");
464		} catch (ClosedChannelException e) {
465			// expected
466		}
467
468		ByteBuffer[] nullBufArrayRef = null;
469		try {
470			source.read(nullBufArrayRef, 0, 1);
471			fail();
472		} catch (NullPointerException expected) {
473		}
474
475		try {
476			source.read(nullBufArrayRef, 0, -1);
477			fail();
478		} catch (NullPointerException expected) {
479		} catch (IndexOutOfBoundsException expected) {
480		}
481
482		try {
483			source.read(new ByteBuffer[0], 0, -1);
484			fail();
485		} catch (IndexOutOfBoundsException expected) {
486		}
487
488		try {
489			source.read(new ByteBuffer[0], -1, 1);
490			fail();
491		} catch (IndexOutOfBoundsException expected) {
492		}
493
494		// ByteBuffer array contains null element
495		ByteBuffer nullBuf = null;
496		ByteBuffer[] nullBufArray1 = { nullBuf };
497		try {
498			source.read(nullBufArray1, 0, 1);
499			fail("should throw ClosedChannelException");
500		} catch (ClosedChannelException e) {
501			// expected
502		}
503		try {
504			source.read(nullBufArray1, 0, -1);
505			fail("should throw IndexOutOfBoundsException");
506		} catch (IndexOutOfBoundsException e) {
507			// expected
508		}
509		try {
510			source.read(nullBufArray1, -1, 0);
511			fail("should throw IndexOutOfBoundsException");
512		} catch (IndexOutOfBoundsException e) {
513			// expected
514		}
515		try {
516			source.read(nullBufArray1, -1, 1);
517			fail("should throw IndexOutOfBoundsException");
518		} catch (IndexOutOfBoundsException e) {
519			// expected
520		}
521
522		ByteBuffer[] nullBufArray2 = { buffer, nullBuf };
523
524		try {
525			source.read(nullBufArray1, 1, -1);
526			fail("should throw IndexOutOfBoundsException");
527		} catch (IndexOutOfBoundsException e) {
528			// expected
529		}
530
531		try {
532			source.read(nullBufArray2, 0, 3);
533			fail("should throw IndexOutOfBoundsException");
534		} catch (IndexOutOfBoundsException e) {
535			// expected
536		}
537
538		try {
539			source.read(nullBufArray2, 0, 2);
540			fail("should throw ClosedChannelException");
541		} catch (ClosedChannelException e) {
542			// expected
543		}
544	}
545
546	/**
547	 * @tests java.nio.channels.Pipe.SourceChannel#close()
548	 */
549	public void test_close() throws IOException {
550		sink.close();
551		assertFalse(sink.isOpen());
552	}
553
554}
555