提交 01f0a918 编写于 作者: S sla

8014506: Test of Jdp feature

Reviewed-by: sla
Contributed-by: NAlex Schenkman <alex.schenkman@oracle.com>
上级 60007043
/*
* 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;
}
}
/*
* 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();
}
......@@ -36,6 +36,7 @@ import java.nio.channels.Selector;
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 @@ public class JdpClient {
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 @@ public class JdpClient {
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 @@ public class JdpClient {
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 @@ public class JdpClient {
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();
......
/*
* 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;
}
}
......@@ -34,7 +34,7 @@ public class JdpDoSomething {
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 class JdpDoSomething {
}
public static void compaireJdpPacketEx(JdpJmxPacket p1, JdpJmxPacket p2)
throws JdpException {
throws JdpException {
if (!Objects.equals(p1, p1)) {
throw new JdpException("Packet mismatch error");
......
/*
* 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;
}
}
/*
* 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();
}
}
/*
* 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();
}
}
/*
* 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;
}
}
......@@ -33,7 +33,7 @@ _compile=yes
# temporary disable jcmd related tests
# _testsuite="01,02,03,04,05"
_testsuite="01,02,04"
_testsuite="01"
_pwd=`pwd`
......
/*
* 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, "");
}
}
/*
* 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);
}
}
/*
* 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"));
}
}
......@@ -33,22 +33,22 @@ import sun.management.jdp.JdpException;
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 @@ public class JdpUnitTest {
JdpDoSomething.compaireJdpPacketEx(p1, p2);
}
System.out.println("OK: Test passed");
System.out.println("OK: Test passed");
}
......
/*
* 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));
}
}
/*
* 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();
}
}
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
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册