1 /* 2 * Copyright (c) 2015, 2018, 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 /** 25 * @test 26 * @summary Basic test for jhsdb launcher 27 * @library /test/lib 28 * @requires vm.hasSAandCanAttach 29 * @build jdk.test.lib.apps.* 30 * @run main BasicLauncherTest 31 */ 32 33 import java.io.BufferedReader; 34 import java.io.IOException; 35 import java.io.OutputStream; 36 import java.io.InputStreamReader; 37 import java.util.ArrayList; 38 import java.util.List; 39 import java.util.Arrays; 40 import java.util.Optional; 41 import jdk.test.lib.process.OutputAnalyzer; 42 import jdk.test.lib.process.ProcessTools; 43 import jdk.test.lib.apps.LingeredApp; 44 import jdk.test.lib.Platform; 45 import jdk.test.lib.JDKToolLauncher; 46 import jdk.test.lib.Utils; 47 48 public class BasicLauncherTest { 49 50 private static LingeredApp theApp = null; 51 private static boolean useJavaLauncher = false; 52 53 private static JDKToolLauncher createSALauncher() { 54 JDKToolLauncher launcher = null; 55 if (useJavaLauncher) { 56 // Use java launcher if we need to pass additional parameters to VM 57 // for debugging purpose 58 // e.g. -Xlog:class+load=info:file=/tmp/BasicLauncherTest.log 59 launcher = JDKToolLauncher.createUsingTestJDK("java"); 60 launcher.addToolArg("sun.jvm.hotspot.SALauncher"); 61 } 62 else { 63 launcher = JDKToolLauncher.createUsingTestJDK("jhsdb"); 64 } 65 66 return launcher; 67 } 68 69 public static void launchCLHSDB() 70 throws IOException { 71 72 System.out.println("Starting LingeredApp"); 73 try { 74 theApp = LingeredApp.startApp(); 75 76 System.out.println("Starting clhsdb against " + theApp.getPid()); 77 JDKToolLauncher launcher = createSALauncher(); 78 launcher.addToolArg("clhsdb"); 79 launcher.addToolArg("--pid=" + Long.toString(theApp.getPid())); 80 81 ProcessBuilder processBuilder = new ProcessBuilder(launcher.getCommand()); 82 processBuilder.redirectError(ProcessBuilder.Redirect.INHERIT); 83 Process toolProcess = processBuilder.start(); 84 85 try (OutputStream out = toolProcess.getOutputStream()) { 86 out.write("universe\n".getBytes()); 87 out.write("quit\n".getBytes()); 88 } 89 90 // By default child process output stream redirected to pipe, so we are reading it in foreground. 91 Exception unexpected = null; 92 try (BufferedReader reader = 93 new BufferedReader(new InputStreamReader(toolProcess.getInputStream()))) { 94 String line; 95 96 while ((line = reader.readLine()) != null) { 97 line = line.trim(); 98 System.out.println(line); 99 100 if (line.contains("unknown subtype of CollectedHeap")) { 101 unexpected = new RuntimeException("CollectedHeap type should be known."); 102 break; 103 } 104 } 105 } 106 107 toolProcess.waitFor(); 108 109 if (toolProcess.exitValue() != 0) { 110 throw new RuntimeException("FAILED CLHSDB terminated with non-zero exit code " + toolProcess.exitValue()); 111 } 112 113 if (unexpected != null) { 114 throw unexpected; 115 } 116 117 } catch (Exception ex) { 118 throw new RuntimeException("Test ERROR " + ex, ex); 119 } finally { 120 LingeredApp.stopApp(theApp); 121 } 122 } 123 124 public static void launchJStack() throws IOException { 125 126 if (Platform.isOSX()) { 127 // Coredump stackwalking is not implemented for Darwin 128 System.out.println("This test is not expected to work on OS X. Skipping"); 129 return; 130 } 131 132 System.out.println("Starting LingeredApp"); 133 try { 134 theApp = LingeredApp.startApp(Arrays.asList("-Xmx256m")); 135 136 System.out.println("Starting jstack against " + theApp.getPid()); 137 JDKToolLauncher launcher = createSALauncher(); 138 139 launcher.addToolArg("jstack"); 140 launcher.addToolArg("--pid=" + Long.toString(theApp.getPid())); 141 142 ProcessBuilder processBuilder = new ProcessBuilder(launcher.getCommand()); 143 OutputAnalyzer output = ProcessTools.executeProcess(processBuilder);; 144 output.shouldContain("No deadlocks found"); 145 output.shouldNotContain("illegal bci"); 146 output.shouldNotContain("AssertionFailure"); 147 output.shouldHaveExitValue(0); 148 149 } catch (Exception ex) { 150 throw new RuntimeException("Test ERROR " + ex, ex); 151 } finally { 152 LingeredApp.stopApp(theApp); 153 } 154 } 155 156 /** 157 * 158 * @param vmArgs - vm and java arguments to launch test app 159 * @return exit code of tool 160 */ 161 public static void launch(String expectedMessage, 162 Optional<String> unexpectedMessage, List<String> toolArgs) 163 throws IOException { 164 165 System.out.println("Starting LingeredApp"); 166 try { 167 theApp = LingeredApp.startApp(Arrays.asList("-Xmx256m")); 168 169 System.out.println("Starting " + toolArgs.get(0) + " against " + theApp.getPid()); 170 JDKToolLauncher launcher = createSALauncher(); 171 172 for (String cmd : toolArgs) { 173 launcher.addToolArg(cmd); 174 } 175 176 launcher.addToolArg("--pid=" + Long.toString(theApp.getPid())); 177 178 ProcessBuilder processBuilder = new ProcessBuilder(launcher.getCommand()); 179 processBuilder.redirectError(ProcessBuilder.Redirect.INHERIT); 180 OutputAnalyzer output = ProcessTools.executeProcess(processBuilder);; 181 output.shouldContain(expectedMessage); 182 unexpectedMessage.ifPresent(output::shouldNotContain); 183 output.shouldHaveExitValue(0); 184 185 } catch (Exception ex) { 186 throw new RuntimeException("Test ERROR " + ex, ex); 187 } finally { 188 LingeredApp.stopApp(theApp); 189 } 190 } 191 192 public static void launch(String expectedMessage, 193 String unexpectedMessage, String... toolArgs) 194 throws IOException { 195 196 launch(expectedMessage, Optional.ofNullable(unexpectedMessage), 197 Arrays.asList(toolArgs)); 198 } 199 200 public static void main(String[] args) throws Exception { 201 202 launchCLHSDB(); 203 204 launch("compiler detected", null, "jmap", "--clstats"); 205 launchJStack(); 206 launch("compiler detected", null, "jmap"); 207 launch("Java System Properties", 208 "System Properties info not available", "jinfo"); 209 launch("java.threads", null, "jsnap"); 210 211 // The test throws RuntimeException on error. 212 // IOException is thrown if LingeredApp can't start because of some bad 213 // environment condition 214 System.out.println("Test PASSED"); 215 } 216 }