blob: b9e23db11a481976c6a69cb77230e2b5a49dc297 [file] [log] [blame]
/*
* Copyright (C) 2016 The Android Open Source Project
*
* Licensed 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 libcore.java.nio.channels;
import java.net.BindException;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketOption;
import java.net.StandardSocketOptions;
import java.nio.channels.AlreadyBoundException;
import java.nio.channels.AsynchronousChannelGroup;
import java.nio.channels.AsynchronousCloseException;
import java.nio.channels.AsynchronousServerSocketChannel;
import java.nio.channels.AsynchronousSocketChannel;
import java.nio.channels.ClosedChannelException;
import java.nio.channels.NotYetBoundException;
import java.nio.channels.UnresolvedAddressException;
import java.nio.channels.spi.AsynchronousChannelProvider;
import java.util.Set;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;
public class AsynchronousServerSocketChannelTest extends junit.framework.TestCase {
public void test_bind() throws Throwable {
AsynchronousServerSocketChannel assc = AsynchronousServerSocketChannel.open();
assertTrue(assc.isOpen());
assertNull(assc.getLocalAddress());
assc.bind(new InetSocketAddress(0));
assertNotNull(assc.getLocalAddress());
try {
assc.bind(new InetSocketAddress(0));
fail();
} catch (AlreadyBoundException expected) {}
assc.close();
assertFalse(assc.isOpen());
}
public void test_bind_null() throws Throwable {
AsynchronousServerSocketChannel assc = AsynchronousServerSocketChannel.open();
assertTrue(assc.isOpen());
assertNull(assc.getLocalAddress());
assc.bind(null);
assertNotNull(assc.getLocalAddress());
try {
assc.bind(null);
fail();
} catch (AlreadyBoundException expected) {}
assc.close();
assertFalse(assc.isOpen());
}
public void test_bind_unresolvedAddress() throws Throwable {
AsynchronousServerSocketChannel assc = AsynchronousServerSocketChannel.open();
try {
assc.bind(new InetSocketAddress("unresolvedname", 31415));
fail();
} catch (UnresolvedAddressException expected) {}
assertNull(assc.getLocalAddress());
assertTrue(assc.isOpen());
assc.close();
}
public void test_bind_used() throws Throwable {
AsynchronousServerSocketChannel assc = AsynchronousServerSocketChannel.open();
ServerSocket ss = new ServerSocket(0);
try {
assc.bind(ss.getLocalSocketAddress());
fail();
} catch (BindException expected) {}
assertNull(assc.getLocalAddress());
ss.close();
assc.close();
}
public void test_futureAccept() throws Throwable {
AsynchronousServerSocketChannel assc = AsynchronousServerSocketChannel.open();
assc.bind(new InetSocketAddress(0));
Future<AsynchronousSocketChannel> acceptFuture = assc.accept();
Socket s = new Socket();
s.connect(assc.getLocalAddress());
AsynchronousSocketChannel asc = acceptFuture.get(1000, TimeUnit.MILLISECONDS);
assertTrue(s.isConnected());
assertNotNull(asc.getLocalAddress());
assertEquals(asc.getLocalAddress(), s.getRemoteSocketAddress());
assertNotNull(asc.getRemoteAddress());
assertEquals(asc.getRemoteAddress(), s.getLocalSocketAddress());
asc.close();
s.close();
assc.close();
}
public void test_completionHandlerAccept() throws Throwable {
AsynchronousServerSocketChannel assc = AsynchronousServerSocketChannel.open();
assc.bind(new InetSocketAddress(0));
FutureLikeCompletionHandler<AsynchronousSocketChannel> acceptCompletionHandler =
new FutureLikeCompletionHandler<AsynchronousSocketChannel>();
assc.accept(null /* attachment */, acceptCompletionHandler);
Socket s = new Socket();
s.connect(assc.getLocalAddress());
AsynchronousSocketChannel asc = acceptCompletionHandler.get(1000);
assertNotNull(asc);
assertTrue(s.isConnected());
assertNotNull(asc.getLocalAddress());
assertEquals(asc.getLocalAddress(), s.getRemoteSocketAddress());
assertNotNull(asc.getRemoteAddress());
assertEquals(asc.getRemoteAddress(), s.getLocalSocketAddress());
assertNull(acceptCompletionHandler.getAttachment());
asc.close();
s.close();
assc.close();
}
public void test_completionHandlerAccept_attachment() throws Throwable {
AsynchronousServerSocketChannel assc = AsynchronousServerSocketChannel.open();
assc.bind(new InetSocketAddress(0));
FutureLikeCompletionHandler<AsynchronousSocketChannel> acceptCompletionHandler =
new FutureLikeCompletionHandler<AsynchronousSocketChannel>();
Integer attachment = new Integer(123);
assc.accept(attachment, acceptCompletionHandler);
Socket s = new Socket();
s.connect(assc.getLocalAddress());
AsynchronousSocketChannel asc = acceptCompletionHandler.get(1000);
assertNotNull(asc);
assertTrue(s.isConnected());
assertEquals(attachment, acceptCompletionHandler.getAttachment());
asc.close();
s.close();
assc.close();
}
public void test_completionHandlerAccept_nyb() throws Throwable {
AsynchronousServerSocketChannel assc = AsynchronousServerSocketChannel.open();
FutureLikeCompletionHandler<AsynchronousSocketChannel> acceptCompletionHandler =
new FutureLikeCompletionHandler<AsynchronousSocketChannel>();
try {
assc.accept(null /* attachment */, acceptCompletionHandler);
fail();
} catch(NotYetBoundException expected) {}
assc.close();
}
public void test_completionHandlerAccept_npe() throws Throwable {
AsynchronousServerSocketChannel assc = AsynchronousServerSocketChannel.open();
assc.bind(new InetSocketAddress(0));
try {
assc.accept(null /* attachment */, null /* completionHandler */);
fail();
} catch(NullPointerException expected) {}
assc.close();
}
public void test_options() throws Throwable {
AsynchronousServerSocketChannel assc = AsynchronousServerSocketChannel.open();
assc.setOption(StandardSocketOptions.SO_RCVBUF, 5000);
assertEquals(5000, (long)assc.getOption(StandardSocketOptions.SO_RCVBUF));
assc.setOption(StandardSocketOptions.SO_REUSEADDR, true);
assertTrue(assc.getOption(StandardSocketOptions.SO_REUSEADDR));
assc.close();
}
public void test_options_iae() throws Throwable {
AsynchronousServerSocketChannel assc = AsynchronousServerSocketChannel.open();
try {
assc.setOption(StandardSocketOptions.SO_KEEPALIVE, true);
fail();
} catch (UnsupportedOperationException expected) {}
assc.close();
}
public void test_group() throws Throwable {
AsynchronousChannelProvider provider =
AsynchronousChannelProvider.provider();
AsynchronousChannelGroup group =
provider.openAsynchronousChannelGroup(2, Executors.defaultThreadFactory());
AsynchronousServerSocketChannel assc = AsynchronousServerSocketChannel.open(group);
assertNull(assc.getLocalAddress());
assc.bind(new InetSocketAddress(0));
assertNotNull(assc.getLocalAddress());
assc.close();
}
public void test_close() throws Throwable {
AsynchronousServerSocketChannel assc = AsynchronousServerSocketChannel.open();
assc.bind(new InetSocketAddress(0));
assc.close();
Future<AsynchronousSocketChannel> acceptFuture = assc.accept();
try {
acceptFuture.get(1000, TimeUnit.MILLISECONDS);
fail();
} catch(ExecutionException expected) {
assertTrue(expected.getCause() instanceof ClosedChannelException);
}
FutureLikeCompletionHandler<AsynchronousSocketChannel> acceptCompletionHandler =
new FutureLikeCompletionHandler<AsynchronousSocketChannel>();
assc.accept(null /* attachment */, acceptCompletionHandler);
try {
acceptCompletionHandler.get(1000);
fail();
} catch(ClosedChannelException expected) {}
try {
assc.bind(new InetSocketAddress(0));
fail();
} catch(ClosedChannelException expected) {}
try {
assc.setOption(StandardSocketOptions.SO_REUSEADDR, true);
fail();
} catch(ClosedChannelException expected) {}
// Try second close
assc.close();
}
public void test_future_concurrent_close() throws Throwable {
AsynchronousServerSocketChannel assc = AsynchronousServerSocketChannel.open();
assc.bind(new InetSocketAddress(0));
final AtomicReference<Exception> killerThreadException =
new AtomicReference<Exception>(null);
final Thread killer = new Thread(new Runnable() {
public void run() {
try {
Thread.sleep(2000);
assc.close();
} catch (Exception ex) {
killerThreadException.set(ex);
}
}
});
killer.start();
Future<AsynchronousSocketChannel> acceptFuture = assc.accept();
try {
// This may timeout on slow devices, they may need more time for the killer thread to
// do its thing.
acceptFuture.get(10000, TimeUnit.MILLISECONDS);
fail();
} catch(ExecutionException expected) {
assertTrue(expected.getCause() instanceof ClosedChannelException);
}
assertNull(killerThreadException.get());
}
public void test_completionHandler_concurrent_close() throws Throwable {
AsynchronousServerSocketChannel assc = AsynchronousServerSocketChannel.open();
assc.bind(new InetSocketAddress(0));
final AtomicReference<Exception> killerThreadException =
new AtomicReference<Exception>(null);
final Thread killer = new Thread(new Runnable() {
public void run() {
try {
Thread.sleep(2000);
assc.close();
} catch (Exception ex) {
killerThreadException.set(ex);
}
}
});
killer.start();
FutureLikeCompletionHandler<AsynchronousSocketChannel> acceptCompletionHandler =
new FutureLikeCompletionHandler<AsynchronousSocketChannel>();
assc.accept(null /* attachment */, acceptCompletionHandler);
try {
// This may timeout on slow devices, they may need more time for the killer thread to
// do its thing.
acceptCompletionHandler.get(10000);
fail();
} catch(AsynchronousCloseException expected) {}
assertNull(killerThreadException.get());
}
public void test_supportedOptions() throws Throwable {
AsynchronousServerSocketChannel assc = AsynchronousServerSocketChannel.open();
Set<SocketOption<?>> supportedOptions = assc.supportedOptions();
assertEquals(2, supportedOptions.size());
assertTrue(supportedOptions.contains(StandardSocketOptions.SO_REUSEADDR));
assertTrue(supportedOptions.contains(StandardSocketOptions.SO_RCVBUF));
// supportedOptions should work after close according to spec
assc.close();
supportedOptions = assc.supportedOptions();
assertEquals(2, supportedOptions.size());
}
}