# HG changeset patch # User Alex Schenkman # Date 1383930972 -3600 # Node ID 666b69dd2c4351331e90a18b60692344add5a284 # Parent a389b4f5723fadaa7341d4c8cfecd06b14f89e40 8014506: Test of Jdp feature Reviewed-by: Contributed-by: Alex Schenkman diff --git a/test/sun/management/jdp/ClientConnection.java b/test/sun/management/jdp/ClientConnection.java new file mode 100644 --- /dev/null +++ b/test/sun/management/jdp/ClientConnection.java @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2012, 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 + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.io.IOException; +import java.net.InetAddress; +import java.net.MulticastSocket; +import java.net.UnknownHostException; + +public class ClientConnection { + + public final String IANA_JDP_ADDRESS = "224.0.23.178"; + public final String IANA_JDP_PORT = "7095"; + public final String UNDEFINED_NAME = "TheVMwithNoName"; + + public final int port; + public final InetAddress address; + public final int pauseInSeconds; + public final String instanceName; + + public ClientConnection() + throws UnknownHostException { + + String discoveryAddress = System.getProperty("com.sun.management.jdp.address", IANA_JDP_ADDRESS); + address = InetAddress.getByName(discoveryAddress); + + String discoveryPort = System.getProperty("com.sun.management.jdp.port", IANA_JDP_PORT); + port = Integer.parseInt(discoveryPort); + + String pause = System.getProperty("com.sun.management.jdp.pause", "1"); + pauseInSeconds = Integer.parseUnsignedInt(pause); + + instanceName = System.getProperty("com.sun.management.jdp.name", UNDEFINED_NAME); + + } + + public MulticastSocket connectWithTimeout(int msTimeOut) throws IOException { + MulticastSocket socket = new MulticastSocket(port); + socket.joinGroup(address); + socket.setSoTimeout(msTimeOut); + return socket; + } +} diff --git a/test/sun/management/jdp/DynamicLauncher.java b/test/sun/management/jdp/DynamicLauncher.java new file mode 100644 --- /dev/null +++ b/test/sun/management/jdp/DynamicLauncher.java @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2013, 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 + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + + +import jdk.testlibrary.OutputAnalyzer; +import jdk.testlibrary.ProcessTools; +import jdk.testlibrary.Utils; + +import java.util.UUID; + + +/** + * This class will try to find an unused port and run a JdpTestCase using it. + * The unused port is needed for jmxremote.port. + * The problem with busy ports arises when running many automated tests on the same host. + * Note that jdp.port is a multicast port and thus it can be binded by different processes at the same time. + */ +public abstract class DynamicLauncher { + + final String jdpName = UUID.randomUUID().toString(); + int jmxPort; + + protected void run() throws Exception { + OutputAnalyzer out; + int retries = 1; + boolean tryAgain; + + do { + tryAgain = false; + jmxPort = Utils.getFreePort(); + out = runVM(); + try { + out.shouldNotContain("Port already in use"); + } catch (RuntimeException e) { + if (retries < 3) { + retries++; + tryAgain = true; + } + } + } while (tryAgain); + } + + protected OutputAnalyzer runVM() throws Exception { + String[] options = this.options(); + ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(options); + OutputAnalyzer out = new OutputAnalyzer(pb.start()); + System.out.println(out.getStdout()); + System.err.println(out.getStderr()); + return out; + } + + protected abstract String[] options(); + +} diff --git a/test/sun/management/jdp/JdpClient.java b/test/sun/management/jdp/JdpClient.java --- a/test/sun/management/jdp/JdpClient.java +++ b/test/sun/management/jdp/JdpClient.java @@ -36,6 +36,7 @@ import java.util.Collections; import java.util.Enumeration; import java.util.Map; + import sun.management.jdp.JdpException; import sun.management.jdp.JdpJmxPacket; import sun.management.jdp.JdpPacketReader; @@ -49,21 +50,21 @@ private static int maxPacketCount = 1; private static int maxEmptyPacketCount = 10; - private void get(Map map, String key) - throws JdpException { + private void get(Map map, String key) + throws JdpException { if (map.get(key) == null) { - throw new JdpException("Test failed, packet field " + key + " missed"); + throw new JdpException("Test failed, packet field " + key + " missed"); } } private void checkFieldPresence(JdpJmxPacket p) - throws IOException, JdpException { + throws IOException, JdpException { byte[] b = p.getPacketData(); JdpPacketReader reader = new JdpPacketReader(b); - Map pMap = reader.getDiscoveryDataAsMap(); + Map pMap = reader.getDiscoveryDataAsMap(); get(pMap, JdpJmxPacket.UUID_KEY); get(pMap, JdpJmxPacket.MAIN_CLASS_KEY); @@ -102,11 +103,11 @@ sel.select(10 * 1000); channel.receive(buf); - if (buf.position() == 0 ){ - if (JdpDoSomething.getVerbose()){ + if (buf.position() == 0) { + if (JdpDoSomething.getVerbose()) { System.err.println("Empty packet received"); } - if (++emptyPacketsCount > maxEmptyPacketCount){ + if (++emptyPacketsCount > maxEmptyPacketCount) { throw new RuntimeException("Test failed, maxEmptyPacketCount reached"); } @@ -120,8 +121,8 @@ JdpJmxPacket packet = new JdpJmxPacket(dgramData); JdpDoSomething.printJdpPacket(packet); checkFieldPresence(packet); - if(++count > maxPacketCount){ - break; + if (++count > maxPacketCount) { + break; } } catch (JdpException e) { e.printStackTrace(); @@ -179,7 +180,7 @@ PacketListener listener = new PacketListener(channel); new Thread(listener, "Jdp Client").start(); - } catch (RuntimeException e){ + } catch (RuntimeException e) { System.out.println("Test failed."); } catch (Exception e) { e.printStackTrace(); diff --git a/test/sun/management/jdp/JdpDefaultsTest.java b/test/sun/management/jdp/JdpDefaultsTest.java new file mode 100644 --- /dev/null +++ b/test/sun/management/jdp/JdpDefaultsTest.java @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2013, 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 + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * A JVM with JDP on should send multicast JDP packets regularly. + * + * @author Alex Schenkman + * @test JdpDefaultsTest + * @summary Assert that we can read JDP packets from a multicast socket connection, on default IP and port. + * @library /lib/testlibrary + * @build ClientConnection JdpTestUtil JdpTestCase JdpOnTestCase DynamicLauncher + * @run main JdpDefaultsTest + */ + +public class JdpDefaultsTest extends DynamicLauncher { + + final String testName = "JdpOnTestCase"; + + public static void main(String[] args) throws Exception { + DynamicLauncher launcher = new JdpDefaultsTest(); + launcher.run(); + } + + /** + * Send Jdp multicast packets to the default IP and port, 224.0.23.178:7095 + */ + protected String[] options() { + String[] options = { + "-Dcom.sun.management.jmxremote.authenticate=false", + "-Dcom.sun.management.jmxremote.ssl=false", + "-Dcom.sun.management.jmxremote=true", + "-Dcom.sun.management.jmxremote.port=" + String.valueOf(jmxPort), + "-Dcom.sun.management.jmxremote.autodiscovery=true", + "-Dcom.sun.management.jdp.pause=1", + "-Dcom.sun.management.jdp.name=" + jdpName, + "-Dcom.sun.management.jdp.address=224.0.23.178", + "-Djava.util.logging.SimpleFormatter.format='%1$tF %1$tT %4$-7s %5$s %n'", + testName + }; + return options; + } +} diff --git a/test/sun/management/jdp/JdpDoSomething.java b/test/sun/management/jdp/JdpDoSomething.java --- a/test/sun/management/jdp/JdpDoSomething.java +++ b/test/sun/management/jdp/JdpDoSomething.java @@ -34,7 +34,7 @@ private static final String lockFileName = "JdpDoSomething.lck"; private static final boolean verbose = false; - public static boolean getVerbose(){ + public static boolean getVerbose() { return verbose; } @@ -61,7 +61,7 @@ } public static void compaireJdpPacketEx(JdpJmxPacket p1, JdpJmxPacket p2) - throws JdpException { + throws JdpException { if (!Objects.equals(p1, p1)) { throw new JdpException("Packet mismatch error"); diff --git a/test/sun/management/jdp/JdpOffTest.java b/test/sun/management/jdp/JdpOffTest.java new file mode 100644 --- /dev/null +++ b/test/sun/management/jdp/JdpOffTest.java @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2013, 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 + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * A JVM with JDP off should not send multicast JDP packets at all. + * com.sun.management.jmxremote.autodiscovery=false should be respected. + * + * @author Alex Schenkman + * @test JdpOffTest.java + * @summary Assert that no JDP packets are sent to the default address and port. + * @library /lib/testlibrary + * @build ClientConnection JdpTestUtil JdpTestCase JdpOffTestCase DynamicLauncher + * @run main JdpOffTest + */ + + +public class JdpOffTest extends DynamicLauncher { + + final String testName = "JdpOffTestCase"; + + public static void main(String[] args) throws Exception { + DynamicLauncher launcher = new JdpOffTest(); + launcher.run(); + } + + /** + * Send Jdp multicast packets to the specified IP and port, 224.0.1.2:1234 + */ + protected String[] options() { + String[] options = { + "-Dcom.sun.management.jmxremote.authenticate=false", + "-Dcom.sun.management.jmxremote.ssl=false", + "-Dcom.sun.management.jmxremote=true", + "-Dcom.sun.management.jmxremote.port=" + String.valueOf(jmxPort), + "-Dcom.sun.management.jmxremote.autodiscovery=false", + "-Dcom.sun.management.jdp.pause=1", + "-Dcom.sun.management.jdp.name=" + jdpName, + "-Djava.util.logging.SimpleFormatter.format='%1$tF %1$tT %4$-7s %5$s %n'", + testName + }; + return options; + } + +} diff --git a/test/sun/management/jdp/JdpOffTestCase.java b/test/sun/management/jdp/JdpOffTestCase.java new file mode 100644 --- /dev/null +++ b/test/sun/management/jdp/JdpOffTestCase.java @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2013, 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 + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * A JVM with JDP off should not send multicast JDP packets at all. + * com.sun.management.jmxremote.autodiscovery=false should be respected. + */ + +import java.net.SocketTimeoutException; +import java.util.Map; + +public class JdpOffTestCase extends JdpTestCase { + + private boolean testPassed = false; + + public JdpOffTestCase(ClientConnection connection) { + super(connection); + } + + /** + * Subclasses: JdpOnTestCase and JdpOffTestCase have different messages. + */ + @Override + protected String initialLogMessage() { + return "Expecting NOT to receive any packets with jdp.name=" + connection.instanceName; + } + + /** + * The socket has not received anything, and this is the expected behavior. + */ + @Override + protected void onSocketTimeOut(SocketTimeoutException e) throws Exception { + log.fine("No packages received. Test passed!"); + testPassed = true; + } + + + /** + * This method is executed after a correct Jdp packet, coming from this VM has been received. + * + * @param payload A dictionary containing the data if the received Jdp packet. + */ + @Override + protected void packetFromThisVMReceived(Map payload) throws Exception { + String message = "Jdp packet from this VM received. This should not happen!"; + log.severe(message); + throw new Exception(message); + } + + + /** + * The test should stop after the socket has timed out. See onSocketTimeOut {@link}. + */ + @Override + protected boolean shouldContinue() { + return !testPassed; + } + + public static void main(String[] args) throws Exception { + JdpTestCase client = new JdpOffTestCase(new ClientConnection()); + client.run(); + } + +} diff --git a/test/sun/management/jdp/JdpOnTestCase.java b/test/sun/management/jdp/JdpOnTestCase.java new file mode 100644 --- /dev/null +++ b/test/sun/management/jdp/JdpOnTestCase.java @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2013, 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 + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * A JVM with JDP on should send multicast JDP packets regularly. + * + * See main for more information on running this test manually. + * See Launcher classes for automated runs. + * + */ + +import java.net.SocketTimeoutException; +import java.util.Map; + +public class JdpOnTestCase extends JdpTestCase { + + private int receivedJDPpackets = 0; + + public JdpOnTestCase(ClientConnection connection) { + super(connection); + } + + /** + * Subclasses: JdpOnTestCase and JdpOffTestCase have different messages. + */ + @Override + protected String initialLogMessage() { + return "Waiting for 3 packets with jdp.name=" + connection.instanceName; + } + + /** + * This method is executed after a correct Jdp packet (coming from this VM) has been received. + * + * @param payload A dictionary containing the data if the received Jdp packet. + */ + protected void packetFromThisVMReceived(Map payload) { + receivedJDPpackets++; + final String jdpName = payload.get("INSTANCE_NAME"); + log.fine("Received correct JDP packet #" + String.valueOf(receivedJDPpackets) + + ", jdp.name=" + jdpName); + } + + /** + * The socket should not timeout. + * It is set to wait for 10 times the defined pause between Jdp packet. See JdpOnTestCase.TIME_OUT_FACTOR. + */ + @Override + protected void onSocketTimeOut(SocketTimeoutException e) throws Exception { + String message = "Timed out waiting for JDP packet. Should arrive within " + + connection.pauseInSeconds + " seconds, but waited for " + + timeOut + " seconds."; + log.severe(message); + throw new Exception(message, e); + } + + /** + * After receiving three Jdp packets the test should end. + */ + @Override + protected boolean shouldContinue() { + return receivedJDPpackets < 3; + } + + /** + * To run this test manually you might need the following VM options: + *

+ * -Dcom.sun.management.jmxremote.authenticate=false + * -Dcom.sun.management.jmxremote.ssl=false + * -Dcom.sun.management.jmxremote.port=4711 (or some other port number) + * -Dcom.sun.management.jmxremote=true + * -Dcom.sun.management.jmxremote.autodiscovery=true + * -Dcom.sun.management.jdp.pause=1 + * -Dcom.sun.management.jdp.name=alex (or some other string to identify this VM) + *

+ * Recommended for nice output: + * -Djava.util.logging.SimpleFormatter.format="%1$tF %1$tT %4$-7s %5$s %n" + * + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception { + JdpTestCase client = new JdpOnTestCase(new ClientConnection()); + client.run(); + } + +} diff --git a/test/sun/management/jdp/JdpSpecificAddressTest.java b/test/sun/management/jdp/JdpSpecificAddressTest.java new file mode 100644 --- /dev/null +++ b/test/sun/management/jdp/JdpSpecificAddressTest.java @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2013, 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 + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * A JVM with JDP on should send multicast JDP packets regularly. + * + * @author Alex Schenkman + * @test JdpSpecificAddressTest + * @summary Assert that we can read JDP packets from a multicast socket connection, on specific IP and port. + * @library /lib/testlibrary + * @build ClientConnection JdpTestUtil JdpTestCase JdpOnTestCase DynamicLauncher + * @run main JdpSpecificAddressTest + */ + + +public class JdpSpecificAddressTest extends DynamicLauncher { + + final String testName = "JdpOnTestCase"; + + public static void main(String[] args) throws Exception { + DynamicLauncher launcher = new JdpSpecificAddressTest(); + launcher.run(); + } + + /** + * Send Jdp multicast packets to the specified IP and port, 224.0.1.2:1234 + */ + protected String[] options() { + String[] options = { + "-Dcom.sun.management.jmxremote.authenticate=false", + "-Dcom.sun.management.jmxremote.ssl=false", + "-Dcom.sun.management.jmxremote=true", + "-Dcom.sun.management.jmxremote.port=" + String.valueOf(jmxPort), + "-Dcom.sun.management.jmxremote.autodiscovery=true", + "-Dcom.sun.management.jdp.pause=1", + "-Dcom.sun.management.jdp.name=" + jdpName, + "-Dcom.sun.management.jdp.address=224.0.1.2", + "-Dcom.sun.management.jdp.port=1234", + "-Djava.util.logging.SimpleFormatter.format='%1$tF %1$tT %4$-7s %5$s %n'", + testName + }; + return options; + } + +} diff --git a/test/sun/management/jdp/JdpTest.sh b/test/sun/management/jdp/JdpTest.sh --- a/test/sun/management/jdp/JdpTest.sh +++ b/test/sun/management/jdp/JdpTest.sh @@ -33,7 +33,7 @@ # temporary disable jcmd related tests # _testsuite="01,02,03,04,05" -_testsuite="01,02,04" +_testsuite="01" _pwd=`pwd` diff --git a/test/sun/management/jdp/JdpTestCase.java b/test/sun/management/jdp/JdpTestCase.java new file mode 100644 --- /dev/null +++ b/test/sun/management/jdp/JdpTestCase.java @@ -0,0 +1,220 @@ +/* + * Copyright (c) 2013, 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 + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * A JVM with JDP on should send multicast JDP packets regularly. + * Look at JdpOnTestCase.java and JdpOffTestCase.java + */ + + +import sun.management.jdp.JdpJmxPacket; + +import java.io.IOException; +import java.io.UnsupportedEncodingException; +import java.net.DatagramPacket; +import java.net.MulticastSocket; +import java.net.SocketTimeoutException; +import java.util.Arrays; +import java.util.Map; +import java.util.logging.Level; +import java.util.logging.Logger; + +public abstract class JdpTestCase { + final Logger log = Logger.getLogger("sun.management.jdp"); + final int MAGIC = 0xC0FFEE42; // Jdp magic number. + private static final int BUFFER_LENGTH = 64 * 1024; // max UDP size, except for IPv6 jumbograms. + private final int TIME_OUT_FACTOR = 10; // Socket times out after 10 times the jdp pause. + protected int timeOut; + private long startTime; + protected ClientConnection connection; + + public JdpTestCase(ClientConnection connection) { + this.connection = connection; + JdpTestUtil.enableConsoleLogging(log, Level.ALL); + } + + public void run() throws Exception { + log.fine("Test started."); + log.fine("Listening for multicast packets at " + connection.address.getHostAddress() + + ":" + String.valueOf(connection.port)); + log.fine(initialLogMessage()); + log.fine("Pause in between packets is: " + connection.pauseInSeconds + " seconds."); + + startTime = System.currentTimeMillis(); + timeOut = connection.pauseInSeconds * TIME_OUT_FACTOR; + log.fine("Timeout set to " + String.valueOf(timeOut) + " seconds."); + + MulticastSocket socket = connection.connectWithTimeout(timeOut * 1000); + + byte[] buffer = new byte[BUFFER_LENGTH]; + DatagramPacket datagram = new DatagramPacket(buffer, buffer.length); + + do { + try { + socket.receive(datagram); + onReceived(extractUDPpayload(datagram)); + } catch (SocketTimeoutException e) { + onSocketTimeOut(e); + } + + if (hasTestLivedLongEnough()) { + shutdown(); + } + + } while (shouldContinue()); + log.fine("Test ended successfully."); + } + + /** + * Subclasses: JdpOnTestCase and JdpOffTestCase have different messages. + */ + protected abstract String initialLogMessage(); + + + /** + * Executed when the socket receives a UDP packet. + */ + private void onReceived(byte[] packet) throws Exception { + if (isJDP(packet)) { + Map payload = checkStructure(packet); + jdpPacketReceived(payload); + } else { + log.fine("Non JDP packet received, ignoring it."); + } + } + + /** + * Determine whether the test should end. + * + * @return + */ + abstract protected boolean shouldContinue(); + + /** + * This method is executed when the socket has not received any packet for timeOut seconds. + */ + abstract protected void onSocketTimeOut(SocketTimeoutException e) throws Exception; + + /** + * This method is executed after a correct Jdp packet has been received. + * + * @param payload A dictionary containing the data if the received Jdp packet. + */ + private void jdpPacketReceived(Map payload) throws Exception { + final String instanceName = payload.get("INSTANCE_NAME"); + if (instanceName.equals(connection.instanceName)) { + packetFromThisVMReceived(payload); + } else { + packetFromOtherVMReceived(payload); + } + } + + /** + * This method is executed after a correct Jdp packet, coming from this VM has been received. + * + * @param payload A dictionary containing the data if the received Jdp packet. + */ + protected abstract void packetFromThisVMReceived(Map payload) throws Exception; + + + /** + * This method is executed after a correct Jdp packet, coming from another VM has been received. + * + * @param payload A dictionary containing the data if the received Jdp packet. + */ + protected void packetFromOtherVMReceived(Map payload) { + final String jdpName = payload.get("INSTANCE_NAME"); + log.fine("Ignoring JDP packet sent by other VM, jdp.name=" + jdpName); + } + + + /** + * The test should stop if it has been 12 times the jdp.pause. + * jdp.pause is how many seconds in between packets. + *

+ * This timeout (12 times)is slightly longer than the socket timeout (10 times) on purpose. + * In the off test case, the socket should time out first. + * + * @return + */ + protected boolean hasTestLivedLongEnough() { + long now = System.currentTimeMillis(); + boolean haslivedLongEnough = (now - startTime) > (timeOut * 1.2 * 1000); + return haslivedLongEnough; + } + + /** + * This exit condition arises when we receive UDP packets but they are not valid Jdp. + */ + protected void shutdown() throws Exception { + log.severe("Shutting down the test."); + throw new Exception("Not enough JDP packets received before timeout!"); + } + + /** + * Assert that this Jdp packet contains the required two keys. + *

+ * We expect zero packet corruption and thus fail on the first corrupted packet. + * This might need revision. + */ + protected Map checkStructure(byte[] packet) throws UnsupportedEncodingException { + Map payload = JdpTestUtil.readPayload(packet); + assertTrue(payload.size() >= 2, "JDP should have minimun 2 entries."); + assertTrue(payload.get(JdpJmxPacket.UUID_KEY).length() > 0); + assertTrue(payload.get(JdpJmxPacket.JMX_SERVICE_URL_KEY).length() > 0); + return payload; + } + + + /** + * Check if packet has correct JDP magic number. + * + * @param packet + * @return + * @throws IOException + */ + private boolean isJDP(byte[] packet) throws IOException { + int magic = JdpTestUtil.decode4ByteInt(packet, 0); + return (magic == MAGIC); + } + + private byte[] extractUDPpayload(DatagramPacket datagram) { + byte[] data = Arrays.copyOf(datagram.getData(), datagram.getLength()); + return data; + } + + /** + * Hack until I find a way to use TestNG's assertions. + */ + private void assertTrue(boolean assertion, String message) { + if (assertion == false) { + log.severe(message); + assert (false); + } + } + + private void assertTrue(boolean assertion) { + assertTrue(assertion, ""); + } + +} diff --git a/test/sun/management/jdp/JdpTestUtil.java b/test/sun/management/jdp/JdpTestUtil.java new file mode 100644 --- /dev/null +++ b/test/sun/management/jdp/JdpTestUtil.java @@ -0,0 +1,142 @@ +/* + * Copyright (c) 2012, 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 + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + + +import java.io.UnsupportedEncodingException; +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; +import java.util.logging.ConsoleHandler; +import java.util.logging.Level; +import java.util.logging.Logger; + +/** + * Utility methods for parsing raw JDP packets. + * + * @author Alex Schenkman + */ +public class JdpTestUtil { + + static final int HEADER_SIZE = 4 + 2; // magic + protocol version + + /** + * Reads two bytes, starting at the given position, + * and converts them into an int. + * + * @param data + * @param pos + * @return + */ + static int decode2ByteInt(byte[] data, int pos) { + return (((data[pos] & 0xFF) << 8) | (data[pos + 1] & 0xFF)); + } + + /** + * Reads four bytes, starting at the given position, + * and converts them into an int. + * + * @param data + * @param pos + * @return + */ + static int decode4ByteInt(byte[] data, int pos) { + int result = data[pos + 3] & 0xFF; + result = result | ((data[pos + 2] & 0xFF) << 8); + result = result | ((data[pos + 1] & 0xFF) << 16); + result = result | ((data[pos] & 0xFF) << 24); + return result; + } + + /** + * Reads an entry from the given byte array, starting at the given position. + * This is an internal function used by @see readRawPayload(byte[] rawPayload, int size). + *

+ * The format of an entry is: + * 2 bytes with the size of the following string. + * n bytes of characters. + * + * @param data + * @param pos + * @return + * @throws UnsupportedEncodingException + */ + static String decodeEntry(byte[] data, int pos) + throws UnsupportedEncodingException { + + int size = JdpTestUtil.decode2ByteInt(data, pos); + pos = pos + 2; + byte[] raw = Arrays.copyOfRange(data, pos, pos + size); + return new String(raw, "UTF-8"); + } + + /** + * Builds a Map with the payload, from the raw data. + * + * @param rawData + * @return + * @throws UnsupportedEncodingException + */ + static Map readPayload(byte[] rawData) + throws UnsupportedEncodingException { + + int totalSize = rawData.length; + int payloadSize = totalSize - HEADER_SIZE; + byte[] rawPayload = Arrays.copyOfRange(rawData, HEADER_SIZE, HEADER_SIZE + payloadSize); + Map payload = readRawPayload(rawPayload, payloadSize); + return payload; + } + + /** + * Builds a map from the payload's raw data. + * This is an internal function used by @see readPayload(byte[] rawData) + * + * @param rawPayload + * @param size + * @return + * @throws UnsupportedEncodingException + */ + static Map readRawPayload(byte[] rawPayload, int size) + throws UnsupportedEncodingException { + + String key, value; + Map payload = new HashMap(); + + for (int pos = 0; pos < size; ) { + key = decodeEntry(rawPayload, pos); + pos = pos + 2 + key.length(); + value = decodeEntry(rawPayload, pos); + pos = pos + 2 + value.length(); + + payload.put(key, value); + } + return payload; + } + + static void enableConsoleLogging(Logger log, Level level) throws SecurityException { + ConsoleHandler handler = new ConsoleHandler(); + handler.setLevel(level); + log.addHandler(handler); + log.setLevel(level); + } + +} diff --git a/test/sun/management/jdp/JdpTestUtilTest.java b/test/sun/management/jdp/JdpTestUtilTest.java new file mode 100644 --- /dev/null +++ b/test/sun/management/jdp/JdpTestUtilTest.java @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2012, 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 + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + + +import org.testng.annotations.Test; + +import java.io.UnsupportedEncodingException; +import java.util.Map; + +import static jdk.testlibrary.Asserts.assertEquals; + + +/* + Unit test for the utility functions in JdpTestUtil. + These are not meant to be by automatically run by JTREG. + They exists to support test development and should be run by the test developer. +*/ + +public class JdpTestUtilTest { + + @Test + public void testDecodeEntry() throws UnsupportedEncodingException { + byte[] data = {'x', 0, 4, 'a', 'l', 'e', 'x'}; + String result = JdpTestUtil.decodeEntry(data, 1); + assertEquals("alex", result); + } + + @Test + public void testDecode2ByteInt() { + byte[] data = {'x', (byte) 0xff, (byte) 0xff}; + int value = JdpTestUtil.decode2ByteInt(data, 1); + assertEquals(65535, value); + } + + @Test + public void testDecode4ByteInt() { + byte[] data = {'x', (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff}; + int value = JdpTestUtil.decode4ByteInt(data, 1); + assertEquals(0xffffffff, value); + + } + + @Test + public void testReadRawPayload() throws UnsupportedEncodingException { + byte[] data = {0, 3, 'f', 'o', 'o', 0, 4, 'b', 'a', 'r', 's'}; + Map payload = JdpTestUtil.readRawPayload(data, data.length); + + assertEquals(1, payload.size()); + assertEquals("bars", payload.get("foo")); + } + + @Test + public void testReadPayload() throws UnsupportedEncodingException { + byte[] data = {1, 2, 3, 4, 1, 2, 0, 3, 'f', 'o', 'o', 0, 4, 'b', 'a', 'r', 's'}; + Map payload = JdpTestUtil.readPayload(data); + + assertEquals(1, payload.size()); + assertEquals("bars", payload.get("foo")); + } + +} diff --git a/test/sun/management/jdp/JdpUnitTest.java b/test/sun/management/jdp/JdpUnitTest.java --- a/test/sun/management/jdp/JdpUnitTest.java +++ b/test/sun/management/jdp/JdpUnitTest.java @@ -33,22 +33,22 @@ public class JdpUnitTest { - static byte[] russian_name = {(byte)0xd0,(byte)0xbf,(byte)0xd1,(byte)0x80,(byte)0xd0,(byte)0xbe,(byte)0xd0,(byte)0xb2, - (byte)0xd0,(byte)0xb5,(byte)0xd1,(byte)0x80,(byte)0xd0,(byte)0xba,(byte)0xd0,(byte)0xb0, - (byte)0x20,(byte)0xd1,(byte)0x81,(byte)0xd0,(byte)0xb2,(byte)0xd1,(byte)0x8f,(byte)0xd0, - (byte)0xb7,(byte)0xd0,(byte)0xb8,(byte)0x0a}; + static byte[] russian_name = {(byte) 0xd0, (byte) 0xbf, (byte) 0xd1, (byte) 0x80, (byte) 0xd0, (byte) 0xbe, (byte) 0xd0, (byte) 0xb2, + (byte) 0xd0, (byte) 0xb5, (byte) 0xd1, (byte) 0x80, (byte) 0xd0, (byte) 0xba, (byte) 0xd0, (byte) 0xb0, + (byte) 0x20, (byte) 0xd1, (byte) 0x81, (byte) 0xd0, (byte) 0xb2, (byte) 0xd1, (byte) 0x8f, (byte) 0xd0, + (byte) 0xb7, (byte) 0xd0, (byte) 0xb8, (byte) 0x0a}; /** * This test tests that complete packet is build correctly */ public static void PacketBuilderTest() - throws IOException, JdpException { + throws IOException, JdpException { /* Complete packet test */ { JdpJmxPacket p1 = new JdpJmxPacket(UUID.randomUUID(), "fake://unit-test"); p1.setMainClass("FakeUnitTest"); - p1.setInstanceName( new String(russian_name,"UTF-8")); + p1.setInstanceName(new String(russian_name, "UTF-8")); byte[] b = p1.getPacketData(); JdpJmxPacket p2 = new JdpJmxPacket(b); @@ -68,7 +68,7 @@ JdpDoSomething.compaireJdpPacketEx(p1, p2); } - System.out.println("OK: Test passed"); + System.out.println("OK: Test passed"); } diff --git a/test/sun/management/jdp/PacketTest.java b/test/sun/management/jdp/PacketTest.java new file mode 100644 --- /dev/null +++ b/test/sun/management/jdp/PacketTest.java @@ -0,0 +1,121 @@ +/* + * Copyright (c) 2012, 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 + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + + +import java.io.IOException; +import java.util.Map; +import java.util.UUID; + +import org.testng.annotations.Test; +import sun.management.jdp.JdpJmxPacket; + +import static org.testng.Assert.assertEquals; + + +/** + * These tests are unit tests used for test development. + * These are not meant to be by automatically run by JTREG. + * They exists to support test development and should be run by the test developer. + *

+ *

+ * The JDP packet format: + *

+ * packet = header + payload + *

+ * header = magic + version + * magic = 4 bytes: 0xCOFFEE42 + * version = 2 bytes: 01 (As of 2013-05-01) + *

+ * payload = list key/value pairs + * keySize = 2 bytes + * key = (keySize) bytes + * valueSize = 2 bytes + * value = (valueSize) bytes + *

+ *

+ * Two entries are mandatory in the payload: + * UUID (JdpJmxPacket.UUID_KEY) + * JMX service URL (JdpJmxPacket.JMX_SERVICE_URL_KEY) + *

+ * These two entries are optional: + * Main Class (JdpJmxPacket.MAIN_CLASS_KEY) + * Instance name (JdpJmxPacket.INSTANCE_NAME_KEY) + * + * @author Alex Schenkman + *

+ * Using TestNG framework. + */ +public class PacketTest { + + final int MAGIC = 0xC0FFEE42; + final UUID id = UUID.randomUUID(); + final String mainClass = "org.happy.Feet"; + final String jmxServiceUrl = "fake://jmxUrl"; + final String instanceName = "Joe"; + + private JdpJmxPacket createDefaultPacket() { + JdpJmxPacket packet = new JdpJmxPacket(id, jmxServiceUrl); + return packet; + } + + private JdpJmxPacket createFullPacket() { + JdpJmxPacket packet = new JdpJmxPacket(id, jmxServiceUrl); + packet.setMainClass(mainClass); + packet.setInstanceName("Joe"); + return packet; + } + + @Test + public void testMagic() throws IOException { + byte[] rawData = createFullPacket().getPacketData(); + int magic = JdpTestUtil.decode4ByteInt(rawData, 0); + assertEquals(MAGIC, magic, "MAGIC does not match!"); + } + + @Test + public void testVersion() throws IOException { + byte[] rawData = createFullPacket().getPacketData(); + assertEquals(1, JdpTestUtil.decode2ByteInt(rawData, 4)); + } + + @Test + public void testAllEntries() throws IOException { + byte[] rawData = createFullPacket().getPacketData(); + Map payload = JdpTestUtil.readPayload(rawData); + + assertEquals(4, payload.size()); + assertEquals(mainClass, payload.get(JdpJmxPacket.MAIN_CLASS_KEY)); + assertEquals(id.toString(), payload.get(JdpJmxPacket.UUID_KEY)); + assertEquals(jmxServiceUrl, payload.get(JdpJmxPacket.JMX_SERVICE_URL_KEY)); + assertEquals(instanceName, payload.get(JdpJmxPacket.INSTANCE_NAME_KEY)); + } + + public void testDefaultEntries() throws IOException { + byte[] rawData = createDefaultPacket().getPacketData(); + Map payload = JdpTestUtil.readPayload(rawData); + + assertEquals(2, payload.size()); + assertEquals(id.toString(), payload.get(JdpJmxPacket.UUID_KEY)); + assertEquals(jmxServiceUrl, payload.get(JdpJmxPacket.JMX_SERVICE_URL_KEY)); + } +} diff --git a/test/sun/management/jdp/PortAlreadyInUseTest.java b/test/sun/management/jdp/PortAlreadyInUseTest.java new file mode 100644 --- /dev/null +++ b/test/sun/management/jdp/PortAlreadyInUseTest.java @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2013, 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 + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + + +import jdk.testlibrary.OutputAnalyzer; +import jdk.testlibrary.Utils; + +import java.io.IOException; +import java.net.ServerSocket; +import java.util.logging.Logger; + +/** + * This test used for test development and it is not meant to be run by JTReg. + *

+ * This test exercises a retry mechanism to avoid a test failure because of + * starting the VM on a busy jmxremote.port. + *

+ * To run this test you'll need to add this VM option: -Dtest.jdk= + */ +public class PortAlreadyInUseTest extends DynamicLauncher { + + ServerSocket socket; + final Logger log = Logger.getLogger("PortAlreadyInUse"); + + protected void go() throws Exception { + jmxPort = Utils.getFreePort(); + occupyPort(); + + log.info("Attempting to start a VM using the same port."); + OutputAnalyzer out = this.runVM(); + out.shouldContain("Port already in use"); + log.info("Failed as expected."); + + log.info("Trying again using retries."); + this.run(); + } + + private void occupyPort() throws IOException { + socket = new ServerSocket(jmxPort); + log.info("Occupying port " + String.valueOf(jmxPort)); + } + + protected String[] options() { + String[] options = { + "-Dcom.sun.management.jmxremote.authenticate=false", + "-Dcom.sun.management.jmxremote.ssl=false", + "-Dcom.sun.management.jmxremote=true", + "-Dcom.sun.management.jmxremote.port=" + String.valueOf(jmxPort), + "-version" + }; + return options; + } + + public static void main(String[] args) throws Exception { + PortAlreadyInUseTest test = new PortAlreadyInUseTest(); + test.go(); + } + +} diff --git a/test/sun/management/jdp/README b/test/sun/management/jdp/README new file mode 100644 --- /dev/null +++ b/test/sun/management/jdp/README @@ -0,0 +1,74 @@ +The following test were contributed by dmitry.samersoff@oracle.com and will be ported in the near future: +JdpClient.java +JdpDoSomething.java +JdpTest.sh +JdpUnitTest.java + + +JdpTest.sh: +------------------------------------- +test_01 - basic test, check if JDP packet assembler and other + parts of JDP is not broken + +test_02 - test if JDP starts with custom parameters. (disabled) + +test_03 - test if jcmd is able to start jdp with + custom parameters (disabled) + +test_04 - test if JDP starts with default parameters (disabled) + +test_05 - test if jcmd is able to start jdp with default + parameters (disabled) + +Only test_01 is enabled at the moment. + +JdpUnitTest.java: contains unit tests used under development. + + +========================================================================== +The other Java-based tests in this folder are contributed by alex.schenkman@oracle.com + +There are three Jdp test cases in this folder: + 1) Jdp is turned off. + 2) Jdp is turned on, using default values + 3) Jdp is turned on, using a specific IP and port + +For the test cases above, the actual tests are: + 1) JdpOffTestCase.java + 2) JdpOnTestCase.java + 3) JdpOnTestCase.java, using different parameters. +All these three test are implemented as subclasses of JdpTestCase.java. + +For all of these three tests, the VM sending the Jdp packets is also catching them. +That is, while the VM itself is sending Jdp multicast packets, the program executed by +that same VM is listening for those packets. + +These tests above work as follows: + 1) Start a VM with Jdp off, make sure that no Jdp packets arrive at the default IP/port. + 2) Start a VM with Jdp on, make sure three packets arrive at the default IP/port. + 3) Start a VM with Jdp on a specific IP/port, make sure three packets arrive. + +To make sure that we are not catching Jdp packets from some other VM, the INSTANCE_NAME +attribute is set to a unique id. The setting of this unique id is done by a launcher. +There are three launchers, one for each of the tests above: + 1) JdpOffTest.java + 2) JdpDefaultsTest.java + 3) JdpSpecificAddressTest.java +All these three tests are implemented as subclasses of DynamicLauncher.java. + +So, JdpOffTest.class will execute JdpOffTestCase.class (using ProcessTools), +and that will exercise test case nr.1; and so on for the other cases. + +These launchers are also the entry points for JTreg. +This means that JTreg will only see these launchers as tests. +You might run the tests without JTreg, as long as you specify all the VM optiones needed. +Look at the launcher to determine what is needed. Do not forget -Dtest.jdk, that is set by JTreg. + +JMX must be enabled in order to enable Jdp. This requires a free port (com.sun.management.jmxremote.port). +To avoid port-busy conflicts, DynamicLauncher.java will try to find a free port up to three times. + +There are some other tests used for test development, and not meant to be run automatically by JTreg. + 1) PortAlreadyInUse.java, used to test the retry mechanism to find a free port. + 2) PacketTest.java, Jdp packet sanity. + 3) JdpTestUtil.java, Utility functions to read a Jdp packet. + 4) JdpTestUtilTest.java, Unit tests for JdpTestUtil.java