Path: blob/master/test/jdk/com/sun/nio/sctp/SctpMultiChannel/Send.java
41155 views
/*1* Copyright (c) 2009, 2010, 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.Set;33import java.util.Iterator;34import java.util.concurrent.CountDownLatch;35import java.util.concurrent.TimeUnit;36import java.nio.ByteBuffer;37import com.sun.nio.sctp.Association;38import com.sun.nio.sctp.InvalidStreamException;39import com.sun.nio.sctp.MessageInfo;40import com.sun.nio.sctp.SctpMultiChannel;41import static java.lang.System.out;42import static java.lang.System.err;4344public class Send {45/* Latches used to synchronize between the client and server so that46* connections without any IO may not be closed without being accepted */47final CountDownLatch clientFinishedLatch = new CountDownLatch(1);48final CountDownLatch serverFinishedLatch = new CountDownLatch(1);4950void test(String[] args) {51SocketAddress address = null;52Server server = null;5354if (!Util.isSCTPSupported()) {55out.println("SCTP protocol is not supported");56out.println("Test cannot be run");57return;58}5960if (args.length == 2) {61/* requested to connecct to a specific address */62try {63int port = Integer.valueOf(args[1]);64address = new InetSocketAddress(args[0], port);65} catch (NumberFormatException nfe) {66err.println(nfe);67}68} else {69/* start server on local machine, default */70try {71server = new Server();72server.start();73address = server.address();74debug("Server started and listening on " + address);75} catch (IOException ioe) {76ioe.printStackTrace();77return;78}79}8081doTest(address);82}8384void doTest(SocketAddress peerAddress) {85SctpMultiChannel channel = null;86ByteBuffer buffer = ByteBuffer.allocate(Util.LARGE_BUFFER);87MessageInfo info = MessageInfo.createOutgoing(null, 0);8889try {90channel = SctpMultiChannel.open();9192/* TEST 1: send small message */93int streamNumber = 0;94debug("sending to " + peerAddress + " on stream number: " + streamNumber);95info = MessageInfo.createOutgoing(peerAddress, streamNumber);96buffer.put(Util.SMALL_MESSAGE.getBytes("ISO-8859-1"));97buffer.flip();98int position = buffer.position();99int remaining = buffer.remaining();100101debug("sending small message: " + buffer);102int sent = channel.send(buffer, info);103104check(sent == remaining, "sent should be equal to remaining");105check(buffer.position() == (position + sent),106"buffers position should have been incremented by sent");107108/* TEST 2: receive the echoed message */109buffer.clear();110info = channel.receive(buffer, null, null);111buffer.flip();112check(info != null, "info is null");113check(info.streamNumber() == streamNumber,114"message not sent on the correct stream");115check(info.bytes() == Util.SMALL_MESSAGE.getBytes("ISO-8859-1").116length, "bytes received not equal to message length");117check(info.bytes() == buffer.remaining(), "bytes != remaining");118check(Util.compare(buffer, Util.SMALL_MESSAGE),119"received message not the same as sent message");120121122/* TEST 3: send large message */123Set<Association> assocs = channel.associations();124check(assocs.size() == 1, "there should be only one association");125Iterator<Association> it = assocs.iterator();126check(it.hasNext());127Association assoc = it.next();128streamNumber = assoc.maxOutboundStreams() - 1;129130debug("sending on stream number: " + streamNumber);131info = MessageInfo.createOutgoing(assoc, null, streamNumber);132buffer.clear();133buffer.put(Util.LARGE_MESSAGE.getBytes("ISO-8859-1"));134buffer.flip();135position = buffer.position();136remaining = buffer.remaining();137138debug("sending large message: " + buffer);139sent = channel.send(buffer, info);140141check(sent == remaining, "sent should be equal to remaining");142check(buffer.position() == (position + sent),143"buffers position should have been incremented by sent");144145/* TEST 4: receive the echoed message */146buffer.clear();147info = channel.receive(buffer, null, null);148buffer.flip();149check(info != null, "info is null");150check(info.streamNumber() == streamNumber,151"message not sent on the correct stream");152check(info.bytes() == Util.LARGE_MESSAGE.getBytes("ISO-8859-1").153length, "bytes received not equal to message length");154check(info.bytes() == buffer.remaining(), "bytes != remaining");155check(Util.compare(buffer, Util.LARGE_MESSAGE),156"received message not the same as sent message");157158159/* TEST 5: InvalidStreamExcepton */160streamNumber = assoc.maxOutboundStreams() + 1;161info = MessageInfo.createOutgoing(assoc, null, streamNumber);162buffer.clear();163buffer.put(Util.SMALL_MESSAGE.getBytes("ISO-8859-1"));164buffer.flip();165position = buffer.position();166remaining = buffer.remaining();167168debug("sending on stream number: " + streamNumber);169debug("sending small message: " + buffer);170try {171sent = channel.send(buffer, info);172fail("should have thrown InvalidStreamExcepton");173} catch (InvalidStreamException ise){174pass();175} catch (IOException ioe) {176unexpected(ioe);177}178check(buffer.remaining() == remaining,179"remaining should not be changed");180check(buffer.position() == position,181"buffers position should not be changed");182183184/* TEST 5: getRemoteAddresses(Association) */185channel.getRemoteAddresses(assoc);186187/* TEST 6: Send from heap buffer to force implementation to188* substitute with a native buffer, then check that its position189* is updated correctly */190info = MessageInfo.createOutgoing(assoc, null, 0);191buffer.clear();192buffer.put(Util.SMALL_MESSAGE.getBytes("ISO-8859-1"));193buffer.flip();194final int offset = 1;195buffer.position(offset);196remaining = buffer.remaining();197198try {199sent = channel.send(buffer, info);200201check(sent == remaining, "sent should be equal to remaining");202check(buffer.position() == (offset + sent),203"buffers position should have been incremented by sent");204} catch (IllegalArgumentException iae) {205fail(iae + ", Error updating buffers position");206}207208} catch (IOException ioe) {209unexpected(ioe);210} finally {211clientFinishedLatch.countDown();212try { serverFinishedLatch.await(10L, TimeUnit.SECONDS); }213catch (InterruptedException ie) { unexpected(ie); }214if (channel != null) {215try { channel.close(); }216catch (IOException e) { unexpected (e);}217}218}219}220221class Server implements Runnable222{223final InetSocketAddress serverAddr;224private SctpMultiChannel serverChannel;225226public Server() throws IOException {227serverChannel = SctpMultiChannel.open().bind(null);228java.util.Set<SocketAddress> addrs = serverChannel.getAllLocalAddresses();229if (addrs.isEmpty())230debug("addrs should not be empty");231232serverAddr = (InetSocketAddress) addrs.iterator().next();233}234235public void start() {236(new Thread(this, "Server-" + serverAddr.getPort())).start();237}238239public InetSocketAddress address() {240return serverAddr;241}242243@Override244public void run() {245ByteBuffer buffer = ByteBuffer.allocateDirect(Util.LARGE_BUFFER);246try {247MessageInfo info;248249/* receive a small message */250do {251info = serverChannel.receive(buffer, null, null);252if (info == null) {253fail("Server: unexpected null from receive");254return;255}256} while (!info.isComplete());257258buffer.flip();259check(info != null, "info is null");260check(info.streamNumber() == 0,261"message not sent on the correct stream");262check(info.bytes() == Util.SMALL_MESSAGE.getBytes("ISO-8859-1").263length, "bytes received not equal to message length");264check(info.bytes() == buffer.remaining(), "bytes != remaining");265check(Util.compare(buffer, Util.SMALL_MESSAGE),266"received message not the same as sent message");267268check(info != null, "info is null");269Set<Association> assocs = serverChannel.associations();270check(assocs.size() == 1, "there should be only one association");271Iterator<Association> it = assocs.iterator();272check(it.hasNext());273Association assoc = it.next();274275/* echo the message */276debug("Server: echoing first message");277buffer.flip();278MessageInfo sendInfo = MessageInfo.createOutgoing(assoc, null, info.streamNumber());279int bytes = serverChannel.send(buffer, sendInfo);280debug("Server: sent " + bytes + "bytes");281282/* receive a large message */283buffer.clear();284do {285info = serverChannel.receive(buffer, null, null);286if (info == null) {287fail("Server: unexpected null from receive");288return;289}290} while (!info.isComplete());291292buffer.flip();293294check(info.streamNumber() == assoc.maxInboundStreams() - 1,295"message not sent on the correct stream");296check(info.bytes() == Util.LARGE_MESSAGE.getBytes("ISO-8859-1").297length, "bytes received not equal to message length");298check(info.bytes() == buffer.remaining(), "bytes != remaining");299check(Util.compare(buffer, Util.LARGE_MESSAGE),300"received message not the same as sent message");301302/* echo the message */303debug("Server: echoing second message");304buffer.flip();305sendInfo = MessageInfo.createOutgoing(assoc, null, info.streamNumber());306bytes = serverChannel.send(buffer, sendInfo);307debug("Server: sent " + bytes + "bytes");308309/* TEST 6 */310ByteBuffer expected = ByteBuffer.allocate(Util.SMALL_BUFFER);311expected.put(Util.SMALL_MESSAGE.getBytes("ISO-8859-1"));312expected.flip();313final int offset = 1;314expected.position(offset);315buffer.clear();316do {317info = serverChannel.receive(buffer, null, null);318if (info == null) {319fail("Server: unexpected null from receive");320return;321}322} while (!info.isComplete());323324buffer.flip();325check(info != null, "info is null");326check(info.streamNumber() == 0, "message not sent on the correct stream");327check(info.bytes() == expected.remaining(),328"bytes received not equal to message length");329check(info.bytes() == buffer.remaining(), "bytes != remaining");330check(expected.equals(buffer),331"received message not the same as sent message");332333clientFinishedLatch.await(10L, TimeUnit.SECONDS);334serverFinishedLatch.countDown();335} catch (IOException ioe) {336unexpected(ioe);337} catch (InterruptedException ie) {338unexpected(ie);339} finally {340try { if (serverChannel != null) serverChannel.close(); }341catch (IOException unused) {}342}343}344}345346//--------------------- Infrastructure ---------------------------347boolean debug = true;348volatile int passed = 0, failed = 0;349void pass() {passed++;}350void fail() {failed++; Thread.dumpStack();}351void fail(String msg) {System.err.println(msg); fail();}352void unexpected(Throwable t) {failed++; t.printStackTrace();}353void check(boolean cond) {if (cond) pass(); else fail();}354void check(boolean cond, String failMessage) {if (cond) pass(); else fail(failMessage);}355void debug(String message) {if(debug) { System.out.println(message); } }356public static void main(String[] args) throws Throwable {357Class<?> k = new Object(){}.getClass().getEnclosingClass();358try {k.getMethod("instanceMain",String[].class)359.invoke( k.newInstance(), (Object) args);}360catch (Throwable e) {throw e.getCause();}}361public void instanceMain(String[] args) throws Throwable {362try {test(args);} catch (Throwable t) {unexpected(t);}363System.out.printf("%nPassed = %d, failed = %d%n%n", passed, failed);364if (failed > 0) throw new AssertionError("Some tests failed");}365366}367368369