Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/test/sun/management/jmxremote/startstop/JMXStartStopTest.java
38867 views
/*1* Copyright (c) 2012, 2014, 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.io.File;24import java.io.IOException;25import java.lang.reflect.Method;26import java.net.ConnectException;27import java.net.ServerSocket;28import java.rmi.NoSuchObjectException;29import java.rmi.registry.LocateRegistry;30import java.rmi.registry.Registry;31import java.util.ArrayList;32import java.util.Arrays;33import java.util.Iterator;34import java.util.List;35import java.util.Objects;36import java.util.Set;37import java.util.concurrent.TimeUnit;38import java.util.concurrent.TimeoutException;39import java.util.concurrent.atomic.AtomicBoolean;40import java.util.function.Consumer;4142import javax.management.*;43import javax.management.remote.*;44import javax.net.ssl.SSLHandshakeException;4546import jdk.testlibrary.ProcessTools;47import jdk.testlibrary.JDKToolLauncher;4849/**50* @test51* @bug 711010452* @library /lib/testlibrary53* @build jdk.testlibrary.* JMXStartStopTest JMXStartStopDoSomething54* @run main/othervm JMXStartStopTest55* @summary Makes sure that enabling/disabling the management agent through56* JCMD achieves the desired results57* @key randomness58*/59public class JMXStartStopTest {60private static final String TEST_SRC = System.getProperty("test.src");6162private static final boolean verbose = false;6364private static void dbg_print(String msg){65if (verbose) {66System.out.println("DBG: " +msg);67}68}6970private static int listMBeans(MBeanServerConnection server,71ObjectName pattern,72QueryExp query)73throws Exception {7475Set<ObjectName> names = server.queryNames(pattern,query);76for (Iterator<ObjectName> i = names.iterator(); i.hasNext(); ) {77ObjectName name = (ObjectName)i.next();78MBeanInfo info = server.getMBeanInfo(name);79dbg_print("Got MBean: " + name);8081MBeanAttributeInfo[] attrs = info.getAttributes();82if (attrs == null)83continue;84for (MBeanAttributeInfo attr : attrs) {85if (attr.isReadable()) {86server.getAttribute(name, attr.getName());87}88}89}90return names.size();91}929394private static void testConnectLocal(int pid)95throws Exception {9697String jmxUrlStr = null;9899try {100jmxUrlStr = sun.management.ConnectorAddressLink.importFrom(pid);101dbg_print("Local Service URL: " +jmxUrlStr);102if ( jmxUrlStr == null ) {103throw new Exception("No Service URL. Local agent not started?");104}105106JMXServiceURL url = new JMXServiceURL(jmxUrlStr);107108JMXConnector c = JMXConnectorFactory.connect(url, null);109110MBeanServerConnection conn = c.getMBeanServerConnection();111ObjectName pattern = new ObjectName("java.lang:type=Memory,*");112113int count = listMBeans(conn,pattern,null);114if (count == 0)115throw new Exception("Expected at least one matching "+116"MBean for "+pattern);117118} catch (IOException e) {119dbg_print("Cannot find process : " + pid);120throw e;121}122}123124private static void testNoConnect(int port) throws Exception {125testNoConnect(port, 0);126}127128private static void testNoConnect(int port, int rmiPort) throws Exception {129try {130testConnect(port, rmiPort);131throw new Exception("Didn't expect the management agent running");132} catch (Exception e) {133Throwable t = e;134while (t != null) {135if (t instanceof NoSuchObjectException ||136t instanceof ConnectException ||137t instanceof SSLHandshakeException) {138break;139}140t = t.getCause();141}142if (t == null) {143throw new Exception("Unexpected exception", e);144}145}146}147148private static void testConnect(int port) throws Exception {149testConnect(port, 0);150}151152private static void testConnect(int port, int rmiPort) throws Exception {153154dbg_print("RmiRegistry lookup...");155156dbg_print("Using port: " + port);157158dbg_print("Using rmi port: " + rmiPort);159160Registry registry = LocateRegistry.getRegistry(port);161162// "jmxrmi"163String[] relist = registry.list();164for (int i = 0; i < relist.length; ++i) {165dbg_print("Got registry: " + relist[i]);166}167168String jmxUrlStr = (rmiPort != 0) ?169String.format(170"service:jmx:rmi://localhost:%d/jndi/rmi://localhost:%d/jmxrmi",171rmiPort,172port) :173String.format(174"service:jmx:rmi:///jndi/rmi://localhost:%d/jmxrmi",175port);176177JMXServiceURL url = new JMXServiceURL(jmxUrlStr);178179JMXConnector c = JMXConnectorFactory.connect(url, null);180181MBeanServerConnection conn = c.getMBeanServerConnection();182ObjectName pattern = new ObjectName("java.lang:type=Memory,*");183184int count = listMBeans(conn,pattern,null);185if (count == 0)186throw new Exception("Expected at least one matching " +187"MBean for " + pattern);188}189190private static class Failure {191private final Throwable cause;192private final String msg;193194public Failure(Throwable cause, String msg) {195this.cause = cause;196this.msg = msg;197}198199public Failure(String msg) {200this(null, msg);201}202203public Throwable getCause() {204return cause;205}206207public String getMsg() {208return msg;209}210211@Override212public int hashCode() {213int hash = 7;214hash = 97 * hash + Objects.hashCode(this.cause);215hash = 97 * hash + Objects.hashCode(this.msg);216return hash;217}218219@Override220public boolean equals(Object obj) {221if (obj == null) {222return false;223}224if (getClass() != obj.getClass()) {225return false;226}227final Failure other = (Failure) obj;228if (!Objects.equals(this.cause, other.cause)) {229return false;230}231if (!Objects.equals(this.msg, other.msg)) {232return false;233}234return true;235}236237@Override238public String toString() {239if (cause != null) {240return msg + "\n" + cause;241} else {242return msg;243}244}245}246247private static List<Failure> failures = new ArrayList<>();248249public static void main(String args[]) throws Exception {250for (Method m : JMXStartStopTest.class.getDeclaredMethods()) {251if (m.getName().startsWith("test_")) {252try {253m.invoke(null);254System.out.println("=== PASSED\n");255} catch (Throwable e) {256failures.add(new Failure(e, m.getName() + " failed"));257}258}259}260261if (!failures.isEmpty()) {262for(Failure f : failures) {263System.err.println(f.getMsg());264f.getCause().printStackTrace(System.err);265}266throw new Error();267}268}269270private static class Something {271private Process p;272private final ProcessBuilder pb;273private final String name;274private final AtomicBoolean started = new AtomicBoolean(false);275private volatile int pid = -1;276277public Something(ProcessBuilder pb, String name) {278this.pb = pb;279this.name = name;280}281282public synchronized void start() throws InterruptedException, IOException, TimeoutException {283if (started.compareAndSet(false, true)) {284try {285p = ProcessTools.startProcess(286"JMXStartStopDoSomething",287pb,288(line) -> {289if (line.toLowerCase().startsWith("pid:")) {290pid = Integer.parseInt(line.split("\\:")[1]);291}292return line.equals("main enter");293},2945,295TimeUnit.SECONDS296);297} catch (TimeoutException e) {298p.destroy();299p.waitFor();300throw e;301}302}303}304305public int getPid() {306return pid;307}308309public synchronized void stop()310throws IOException, InterruptedException {311if (started.compareAndSet(true, false)) {312p.getOutputStream().write(0);313p.getOutputStream().flush();314int ec = p.waitFor();315if (ec != 0) {316StringBuilder msg = new StringBuilder();317msg.append("Test application '").append(name);318msg.append("' failed with exit code: ");319msg.append(ec);320321failures.add(new Failure(msg.toString()));322}323}324}325}326327/**328* Runs the test application "JMXStartStopDoSomething"329* @param name Test run name330* @param args Additional arguments331* @return Returns a {@linkplain Something} instance representing the run332* @throws IOException333* @throws InterruptedException334* @throws TimeoutException335*/336private static Something doSomething(String name, String ... args)337throws Exception {338List<String> pbArgs = new ArrayList<>(Arrays.asList(339"-cp",340System.getProperty("test.class.path")341));342pbArgs.addAll(Arrays.asList(args));343pbArgs.add("JMXStartStopDoSomething");344345ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(346pbArgs.toArray(new String[pbArgs.size()])347);348Something s = new Something(pb, name);349s.start();350return s;351}352353/**354* Run the "jcmd" command355*356* @param command Command with parameters; space separated string357* @throws IOException358* @throws InterruptedException359*/360private static void jcmd(String ... command) throws IOException, InterruptedException {361if (command.length == 0) {362jcmd(null, (Consumer<String>)null);363} else {364jcmd(null, command);365}366}367368/**369* Run the "jcmd" command370*371* @param c {@linkplain Consumer} instance; may be null372* @param command Command with parameters; space separated string373* @throws IOException374* @throws InterruptedException375*/376private static void jcmd(Consumer<String> c, String ... command) throws IOException, InterruptedException {377jcmd("JMXStartStopDoSomething", c, command);378}379380/**381* Run the "jcmd" command382* @param target The target application name (or PID)383* @param c {@linkplain Consumer} instance; may be null384* @param command Command with parameters; space separated string385* @throws IOException386* @throws InterruptedException387*/388private static void jcmd(String target, final Consumer<String> c, String ... command) throws IOException, InterruptedException {389dbg_print("[jcmd] " + (command.length > 0 ? command[0] : "list"));390391JDKToolLauncher l = JDKToolLauncher.createUsingTestJDK("jcmd");392l.addToolArg(target);393for(String cmd : command) {394l.addToolArg(cmd);395}396Process p = ProcessTools.startProcess(397"jcmd",398new ProcessBuilder(l.getCommand()),399c400);401402p.waitFor();403dbg_print("[jcmd] --------");404}405406private static final String CMD_STOP = "ManagementAgent.stop";407private static final String CMD_START= "ManagementAgent.start";408private static final String CMD_START_LOCAL = "ManagementAgent.start_local";409private static final int port1 = 50234;410private static final int port2 = 50235;411412static void test_01() throws Exception {413// Run an app with JMX enabled stop it and414// restart on other port415416System.out.println("**** Test one ****");417418Something s = doSomething(419"test_01",420"-Dcom.sun.management.jmxremote.port=" + port1,421"-Dcom.sun.management.jmxremote.authenticate=false",422"-Dcom.sun.management.jmxremote.ssl=false");423424try {425testConnect(port1);426427jcmd(CMD_STOP);428testNoConnect(port1);429430jcmd(CMD_START, "jmxremote.port=" + port2);431testConnect(port2);432} finally {433s.stop();434}435}436437static void test_02() throws Exception {438// Run an app without JMX enabled439// start JMX by jcmd440441System.out.println("**** Test two ****");442443Something s = doSomething("test_02");444try {445jcmd(CMD_START,446"jmxremote.port=" + port1,447"jmxremote.authenticate=false",448"jmxremote.ssl=false");449450testConnect(port1);451} finally {452s.stop();453}454}455456static void test_03() throws Exception {457// Run an app without JMX enabled458// start JMX by jcmd on one port than on other one459460System.out.println("**** Test three ****");461462Something s = doSomething("test_03");463try {464jcmd(CMD_START,465"jmxremote.port=" + port1,466"jmxremote.authenticate=false",467"jmxremote.ssl=false");468469// Second agent shouldn't start470jcmd(CMD_START,471"jmxremote.port=" + port2,472"jmxremote.authenticate=false",473"jmxremote.ssl=false");474475// First agent should connect476testConnect(port1);477478// Second agent should not connect479testNoConnect(port2);480} finally {481s.stop();482}483}484485static void test_04() throws Exception {486// Run an app without JMX enabled487// start JMX by jcmd on one port, specify rmi port explicitly488489System.out.println("**** Test four ****");490491Something s = doSomething("test_04");492493try {494jcmd(CMD_START,495"jmxremote.port=" + port1,496"jmxremote.rmi.port=" + port2,497"jmxremote.authenticate=false",498"jmxremote.ssl=false");499500testConnect(port1, port2);501} finally {502s.stop();503}504}505506static void test_05() throws Exception {507// Run an app without JMX enabled, it will enable local server508// but should leave remote server disabled509510System.out.println("**** Test five ****");511512Something s = doSomething("test_05");513try {514jcmd(CMD_START_LOCAL);515516testNoConnect(port1);517testConnectLocal(s.getPid());518} finally {519s.stop();520}521}522523static void test_06() throws Exception {524// Run an app without JMX enabled525// start JMX by jcmd on one port, specify rmi port explicitly526// attempt to start it again527// 1) with the same port528// 2) with other port529// 3) attempt to stop it twice530// Check for valid messages in the output531532System.out.println("**** Test six ****");533534Something s = doSomething("test_06");535536try {537jcmd(CMD_START,538"jmxremote.port=" + port1,539"jmxremote.authenticate=false",540"jmxremote.ssl=false");541542testConnect(port1, port2);543544final boolean[] checks = new boolean[3];545jcmd(546line -> {547if (line.contains("java.lang.RuntimeException: Invalid agent state")) {548checks[0] = true;549}550},551CMD_START,552"jmxremote.port=" + port1,553"jmxremote.authenticate=false",554"jmxremote.ssl=false");555556jcmd(557line -> {558if (line.contains("java.lang.RuntimeException: Invalid agent state")) {559checks[1] = true;560}561},562CMD_START,563"jmxremote.port=" + port2,564"jmxremote.authenticate=false",565"jmxremote.ssl=false");566567jcmd(CMD_STOP);568jcmd(CMD_STOP);569570ServerSocket ss = new ServerSocket(0);571572jcmd(573line -> {574if (line.contains("Port already in use: " + ss.getLocalPort())) {575checks[2] = true;576}577},578CMD_START,579"jmxremote.port=" + ss.getLocalPort(),580"jmxremote.rmi.port=" + port2,581"jmxremote.authenticate=false",582"jmxremote.ssl=false");583if (!checks[0]) {584throw new Exception("Starting agent on port " + port1 + " should " +585"report an invalid agent state");586}587if (!checks[1]) {588throw new Exception("Starting agent on poprt " + port2 + " should " +589"report an invalid agent state");590}591if (!checks[2]) {592throw new Exception("Starting agent on port " + ss.getLocalPort() + " should " +593"report port in use");594}595} finally {596s.stop();597}598}599600private static void test_07() throws Exception {601// Run an app without JMX enabled, but with some properties set602// in command line.603// make sure these properties overridden corectly604605System.out.println("**** Test seven ****");606607Something s = doSomething(608"test_07",609"-Dcom.sun.management.jmxremote.authenticate=false",610"-Dcom.sun.management.jmxremote.ssl=true");611612try {613testNoConnect(port1);614jcmd(615CMD_START,616"jmxremote.port=" + port2,617"jmxremote.authenticate=false",618"jmxremote.ssl=false"619);620testConnect(port2);621} finally {622s.stop();623}624}625626static void test_08() throws Exception {627// Run an app with JMX enabled and with some properties set628// in command line.629// stop JMX agent and then start it again with different property values630// make sure these properties overridden corectly631632System.out.println("**** Test eight ****");633634Something s = doSomething(635"test_08",636"-Dcom.sun.management.jmxremote.port=" + port1,637"-Dcom.sun.management.jmxremote.authenticate=false",638"-Dcom.sun.management.jmxremote.ssl=true");639640try {641testNoConnect(port1);642643jcmd(CMD_STOP);644645testNoConnect(port1);646647jcmd(648CMD_START,649"jmxremote.port=" + port2,650"jmxremote.authenticate=false",651"jmxremote.ssl=false"652);653654testConnect(port2);655} finally {656s.stop();657}658}659660static void test_09() throws Exception {661// Run an app with JMX enabled and with some properties set662// in command line.663// stop JMX agent and then start it again with different property values664// specifing some property in management config file and some of them665// in command line666// make sure these properties overridden corectly667668System.out.println("**** Test nine ****");669670Something s = doSomething("test_09",671"-Dcom.sun.management.config.file=" +672TEST_SRC + File.separator + "management_cl.properties",673"-Dcom.sun.management.jmxremote.authenticate=false"674);675676try {677testNoConnect(port1);678679jcmd(CMD_STOP);680681testNoConnect(port1);682683jcmd(CMD_START,684"config.file=" + TEST_SRC + File.separator +685"management_jcmd.properties",686"jmxremote.authenticate=false",687"jmxremote.port=" + port2688);689690testConnect(port2);691} finally {692s.stop();693}694}695696static void test_10() throws Exception {697// Run an app with JMX enabled and with some properties set698// in command line.699// stop JMX agent and then start it again with different property values700// stop JMX agent again and then start it without property value701// make sure these properties overridden corectly702703System.out.println("**** Test ten ****");704705Something s = doSomething(706"test_10",707"-Dcom.sun.management.jmxremote.port=" + port1,708"-Dcom.sun.management.jmxremote.authenticate=false",709"-Dcom.sun.management.jmxremote.ssl=true");710711try {712testNoConnect(port1);713714jcmd(CMD_STOP);715jcmd(CMD_START,716"jmxremote.ssl=false",717"jmxremote.port=" + port1718);719testConnect(port1);720721jcmd(CMD_STOP);722jcmd(CMD_START,723"jmxremote.port=" + port1724);725726testNoConnect(port1);727} finally {728s.stop();729}730}731732static void test_11() throws Exception {733// Run an app with JMX enabled734// stop remote agent735// make sure local agent is not affected736737System.out.println("**** Test eleven ****");738739Something s = doSomething(740"test_11",741"-Dcom.sun.management.jmxremote.port=" + port1,742"-Dcom.sun.management.jmxremote.authenticate=false",743"-Dcom.sun.management.jmxremote.ssl=false");744try {745testConnect(port1);746jcmd(CMD_STOP);747testConnectLocal(s.getPid());748} finally {749s.stop();750}751}752753static void test_12() throws Exception {754// Run an app with JMX disabled755// start local agent only756757System.out.println("**** Test twelve ****");758759Something s = doSomething("test_12");760761try {762testNoConnect(port1);763jcmd(CMD_START + "_local");764765testConnectLocal(s.getPid());766767} finally {768s.stop();769}770}771}772773774