diff -r 8c0e8cff877f -r 1a8d65e71a66 test/jdk/com/sun/jdi/JdwpAttachTest.java --- a/test/jdk/com/sun/jdi/JdwpAttachTest.java Tue Oct 29 15:08:19 2019 +0100 +++ b/test/jdk/com/sun/jdi/JdwpAttachTest.java Thu Oct 31 14:23:06 2019 -0700 @@ -32,6 +32,7 @@ import java.net.InetAddress; import java.net.NetworkInterface; import java.net.SocketException; +import java.net.UnknownHostException; import java.util.Arrays; import java.util.Enumeration; import java.util.Iterator; @@ -41,7 +42,6 @@ import java.util.concurrent.Callable; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; -import java.util.concurrent.TimeUnit; /* * @test @@ -54,24 +54,36 @@ */ public class JdwpAttachTest { + private static final boolean IsWindows = System.getProperty("os.name").toLowerCase().contains("windows"); + + // Set to true to perform testing of attach from wrong address (expected to fail). + // It's off by default as it caused significant test time increase\ + // (tests * cases, each case fails by timeout). + private static boolean testFailedAttach = false; + public static void main(String[] args) throws Exception { List addresses = getAddresses(); boolean ipv4EnclosedTested = false; boolean ipv6EnclosedTested = false; for (InetAddress addr: addresses) { - // also test that addresses enclosed in square brackets are supported - attachTest(addr.getHostAddress(), addr.getHostAddress()); + if (testFailedAttach) { + for (InetAddress connectAddr : addresses) { + attachTest(addr.getHostAddress(), connectAddr.getHostAddress(), addr.equals(connectAddr)); + } + } else { + attachTest(addr.getHostAddress(), addr.getHostAddress(), true); + } // listening on "*" should accept connections from all addresses - attachTest("*", addr.getHostAddress()); + attachTest("*", addr.getHostAddress(), true); - // test that addresses enclosed in square brackets are supported. + // also test that addresses enclosed in square brackets are supported. if (addr instanceof Inet4Address && !ipv4EnclosedTested) { - attachTest("[" + addr.getHostAddress() + "]", "[" + addr.getHostAddress() + "]"); + attachTest("[" + addr.getHostAddress() + "]", "[" + addr.getHostAddress() + "]", true); ipv4EnclosedTested = true; } if (addr instanceof Inet6Address && !ipv6EnclosedTested) { - attachTest("[" + addr.getHostAddress() + "]", "[" + addr.getHostAddress() + "]"); + attachTest("[" + addr.getHostAddress() + "]", "[" + addr.getHostAddress() + "]", true); ipv6EnclosedTested = true; } } @@ -80,13 +92,14 @@ // we should be able to attach to both IPv4 and IPv6 addresses (127.0.0.1 & ::1) InetAddress localAddresses[] = InetAddress.getAllByName("localhost"); for (int i = 0; i < localAddresses.length; i++) { - attachTest(localAddresses[i].getHostAddress(), ""); + attachTest(localAddresses[i].getHostAddress(), "", true); } } - private static void attachTest(String listenAddress, String connectAddresses) + private static void attachTest(String listenAddress, String connectAddress, boolean expectedResult) throws Exception { - log("Starting listening at " + listenAddress); + log("\nTest: listen on '" + listenAddress + "', attach to '" + connectAddress + "'"); + log(" Starting listening at " + listenAddress); ListeningConnector connector = getListenConnector(); Map args = connector.defaultArguments(); setConnectorArg(args, "localAddress", listenAddress); @@ -100,31 +113,48 @@ throw new RuntimeException("values from connector.startListening (" + actualPort + " is not equal to values from arguments (" + port + ")"); } - log("Listening port: " + port); + log(" Listening port: " + port); - log("Attaching from " + connectAddresses); + log(" Attaching from " + connectAddress); try { ExecutorService executor = Executors.newSingleThreadExecutor(); executor.submit((Callable)() -> { VirtualMachine vm = connector.accept(args); - log("ACCEPTED."); vm.dispose(); return null; }); executor.shutdown(); - LingeredApp debuggee = LingeredApp.startApp( - Arrays.asList("-agentlib:jdwp=transport=dt_socket" - +",address=" + connectAddresses + ":" + port - + ",server=n,suspend=n")); - debuggee.stopApp(); - - executor.awaitTermination(20, TimeUnit.SECONDS); + try { + LingeredApp debuggee = LingeredApp.startApp( + Arrays.asList("-agentlib:jdwp=transport=dt_socket" + + ",address=" + connectAddress + ":" + port + + ",server=n,suspend=n" + // if failure is expected set small timeout (default is 20 sec) + + (!expectedResult ? ",timeout=1000" : ""))); + debuggee.stopApp(); + if (expectedResult) { + log("OK: attached as expected"); + } else { + throw new RuntimeException("ERROR: LingeredApp.startApp was able to attach"); + } + } catch (Exception ex) { + if (expectedResult) { + throw new RuntimeException("ERROR: LingeredApp.startApp was able to attach"); + } else { + log("OK: failed to attach as expected"); + } + } } finally { connector.stopListening(args); } } + private static void addAddr(List list, InetAddress addr) { + log(" - (" + addr.getClass().getSimpleName() + ") " + addr.getHostAddress()); + list.add(addr); + } + private static List getAddresses() { List result = new LinkedList<>(); try { @@ -136,17 +166,37 @@ Enumeration addresses = iface.getInetAddresses(); while (addresses.hasMoreElements()) { InetAddress addr = addresses.nextElement(); - // Java reports link local addresses with named scope, - // but Windows sockets routines support only numeric scope id. - // skip such addresses. + // Java reports link local addresses with symbolic scope, + // but on Windows java.net.NetworkInterface generates its own scope names + // which are incompatible with native Windows routines. + // So on Windows test only addresses with numeric scope. + // On other platforms test both symbolic and numeric scopes. if (addr instanceof Inet6Address) { Inet6Address addr6 = (Inet6Address)addr; - if (addr6.getScopedInterface() != null) { - continue; + NetworkInterface scopeIface = addr6.getScopedInterface(); + if (scopeIface != null && scopeIface.getName() != null) { + // On some test machines VPN creates link local addresses + // which we cannot connect to. + // Skip them. + if (scopeIface.isPointToPoint()) { + continue; + } + + try { + // the same address with numeric scope + addAddr(result, Inet6Address.getByAddress(null, addr6.getAddress(), addr6.getScopeId())); + } catch (UnknownHostException e) { + // cannot happen! + throw new RuntimeException("Unexpected", e); + } + + if (IsWindows) { + // don't add addresses with symbolic scope + continue; + } } } - log(" - (" + addr.getClass().getSimpleName() + ") " + addr.getHostAddress()); - result.add(addr); + addAddr(result, addr); } } } catch (SocketException e) { @@ -184,8 +234,11 @@ arg.setValue(value); } + private static long startTime = System.currentTimeMillis(); + private static void log(Object o) { - System.out.println(String.valueOf(o)); + long time = System.currentTimeMillis() - startTime; + System.out.println(String.format("[%7.3f] %s", (time / 1000f), String.valueOf(o))); } }