8059038: Create new launcher for SA tools
Summary: Proivide jhsdb command to launch sa based tools
Reviewed-by: sspitsyn, jbachorik
--- a/jdk/make/launcher/Launcher-jdk.hotspot.agent.gmk Tue Jul 21 20:37:19 2015 +0200
+++ b/jdk/make/launcher/Launcher-jdk.hotspot.agent.gmk Thu Jul 23 18:17:02 2015 +0300
@@ -27,6 +27,10 @@
$(eval $(call SetupLauncher,jsadebugd, \
-DJAVA_ARGS='{ "-J-ms8m"$(COMMA) "sun.jvm.hotspot.jdi.SADebugServer"$(COMMA) }' \
- -DAPP_CLASSPATH='{ "/lib/tools.jar"$(COMMA) "/lib/sa-jdi.jar"$(COMMA) "/classes" }' \
,,,,,,,,,Info-privileged.plist))
+
+$(eval $(call SetupLauncher,jhsdb, \
+ -DJAVA_ARGS='{ "-J-ms8m"$(COMMA) "sun.jvm.hotspot.SALauncher"$(COMMA) }' \
+ ,,,,,,,,,Info-privileged.plist))
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/tools/jhsdb/BasicLauncherTest.java Thu Jul 23 18:17:02 2015 +0300
@@ -0,0 +1,145 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @summary Basic test for jhsdb launcher
+ * @library /../../test/lib/share/classes
+ * @library /lib/testlibrary
+ * @build jdk.testlibrary.*
+ * @build jdk.test.lib.apps.*
+ * @run main BasicLauncherTest
+ */
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Arrays;
+import jdk.testlibrary.JDKToolLauncher;
+import jdk.testlibrary.Utils;
+import jdk.testlibrary.OutputAnalyzer;
+import jdk.testlibrary.ProcessTools;
+import jdk.test.lib.apps.LingeredApp;
+
+public class BasicLauncherTest {
+
+ private final static String toolName = "jhsdb";
+ private static LingeredApp theApp = null;
+
+ /**
+ *
+ * @return exit code of tool
+ */
+ public static int launchCLHSDB()
+ throws IOException {
+
+ System.out.println("Starting LingeredApp");
+ try {
+ theApp = LingeredApp.startApp();
+
+ System.out.println("Starting clhsdb against " + theApp.getPid());
+ JDKToolLauncher launcher = JDKToolLauncher.createUsingTestJDK(toolName);
+ launcher.addToolArg("clhsdb");
+ launcher.addToolArg("--pid=" + Long.toString(theApp.getPid()));
+
+ ProcessBuilder processBuilder = new ProcessBuilder(launcher.getCommand());
+ processBuilder.redirectError(ProcessBuilder.Redirect.INHERIT);
+ Process toolProcess = processBuilder.start();
+ toolProcess.getOutputStream().write("quit\n".getBytes());
+ toolProcess.getOutputStream().close();
+
+ // By default child process output stream redirected to pipe, so we are reading it in foreground.
+ BufferedReader reader = new BufferedReader(new InputStreamReader(toolProcess.getInputStream()));
+
+ String line;
+ while ((line = reader.readLine()) != null) {
+ System.out.println(line.trim());
+ }
+
+ toolProcess.waitFor();
+
+ return toolProcess.exitValue();
+ } catch (Exception ex) {
+ throw new RuntimeException("Test ERROR " + ex, ex);
+ } finally {
+ LingeredApp.stopApp(theApp);
+ }
+ }
+
+ /**
+ *
+ * @param vmArgs - vm and java arguments to launch test app
+ * @return exit code of tool
+ */
+ public static void launch(String expectedMessage, List<String> toolArgs)
+ throws IOException {
+
+ System.out.println("Starting LingeredApp");
+ try {
+ theApp = LingeredApp.startApp();
+
+ System.out.println("Starting " + toolName + " " + toolArgs.get(0) + " against " + theApp.getPid());
+ JDKToolLauncher launcher = JDKToolLauncher.createUsingTestJDK(toolName);
+
+ for (String cmd : toolArgs) {
+ launcher.addToolArg(cmd);
+ }
+
+ launcher.addToolArg("--pid=" + Long.toString(theApp.getPid()));
+
+ ProcessBuilder processBuilder = new ProcessBuilder(launcher.getCommand());
+ processBuilder.redirectError(ProcessBuilder.Redirect.INHERIT);
+ OutputAnalyzer output = ProcessTools.executeProcess(processBuilder);;
+ output.shouldContain(expectedMessage);
+ output.shouldHaveExitValue(0);
+
+ } catch (Exception ex) {
+ throw new RuntimeException("Test ERROR " + ex, ex);
+ } finally {
+ LingeredApp.stopApp(theApp);
+ }
+ }
+
+ public static void launch(String expectedMessage, String... toolArgs)
+ throws IOException {
+
+ launch(expectedMessage, Arrays.asList(toolArgs));
+ }
+
+ public static void main(String[] args)
+ throws IOException {
+
+ launchCLHSDB();
+
+ launch("No deadlocks found", "jstack");
+ launch("Server compiler detected", "jmap");
+ launch("Java System Properties", "jinfo");
+
+ // The test throws RuntimeException on error.
+ // IOException is thrown if LingeredApp can't start because of some bad
+ // environment condition
+ System.out.println("Test PASSED");
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/tools/jhsdb/SAGetoptTest.java Thu Jul 23 18:17:02 2015 +0300
@@ -0,0 +1,156 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+ /*
+ * @test
+ * @summary unit test for SAGetopt function
+ * @compile -XDignore.symbol.file SAGetoptTest.java
+ * @run main SAGetoptTest
+ */
+
+import sun.jvm.hotspot.SAGetopt;
+
+public class SAGetoptTest {
+
+ private static boolean a_opt;
+ private static boolean b_opt;
+ private static boolean c_opt;
+ private static boolean e_opt;
+ private static boolean mixed_opt;
+
+ private static String d_value;
+ private static String exe_value;
+ private static String core_value;
+
+ private static void initArgValues() {
+ a_opt = false;
+ b_opt = false;
+ c_opt = false;
+ e_opt = false;
+ mixed_opt = false;
+
+ d_value = "";
+ exe_value = "";
+ core_value = "";
+ }
+
+
+ private static void optionsTest(String[] args) {
+ initArgValues();
+
+ SAGetopt sg = new SAGetopt(args);
+
+ String[] longOpts = {"exe=","core=","mixed"};
+ String shortOpts = "abcd:e";
+ String s;
+
+ while((s = sg.next(shortOpts, longOpts)) != null) {
+ if (s.equals("a")) {
+ a_opt = true;
+ continue;
+ }
+
+ if (s.equals("b")) {
+ b_opt = true;
+ continue;
+ }
+
+ if (s.equals("c")) {
+ c_opt = true;
+ continue;
+ }
+
+ if (s.equals("e")) {
+ e_opt = true;
+ continue;
+ }
+
+ if (s.equals("mixed")) {
+ mixed_opt = true;
+ continue;
+ }
+
+ if (s.equals("d")) {
+ d_value = sg.getOptarg();
+ continue;
+ }
+
+ if (s.equals("exe")) {
+ exe_value = sg.getOptarg();
+ continue;
+ }
+
+ if (s.equals("core")) {
+ core_value = sg.getOptarg();
+ continue;
+ }
+ }
+ }
+
+ private static void badOptionsTest(int setNumber, String[] args, String expectedMessage) {
+ String msg = null;
+ try {
+ optionsTest(args);
+ } catch(RuntimeException ex) {
+ msg = ex.getMessage();
+ }
+
+ if (msg == null || !msg.equals(expectedMessage)) {
+ if (msg != null) {
+ System.err.println("Unexpected error '" + msg + "'");
+ }
+ throw new RuntimeException("Bad option test " + setNumber + " failed");
+ }
+ }
+
+ public static void main(String[] args) {
+ String[] optionSet1 = {"-abd", "bla", "-c"};
+ optionsTest(optionSet1);
+ if (!a_opt || !b_opt || !d_value.equals("bla") || !c_opt) {
+ throw new RuntimeException("Good optionSet 1 failed");
+ }
+
+ String[] optionSet2 = {"-e", "--mixed"};
+ optionsTest(optionSet2);
+ if (!e_opt || !mixed_opt) {
+ throw new RuntimeException("Good optionSet 2 failed");
+ }
+
+ String[] optionSet3 = {"--exe=bla", "--core", "bla_core", "--mixed"};
+ optionsTest(optionSet3);
+ if (!exe_value.equals("bla") || !core_value.equals("bla_core") || !mixed_opt) {
+ throw new RuntimeException("Good optionSet 3 failed");
+ }
+
+ // Bad options test
+ String[] optionSet4 = {"-abd", "-c"};
+ badOptionsTest(4, optionSet4, "Argument is expected for 'd'");
+
+ String[] optionSet5 = {"-exe", "bla", "--core"};
+ badOptionsTest(5, optionSet5, "Invalid option 'x'");
+
+ String[] optionSet6 = {"--exe", "--core", "bla_core"};
+ badOptionsTest(6, optionSet6, "Argument is expected for 'exe'");
+ }
+ }