blob: eb2f9dd05a5db574e830fa7d3d112a1c8eaf8ae0 [file] [log] [blame]
/* 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.nio.tests.java.nio.channels;
import dalvik.annotation.TestTargetNew;
import dalvik.annotation.TestLevel;
import dalvik.annotation.TestTargetClass;
import dalvik.annotation.TestTargets;
import dalvik.annotation.AndroidOnly;
import java.io.IOException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.AsynchronousCloseException;
import java.nio.channels.ClosedByInterruptException;
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 java.nio.channels.Pipe.SinkChannel;
import java.nio.channels.spi.SelectorProvider;
import junit.framework.TestCase;
/**
* Tests for Pipe.SinkChannel class
*/
@TestTargetClass(
value = java.nio.channels.Pipe.SinkChannel.class,
untestedMethods = {
@TestTargetNew(
level = TestLevel.SUFFICIENT,
notes = "AsynchronousCloseException can not easily be tested",
method = "write",
args = {java.nio.ByteBuffer[].class}
),
@TestTargetNew(
level = TestLevel.SUFFICIENT,
notes = "ClosedByInterruptException can not easily be tested",
method = "write",
args = {java.nio.ByteBuffer[].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()
*/
@TestTargetNew(
level = TestLevel.COMPLETE,
notes = "",
method = "validOps",
args = {}
)
public void test_validOps() {
assertEquals(SelectionKey.OP_WRITE, sink.validOps());
}
/**
* @tests java.nio.channels.Pipe.SinkChannel#write(ByteBuffer [])
*/
@TestTargetNew(
level = TestLevel.PARTIAL_COMPLETE,
notes = "",
method = "write",
args = {java.nio.ByteBuffer[].class}
)
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)
*/
@TestTargetNew(
level = TestLevel.PARTIAL_COMPLETE,
notes = "",
method = "write",
args = {java.nio.ByteBuffer[].class}
)
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 disabled_test_read_LByteBuffer_mutliThread_close() throws Exception {
ByteBuffer sourceBuf = ByteBuffer.allocate(1000);
sink.configureBlocking(true);
new Thread() {
public void run() {
try {
Thread.currentThread().sleep(500);
sink.close();
} catch (Exception e) {
//ignore
}
}
}.start();
try {
sink.write(sourceBuf);
fail("should throw AsynchronousCloseException");
} catch (AsynchronousCloseException e) {
// ok
}
}
/**
* @tests java.nio.channels.Pipe.SinkChannel#write(ByteBuffer)
*/
public void disabled_test_read_LByteBuffer_mutliThread_interrupt() throws Exception {
sink.configureBlocking(true);
Thread thread = new Thread() {
public void run() {
try {
sink.write(ByteBuffer.allocate(10));
fail("should have thrown a ClosedByInterruptException.");
} catch (ClosedByInterruptException e) {
// expected
return;
} catch (IOException e) {
fail("should throw a ClosedByInterruptException but " +
"threw " + e.getClass() + ": " + e.getMessage());
}
}
};
thread.start();
Thread.currentThread().sleep(500);
thread.interrupt();
}
/**
* @tests java.nio.channels.Pipe.SinkChannel#write(ByteBuffer)
*/
@TestTargetNew(
level = TestLevel.PARTIAL_COMPLETE,
notes = "Verifies NullPointerException.",
method = "write",
args = {java.nio.ByteBuffer[].class}
)
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
}
}
/**
* @tests java.nio.channels.Pipe.SinkChannel#write(ByteBuffer)
*/
@TestTargetNew(
level = TestLevel.PARTIAL_COMPLETE,
notes = "",
method = "write",
args = {java.nio.ByteBuffer[].class}
)
@AndroidOnly("seems to run on newer RI versions")
public void test_write_LByteBuffer_SourceClosed() throws IOException {
source.close();
int written = sink.write(buffer);
assertEquals(BUFFER_SIZE, written);
}
/**
* @tests java.nio.channels.Pipe.SinkChannel#write(ByteBuffer)
*/
@TestTargetNew(
level = TestLevel.PARTIAL_COMPLETE,
notes = "Verifies ClosedChannelException, NullPointerException.",
method = "write",
args = {java.nio.ByteBuffer[].class}
)
public void test_write_LByteBuffer_SinkClosed() throws IOException {
sink.close();
try {
sink.write(buffer);
fail("should throw ClosedChannelException");
} catch (ClosedChannelException e) {
// expected
}
// write null ByteBuffer
ByteBuffer nullBuf = null;
try {
sink.write(nullBuf);
fail("should throw NullPointerException");
} catch (ClosedChannelException e) {
// expected on RI
} catch (NullPointerException e) {
// expected on Harmony/Android
}
}
/**
* @tests java.nio.channels.Pipe.SinkChannel#write(ByteBuffer[])
*/
@TestTargetNew(
level = TestLevel.PARTIAL_COMPLETE,
notes = "",
method = "write",
args = {java.nio.ByteBuffer[].class}
)
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[])
*/
@TestTargetNew(
level = TestLevel.PARTIAL_COMPLETE,
notes = "Verifies NullPointerException.",
method = "write",
args = {java.nio.ByteBuffer[].class}
)
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
}
}
/**
* @tests java.nio.channels.Pipe.SinkChannel#write(ByteBuffer[])
*/
@TestTargetNew(
level = TestLevel.PARTIAL_COMPLETE,
notes = "",
method = "write",
args = {java.nio.ByteBuffer[].class}
)
@AndroidOnly("seems to run on newer RI versions")
public void test_write_$LByteBuffer_SourceClosed() throws IOException {
ByteBuffer[] bufArray = { buffer };
source.close();
long written = sink.write(bufArray);
assertEquals(BUFFER_SIZE, written);
}
/**
* @tests java.nio.channels.Pipe.SinkChannel#write(ByteBuffer[])
*/
@TestTargetNew(
level = TestLevel.PARTIAL_COMPLETE,
notes = "Verifies ClosedChannelException, NullPointerException.",
method = "write",
args = {java.nio.ByteBuffer[].class}
)
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)
*/
@TestTargetNew(
level = TestLevel.PARTIAL_COMPLETE,
notes = "",
method = "write",
args = {java.nio.ByteBuffer[].class, int.class, int.class}
)
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());
}
}
/**
* @tests java.nio.channels.Pipe.SinkChannel#write(ByteBuffer[], int, int)
*/
@TestTargetNew(
level = TestLevel.PARTIAL_COMPLETE,
notes = "Verifies NullPointerException, IndexOutOfBoundsException.",
method = "write",
args = {java.nio.ByteBuffer[].class, int.class, int.class}
)
public void test_write_$LByteBufferII_Exception() throws IOException {
// write null ByteBuffer[]
ByteBuffer[] nullBufArrayRef = null;
try {
sink.write(nullBufArrayRef, 0, 1);
fail("should throw NullPointerException");
} catch (NullPointerException e) {
// expected
}
try {
sink.write(nullBufArrayRef, 0, -1);
fail("should throw IndexOutOfBoundsException");
} catch (IndexOutOfBoundsException e) {
// 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
}
}
/**
* @tests java.nio.channels.Pipe.SinkChannel#write(ByteBuffer[], int, int)
*/
@TestTargetNew(
level = TestLevel.PARTIAL_COMPLETE,
notes = "",
method = "write",
args = {java.nio.ByteBuffer[].class, int.class, int.class}
)
@AndroidOnly("seems to run on newer RI versions")
public void test_write_$LByteBufferII_SourceClosed() throws IOException {
ByteBuffer[] bufArray = { buffer };
source.close();
long written = sink.write(bufArray, 0, 1);
assertEquals(BUFFER_SIZE, written);
}
/**
* @tests java.nio.channels.Pipe.SinkChannel#write(ByteBuffer[], int, int)
*/
@TestTargetNew(
level = TestLevel.PARTIAL_COMPLETE,
notes = "Verifies ClosedChannelException, NullPointerException, IndexOutOfBoundsException.",
method = "write",
args = {java.nio.ByteBuffer[].class, int.class, int.class}
)
public void test_write_$LByteBufferII_SinkClosed() throws IOException {
ByteBuffer[] bufArray = { buffer };
sink.close();
try {
sink.write(bufArray, 0, 1);
fail("should throw ClosedChannelException");
} catch (ClosedChannelException e) {
// expected
}
// write null ByteBuffer[]
ByteBuffer[] nullBufArrayRef = null;
try {
sink.write(nullBufArrayRef, 0, 1);
fail("should throw NullPointerException");
} catch (NullPointerException e) {
// expected
}
// illegal array index
try {
sink.write(nullBufArrayRef, 0, -1);
fail("should throw IndexOutOfBoundsException");
} catch (IndexOutOfBoundsException e) {
// 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
}
}
/**
* @tests java.nio.channels.Pipe.SinkChannel#close()
* @tests {@link java.nio.channels.Pipe.SinkChannel#isOpen()}
*/
@TestTargets({
@TestTargetNew(
level = TestLevel.PARTIAL_COMPLETE,
notes = "",
method = "close",
args = {}
),@TestTargetNew(
level = TestLevel.PARTIAL_COMPLETE,
notes = "",
method = "isOpen",
args = {}
)
})
public void test_close() throws IOException {
assertTrue(sink.isOpen());
sink.close();
assertFalse(sink.isOpen());
}
@TestTargetNew(
level = TestLevel.COMPLETE,
notes = "",
method = "SinkChannel",
args = {java.nio.channels.spi.SelectorProvider.class}
)
public void testConstructor() throws IOException {
SinkChannel channel =
SelectorProvider.provider().openPipe().sink();
assertNotNull(channel);
assertSame(SelectorProvider.provider(),channel.provider());
channel = Pipe.open().sink();
assertNotNull(channel);
assertSame(SelectorProvider.provider(),channel.provider());
}
@TestTargetNew(
level = TestLevel.PARTIAL_COMPLETE,
notes = "Verifies that NullPointerException is thrown if write" +
"method is called for closed channel.",
method = "write",
args = {java.nio.ByteBuffer.class}
)
public void test_socketChannel_closed() 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();
}
@TestTargetNew(
level = TestLevel.PARTIAL_COMPLETE,
notes = "Verifies NullPointerException.",
method = "write",
args = {java.nio.ByteBuffer[].class, int.class, int.class}
)
public void test_socketChannel_empty() 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 e){
// expected
}
ssc.close();
sc.close();
ByteBuffer target = ByteBuffer.allocate(10);
assertEquals(-1, sock.read(target));
}
}