/* Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.harmony.tests.java.nio.channels; import java.io.IOException; import java.net.InetAddress; import java.net.InetSocketAddress; import java.nio.ByteBuffer; import java.nio.channels.ClosedChannelException; import java.nio.channels.Pipe; import java.nio.channels.SelectionKey; import java.nio.channels.ServerSocketChannel; import java.nio.channels.SocketChannel; import junit.framework.TestCase; /** * Tests for Pipe.SinkChannel class */ public class SinkChannelTest extends TestCase { private static final int BUFFER_SIZE = 5; private static final String ISO8859_1 = "ISO8859-1"; private Pipe pipe; private Pipe.SinkChannel sink; private Pipe.SourceChannel source; private ByteBuffer buffer; private ByteBuffer positionedBuffer; protected void setUp() throws Exception { super.setUp(); pipe = Pipe.open(); sink = pipe.sink(); source = pipe.source(); buffer = ByteBuffer.wrap("bytes".getBytes(ISO8859_1)); positionedBuffer = ByteBuffer.wrap("12345bytes".getBytes(ISO8859_1)); positionedBuffer.position(BUFFER_SIZE); } /** * @tests java.nio.channels.Pipe.SinkChannel#validOps() */ public void test_validOps() { assertEquals(SelectionKey.OP_WRITE, sink.validOps()); } /** * @tests java.nio.channels.Pipe.SinkChannel#write(ByteBuffer) */ public void test_write_LByteBuffer() throws IOException { ByteBuffer[] bufArray = { buffer, positionedBuffer }; boolean[] sinkBlockingMode = { true, true, false, false }; boolean[] sourceBlockingMode = { true, false, true, false }; int oldPosition; int currentPosition; for (int i = 0; i < sinkBlockingMode.length; ++i) { sink.configureBlocking(sinkBlockingMode[i]); source.configureBlocking(sourceBlockingMode[i]); // if sink and source both are blocking mode, source only needs read // once to get what sink write. boolean isBlocking = sinkBlockingMode[i] && sourceBlockingMode[i]; for (ByteBuffer buf : bufArray) { buf.mark(); oldPosition = buf.position(); sink.write(buf); ByteBuffer readBuf = ByteBuffer.allocate(BUFFER_SIZE); int totalCount = 0; do { int count = source.read(readBuf); if (count > 0) { totalCount += count; } } while (totalCount != BUFFER_SIZE && !isBlocking); currentPosition = buf.position(); assertEquals(BUFFER_SIZE, currentPosition - oldPosition); assertEquals("bytes", new String(readBuf.array(), ISO8859_1)); buf.reset(); } } } /** * @tests java.nio.channels.Pipe.SinkChannel#write(ByteBuffer) */ public void test_write_LByteBuffer_mutliThread() throws IOException, InterruptedException { final int THREAD_NUM = 20; final byte[] strbytes = "bytes".getBytes(ISO8859_1); Thread[] thread = new Thread[THREAD_NUM]; for (int i = 0; i < THREAD_NUM; i++) { thread[i] = new Thread() { public void run() { try { sink.write(ByteBuffer.wrap(strbytes)); } catch (IOException e) { throw new RuntimeException(e); } } }; } for (int i = 0; i < THREAD_NUM; i++) { thread[i].start(); } for (int i = 0; i < THREAD_NUM; i++) { thread[i].join(); } ByteBuffer readBuf = ByteBuffer.allocate(THREAD_NUM * BUFFER_SIZE); long totalCount = 0; do { long count = source.read(readBuf); if (count < 0) { break; } totalCount += count; } while (totalCount != (THREAD_NUM * BUFFER_SIZE)); StringBuffer buf = new StringBuffer(); for (int i = 0; i < THREAD_NUM; i++) { buf.append("bytes"); } String readString = buf.toString(); assertEquals(readString, new String(readBuf.array(), ISO8859_1)); } /** * @tests java.nio.channels.Pipe.SinkChannel#write(ByteBuffer) */ public void test_write_LByteBuffer_Exception() throws IOException { // write null ByteBuffer ByteBuffer nullBuf = null; try { sink.write(nullBuf); fail("should throw NullPointerException"); } catch (NullPointerException e) { // expected } } public void test_write_LByteBuffer_SourceClosed() throws IOException { source.close(); try { int written = sink.write(buffer); fail(); } catch (IOException expected) { } } public void test_write_LByteBuffer_SinkClosed() throws IOException { sink.close(); try { sink.write(buffer); fail("should throw ClosedChannelException"); } catch (ClosedChannelException expected) { } } /** * @tests java.nio.channels.Pipe.SinkChannel#write(ByteBuffer[]) */ public void test_write_$LByteBuffer() throws IOException { ByteBuffer[] bufArray = { buffer, positionedBuffer }; boolean[] sinkBlockingMode = { true, true, false, false }; boolean[] sourceBlockingMode = { true, false, true, false }; for (int i = 0; i < sinkBlockingMode.length; ++i) { sink.configureBlocking(sinkBlockingMode[i]); source.configureBlocking(sourceBlockingMode[i]); buffer.position(0); positionedBuffer.position(BUFFER_SIZE); sink.write(bufArray); // if sink and source both are blocking mode, source only needs read // once to get what sink write. boolean isBlocking = sinkBlockingMode[i] && sourceBlockingMode[i]; for (int j = 0; j < bufArray.length; ++j) { ByteBuffer readBuf = ByteBuffer.allocate(BUFFER_SIZE); int totalCount = 0; do { int count = source.read(readBuf); if (count < 0) { break; } totalCount += count; } while (totalCount != BUFFER_SIZE && !isBlocking); assertEquals("bytes", new String(readBuf.array(), ISO8859_1)); } assertEquals(BUFFER_SIZE, buffer.position()); assertEquals(10, positionedBuffer.position()); } } /** * @tests java.nio.channels.Pipe.SinkChannel#write(ByteBuffer[]) */ public void test_write_$LByteBuffer_Exception() throws IOException { // write null ByteBuffer[] ByteBuffer[] nullBufArrayRef = null; try { sink.write(nullBufArrayRef); fail("should throw NullPointerException"); } catch (NullPointerException e) { // expected } // write ByteBuffer[] contains null element ByteBuffer nullBuf = null; ByteBuffer[] nullBufArray = { buffer, nullBuf }; try { sink.write(nullBufArray); fail("should throw NullPointerException"); } catch (NullPointerException e) { // expected } } public void test_write_$LByteBuffer_SourceClosed() throws IOException { ByteBuffer[] bufArray = { buffer }; source.close(); try { long written = sink.write(bufArray); fail(); } catch (IOException expected) { } } /** * @tests java.nio.channels.Pipe.SinkChannel#write(ByteBuffer[]) */ public void test_write_$LByteBuffer_SinkClosed() throws IOException { ByteBuffer[] bufArray = { buffer }; sink.close(); try { sink.write(bufArray); fail("should throw ClosedChannelException"); } catch (ClosedChannelException e) { // expected } ByteBuffer[] nullBufArrayRef = null; try { sink.write(nullBufArrayRef); fail("should throw NullPointerException"); } catch (NullPointerException e) { // expected } ByteBuffer nullBuf = null; ByteBuffer[] nullBufArray = { nullBuf }; // write ByteBuffer[] contains null element try { sink.write(nullBufArray); fail("should throw ClosedChannelException"); } catch (ClosedChannelException e) { // expected } } /** * @tests java.nio.channels.Pipe.SinkChannel#write(ByteBuffer[], int, int) */ public void test_write_$LByteBufferII() throws IOException { ByteBuffer[] bufArray = { buffer, positionedBuffer }; boolean[] sinkBlockingMode = { true, true, false, false }; boolean[] sourceBlockingMode = { true, false, true, false }; for (int i = 0; i < sinkBlockingMode.length; ++i) { sink.configureBlocking(sinkBlockingMode[i]); source.configureBlocking(sourceBlockingMode[i]); positionedBuffer.position(BUFFER_SIZE); sink.write(bufArray, 1, 1); // if sink and source both are blocking mode, source only needs read // once to get what sink write. boolean isBlocking = sinkBlockingMode[i] && sourceBlockingMode[i]; ByteBuffer readBuf = ByteBuffer.allocate(BUFFER_SIZE); int totalCount = 0; do { int count = source.read(readBuf); if (count < 0) { break; } totalCount += count; } while (totalCount != BUFFER_SIZE && !isBlocking); assertEquals("bytes", new String(readBuf.array(), ISO8859_1)); assertEquals(10, positionedBuffer.position()); } } public void test_write_$LByteBufferII_Exception() throws IOException { try { sink.write(null, 0, 1); fail(); } catch (NullPointerException expected) { } try { sink.write(new ByteBuffer[2], 0, -1); fail(); } catch (IndexOutOfBoundsException expected) { } // write ByteBuffer[] contains null element ByteBuffer nullBuf = null; ByteBuffer[] nullBufArray = { nullBuf }; try { sink.write(nullBufArray, 0, 1); fail("should throw NullPointerException"); } catch (NullPointerException e) { // expected } try { sink.write(nullBufArray, 0, -1); fail("should throw IndexOutOfBoundsException"); } catch (IndexOutOfBoundsException e) { // expected } ByteBuffer[] bufArray = { buffer, nullBuf }; try { sink.write(bufArray, 0, -1); fail("should throw IndexOutOfBoundsException"); } catch (IndexOutOfBoundsException e) { // expected } try { sink.write(bufArray, -1, 0); fail("should throw IndexOutOfBoundsException"); } catch (IndexOutOfBoundsException e) { // expected } try { sink.write(bufArray, -1, 1); fail("should throw IndexOutOfBoundsException"); } catch (IndexOutOfBoundsException e) { // expected } try { sink.write(bufArray, 0, 3); fail("should throw IndexOutOfBoundsException"); } catch (IndexOutOfBoundsException e) { // expected } try { sink.write(bufArray, 0, 2); fail("should throw NullPointerException"); } catch (NullPointerException e) { // expected } } public void test_write_$LByteBufferII_SourceClosed() throws IOException { ByteBuffer[] bufArray = { buffer }; source.close(); try { long written = sink.write(bufArray, 0, 1); fail(); } catch (IOException expected) { } } public void test_write_$LByteBufferII_SinkClosed() throws IOException { ByteBuffer[] bufArray = { buffer }; sink.close(); try { sink.write(bufArray, 0, 1); fail(); } catch (ClosedChannelException expected) { } try { sink.write(null, 0, 1); fail(); } catch (NullPointerException expected) { } try { sink.write(new ByteBuffer[2], 0, -1); fail(); } catch (IndexOutOfBoundsException expected) { } // write ByteBuffer[] contains null element ByteBuffer nullBuf = null; ByteBuffer[] nullBufArray = { nullBuf }; try { sink.write(nullBufArray, 0, 1); fail("should throw ClosedChannelException"); } catch (ClosedChannelException e) { // expected } // illegal array index try { sink.write(nullBufArray, 0, -1); fail("should throw IndexOutOfBoundsException"); } catch (IndexOutOfBoundsException e) { // expected } ByteBuffer[] bufArray2 = { buffer, nullBuf }; // illegal array index try { sink.write(bufArray2, 0, -1); fail("should throw IndexOutOfBoundsException"); } catch (IndexOutOfBoundsException e) { // expected } try { sink.write(bufArray2, -1, 0); fail("should throw IndexOutOfBoundsException"); } catch (IndexOutOfBoundsException e) { // expected } try { sink.write(bufArray2, -1, 1); fail("should throw IndexOutOfBoundsException"); } catch (IndexOutOfBoundsException e) { // expected } try { sink.write(bufArray2, 0, 3); fail("should throw IndexOutOfBoundsException"); } catch (IndexOutOfBoundsException e) { // expected } try { sink.write(bufArray2, 0, 2); fail("should throw ClosedChannelException"); } catch (ClosedChannelException e) { // expected } } public void test_close() throws IOException { sink.close(); assertFalse(sink.isOpen()); } public void test_socketChannel_read_close() throws Exception { ServerSocketChannel ssc = ServerSocketChannel.open(); ssc.socket().bind(new InetSocketAddress(InetAddress.getLocalHost(),49999)); SocketChannel sc = SocketChannel.open(); ByteBuffer buf = null; try{ sc.write(buf); fail("should throw NPE"); }catch (NullPointerException e){ // expected } sc.connect(new InetSocketAddress(InetAddress.getLocalHost(),49999)); SocketChannel sock = ssc.accept(); ssc.close(); sc.close(); try{ sc.write(buf); fail("should throw NPE"); }catch (NullPointerException e){ // expected } sock.close(); } public void test_socketChannel_read_write() throws Exception { ServerSocketChannel ssc = ServerSocketChannel.open(); ssc.socket().bind(new InetSocketAddress(InetAddress.getLocalHost(),49999)); SocketChannel sc = SocketChannel.open(); sc.connect(new InetSocketAddress(InetAddress.getLocalHost(),49999)); SocketChannel sock = ssc.accept(); ByteBuffer[] buf = {ByteBuffer.allocate(10),null}; try { sc.write(buf,0,2); fail("should throw NPE"); } catch (NullPointerException expected) { } ssc.close(); sc.close(); ByteBuffer target = ByteBuffer.allocate(10); assertEquals(-1, sock.read(target)); } }