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