blob: c0edc58993bc1d0c370306e9642815b1a1ee06c6 [file] [log] [blame]
/*
* 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;
}
}