blob: bf8a499353ff232dce369f882ba62729f1fd0718 [file] [log] [blame]
/*
* Copyright (c) 2017, 2018, 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.
*/
import java.io.IOException;
import java.io.OutputStream;
import java.util.List;
import java.util.Map;
import jdk.test.lib.apps.LingeredApp;
import jdk.test.lib.Platform;
import jdk.test.lib.JDKToolLauncher;
import jdk.test.lib.JDKToolFinder;
import jdk.test.lib.process.OutputAnalyzer;
/**
* This is a framework to run 'jhsdb clhsdb' commands.
* See open/test/hotspot/jtreg/serviceability/sa/ClhsdbLongConstant.java for
* an example of how to write a test.
*/
public class ClhsdbLauncher {
private Process toolProcess;
public ClhsdbLauncher() {
toolProcess = null;
}
/**
*
* Launches 'jhsdb clhsdb' and attaches to the Lingered App process.
* @param lingeredAppPid - pid of the Lingered App or one its sub-classes.
*/
private void attach(long lingeredAppPid)
throws IOException {
JDKToolLauncher launcher = JDKToolLauncher.createUsingTestJDK("jhsdb");
launcher.addToolArg("clhsdb");
if (lingeredAppPid != -1) {
launcher.addToolArg("--pid=" + Long.toString(lingeredAppPid));
System.out.println("Starting clhsdb against " + lingeredAppPid);
}
ProcessBuilder processBuilder = new ProcessBuilder(launcher.getCommand());
processBuilder.redirectError(ProcessBuilder.Redirect.INHERIT);
toolProcess = processBuilder.start();
}
/**
*
* Launches 'jhsdb clhsdb' and loads a core file.
* @param coreFileName - Name of the corefile to be loaded.
*/
private void loadCore(String coreFileName)
throws IOException {
JDKToolLauncher launcher = JDKToolLauncher.createUsingTestJDK("jhsdb");
launcher.addToolArg("clhsdb");
launcher.addToolArg("--core=" + coreFileName);
launcher.addToolArg("--exe=" + JDKToolFinder.getTestJDKTool("java"));
System.out.println("Starting clhsdb against corefile " + coreFileName +
" and exe " + JDKToolFinder.getTestJDKTool("java"));
ProcessBuilder processBuilder = new ProcessBuilder(launcher.getCommand());
processBuilder.redirectError(ProcessBuilder.Redirect.INHERIT);
toolProcess = processBuilder.start();
}
/**
*
* Runs 'jhsdb clhsdb' commands and checks for expected and unexpected strings.
* @param commands - clhsdb commands to execute.
* @param expectedStrMap - Map of expected strings per command which need to
* be checked in the output of the command.
* @param unExpectedStrMap - Map of unexpected strings per command which should
* not be present in the output of the command.
* @return Output of the commands as a String.
*/
private String runCmd(List<String> commands,
Map<String, List<String>> expectedStrMap,
Map<String, List<String>> unExpectedStrMap)
throws IOException, InterruptedException {
String output;
if (commands == null) {
throw new RuntimeException("CLHSDB command must be provided\n");
}
try (OutputStream out = toolProcess.getOutputStream()) {
for (String cmd : commands) {
out.write((cmd + "\n").getBytes());
}
out.write("quit\n".getBytes());
out.flush();
}
OutputAnalyzer oa = new OutputAnalyzer(toolProcess);
try {
toolProcess.waitFor();
} catch (InterruptedException ie) {
toolProcess.destroyForcibly();
throw new Error("Problem awaiting the child process: " + ie);
}
oa.shouldHaveExitValue(0);
output = oa.getOutput();
System.out.println(output);
String[] parts = output.split("hsdb>");
for (String cmd : commands) {
int index = commands.indexOf(cmd) + 1;
OutputAnalyzer out = new OutputAnalyzer(parts[index]);
if (expectedStrMap != null) {
List<String> expectedStr = expectedStrMap.get(cmd);
if (expectedStr != null) {
for (String exp : expectedStr) {
out.shouldContain(exp);
}
}
}
if (unExpectedStrMap != null) {
List<String> unExpectedStr = unExpectedStrMap.get(cmd);
if (unExpectedStr != null) {
for (String unExp : unExpectedStr) {
out.shouldNotContain(unExp);
}
}
}
}
return output;
}
/**
*
* Launches 'jhsdb clhsdb', attaches to the Lingered App, executes the commands,
* checks for expected and unexpected strings.
* @param lingeredAppPid - pid of the Lingered App or one its sub-classes.
* @param commands - clhsdb commands to execute.
* @param expectedStrMap - Map of expected strings per command which need to
* be checked in the output of the command.
* @param unExpectedStrMap - Map of unexpected strings per command which should
* not be present in the output of the command.
* @return Output of the commands as a String.
*/
public String run(long lingeredAppPid,
List<String> commands,
Map<String, List<String>> expectedStrMap,
Map<String, List<String>> unExpectedStrMap)
throws IOException, InterruptedException {
if (!Platform.shouldSAAttach()) {
// Silently skip the test if we don't have enough permissions to attach
System.out.println("SA attach not expected to work - test skipped.");
return null;
}
attach(lingeredAppPid);
return runCmd(commands, expectedStrMap, unExpectedStrMap);
}
/**
*
* Launches 'jhsdb clhsdb', loads a core file, executes the commands,
* checks for expected and unexpected strings.
* @param coreFileName - Name of the core file to be debugged.
* @param commands - clhsdb commands to execute.
* @param expectedStrMap - Map of expected strings per command which need to
* be checked in the output of the command.
* @param unExpectedStrMap - Map of unexpected strings per command which should
* not be present in the output of the command.
* @return Output of the commands as a String.
*/
public String runOnCore(String coreFileName,
List<String> commands,
Map<String, List<String>> expectedStrMap,
Map<String, List<String>> unExpectedStrMap)
throws IOException, InterruptedException {
if (!Platform.shouldSAAttach()) {
// Silently skip the test if we don't have enough permissions to attach
System.out.println("SA attach not expected to work - test skipped.");
return null;
}
loadCore(coreFileName);
return runCmd(commands, expectedStrMap, unExpectedStrMap);
}
}