/*
* Copyright (c) 2001, 2002, 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
* @bug 4407397
* @summary Test the requesting of exception events
*
* @author Robert Field
*
* @library scaffold
* @run build TestScaffold VMConnection
* @run compile -g ExceptionEvents.java
*
* @run main/othervm ExceptionEvents N A StackOverflowCaughtTarg java.lang.Exception
* @run main/othervm ExceptionEvents C A StackOverflowCaughtTarg null
* @run main/othervm ExceptionEvents C A StackOverflowCaughtTarg java.lang.Error
* @run main/othervm ExceptionEvents C A StackOverflowCaughtTarg java.lang.StackOverflowError
* @run main/othervm ExceptionEvents N A StackOverflowCaughtTarg java.lang.NullPointerException
* @run main/othervm ExceptionEvents N T StackOverflowCaughtTarg java.lang.Exception
* @run main/othervm ExceptionEvents C T StackOverflowCaughtTarg null
* @run main/othervm ExceptionEvents C T StackOverflowCaughtTarg java.lang.Error
* @run main/othervm ExceptionEvents C T StackOverflowCaughtTarg java.lang.StackOverflowError
* @run main/othervm ExceptionEvents N T StackOverflowCaughtTarg java.lang.NullPointerException
* @run main/othervm ExceptionEvents N N StackOverflowCaughtTarg java.lang.Exception
* @run main/othervm ExceptionEvents C N StackOverflowCaughtTarg null
* @run main/othervm ExceptionEvents C N StackOverflowCaughtTarg java.lang.Error
* @run main/othervm ExceptionEvents C N StackOverflowCaughtTarg java.lang.StackOverflowError
* @run main/othervm ExceptionEvents N N StackOverflowCaughtTarg java.lang.NullPointerException
* @run main/othervm ExceptionEvents N A StackOverflowUncaughtTarg java.lang.Exception
* @run main/othervm ExceptionEvents U A StackOverflowUncaughtTarg null
* @run main/othervm ExceptionEvents U A StackOverflowUncaughtTarg java.lang.Error
* @run main/othervm ExceptionEvents U A StackOverflowUncaughtTarg java.lang.StackOverflowError
* @run main/othervm ExceptionEvents N A StackOverflowUncaughtTarg java.lang.NullPointerException
* @run main/othervm ExceptionEvents N T StackOverflowUncaughtTarg java.lang.NullPointerException
* @run main/othervm ExceptionEvents N N StackOverflowUncaughtTarg java.lang.NullPointerException
*/
import com.sun.jdi.*;
import com.sun.jdi.event.*;
import com.sun.jdi.request.*;
import java.util.*;
class StackOverflowCaughtTarg {
public static void main(String[] args) {
try {
throw new StackOverflowError();
} catch (Throwable exc) {
// ignore
}
}
}
class StackOverflowUncaughtTarg {
public static void main(String[] args) {
thrower();
}
static void thrower() {
throw new StackOverflowError();
}
}
class StackOverflowIndirectTarg {
public static void main(String[] args) {
try {
thrower();
} catch (Throwable exc) {
System.out.println("Got exception: " + exc);
}
}
static void thrower() {
throw new StackOverflowError();
}
}
public class ExceptionEvents extends TestScaffold {
static int failureCount = 0;
static StringBuffer tooManySummary = new StringBuffer();
static StringBuffer notSentSummary = new StringBuffer();
static StringBuffer unexpectedSummary = new StringBuffer();
static int globalSuspendPolicy = -1;
static String[] flags;
final String target;
final String exceptionName;
final boolean caught;
final boolean uncaught;
final int suspendPolicy;
int eventCount = 0;
ExceptionRequest request;
ExceptionEvents(String target,
String exceptionName,
boolean caught, boolean uncaught,
int suspendPolicy) {
super(flags);
this.target = target;
this.exceptionName = exceptionName;
this.caught = caught;
this.uncaught = uncaught;
this.suspendPolicy = suspendPolicy;
}
static void everything() throws Exception {
goNeither("StackOverflowCaughtTarg", "java.lang.Exception");
goCaught("StackOverflowCaughtTarg", null);
goCaught("StackOverflowCaughtTarg", "java.lang.Error");
goCaught("StackOverflowCaughtTarg", "java.lang.StackOverflowError");
goNeither("StackOverflowCaughtTarg", "java.lang.NullPointerException");
goNeither("StackOverflowUncaughtTarg", "java.lang.Exception");
goUncaught("StackOverflowUncaughtTarg", null);
goUncaught("StackOverflowUncaughtTarg", "java.lang.Error");
goUncaught("StackOverflowUncaughtTarg", "java.lang.StackOverflowError");
goNeither("StackOverflowUncaughtTarg", "java.lang.NullPointerException");
}
static void usage() throws Exception {
System.err.println("Use either with no arguments or");
System.err.println(" c|u|n a|t|n <TargetClass> <Exception>|null");
System.err.println("or for verbose folk");
System.err.println(" caught|uncaught|neither all|thread|none <TargetClass> <Exception>|null");
throw new IllegalArgumentException("see usage");
}
public static void main(String[] args) throws Exception {
StringBuffer testName = new StringBuffer("ExceptionEvents(");
List flagList = new ArrayList();
List argList = new ArrayList();
for (int i = 0; i < args.length; ++i) {
String arg = args[i];
if (arg.startsWith("-")) {
flagList.add(arg);
} else {
argList.add(arg);
}
}
flags = (String[])flagList.toArray(new String[0]);
args = (String[])argList.toArray(new String[0]);
if (args.length == 0) {
everything();
testName.append("Full Test");
} else if (args.length == 4) {
switch (args[1].toLowerCase().charAt(0)) {
case 'a':
globalSuspendPolicy = EventRequest.SUSPEND_ALL;
break;
case 't':
globalSuspendPolicy = EventRequest.SUSPEND_EVENT_THREAD;
break;
case 'n':
globalSuspendPolicy = EventRequest.SUSPEND_NONE;
break;
default:
usage();
}
String excString = args[3];
if (excString.equals("null")) {
excString = null;
}
switch (args[0].toLowerCase().charAt(0)) {
case 'c':
goCaught(args[2], excString);
break;
case 'u':
goUncaught(args[2], excString);
break;
case 'n':
goNeither(args[2], excString);
break;
default:
usage();
}
testName.append(args[0]);
testName.append(" ");
testName.append(args[1]);
testName.append(" ");
testName.append(args[2]);
} else {
usage();
}
testName.append(")");
summarize(testName.toString());
}
static void summarize(String testName) throws Exception {
// final analyse
if (tooManySummary.length() > 0) {
System.out.println("\nSummary of tests with too many events:\n" +
tooManySummary.toString());
}
if (notSentSummary.length() > 0) {
System.out.println("\nSummary of tests with expected events not sent:\n" +
notSentSummary.toString());
}
if (unexpectedSummary.length() > 0) {
System.out.println("\nSummary of tests with events when none expected:\n" +
unexpectedSummary.toString());
}
if (failureCount > 0) {
throw new Exception(testName + " FAILED " +
failureCount + " tests!");
} else {
System.out.println("\n" + testName + " test PASSED");
}
}
/**
* Target throws caught exception.
* Events if caught enabled.
*/
static void goCaught(String target,
String exceptionName) throws Exception {
goSuspendPolicy(target, true, exceptionName,
true, true);
goSuspendPolicy(target, true, exceptionName,
true, false);
goSuspendPolicy(target, false, exceptionName,
false, true);
goSuspendPolicy(target, false, exceptionName,
false, false);
}
/**
* Target throws uncaught exception.
* Events if uncaught enabled.
*/
static void goUncaught(String target,
String exceptionName) throws Exception {
goSuspendPolicy(target, true, exceptionName,
true, true);
goSuspendPolicy(target, true, exceptionName,
false, true);
goSuspendPolicy(target, false, exceptionName,
true, false);
goSuspendPolicy(target, false, exceptionName,
false, false);
}
/**
* Target doesn't throw named exception. No events.
*/
static void goNeither(String target,
String exceptionName) throws Exception {
goSuspendPolicy(target, false, exceptionName,
true, true);
goSuspendPolicy(target, false, exceptionName,
false, true);
goSuspendPolicy(target, false, exceptionName,
true, false);
goSuspendPolicy(target, false, exceptionName,
false, false);
}
/**
* Suspend policy should make no difference.
* Iterate over all of them.
*/
static void goSuspendPolicy(String target,
boolean expectedEvent,
String exceptionName,
boolean caught, boolean uncaught) throws Exception {
if (globalSuspendPolicy != -1) {
go(target, expectedEvent, exceptionName,
caught, uncaught, globalSuspendPolicy);
} else {
go(target, expectedEvent, exceptionName,
caught, uncaught, EventRequest.SUSPEND_ALL);
go(target, expectedEvent, exceptionName,
caught, uncaught, EventRequest.SUSPEND_EVENT_THREAD);
go(target, expectedEvent, exceptionName,
caught, uncaught, EventRequest.SUSPEND_NONE);
}
}
static void go(String target,
boolean expectedEvent,
String exceptionName,
boolean caught, boolean uncaught,
int suspendPolicy) throws Exception {
String description = target + " with " +
exceptionName +
"/caught=" + caught +
"/uncaught=" + uncaught +
" suspend=";
switch (suspendPolicy) {
case EventRequest.SUSPEND_ALL:
description += "All";
break;
case EventRequest.SUSPEND_EVENT_THREAD:
description += "Thread";
break;
case EventRequest.SUSPEND_NONE:
description += "None";
break;
default:
throw new Exception("Test failure: bad suspend policy - " +
suspendPolicy);
}
description += "\n";
System.out.print("\nTesting " + description);
ExceptionEvents aRun = new ExceptionEvents(
target,
exceptionName, caught, uncaught,
suspendPolicy);
aRun.startTests();
aRun.analyse(expectedEvent, description);
}
void analyse(boolean expectedEvent, String description) {
if (expectedEvent) {
if (eventCount == 1) {
println("pass: got expected event");
} else if (eventCount > 1) {
failure("FAILURE: expected only one event got: " +
eventCount);
tooManySummary.append(description);
++failureCount;
} else {
failure("FAILURE: expected event not sent");
notSentSummary.append(description);
++failureCount;
}
} else {
if (eventCount > 0) {
failure("FAILURE: unexpected event sent");
unexpectedSummary.append(description);
++failureCount;
} else {
println("pass: as expected no event sent");
}
}
}
/********** event handlers **********/
public void exceptionThrown(ExceptionEvent event) {
if (event.request() == request) {
try {
System.out.print("ExceptionEvent: ");
System.out.print("" + event.exception().referenceType().name());
Location loc = event.location();
System.out.print(" @ " + loc.method().name());
System.out.print(":" + loc.lineNumber());
} catch (VMDisconnectedException exc) {
System.out.print("Oops - " + exc.toString());
}
System.out.println();
eventCount++;
} else {
System.out.print("alien exception: ");
try {
println(event.toString());
} catch (VMDisconnectedException exc) {
println("Oops - " + exc.toString());
}
}
}
/**
* Turn off default Exception Handling
*/
protected void createDefaultExceptionRequest() {
}
/********** test core **********/
protected void runTests() throws Exception {
/*
* Get to the top of main()
*/
startToMain(target);
ReferenceType exceptionClass;
if (exceptionName == null) {
exceptionClass = null;
} else {
exceptionClass = findReferenceType(exceptionName);
if (exceptionName == null) {
throw new Exception("test failure - cannot find: " +
exceptionName);
}
}
request = eventRequestManager().createExceptionRequest(exceptionClass,
caught, uncaught);
request.addClassExclusionFilter("java.*");
request.addClassExclusionFilter("sun.*");
request.addClassExclusionFilter("com.sun.*");
request.setSuspendPolicy(suspendPolicy);
request.enable();
listenUntilVMDisconnect();
}
}