changeset 8779:0cacac7f5c37

8014506: Test of Jdp feature Reviewed-by: sla Contributed-by: Alex Schenkman <alex.schenkman@oracle.com>
author sla
date Fri, 08 Nov 2013 18:16:12 +0100
parents 59ff7957c26f
children 8e8e423fa3dc
files test/sun/management/jdp/ClientConnection.java test/sun/management/jdp/DynamicLauncher.java test/sun/management/jdp/JdpClient.java test/sun/management/jdp/JdpDefaultsTest.java test/sun/management/jdp/JdpDoSomething.java test/sun/management/jdp/JdpOffTest.java test/sun/management/jdp/JdpOffTestCase.java test/sun/management/jdp/JdpOnTestCase.java test/sun/management/jdp/JdpSpecificAddressTest.java test/sun/management/jdp/JdpTest.sh test/sun/management/jdp/JdpTestCase.java test/sun/management/jdp/JdpTestUtil.java test/sun/management/jdp/JdpTestUtilTest.java test/sun/management/jdp/JdpUnitTest.java test/sun/management/jdp/PacketTest.java test/sun/management/jdp/PortAlreadyInUseTest.java test/sun/management/jdp/README
diffstat 17 files changed, 1256 insertions(+), 21 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/sun/management/jdp/ClientConnection.java	Fri Nov 08 18:16:12 2013 +0100
@@ -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;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/sun/management/jdp/DynamicLauncher.java	Fri Nov 08 18:16:12 2013 +0100
@@ -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();
+
+}
--- a/test/sun/management/jdp/JdpClient.java	Mon Nov 11 14:22:22 2013 -0500
+++ b/test/sun/management/jdp/JdpClient.java	Fri Nov 08 18:16:12 2013 +0100
@@ -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<String,String> pMap = reader.getDiscoveryDataAsMap();
+            Map<String, String> 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();
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/sun/management/jdp/JdpDefaultsTest.java	Fri Nov 08 18:16:12 2013 +0100
@@ -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;
+    }
+}
--- a/test/sun/management/jdp/JdpDoSomething.java	Mon Nov 11 14:22:22 2013 -0500
+++ b/test/sun/management/jdp/JdpDoSomething.java	Fri Nov 08 18:16:12 2013 +0100
@@ -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");
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/sun/management/jdp/JdpOffTest.java	Fri Nov 08 18:16:12 2013 +0100
@@ -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;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/sun/management/jdp/JdpOffTestCase.java	Fri Nov 08 18:16:12 2013 +0100
@@ -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<String, String> 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();
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/sun/management/jdp/JdpOnTestCase.java	Fri Nov 08 18:16:12 2013 +0100
@@ -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<String, String> 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:
+     * <p/>
+     * -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)
+     * <p/>
+     * 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();
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/sun/management/jdp/JdpSpecificAddressTest.java	Fri Nov 08 18:16:12 2013 +0100
@@ -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;
+    }
+
+}
--- a/test/sun/management/jdp/JdpTest.sh	Mon Nov 11 14:22:22 2013 -0500
+++ b/test/sun/management/jdp/JdpTest.sh	Fri Nov 08 18:16:12 2013 +0100
@@ -33,7 +33,7 @@
 
 # temporary disable jcmd related tests
 # _testsuite="01,02,03,04,05"
-_testsuite="01,02,04"
+_testsuite="01"
 
 _pwd=`pwd`
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/sun/management/jdp/JdpTestCase.java	Fri Nov 08 18:16:12 2013 +0100
@@ -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<String, String> 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<String, String> 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<String, String> 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<String, String> 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.
+     * <p/>
+     * 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.
+     * <p/>
+     * We expect zero packet corruption and thus fail on the first corrupted packet.
+     * This might need revision.
+     */
+    protected Map<String, String> checkStructure(byte[] packet) throws UnsupportedEncodingException {
+        Map<String, String> 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, "");
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/sun/management/jdp/JdpTestUtil.java	Fri Nov 08 18:16:12 2013 +0100
@@ -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).
+     * <p/>
+     * 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<String, String> 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<String, String> 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<String, String> readRawPayload(byte[] rawPayload, int size)
+            throws UnsupportedEncodingException {
+
+        String key, value;
+        Map<String, String> payload = new HashMap<String, String>();
+
+        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);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/sun/management/jdp/JdpTestUtilTest.java	Fri Nov 08 18:16:12 2013 +0100
@@ -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<String, String> 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<String, String> payload = JdpTestUtil.readPayload(data);
+
+        assertEquals(1, payload.size());
+        assertEquals("bars", payload.get("foo"));
+    }
+
+}
--- a/test/sun/management/jdp/JdpUnitTest.java	Mon Nov 11 14:22:22 2013 -0500
+++ b/test/sun/management/jdp/JdpUnitTest.java	Fri Nov 08 18:16:12 2013 +0100
@@ -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");
 
     }
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/sun/management/jdp/PacketTest.java	Fri Nov 08 18:16:12 2013 +0100
@@ -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.
+ * <p/>
+ * <p/>
+ * The JDP packet format:
+ * <p/>
+ * packet = header + payload
+ * <p/>
+ * header  = magic + version
+ * magic       = 4 bytes: 0xCOFFEE42
+ * version     = 2 bytes: 01 (As of 2013-05-01)
+ * <p/>
+ * payload = list key/value pairs
+ * keySize     = 2 bytes
+ * key         = (keySize) bytes
+ * valueSize   = 2 bytes
+ * value       = (valueSize) bytes
+ * <p/>
+ * <p/>
+ * Two entries are mandatory in the payload:
+ * UUID            (JdpJmxPacket.UUID_KEY)
+ * JMX service URL (JdpJmxPacket.JMX_SERVICE_URL_KEY)
+ * <p/>
+ * These two entries are optional:
+ * Main Class      (JdpJmxPacket.MAIN_CLASS_KEY)
+ * Instance name   (JdpJmxPacket.INSTANCE_NAME_KEY)
+ *
+ * @author Alex Schenkman
+ *         <p/>
+ *         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<String, String> 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<String, String> 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));
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/sun/management/jdp/PortAlreadyInUseTest.java	Fri Nov 08 18:16:12 2013 +0100
@@ -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.
+ * <p/>
+ * This test exercises a retry mechanism to avoid a test failure because of
+ * starting the VM on a busy jmxremote.port.
+ * <p/>
+ * To run this test you'll need to add this VM option: -Dtest.jdk=<path-to-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();
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/sun/management/jdp/README	Fri Nov 08 18:16:12 2013 +0100
@@ -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