/* * 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; } }