Path: blob/master/test/jdk/com/sun/nio/sctp/SctpChannel/Receive.java
41155 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 492764025* @summary Tests the SCTP protocol implementation26* @author chegar27*/2829import java.net.InetSocketAddress;30import java.net.SocketAddress;31import java.io.IOException;32import java.util.concurrent.CountDownLatch;33import java.util.concurrent.TimeUnit;34import java.nio.ByteBuffer;35import java.nio.channels.NotYetConnectedException;36import java.nio.channels.ClosedChannelException;37import com.sun.nio.sctp.AbstractNotificationHandler;38import com.sun.nio.sctp.AssociationChangeNotification;39import com.sun.nio.sctp.AssociationChangeNotification.AssocChangeEvent;40import com.sun.nio.sctp.HandlerResult;41import com.sun.nio.sctp.IllegalReceiveException;42import com.sun.nio.sctp.MessageInfo;43import com.sun.nio.sctp.Notification;44import com.sun.nio.sctp.SctpChannel;45import com.sun.nio.sctp.SctpServerChannel;46import com.sun.nio.sctp.ShutdownNotification;47import static java.lang.System.out;48import static java.lang.System.err;4950public class Receive {51/* Latches used to synchronize between the client and server so that52* connections without any IO may not be closed without being accepted */53final CountDownLatch clientFinishedLatch = new CountDownLatch(1);54final CountDownLatch serverFinishedLatch = new CountDownLatch(1);5556/* Used to verify that the ppid is being sent and received correctly */57static final int PPID = 5;5859void test(String[] args) {60SocketAddress address = null;61Server server;626364if (!Util.isSCTPSupported()) {65out.println("SCTP protocol is not supported");66out.println("Test cannot be run");67return;68}6970if (args.length == 2) {71/* requested to connecct to a specific address */72try {73int port = Integer.valueOf(args[1]);74address = new InetSocketAddress(args[0], port);75} catch (NumberFormatException nfe) {76err.println(nfe);77}78} else {79/* start server on local machine, default */80try {81server = new Server();82server.start();83address = server.address();84debug("Server started and listening on " + address);85} catch (IOException ioe) {86ioe.printStackTrace();87return;88}89}9091doTest(address);92}9394void doTest(SocketAddress peerAddress) {95SctpChannel channel = null;96ByteBuffer buffer = ByteBuffer.allocate(Util.LARGE_BUFFER);97MessageInfo info;9899try {100channel = SctpChannel.open();101ReceiveNotificationHandler handler =102new ReceiveNotificationHandler(channel);103104/* TEST 1: Verify NotYetConnectedException thrown */105try {106channel.receive(buffer, null, handler);107fail("should have thrown NotYetConnectedException");108} catch (NotYetConnectedException unused) {109pass();110} catch (IOException ioe) {111unexpected(ioe);112}113114channel.connect(peerAddress);115116/* TEST 2: receive small message */117do {118debug("Test 2: invoking receive");119info = channel.receive(buffer, null, handler);120if (info == null) {121fail("unexpected null from receive");122return;123}124} while (!info.isComplete());125126buffer.flip();127check(handler.receivedCommUp(), "SCTP_COMM_UP not received");128check(info != null, "info is null");129check(info.address() != null, "address is null");130check(info.association() != null, "association is null");131check(info.isComplete(), "message is not complete");132check(info.isUnordered() != true,133"message should not be unordered");134check(info.streamNumber() >= 0, "invalid stream number");135check(info.payloadProtocolID() == PPID, "PPID incorrect");136check(info.bytes() == Util.SMALL_MESSAGE.getBytes("ISO-8859-1").137length, "bytes received not equal to message length");138check(info.bytes() == buffer.remaining(), "bytes != remaining");139check(Util.compare(buffer, Util.SMALL_MESSAGE),140"received message not the same as sent message");141142buffer.clear();143144/* TEST 3: receive large message */145do {146debug("Test 3: invoking receive");147info = channel.receive(buffer, null, handler);148if (info == null) {149fail("unexpected null from receive");150return;151}152} while (!info.isComplete());153154buffer.flip();155check(info != null, "info is null");156check(info.address() != null, "address is null");157check(info.association() != null, "association is null");158check(info.isComplete(), "message is not complete");159check(info.isUnordered() != true,160"message should not be unordered");161check(info.streamNumber() >= 0, "invalid stream number");162check(info.bytes() == Util.LARGE_MESSAGE.getBytes("ISO-8859-1").163length, "bytes received not equal to message length");164check(info.bytes() == buffer.remaining(), "bytes != remaining");165check(Util.compare(buffer, Util.LARGE_MESSAGE),166"received message not the same as sent message");167168buffer.clear();169170/* TEST 4: EOF */171buffer.clear(); // buffer position 0172info = channel.receive(buffer,null, handler);173check(info != null, "info is null");174check(info.bytes() == -1, "should have received EOF");175check(buffer.position() == 0, "buffer position should be unchanged");176177/* TEST 5: ClosedChannelException */178channel.close();179try {180channel.receive(buffer, null, null);181fail("should have thrown ClosedChannelException");182} catch (ClosedChannelException cce) {183pass();184} catch (IOException ioe) {185unexpected(ioe);186}187handler = null;188189/* TEST 6: handler returns RETURN after handling a notification */190ReceiveNotificationHandler handler2 =191new ReceiveNotificationHandler(null); /* HandlerResult.RETURN */192channel = SctpChannel.open(peerAddress, 0, 0);193info = channel.receive(buffer, null, handler2);194check(info == null, "channel should return null");195check(handler2.receivedCommUp(), "SCTP_COMM_UP not received");196check(buffer.position() == 0, "buffer position should be unchanged");197198/* TEST 7: Non blocking channel return null if no data */199channel.configureBlocking(false);200info = channel.receive(buffer, null, null);201check(info == null, "non-blocking channel should return null");202check(buffer.position() == 0, "buffer position should be unchanged");203} catch (IOException ioe) {204unexpected(ioe);205} finally {206clientFinishedLatch.countDown();207try { serverFinishedLatch.await(10L, TimeUnit.SECONDS); }208catch (InterruptedException ie) { unexpected(ie); }209if (channel != null) {210try { channel.close(); }211catch (IOException e) { unexpected (e);}212}213}214}215216class Server implements Runnable217{218final InetSocketAddress serverAddr;219private SctpServerChannel ssc;220221public Server() throws IOException {222ssc = SctpServerChannel.open().bind(null);223java.util.Set<SocketAddress> addrs = ssc.getAllLocalAddresses();224if (addrs.isEmpty())225debug("addrs should not be empty");226227serverAddr = (InetSocketAddress) addrs.iterator().next();228}229230public void start() {231(new Thread(this, "Server-" + serverAddr.getPort())).start();232}233234public InetSocketAddress address() {235return serverAddr;236}237238@Override239public void run() {240try {241SctpChannel sc = ssc.accept();242243/* send a small message */244MessageInfo info = MessageInfo.createOutgoing(null, 0)245.payloadProtocolID(PPID);246ByteBuffer buf = ByteBuffer.allocateDirect(Util.SMALL_BUFFER);247buf.put(Util.SMALL_MESSAGE.getBytes("ISO-8859-1"));248buf.flip();249250debug("sending small message: " + buf);251sc.send(buf, info);252253/* send a large message */254buf = ByteBuffer.allocateDirect(Util.LARGE_BUFFER);255buf.put(Util.LARGE_MESSAGE.getBytes("ISO-8859-1"));256buf.flip();257258debug("sending large message: " + buf);259sc.send(buf, info);260sc.shutdown();261debug("shutdown");262ReceiveNotificationHandler handler =263new ReceiveNotificationHandler(sc);264sc.receive(buf, null, handler);265sc.close();266267/* accept another socket for the TEST 6 */268sc = ssc.accept();269ssc.close();270271clientFinishedLatch.await(10L, TimeUnit.SECONDS);272serverFinishedLatch.countDown();273sc.close();274} catch (IOException ioe) {275unexpected(ioe);276} catch (InterruptedException ie) {277unexpected(ie);278}279}280}281282class ReceiveNotificationHandler extends AbstractNotificationHandler<Object>283{284SctpChannel channel;285boolean receivedCommUp; // false286287public ReceiveNotificationHandler(SctpChannel channel) {288this.channel = channel;289}290291public boolean receivedCommUp() {292return receivedCommUp;293}294295@Override296public HandlerResult handleNotification(297Notification notification, Object attachment) {298fail("Unknown notification type");299return HandlerResult.CONTINUE;300}301302@Override303public HandlerResult handleNotification(304AssociationChangeNotification notification, Object attachment) {305AssocChangeEvent event = notification.event();306debug("AssociationChangeNotification");307debug(" Association: " + notification.association());308debug(" Event: " + event);309310if (event.equals(AssocChangeEvent.COMM_UP))311receivedCommUp = true;312313if (channel == null)314return HandlerResult.RETURN;315316/* TEST 4: IllegalReceiveException - If the given handler invokes317* the receive method of this channel*/318ByteBuffer buffer = ByteBuffer.allocate(10);319try {320channel.receive(buffer, null, this);321fail("IllegalReceiveException expected");322} catch (IllegalReceiveException unused) {323pass();324} catch (IOException ioe) {325unexpected(ioe);326}327328return HandlerResult.CONTINUE;329}330331@Override332public HandlerResult handleNotification(333ShutdownNotification notification, Object attachment) {334debug("ShutdownNotification");335debug(" Association: " + notification.association());336return HandlerResult.CONTINUE;337}338}339//--------------------- Infrastructure ---------------------------340boolean debug = true;341volatile int passed = 0, failed = 0;342void pass() {passed++;}343void fail() {failed++; Thread.dumpStack();}344void fail(String msg) {System.err.println(msg); fail();}345void unexpected(Throwable t) {failed++; t.printStackTrace();}346void check(boolean cond) {if (cond) pass(); else fail();}347void check(boolean cond, String failMessage) {if (cond) pass(); else fail(failMessage);}348void debug(String message) {if(debug) {349System.out.println(Thread.currentThread() + " " + message); } }350public static void main(String[] args) throws Throwable {351Class<?> k = new Object(){}.getClass().getEnclosingClass();352try {k.getMethod("instanceMain",String[].class)353.invoke( k.newInstance(), (Object) args);}354catch (Throwable e) {throw e.getCause();}}355public void instanceMain(String[] args) throws Throwable {356try {test(args);} catch (Throwable t) {unexpected(t);}357System.out.printf("%nPassed = %d, failed = %d%n%n", passed, failed);358if (failed > 0) throw new AssertionError("Some tests failed");}359360}361362363