Path: blob/master/test/jdk/javax/management/security/Utils.java
41152 views
/*1* Copyright (c) 2005, 2015, 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*/2223import java.util.Map;24import java.util.HashMap;25import java.util.Properties;26import java.util.StringTokenizer;27import java.lang.reflect.Method;28import javax.management.remote.JMXConnectorServerMBean;2930// utility class for MXBean* tests coming from JMX Tonga test suite31class Utils {3233private static final String SERVER_SIDE_NAME = "-server";34private static final String CLIENT_SIDE_NAME = "-client";3536// DEBUG is printed depending on the DEBUG and DEBUG_LEVEL JAVA property37private static final String DEBUG_HEADER = "[debug] ";3839// DEBUG levels40private static int selectedDebugLevel = 0;41static final int DEBUG_STANDARD = 1;42static final int DEBUG_VERBOSE = 2; // Mainly used for stress tests43static final int DEBUG_ALL = DEBUG_STANDARD | DEBUG_VERBOSE;4445static void parseDebugProperties() {46int level = 0;47Properties p = System.getProperties();4849// get selected levels50if (p.getProperty("DEBUG_STANDARD") != null) {51level |= DEBUG_STANDARD;52}5354if (p.getProperty("DEBUG_VERBOSE") != null) {55level |= DEBUG_VERBOSE;56}5758if (p.getProperty("DEBUG_ALL") != null) {59level |= DEBUG_ALL;60}6162selectedDebugLevel = level;63}6465/**66* Reproduces the original parsing and collection of test parameters67* from the DTonga JMX test suite.68*69* Collects passed args and returns them in a map(argname, value) structure,70* which will be then propagated as necessary to various called methods.71*/72static Map<String, Object> parseParameters(String args[])73throws Exception {74Utils.debug(DEBUG_STANDARD, "TestRoot::parseParameters: Start");75HashMap<String, Object> map = new HashMap<>();7677for ( int i = 0; i < args.length; i++ ) {78if ( args[i].trim().startsWith("-") ) {79if ((i+1) < args.length && !args[i+1].startsWith("-") ) {80Utils.debug(DEBUG_STANDARD,81"TestRoot::parseParameters: added in map = " +82args[i] +83" with value " +84args[i+1]) ;85map.put(args[i].trim(), args[i+1].trim()) ;86} else if ((i+1) < args.length && args[i+1].startsWith("-") ||87(i+1) == args.length ) {88Utils.debug(DEBUG_STANDARD,89"TestRoot::parseParameters: added in map = " +90args[i] +91" with null value") ;92map.put(args[i].trim(), null) ;93} else {94System.out.println(95"TestRoot::parseParameters: (WARNING) not added in map = " +96args[i]) ;97}98}99}100101Utils.debug(DEBUG_STANDARD, "TestRoot::parseParameters: Done") ;102return map ;103}104105// Parse server parameters and put them in passed serverMap106static int parseServerParameters(String args[],107String serverSideName,108Map<String, Object> serverMap )109throws Exception {110Utils.debug(Utils.DEBUG_STANDARD,111serverSideName + "::parseServerParameters: Start");112113int nextIndex = 0;114boolean seenServerFlag = false;115116for ( int i = 0; i < args.length; i++ ) {117// Case of reaching "-server" flag parameter118if (args[i].equals(SERVER_SIDE_NAME)) {119if (!seenServerFlag) {120seenServerFlag = true;121continue;122} else {123// Already parsing server params, invalid params list124Utils.debug(Utils.DEBUG_STANDARD,125serverSideName + "::parseParameters: Invalid " +126args[i] + " parameter detected in " +127SERVER_SIDE_NAME + " parameters list");128nextIndex = -1;129throw new RuntimeException("Invalid Parameter list");130}131}132133// Case of reaching "-client" flag parameter134if (args[i].equals(CLIENT_SIDE_NAME)) {135// While parsing server parameters, then parsing is done.136Utils.debug(Utils.DEBUG_STANDARD,137serverSideName + "::parseServerParameters: Parsing of " +138SERVER_SIDE_NAME + " parameters done.");139return i;140}141142i = parseParamAtIndex(args, i, serverMap);143nextIndex = i;144}145146Utils.debug(Utils.DEBUG_STANDARD,147serverSideName + "::parseServerParameters: Parsing of parameters done");148149return nextIndex;150}151152// Parse client parameters and put them in passed clientMap153static void parseClientParameters(String args[],154String clientSideName,155Map<String, Object> clientMap )156throws Exception {157158Utils.debug(Utils.DEBUG_STANDARD,159clientSideName + "::parseClientParameters: Start");160161boolean seenClientFlag = false;162163for ( int i = 0; i < args.length; i++ ) {164// Case of reaching "-client" flag parameter165if (args[i].equals(CLIENT_SIDE_NAME)) {166if (!seenClientFlag) {167seenClientFlag = true;168continue;169} else {170// Already parsing client params, invalid params list171Utils.debug(Utils.DEBUG_STANDARD,172clientSideName + "::parseClientParameters: Invalid " +173CLIENT_SIDE_NAME + " parameter detected in " +174CLIENT_SIDE_NAME + " parameters list.");175throw new RuntimeException("Invalid parameter in " +176clientSideName + " parameter list");177}178}179180// Case of reaching "-server" flag parameter181if (args[i].equals(SERVER_SIDE_NAME)) {182// While parsing client parameters, invalid parameter list.183Utils.debug(Utils.DEBUG_STANDARD,184clientSideName + "::parseClientParameters: Invalid " +185SERVER_SIDE_NAME + " parameter inside " +186CLIENT_SIDE_NAME + " parameters list.");187throw new RuntimeException("Invalid parameter in " +188clientSideName + " parameter list");189}190191i = parseParamAtIndex(args, i, clientMap);192}193194Utils.debug(Utils.DEBUG_STANDARD,195clientSideName + "::parseClientParameters: Parsing of parameters done.");196}197198// Add param found at index to passed map199// We only accept either "-param value" or "-param" form.200// The "value" form is invalid but just ignored.201private static int parseParamAtIndex(String args[],202int index,203Map<String, Object> map) {204205if (args[index].trim().startsWith("-") ) {206// Case of a "-param value" form207if ((index+1) < args.length && !args[index+1].startsWith("-") ) {208Utils.debug(Utils.DEBUG_STANDARD,209"TestRoot::parseParamAtIndex: added in map = "210+ args[index]211+ " with value "212+ args[index+1]) ;213// adding ("param", value) to the passed map214map.put(args[index].trim(), args[index+1].trim()) ;215// value should not be parsed a second time216return index+1;217}218// Case of a "-param" form (flag parameter)219else if (((index+1) < args.length && args[index+1].startsWith("-")) ||220(index+1) == args.length ) {221Utils.debug(Utils.DEBUG_STANDARD,222"TestRoot::parseParamAtIndex: added in map = "223+ args[index]224+ " with null value") ;225// adding ("param", null) to passed map226map.put(args[index].trim(), null) ;227}228} else {229// Unsupported "value" alone parameter230Utils.debug(Utils.DEBUG_STANDARD,231"TestRoot::parseParamAtIndex: invalid " +232" value-alone \"" + args[index] + "\" parameter." +233" Parameter ignored.");234}235236return index;237}238239/**240* This method is to be used in all tests to print anything241* that is temporary.242* Printing is done only when debug is activated by the property DEBUG.243* Printing depends also on the DEBUG_LEVEL property.244* Here it encapsulates a System.out.println.245*/246static void debug(int level, String line) {247if ((selectedDebugLevel & level) != 0) {248System.out.println(DEBUG_HEADER + line);249}250}251252/**253* Do print stack trace when withStack is true.254* Does try to call getTargetException() and getTargetError() then255* print embedded stacks in the case of an Exception wrapping256* another Exception or an Error. Recurse until no more wrapping257* is found.258*/259static void printThrowable(Throwable theThro, boolean withStack) {260try {261if (withStack) {262theThro.printStackTrace(System.out);263}264if (theThro instanceof Exception) {265Exception t = (Exception) theThro;266Method target = null;267String blank = " ";268try {269target = t.getClass().getMethod("getTargetException",270(java.lang.Class<?>[]) null);271} catch (Exception ee) {272// OK: getTargetException method could be there or not273}274System.out.println(blank + t.getClass() + "==>" + t.getMessage());275while (target != null) {276try {277t = (Exception) target.invoke(t,278(java.lang.Object[]) null);279} catch (Exception ee) {280t = null;281}282try {283if (t != null) {284blank = blank + " ";285System.out.println(blank + t.getClass() + "==>" +286t.getMessage());287try {288target =289t.getClass().getMethod("getTargetException",290(java.lang.Class<?>[]) null);291} catch (Exception ee) {292// OK: getTargetException method could be there or not }293}294} else {295target = null;296}297} catch (Exception ee) {298target = null;299}300}301302// We may have exceptions wrapping an Error then it is303// getTargetError that is likely to be called304try {305target = ((Exception) theThro).getClass().getMethod("getTargetError",306(java.lang.Class<?>[]) null);307} catch (Exception ee) {308// OK: getTargetError method could be there or not309}310Throwable err = theThro;311while (target != null) {312try {313err = (Error) target.invoke(err,314(java.lang.Object[]) null);315} catch (Exception ee) {316err = null;317}318try {319if (err != null) {320blank = blank + " ";321System.out.println(blank + err.getClass() + "==>" +322err.getMessage());323if (withStack) {324err.printStackTrace(System.out);325}326try {327target = err.getClass().getMethod("getTargetError",328(java.lang.Class<?>[]) null);329} catch (Exception ee) {330// OK: getTargetError method could be there or not331}332} else {333target = null;334}335} catch (Exception ee) {336target = null;337}338}339} else {340System.out.println("Throwable is : " + theThro);341}342} catch (Throwable x) {343System.out.println("Exception : raised in printException : " + x);344}345}346347/**348* Wait up to maxTimeInSeconds second(s) the given JMX connector server349* comes up (which means isActive returns true).350* If it fails to do so we throw a RunTime exception.351*/352static void waitReady(JMXConnectorServerMBean server,353int maxTimeInSeconds) throws Exception {354int elapsed = 0;355356while (!server.isActive() && elapsed < maxTimeInSeconds) {357Thread.sleep(1000);358elapsed++;359}360361if (server.isActive()) {362String message = "Utils::waitReady: JMX connector server came up";363if ( elapsed == 0) {364message += " immediately";365} else {366message += " after " + elapsed + " seconds";367}368message += " [" + server.getAddress() + "]";369Utils.debug(DEBUG_STANDARD, message);370} else {371String message = "Utils::waitReady: (ERROR) JMX connector" +372" server didn't come up after " + elapsed + " seconds [" +373server.getAddress() + "]";374System.out.println(message);375throw new RuntimeException(message);376}377}378379/**380* This method is used to compare the specified Throwable and possibly381* the derived causes to the specified String argument.382* The expected String argument format is :383* throwable_1;throwable_2;...;throwable_N384* where throwable_i can be :385* - either a throwable class name386* - or the "*" character meaning several unknown throwable class names387* This character must be followed by a throwable class name388*/389static boolean compareThrowable(390Throwable t,391String expectedThrowable) {392393// First parse the expectedThrowable String394StringTokenizer tokenizer = new StringTokenizer(expectedThrowable, ";");395String token = null;396397try {398while (tokenizer.hasMoreTokens()) {399token = tokenizer.nextToken();400if (!token.equals("*")) {401if (!Class.forName(token).isInstance(t)) {402return false;403}404} else {405token = tokenizer.nextToken();406while (!Class.forName(token).isInstance(t)) {407t = t.getCause();408if (t == null) {409return false;410}411}412}413t = t.getCause();414}415} catch (ClassNotFoundException cnfe) {416String msg = "Expected throwable class(es) " + expectedThrowable +417" cannot be located";418System.out.println(msg);419throw new IllegalArgumentException(msg);420}421return true;422}423}424425426