239 lines
8.5 KiB
Java
239 lines
8.5 KiB
Java
|
/*
|
||
|
* Copyright (c) 2002, 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.
|
||
|
*/
|
||
|
|
||
|
package nsk.share.jdb;
|
||
|
|
||
|
import nsk.share.*;
|
||
|
import nsk.share.jpda.*;
|
||
|
|
||
|
import java.io.*;
|
||
|
import java.util.*;
|
||
|
|
||
|
public abstract class JdbTest {
|
||
|
public static final int PASSED = 0; // Exit code for passed test
|
||
|
public static final int FAILED = 2; // Exit code for failed test
|
||
|
public static final int JCK_STATUS_BASE = 95; // Standard JCK-compatible exit code bias
|
||
|
|
||
|
/* Flag if the test passes */
|
||
|
protected boolean success = true;
|
||
|
|
||
|
/* Flag if debuggee should fail in a test */
|
||
|
protected static boolean debuggeeShouldFail = false;
|
||
|
|
||
|
/* Handler of command line arguments. */
|
||
|
protected static JdbArgumentHandler argumentHandler = null;
|
||
|
|
||
|
/* Log class to print log messages. */
|
||
|
protected static Log log = null;
|
||
|
|
||
|
protected static Jdb jdb = null;
|
||
|
protected static Debuggee debuggee = null;
|
||
|
protected static Launcher launcher = null;
|
||
|
protected static String debuggeeClass = "";
|
||
|
protected static String firstBreak = "";
|
||
|
protected static String lastBreak = "";
|
||
|
protected static String compoundPromptIdent = null;
|
||
|
|
||
|
/* Constructors */
|
||
|
protected JdbTest (boolean debuggeeShouldFail) {
|
||
|
this.debuggeeShouldFail = debuggeeShouldFail;
|
||
|
}
|
||
|
|
||
|
protected JdbTest () {
|
||
|
this.debuggeeShouldFail = false;
|
||
|
}
|
||
|
|
||
|
abstract protected void runCases();
|
||
|
|
||
|
protected boolean shouldPass() {
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
protected void failure(String errMessage) {
|
||
|
success = false;
|
||
|
log.complain(errMessage);
|
||
|
}
|
||
|
|
||
|
protected void display(String message) {
|
||
|
log.display(message);
|
||
|
}
|
||
|
|
||
|
protected void launchJdbAndDebuggee(String debuggeeClass) throws Exception {
|
||
|
launcher = new Launcher(argumentHandler, log);
|
||
|
launcher.launchJdbAndDebuggee(debuggeeClass);
|
||
|
jdb = launcher.getJdb();
|
||
|
|
||
|
if (jdb == null) {
|
||
|
throw new Failure("jdb object points to null");
|
||
|
}
|
||
|
if (debuggeeClass != null) {
|
||
|
if (jdb.terminated()) {
|
||
|
throw new Failure("jdb exited before testing with code " + jdb.waitFor());
|
||
|
}
|
||
|
|
||
|
if (argumentHandler.isAttachingConnector() || argumentHandler.isListeningConnector()) {
|
||
|
debuggee = launcher.getDebuggee();
|
||
|
|
||
|
if (debuggee.terminated()) {
|
||
|
throw new Failure("Debuggee exited before testing");
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
protected void initJdb() {
|
||
|
String[] reply;
|
||
|
|
||
|
jdb.setCompoundPromptIdent(compoundPromptIdent);
|
||
|
|
||
|
// wait for prompts after connection established
|
||
|
if (argumentHandler.isAttachingConnector() || argumentHandler.isListeningConnector()) {
|
||
|
// wait for two prompts (after connection established and VM_INIT received)
|
||
|
jdb.waitForPrompt(0, false, 2);
|
||
|
} else if (argumentHandler.isLaunchingConnector()) {
|
||
|
// wait for one prompt (after connection established)
|
||
|
jdb.waitForPrompt(0, false);
|
||
|
} else {
|
||
|
throw new TestBug("Unexpected connector kind: " + argumentHandler.getConnectorType());
|
||
|
}
|
||
|
|
||
|
display("Setting first breakpoint");
|
||
|
jdb.setDeferredBreakpointInMethod(firstBreak);
|
||
|
|
||
|
display("Starting debuggee class");
|
||
|
jdb.startDebuggeeClass();
|
||
|
}
|
||
|
|
||
|
protected void afterJdbExit() {
|
||
|
}
|
||
|
|
||
|
protected int runTest(String argv[], PrintStream out) {
|
||
|
try {
|
||
|
argumentHandler = new JdbArgumentHandler(argv);
|
||
|
log = new Log(out, argumentHandler);
|
||
|
|
||
|
if (shouldPass()) {
|
||
|
log.println("TEST PASSED");
|
||
|
return PASSED;
|
||
|
}
|
||
|
|
||
|
try {
|
||
|
launchJdbAndDebuggee(debuggeeClass);
|
||
|
|
||
|
try {
|
||
|
initJdb();
|
||
|
|
||
|
/* START OF TEST CASES */
|
||
|
display("Test cases starts.");
|
||
|
|
||
|
runCases();
|
||
|
|
||
|
display("Test cases ends.");
|
||
|
/* END OF TEST CASES */
|
||
|
|
||
|
} catch (DebuggeeUncaughtException ex) {
|
||
|
jdb.quit();
|
||
|
throw new TestFailure(ex);
|
||
|
} catch (Exception e) {
|
||
|
failure("Caught unexpected exception while executing the test: " + e);
|
||
|
e.printStackTrace(log.getOutStream());
|
||
|
} finally {
|
||
|
display("Waiting for jdb exits");
|
||
|
int code = jdb.waitFor(argumentHandler.getWaitTime() * 60 * 1000);
|
||
|
if (code == PASSED) {
|
||
|
display("jdb normally exited");
|
||
|
afterJdbExit();
|
||
|
} else if (code == LocalProcess.PROCESS_IS_ALIVE) {
|
||
|
failure("jdb did not exit after timeout.");
|
||
|
if (!jdb.terminated()) {
|
||
|
display("Sending quit command to jdb.");
|
||
|
jdb.quit();
|
||
|
} else {
|
||
|
throw new TestBug("code PROCESS_IS_ALIVE is returned for terminated jdb");
|
||
|
}
|
||
|
} else {
|
||
|
failure("jdb abnormally exited with code: " + code);
|
||
|
}
|
||
|
jdb = null;
|
||
|
|
||
|
if (debuggee != null
|
||
|
&& (argumentHandler.isAttachingConnector()
|
||
|
|| argumentHandler.isListeningConnector())) {
|
||
|
display("Waiting for debuggee exits");
|
||
|
code = debuggee.waitForDebuggee();
|
||
|
if (debuggeeShouldFail) {
|
||
|
if (code == JCK_STATUS_BASE + PASSED) {
|
||
|
failure("Debuggee PASSED with exit code: " + code + " but should fail");
|
||
|
} else {
|
||
|
display("Debuggee FAILED as expected with exit code: " + code);
|
||
|
}
|
||
|
} else {
|
||
|
if (code == JCK_STATUS_BASE + PASSED) {
|
||
|
display("Debuggee PASSED with exit code: " + code);
|
||
|
} else {
|
||
|
failure("Debuggee FAILED with exit code: " + code);
|
||
|
}
|
||
|
}
|
||
|
// debuggee = null;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
} catch (Exception e) {
|
||
|
failure("Caught unexpected exception: " + e);
|
||
|
e.printStackTrace(out);
|
||
|
|
||
|
if (jdb != null) {
|
||
|
try {
|
||
|
jdb.finalize();
|
||
|
} catch (Throwable ex) {
|
||
|
failure("Caught exception/error while finalization of jdb:\n\t" + ex);
|
||
|
ex.printStackTrace(log.getOutStream());
|
||
|
}
|
||
|
} else {
|
||
|
log.complain("jdb reference is null, cannot run jdb.finalize() method");
|
||
|
}
|
||
|
|
||
|
if (debuggee != null) {
|
||
|
debuggee.killDebuggee();
|
||
|
} else {
|
||
|
log.complain("debuggee reference is null, cannot run debuggee.finalize() method");
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
if (!success) {
|
||
|
log.complain("TEST FAILED");
|
||
|
return FAILED;
|
||
|
}
|
||
|
|
||
|
} catch (Exception e) {
|
||
|
out.println("Caught unexpected exception while starting the test: " + e);
|
||
|
e.printStackTrace(out);
|
||
|
out.println("TEST FAILED");
|
||
|
return FAILED;
|
||
|
}
|
||
|
out.println("TEST PASSED");
|
||
|
return PASSED;
|
||
|
}
|
||
|
}
|