Path: blob/master/test/jdk/sun/management/jdp/JdpTestCase.java
41149 views
/*1* Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/2223/**24* A JVM with JDP on should send multicast JDP packets regularly.25* Look at JdpOnTestCase.java and JdpOffTestCase.java26*/272829import sun.management.jdp.JdpJmxPacket;3031import java.io.IOException;32import java.io.UnsupportedEncodingException;33import java.net.DatagramPacket;34import java.net.MulticastSocket;35import java.net.SocketTimeoutException;36import java.util.Arrays;37import java.util.Map;38import java.util.logging.Level;39import java.util.logging.Logger;4041public abstract class JdpTestCase {42final Logger log = Logger.getLogger("sun.management.jdp");43final int MAGIC = 0xC0FFEE42; // Jdp magic number.44private static final int BUFFER_LENGTH = 64 * 1024; // max UDP size, except for IPv6 jumbograms.45private final int TIME_OUT_FACTOR = 10; // Socket times out after 10 times the jdp pause.46protected int timeOut;47private long startTime;48protected ClientConnection connection;4950public JdpTestCase(ClientConnection connection) {51this.connection = connection;52JdpTestUtil.enableConsoleLogging(log, Level.ALL);53}5455public void run() throws Exception {56log.fine("Test started.");57log.fine("Listening for multicast packets at " + connection.address.getHostAddress()58+ ":" + String.valueOf(connection.port));59log.fine(initialLogMessage());60log.fine("Pause in between packets is: " + connection.pauseInSeconds + " seconds.");6162startTime = System.currentTimeMillis();63timeOut = connection.pauseInSeconds * TIME_OUT_FACTOR;64log.fine("Timeout set to " + String.valueOf(timeOut) + " seconds.");6566MulticastSocket socket = connection.connectWithTimeout(timeOut * 1000);6768byte[] buffer = new byte[BUFFER_LENGTH];69DatagramPacket datagram = new DatagramPacket(buffer, buffer.length);7071do {72try {73socket.receive(datagram);74onReceived(extractUDPpayload(datagram));75} catch (SocketTimeoutException e) {76onSocketTimeOut(e);77}7879if (!shouldContinue()) {80break;81}8283if (hasTestLivedLongEnough()) {84shutdown();85}8687} while (true);88log.fine("Test ended successfully.");89}9091/**92* Subclasses: JdpOnTestCase and JdpOffTestCase have different messages.93*/94protected abstract String initialLogMessage();959697/**98* Executed when the socket receives a UDP packet.99*/100private void onReceived(byte[] packet) throws Exception {101if (isJDP(packet)) {102Map<String, String> payload = checkStructure(packet);103jdpPacketReceived(payload);104} else {105log.fine("Non JDP packet received, ignoring it.");106}107}108109/**110* Determine whether the test should end.111*112* @return113*/114abstract protected boolean shouldContinue();115116/**117* This method is executed when the socket has not received any packet for timeOut seconds.118*/119abstract protected void onSocketTimeOut(SocketTimeoutException e) throws Exception;120121/**122* This method is executed after a correct Jdp packet has been received.123*124* @param payload A dictionary containing the data if the received Jdp packet.125*/126private void jdpPacketReceived(Map<String, String> payload) throws Exception {127final String instanceName = payload.get("INSTANCE_NAME");128if (instanceName != null && instanceName.equals(connection.instanceName)) {129packetFromThisVMReceived(payload);130} else {131packetFromOtherVMReceived(payload);132}133}134135/**136* This method is executed after a correct Jdp packet, coming from this VM has been received.137*138* @param payload A dictionary containing the data if the received Jdp packet.139*/140protected abstract void packetFromThisVMReceived(Map<String, String> payload) throws Exception;141142143/**144* This method is executed after a correct Jdp packet, coming from another VM has been received.145*146* @param payload A dictionary containing the data if the received Jdp packet.147*/148protected void packetFromOtherVMReceived(Map<String, String> payload) {149final String jdpName = payload.get("INSTANCE_NAME");150log.fine("Ignoring JDP packet sent by other VM, jdp.name=" + jdpName);151}152153154/**155* The test should stop if it has been 12 times the jdp.pause.156* jdp.pause is how many seconds in between packets.157* <p/>158* This timeout (12 times)is slightly longer than the socket timeout (10 times) on purpose.159* In the off test case, the socket should time out first.160*161* @return162*/163protected boolean hasTestLivedLongEnough() {164long now = System.currentTimeMillis();165boolean haslivedLongEnough = (now - startTime) > (timeOut * 1.2 * 1000);166return haslivedLongEnough;167}168169/**170* This exit condition arises when we receive UDP packets but they are not valid Jdp.171*/172protected void shutdown() throws Exception {173log.severe("Shutting down the test.");174throw new Exception("Not enough JDP packets received before timeout!");175}176177/**178* Assert that this Jdp packet contains the required two keys.179* <p/>180* We expect zero packet corruption and thus fail on the first corrupted packet.181* This might need revision.182*/183protected Map<String, String> checkStructure(byte[] packet) throws UnsupportedEncodingException {184Map<String, String> payload = JdpTestUtil.readPayload(packet);185assertTrue(payload.size() >= 2, "JDP should have minimun 2 entries.");186assertTrue(payload.get(JdpJmxPacket.UUID_KEY).length() > 0);187assertTrue(payload.get(JdpJmxPacket.JMX_SERVICE_URL_KEY).length() > 0);188return payload;189}190191192/**193* Check if packet has correct JDP magic number.194*195* @param packet196* @return197* @throws IOException198*/199private boolean isJDP(byte[] packet) throws IOException {200int magic = JdpTestUtil.decode4ByteInt(packet, 0);201return (magic == MAGIC);202}203204private byte[] extractUDPpayload(DatagramPacket datagram) {205byte[] data = Arrays.copyOf(datagram.getData(), datagram.getLength());206return data;207}208209/**210* Hack until I find a way to use TestNG's assertions.211*/212private void assertTrue(boolean assertion, String message) {213if (assertion == false) {214log.severe(message);215assert (false);216}217}218219private void assertTrue(boolean assertion) {220assertTrue(assertion, "");221}222223}224225226