1 /* 2 * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24 import java.io.File; 25 import java.io.IOException; 26 import java.lang.reflect.Method; 27 import java.lang.reflect.Modifier; 28 import java.nio.file.FileSystem; 29 import java.nio.file.FileSystems; 30 import java.nio.file.Files; 31 import java.nio.file.Path; 32 import java.util.ArrayList; 33 import java.util.List; 34 import java.util.concurrent.TimeUnit; 35 import java.util.concurrent.atomic.AtomicReference; 36 37 /** 38 * @test 39 * @library /lib/testlibrary 40 * @bug 5016507 6173612 6319776 6342019 6484550 8004926 41 * @summary Start a managed VM and test that a management tool can connect 42 * without connection or username/password details. 43 * TestManager will attempt a connection to the address obtained from 44 * both agent properties and jvmstat buffer. 45 * @build jdk.testlibrary.* TestManager TestApplication 46 * @run main/othervm/timeout=300 -XX:+UsePerfData LocalManagementTest 47 */ 48 49 import jdk.testlibrary.ProcessTools; 50 import jdk.testlibrary.Utils; 51 52 public class LocalManagementTest { 53 private static final String TEST_CLASSPATH = System.getProperty("test.class.path"); 54 private static final String TEST_JDK = System.getProperty("test.jdk"); 55 private static int MAX_GET_FREE_PORT_TRIES = 10; 56 57 public static void main(String[] args) throws Exception { 58 try { 59 MAX_GET_FREE_PORT_TRIES = Integer.parseInt(System.getProperty("test.getfreeport.max.tries", "10")); 60 } catch (NumberFormatException ex) { 61 } 62 63 int failures = 0; 64 for(Method m : LocalManagementTest.class.getDeclaredMethods()) { 65 if (Modifier.isStatic(m.getModifiers()) && 66 m.getName().startsWith("test")) { 67 m.setAccessible(true); 68 try { 69 System.out.println(m.getName()); 70 System.out.println("=========="); 71 Boolean rslt = (Boolean)m.invoke(null); 72 if (!rslt) { 73 System.err.println(m.getName() + " failed"); 74 failures++; 75 } 76 } catch (Exception e) { 77 e.printStackTrace(); 78 failures++; 79 } 80 } 81 } 82 if (failures > 0) { 83 throw new Error("Test failed"); 84 } 85 } 86 87 private static boolean test1() throws Exception { 88 return doTest("1", "-Dcom.sun.management.jmxremote"); 89 } 90 91 private static boolean test2() throws Exception { 92 Path agentPath = findAgent(); 93 if (agentPath != null) { 94 String agent = agentPath.toString(); 95 return doTest("2", "-javaagent:" + agent); 96 } else { 97 return false; 98 } 99 } 100 101 /** 102 * no args (blank) - manager should attach and start agent 103 */ 104 private static boolean test3() throws Exception { 105 return doTest("3", null); 106 } 107 108 /** 109 * sanity check arguments to management-agent.jar 110 */ 111 private static boolean test4() throws Exception { 112 Path agentPath = findAgent(); 113 if (agentPath != null) { 114 115 for (int i = 0; i < MAX_GET_FREE_PORT_TRIES; ++i) { 116 ProcessBuilder builder = ProcessTools.createJavaProcessBuilder( 117 "-javaagent:" + agentPath.toString() + 118 "=com.sun.management.jmxremote.port=" + Utils.getFreePort() + "," + 119 "com.sun.management.jmxremote.authenticate=false," + 120 "com.sun.management.jmxremote.ssl=false", 121 "-cp", 122 TEST_CLASSPATH, 123 "TestApplication", 124 "-exit" 125 ); 126 127 Process prc = null; 128 final AtomicReference<Boolean> isBindExceptionThrown = new AtomicReference<>(); 129 isBindExceptionThrown.set(new Boolean(false)); 130 try { 131 prc = ProcessTools.startProcess( 132 "TestApplication", 133 builder, 134 (String line) -> { 135 if (line.contains("Exception thrown by the agent : " + 136 "java.rmi.server.ExportException: Port already in use")) { 137 isBindExceptionThrown.set(new Boolean(true)); 138 } 139 }); 140 141 prc.waitFor(); 142 143 if (prc.exitValue() == 0) { 144 return true; 145 } 146 147 if (isBindExceptionThrown.get().booleanValue()) { 148 System.out.println("'Port already in use' error detected. Try again"); 149 } else { 150 return false; 151 } 152 } finally { 153 if (prc != null) { 154 prc.destroy(); 155 prc.waitFor(); 156 } 157 } 158 } 159 } 160 return false; 161 } 162 163 /** 164 * use DNS-only name service 165 */ 166 private static boolean test5() throws Exception { 167 return doTest("5", "-Dsun.net.spi.namservice.provider.1=\"dns,sun\""); 168 } 169 170 private static Path findAgent() { 171 FileSystem FS = FileSystems.getDefault(); 172 Path agentPath = FS.getPath( 173 TEST_JDK, "jre", "lib", "management-agent.jar" 174 ); 175 if (!isFileOk(agentPath)) { 176 agentPath = FS.getPath( 177 TEST_JDK, "lib", "management-agent.jar" 178 ); 179 } 180 if (!isFileOk(agentPath)) { 181 System.err.println("Can not locate management-agent.jar"); 182 return null; 183 } 184 return agentPath; 185 } 186 187 private static boolean isFileOk(Path path) { 188 return Files.isRegularFile(path) && Files.isReadable(path); 189 } 190 191 private static boolean doTest(String testId, String arg) throws Exception { 192 List<String> args = new ArrayList<>(); 193 args.add("-cp"); 194 args.add(TEST_CLASSPATH); 195 196 if (arg != null) { 197 args.add(arg); 198 } 199 args.add("TestApplication"); 200 ProcessBuilder server = ProcessTools.createJavaProcessBuilder( 201 args.toArray(new String[args.size()]) 202 ); 203 204 Process serverPrc = null, clientPrc = null; 205 try { 206 final AtomicReference<String> port = new AtomicReference<>(); 207 final AtomicReference<String> pid = new AtomicReference<>(); 208 209 serverPrc = ProcessTools.startProcess( 210 "TestApplication(" + testId + ")", 211 server, 212 (String line) -> { 213 if (line.startsWith("port:")) { 214 port.set(line.split("\\:")[1]); 215 } else if (line.startsWith("pid:")) { 216 pid.set(line.split("\\:")[1]); 217 } else if (line.startsWith("waiting")) { 218 return true; 219 } 220 return false; 221 }, 222 5, 223 TimeUnit.SECONDS 224 ); 225 226 System.out.println("Attaching test manager:"); 227 System.out.println("========================="); 228 System.out.println(" PID : " + pid.get()); 229 System.out.println(" shutdown port : " + port.get()); 230 231 ProcessBuilder client = ProcessTools.createJavaProcessBuilder( 232 "-cp", 233 TEST_CLASSPATH + 234 File.pathSeparator + 235 TEST_JDK + 236 File.separator + 237 "lib" + 238 File.separator + 239 "tools.jar", 240 "TestManager", 241 pid.get(), 242 port.get(), 243 "true" 244 ); 245 246 clientPrc = ProcessTools.startProcess( 247 "TestManager", 248 client, 249 (String line) -> line.startsWith("Starting TestManager for PID"), 250 10, 251 TimeUnit.SECONDS 252 ); 253 254 int clientExitCode = clientPrc.waitFor(); 255 int serverExitCode = serverPrc.waitFor(); 256 return clientExitCode == 0 && serverExitCode == 0; 257 } finally { 258 if (clientPrc != null) { 259 System.out.println("Stopping process " + clientPrc); 260 clientPrc.destroy(); 261 clientPrc.waitFor(); 262 } 263 if (serverPrc != null) { 264 System.out.println("Stopping process " + serverPrc); 265 serverPrc.destroy(); 266 serverPrc.waitFor(); 267 } 268 } 269 } 270 }