Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/test/com/sun/nio/sctp/SctpChannel/CommUp.java
38867 views
/*1* Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/2223/* @test24* @bug 686311025* @summary Newly connected/accepted SctpChannel should fire OP_READ if registered with a Selector26* @author chegar27*/2829import java.net.InetSocketAddress;30import java.net.SocketAddress;31import java.io.IOException;32import java.util.Iterator;33import java.util.Set;34import java.util.concurrent.CountDownLatch;35import java.nio.ByteBuffer;36import java.nio.channels.Selector;37import java.nio.channels.SelectionKey;38import com.sun.nio.sctp.AbstractNotificationHandler;39import com.sun.nio.sctp.AssociationChangeNotification;40import com.sun.nio.sctp.AssociationChangeNotification.AssocChangeEvent;41import com.sun.nio.sctp.HandlerResult;42import com.sun.nio.sctp.Notification;43import com.sun.nio.sctp.SctpChannel;44import com.sun.nio.sctp.SctpServerChannel;45import com.sun.nio.sctp.ShutdownNotification;46import static java.lang.System.out;47import static java.lang.System.err;48import static java.nio.channels.SelectionKey.OP_CONNECT;49import static java.nio.channels.SelectionKey.OP_READ;5051public class CommUp {52static CountDownLatch acceptLatch = new CountDownLatch(1);53static final int TIMEOUT = 10000;5455CommUpNotificationHandler clientHandler = new CommUpNotificationHandler();56CommUpNotificationHandler serverHandler = new CommUpNotificationHandler();57CommUpServer server;58Thread clientThread;5960void test(String[] args) {61SocketAddress address = null;6263if (!Util.isSCTPSupported()) {64out.println("SCTP protocol is not supported");65out.println("Test cannot be run");66return;67}6869if (args.length == 2) {70/* requested to connecct to a specific address */71try {72int port = Integer.valueOf(args[1]);73address = new InetSocketAddress(args[0], port);74} catch (NumberFormatException nfe) {75err.println(nfe);76}77} else {78/* start server on local machine, default */79try {80server = new CommUpServer();81server.start();82address = server.address();83debug("Server started and listening on " + address);84} catch (IOException ioe) {85ioe.printStackTrace();86return;87}88}8990/* store the main thread so that the server can interrupt it, if necessary */91clientThread = Thread.currentThread();9293doClient(address);94}9596void doClient(SocketAddress peerAddress) {97SctpChannel sc = null;98try {99debug("connecting to " + peerAddress);100sc = SctpChannel.open();101sc.configureBlocking(false);102check(sc.isBlocking() == false, "Should be in non-blocking mode");103sc.connect(peerAddress);104105Selector selector = Selector.open();106SelectionKey selectiontKey = sc.register(selector, OP_CONNECT);107108/* Expect two interest Ops */109boolean opConnectReceived = false;110boolean opReadReceived = false;111for (int z=0; z<2; z++) {112debug("select " + z);113int keysAdded = selector.select(TIMEOUT);114debug("returned " + keysAdded + " keys");115if (keysAdded > 0) {116Set<SelectionKey> keys = selector.selectedKeys();117Iterator<SelectionKey> i = keys.iterator();118while(i.hasNext()) {119SelectionKey sk = i.next();120i.remove();121SctpChannel readyChannel =122(SctpChannel)sk.channel();123124/* OP_CONNECT */125if (sk.isConnectable()) {126/* some trivial checks */127check(opConnectReceived == false,128"should only received one OP_CONNECT");129check(opReadReceived == false,130"should not receive OP_READ before OP_CONNECT");131check(readyChannel.equals(sc),132"channels should be equal");133check(!sk.isAcceptable(),134"key should not be acceptable");135check(!sk.isReadable(),136"key should not be readable");137check(!sk.isWritable(),138"key should not be writable");139140/* now process the OP_CONNECT */141opConnectReceived = true;142check((sk.interestOps() & OP_CONNECT) == OP_CONNECT,143"selection key interest ops should contain OP_CONNECT");144sk.interestOps(OP_READ);145check((sk.interestOps() & OP_CONNECT) != OP_CONNECT,146"selection key interest ops should not contain OP_CONNECT");147check(sc.finishConnect(),148"finishConnect should return true");149} /* OP_READ */150else if (sk.isReadable()) {151/* some trivial checks */152check(opConnectReceived == true,153"should receive one OP_CONNECT before OP_READ");154check(opReadReceived == false,155"should not receive OP_READ before OP_CONNECT");156check(readyChannel.equals(sc),157"channels should be equal");158check(!sk.isAcceptable(),159"key should not be acceptable");160check(sk.isReadable(),161"key should be readable");162check(!sk.isWritable(),163"key should not be writable");164check(!sk.isConnectable(),165"key should not be connectable");166167/* now process the OP_READ */168opReadReceived = true;169selectiontKey.cancel();170171/* try with small buffer to see if native172* implementation can handle this */173ByteBuffer buffer = ByteBuffer.allocateDirect(1);174readyChannel.receive(buffer, null, clientHandler);175check(clientHandler.receivedCommUp(),176"Client should have received COMM_UP");177178/* dont close (or put anything on) the channel until179* we check that the server's accepted channel also180* received COMM_UP */181serverHandler.waitForCommUp();182} else {183fail("Unexpected selection key");184}185}186} else {187fail("Client selector returned 0 ready keys");188/* stop the server */189server.thread().interrupt();190}191} //for192193} catch (IOException ioe) {194unexpected(ioe);195} catch (InterruptedException ie) {196unexpected(ie);197}198}199200class CommUpServer implements Runnable201{202final InetSocketAddress serverAddr;203private SctpServerChannel ssc;204private Thread serverThread;205206public CommUpServer() throws IOException {207ssc = SctpServerChannel.open().bind(null);208java.util.Set<SocketAddress> addrs = ssc.getAllLocalAddresses();209if (addrs.isEmpty())210debug("addrs should not be empty");211212serverAddr = (InetSocketAddress) addrs.iterator().next();213}214215void start() {216serverThread = new Thread(this, "CommUpServer-" +217serverAddr.getPort());218serverThread.start();219}220221InetSocketAddress address () {222return serverAddr;223}224225Thread thread() {226return serverThread;227}228229@Override230public void run() {231Selector selector = null;232SctpChannel sc = null;233SelectionKey readKey = null;234try {235sc = ssc.accept();236debug("accepted " + sc);237238selector = Selector.open();239sc.configureBlocking(false);240check(sc.isBlocking() == false, "Should be in non-blocking mode");241readKey = sc.register(selector, SelectionKey.OP_READ);242243debug("select");244int keysAdded = selector.select(TIMEOUT);245debug("returned " + keysAdded + " keys");246if (keysAdded > 0) {247Set<SelectionKey> keys = selector.selectedKeys();248Iterator<SelectionKey> i = keys.iterator();249while(i.hasNext()) {250SelectionKey sk = i.next();251i.remove();252SctpChannel readyChannel =253(SctpChannel)sk.channel();254check(readyChannel.equals(sc),255"channels should be equal");256check(!sk.isAcceptable(),257"key should not be acceptable");258check(sk.isReadable(),259"key should be readable");260check(!sk.isWritable(),261"key should not be writable");262check(!sk.isConnectable(),263"key should not be connectable");264265/* block until we check if the client has received its COMM_UP*/266clientHandler.waitForCommUp();267268ByteBuffer buffer = ByteBuffer.allocateDirect(1);269sc.receive(buffer, null, serverHandler);270check(serverHandler.receivedCommUp(),271"Accepted channel should have received COMM_UP");272}273} else {274fail("Server selector returned 0 ready keys");275/* stop the client */276clientThread.interrupt();277}278} catch (IOException ioe) {279ioe.printStackTrace();280} catch (InterruptedException unused) {281} finally {282if (readKey != null) readKey.cancel();283try { if (selector != null) selector.close(); }284catch (IOException ioe) { unexpected(ioe); }285try { if (ssc != null) ssc.close(); }286catch (IOException ioe) { unexpected(ioe); }287try { if (sc != null) sc.close(); }288catch (IOException ioe) { unexpected(ioe); }289}290}291}292293class CommUpNotificationHandler extends AbstractNotificationHandler<Object>294{295private boolean receivedCommUp; // false296297public synchronized boolean receivedCommUp() {298return receivedCommUp;299}300301public synchronized boolean waitForCommUp() throws InterruptedException {302while (receivedCommUp == false) {303wait();304}305306return false;307}308309@Override310public HandlerResult handleNotification(311Notification notification, Object attachment) {312fail("Unknown notification type");313return HandlerResult.CONTINUE;314}315316@Override317public synchronized HandlerResult handleNotification(318AssociationChangeNotification notification, Object attachment) {319AssocChangeEvent event = notification.event();320debug("AssociationChangeNotification");321debug(" Association: " + notification.association());322debug(" Event: " + event);323324if (event.equals(AssocChangeEvent.COMM_UP)) {325receivedCommUp = true;326notifyAll();327}328329return HandlerResult.RETURN;330}331332@Override333public HandlerResult handleNotification(334ShutdownNotification notification, Object attachment) {335debug("ShutdownNotification");336debug(" Association: " + notification.association());337return HandlerResult.RETURN;338}339}340341//--------------------- Infrastructure ---------------------------342boolean debug = true;343volatile int passed = 0, failed = 0;344void pass() {passed++;}345void fail() {failed++; Thread.dumpStack();}346void fail(String msg) {err.println(msg); fail();}347void unexpected(Throwable t) {failed++; t.printStackTrace();}348void check(boolean cond) {if (cond) pass(); else fail();}349void check(boolean cond, String failMessage) {if (cond) pass(); else fail(failMessage);}350void debug(String message) {if(debug) { out.println(Thread.currentThread().getName() + ": " + message); } }351void sleep(long millis) { try { Thread.currentThread().sleep(millis); }352catch(InterruptedException ie) { unexpected(ie); }}353public static void main(String[] args) throws Throwable {354Class<?> k = new Object(){}.getClass().getEnclosingClass();355try {k.getMethod("instanceMain",String[].class)356.invoke( k.newInstance(), (Object) args);}357catch (Throwable e) {throw e.getCause();}}358public void instanceMain(String[] args) throws Throwable {359try {test(args);} catch (Throwable t) {unexpected(t);}360out.printf("%nPassed = %d, failed = %d%n%n", passed, failed);361if (failed > 0) throw new AssertionError("Some tests failed");}362363}364365366