Skip to content

Commit

Permalink
8335771
Browse files Browse the repository at this point in the history
  • Loading branch information
dfuch committed Jul 5, 2024
1 parent c8acea8 commit a5d41fd
Show file tree
Hide file tree
Showing 11 changed files with 347 additions and 103 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
Expand Down Expand Up @@ -48,6 +48,7 @@
import java.util.stream.Collectors;
import static java.net.StandardSocketOptions.*;
import static java.net.StandardProtocolFamily.*;
import static jdk.test.lib.NetworkConfiguration.isSameInterface;

import jdk.test.lib.NetworkConfiguration;
import jdk.test.lib.net.IPSupport;
Expand Down Expand Up @@ -295,8 +296,8 @@ static void testNetworkInterface(MulticastSocket s,

// setNetworkInterface
s.setNetworkInterface(ni);
assertTrue(s.getNetworkInterface().equals(ni));
assertTrue(s.getOption(IP_MULTICAST_IF).equals(ni));
assertTrue(isSameInterface(s.getNetworkInterface(), ni));
assertTrue(isSameInterface(s.getOption(IP_MULTICAST_IF), ni));
InetAddress address = s.getInterface();
assertTrue(ni.inetAddresses().filter(address::equals).findAny().isPresent());

Expand All @@ -315,8 +316,8 @@ static void testNetworkInterface(MulticastSocket s,

// setOption(IP_MULTICAST_IF)
s.setOption(IP_MULTICAST_IF, ni);
assertTrue(s.getOption(IP_MULTICAST_IF).equals(ni));
assertTrue(s.getNetworkInterface().equals(ni));
assertTrue(isSameInterface(s.getOption(IP_MULTICAST_IF), ni));
assertTrue(isSameInterface(s.getNetworkInterface(), ni));

// bad values for IP_MULTICAST_IF
assertThrows(IllegalArgumentException.class,
Expand Down Expand Up @@ -401,6 +402,10 @@ static void testLoopbackMode(MulticastSocket s) throws IOException {
() -> s.setOption((SocketOption) IP_MULTICAST_LOOP, "badValue"));
}

static int getPort(SocketAddress address) {
return ((InetSocketAddress) address).getPort();
}

/**
* Send a datagram to the given multicast group and check that it is received.
*/
Expand All @@ -412,7 +417,8 @@ static void testSendReceive(MulticastSocket s, InetAddress group) throws IOExcep
assertTrue(s.getOption(IP_MULTICAST_IF) != null);

SocketAddress target = new InetSocketAddress(group, s.getLocalPort());
byte[] message = "hello".getBytes("UTF-8");
String msg = "AdaptorMulticasting: " + System.nanoTime();
byte[] message = msg.getBytes("UTF-8");

// send message to multicast group
DatagramPacket p = new DatagramPacket(message, message.length);
Expand All @@ -421,8 +427,22 @@ static void testSendReceive(MulticastSocket s, InetAddress group) throws IOExcep

// receive message
s.setSoTimeout(0);
p = new DatagramPacket(new byte[1024], 100);
s.receive(p);
do {
p = new DatagramPacket(new byte[1024], 100);
s.receive(p);
if (getPort(p.getSocketAddress()) == getPort(s.getLocalSocketAddress())) {
String str = new String(p.getData(), p.getOffset(), p.getLength(), "UTF-8");
if (Arrays.equals(p.getData(), p.getOffset(), p.getLength(), message, 0, message.length)) {
System.out.format("Got expected message \"%s\" from %s%n", str, p.getSocketAddress());
break;
}
System.out.println("Unexpected message received. Expected: " + msg);
System.out.println("Received message doesn't match - skipping: " + str);
} else {
System.out.println("Unexpected message received. Expected message from: " + s.getLocalAddress());
System.out.println("Received message sender doesn't match - skipping: " + p.getSocketAddress());
}
} while(true);

assertTrue(p.getLength() == message.length);
assertTrue(p.getPort() == s.getLocalPort());
Expand Down
98 changes: 78 additions & 20 deletions test/jdk/java/nio/channels/DatagramChannel/AfterDisconnect.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
Expand Down Expand Up @@ -31,6 +31,7 @@
*/

import java.io.IOException;
import java.net.BindException;
import java.net.InetAddress;
import java.net.Inet6Address;
import java.net.InetSocketAddress;
Expand All @@ -46,6 +47,7 @@
import java.nio.channels.Selector;
import java.util.HashMap;
import java.util.Map;
import java.util.function.Predicate;

import org.testng.annotations.Test;
import static org.testng.Assert.*;
Expand All @@ -54,37 +56,77 @@

public class AfterDisconnect {

public interface RetryableTest<T extends Exception> {
public void runTest() throws T;
}

/**
* When calling {@link DatagramChannel#disconnect()} a {@link BindException}
* may occur. In which case we want to retry the test.
*/
public class BindExceptionOnDisconnect extends BindException {
BindExceptionOnDisconnect(BindException x) {
super(x.getMessage());
initCause(x);
}
}

@Test
public void execute() throws IOException {
IPSupport.throwSkippedExceptionIfNonOperational();
boolean preferIPv6 = Boolean.getBoolean("java.net.preferIPv6Addresses");
InetAddress lb = InetAddress.getLoopbackAddress();

// test with default protocol family
try (DatagramChannel dc = DatagramChannel.open()) {
System.out.println("Test with default");
dc.bind(new InetSocketAddress(lb, 0));
test(dc);
test(dc);
}

// test with IPv6 socket
if (IPSupport.hasIPv6()) {
System.out.println("Test with IPv6 socket");
try (DatagramChannel dc = DatagramChannel.open(StandardProtocolFamily.INET6)) {
System.out.println("Test with default");
retry(() -> {
try (DatagramChannel dc = DatagramChannel.open()) {
dc.bind(new InetSocketAddress(lb, 0));
test(dc);
test(dc);
}
}, BindExceptionOnDisconnect.class::isInstance, 5);

// test with IPv6 socket
if (IPSupport.hasIPv6()) {
System.out.println("Test with IPv6 socket");
retry(() -> {
try (DatagramChannel dc = DatagramChannel.open(StandardProtocolFamily.INET6)) {
dc.bind(new InetSocketAddress(lb, 0));
test(dc);
test(dc);
}
}, BindExceptionOnDisconnect.class::isInstance, 5);
}

// test with IPv4 socket
if (IPSupport.hasIPv4() && !preferIPv6) {
System.out.println("Test with IPv4 socket");
try (DatagramChannel dc = DatagramChannel.open(StandardProtocolFamily.INET)) {
dc.bind(new InetSocketAddress(lb, 0));
test(dc);
test(dc);
retry(() -> {
try (DatagramChannel dc = DatagramChannel.open(StandardProtocolFamily.INET)) {
dc.bind(new InetSocketAddress(lb, 0));
test(dc);
test(dc);
}
}, BindExceptionOnDisconnect.class::isInstance, 5);
}
}

// retry the given lambda (RetryableTest) if an exception
// that satisfies the predicate (retryOn) is caught.
<T extends Exception> void retry(RetryableTest<T> test,
Predicate<Throwable> retryOn,
int max) throws T {
for (int i=0; i < max; i++) {
try {
test.runTest();
break;
} catch (Throwable t) {
if (i < max -1 && retryOn.test(t)) {
System.out.println("Got " + t + "; will retry");
continue;
}
throw t;
}
}
}
Expand All @@ -111,7 +153,11 @@ void testLocalAddress(DatagramChannel dc) throws IOException {
assertEquals(dc.getLocalAddress(), local);
assertEquals(dc.getRemoteAddress(), remote);

dc.disconnect();
try {
dc.disconnect();
} catch (BindException x) {
throw new BindExceptionOnDisconnect(x);
}
assertFalse(dc.isConnected());
assertEquals(dc.getLocalAddress(), local);
assertTrue(dc.getRemoteAddress() == null);
Expand All @@ -134,7 +180,11 @@ void testSocketOptions(DatagramChannel dc) throws IOException {
Map<SocketOption<?>, Object> map = options(dc);

dc.connect(dc.getLocalAddress());
dc.disconnect();
try {
dc.disconnect();
} catch (BindException x) {
throw new BindExceptionOnDisconnect(x);
}

// check socket options have not changed
assertEquals(map, options(dc));
Expand Down Expand Up @@ -168,7 +218,11 @@ void testSelectorRegistration(DatagramChannel dc) throws IOException {
sel.selectNow();

dc.connect(dc.getLocalAddress());
dc.disconnect();
try {
dc.disconnect();
} catch (BindException x) {
throw new BindExceptionOnDisconnect(x);
}

// selection key should still be valid
assertTrue(key.isValid());
Expand Down Expand Up @@ -210,7 +264,11 @@ void testMulticastGroups(DatagramChannel dc) throws IOException {
MembershipKey key = dc.join(group, ni);

dc.connect(dc.getLocalAddress());
dc.disconnect();
try {
dc.disconnect();
} catch (BindException x) {
throw new BindExceptionOnDisconnect(x);
}

// membership key should still be valid
assertTrue(key.isValid());
Expand Down
11 changes: 10 additions & 1 deletion test/jdk/java/nio/channels/DatagramChannel/Connect.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2001, 2023, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
Expand All @@ -23,6 +23,8 @@

/* @test
* @bug 4313882 7183800
* @library /test/lib
* @build jdk.test.lib.Platform Connect
* @run main/othervm Connect
* @summary Test DatagramChannel's send and receive methods
*/
Expand All @@ -38,6 +40,8 @@
import java.util.concurrent.CompletionException;
import java.util.stream.Stream;

import jdk.test.lib.Platform;

import static java.nio.charset.StandardCharsets.US_ASCII;

public class Connect {
Expand Down Expand Up @@ -114,9 +118,14 @@ public void run() {
ByteBuffer bb = ByteBuffer.allocateDirect(MAX);
bb.put(bytes);
bb.flip();
if (Platform.isOSX()) {
dc.bind(new InetSocketAddress(((InetSocketAddress)connectSocketAddress).getAddress(), 0));
err.println("Initiator bound to: " + connectSocketAddress);
}
err.println("Initiator connecting to: " + connectSocketAddress);
dc.connect(connectSocketAddress);
err.println("Initiator bound to: " + dc.getLocalAddress());
assert !connectSocketAddress.equals(dc.getLocalAddress());

// Send a message
err.println("Initiator attempting to write to Responder at " + connectSocketAddress);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
Expand All @@ -24,7 +24,8 @@
/* @test
* @bug 8234805 8235193
* @summary Test DatagramChannel send/receive and that receive returns the expected
* sender address
* sender address. This test may fail intermittently on macOS if other datagram
* channel tests are running concurrently on the same host.
* @run main/othervm ManySourcesAndTargets
* @run main/othervm -Djava.net.preferIPv4Stack=true ManySourcesAndTargets
*/
Expand Down Expand Up @@ -63,6 +64,7 @@ public static void main(String[] args) throws Exception {
try (DatagramChannel reader = DatagramChannel.open()) {
// bind reader to wildcard address so it can receive from any address
reader.bind(new InetSocketAddress(0));
System.out.println("\nReader bound to: " + reader.getLocalAddress());
for (InetAddress address : addresses) {
System.out.format("%n-- %s --%n", address.getHostAddress());

Expand All @@ -75,6 +77,7 @@ public static void main(String[] args) throws Exception {
try (DatagramChannel sender = DatagramChannel.open()) {
// bind sender to wildcard address so it can send to any address
sender.bind(new InetSocketAddress(0));
System.out.println("\nSender bound to: " + sender.getLocalAddress());
for (InetAddress address : addresses) {
System.out.format("%n-- %s --%n", address.getHostAddress());

Expand All @@ -97,6 +100,11 @@ static void testSend(int count, InetAddress address, DatagramChannel reader) thr
sender.bind(new InetSocketAddress(address, 0));

SocketAddress local = sender.getLocalAddress();
System.out.println("Sender bound to: " + local);
if (((InetSocketAddress)local).getPort() == remotePort) {
System.out.println("testSend: Sender and reader have same port: skipping");
return;
}
byte[] bytes = serialize(local);

SocketAddress previousSource = null;
Expand All @@ -105,6 +113,8 @@ static void testSend(int count, InetAddress address, DatagramChannel reader) thr
sender.send(ByteBuffer.wrap(bytes), remote);

ByteBuffer bb = ByteBuffer.allocate(1000);
System.out.format("testSend: reader waiting to receive at: %s%n",
reader.getLocalAddress());
SocketAddress source = reader.receive(bb);
System.out.format("received datagram from %s%n", source);

Expand Down Expand Up @@ -138,11 +148,18 @@ static void testReceive(int count, DatagramChannel sender, InetAddress address)

SocketAddress remote = reader.getLocalAddress();

System.out.println("Reader bound to: " + remote);
if (((InetSocketAddress)local).getPort() == ((InetSocketAddress)remote).getPort()) {
System.out.println("testReceive: Sender and reader have same port: skipping");
return;
}
for (int i = 0; i < count; i++) {
System.out.format("send %s -> %s%n", local, remote);
sender.send(ByteBuffer.allocate(32), remote);

ByteBuffer bb = ByteBuffer.allocate(1000);
System.out.format("testReceive: reader waiting to receive at: %s%n",
reader.getLocalAddress());
SocketAddress source = reader.receive(bb);
System.out.format("received datagram from %s%n", source);
}
Expand All @@ -165,7 +182,12 @@ private static SocketAddress deserialize(byte[] bytes) throws Exception {

private static Optional<NetworkInterface> networkInterface(InetAddress ia) {
try {
return Optional.ofNullable(NetworkInterface.getByInetAddress(ia));
NetworkInterface nif = NetworkInterface.getByInetAddress(ia);
if (nif != null) {
System.out.format("Selecting interface %s[%d]%n\twith addresses:%n\t%s%n",
nif.getDisplayName(), nif.getIndex(), nif.inetAddresses().toList());
}
return Optional.ofNullable(nif);
} catch (SocketException e) {
return Optional.empty();
}
Expand Down
Loading

0 comments on commit a5d41fd

Please sign in to comment.