--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/jdk/jshell/ExceptionsTest.java Mon Oct 19 19:15:16 2015 +0200
@@ -0,0 +1,244 @@
+/*
+ * Copyright (c) 2015, 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
+ * @summary Tests for exceptions
+ * @build KullaTesting TestingInputStream
+ * @run testng ExceptionsTest
+ */
+
+import jdk.jshell.SnippetEvent;
+import jdk.jshell.EvalException;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+
+import jdk.jshell.Snippet;
+import org.testng.annotations.Test;
+
+import static org.testng.Assert.*;
+
+@Test
+public class ExceptionsTest extends KullaTesting {
+
+ public void throwUncheckedException() {
+ String message = "error_message";
+ SnippetEvent cr = assertEvalException("throw new RuntimeException(\"" + message + "\");");
+ assertExceptionMatch(cr,
+ new ExceptionInfo(RuntimeException.class, message,
+ newStackTraceElement("", "", cr.snippet(), 1)));
+ }
+
+ public void throwCheckedException() {
+ String message = "error_message";
+ SnippetEvent cr = assertEvalException("throw new Exception(\"" + message + "\");");
+ assertExceptionMatch(cr,
+ new ExceptionInfo(Exception.class, message,
+ newStackTraceElement("", "", cr.snippet(), 1)));
+ }
+
+ public void throwFromStaticMethodOfClass() {
+ String message = "error_message";
+ Snippet s1 = methodKey(assertEval("void f() { throw new RuntimeException(\"" + message + "\"); }"));
+ Snippet s2 = classKey(assertEval("class A { static void g() { f(); } }"));
+ SnippetEvent cr3 = assertEvalException("A.g();");
+ assertExceptionMatch(cr3,
+ new ExceptionInfo(RuntimeException.class, message,
+ newStackTraceElement("", "f", s1, 1),
+ newStackTraceElement("A", "g", s2, 1),
+ newStackTraceElement("", "", cr3.snippet(), 1)));
+ }
+
+ public void throwFromStaticMethodOfInterface() {
+ String message = "error_message";
+ Snippet s1 = methodKey(assertEval("void f() { throw new RuntimeException(\"" + message + "\"); }"));
+ Snippet s2 = classKey(assertEval("interface A { static void g() { f(); } }"));
+ SnippetEvent cr3 = assertEvalException("A.g();");
+ assertExceptionMatch(cr3,
+ new ExceptionInfo(RuntimeException.class, message,
+ newStackTraceElement("", "f", s1, 1),
+ newStackTraceElement("A", "g", s2, 1),
+ newStackTraceElement("", "", cr3.snippet(), 1)));
+ }
+
+ public void throwFromConstructor() {
+ String message = "error_message";
+ Snippet s1 = methodKey(assertEval("void f() { throw new RuntimeException(\"" + message + "\"); }"));
+ Snippet s2 = classKey(assertEval("class A { A() { f(); } }"));
+ SnippetEvent cr3 = assertEvalException("new A();");
+ assertExceptionMatch(cr3,
+ new ExceptionInfo(RuntimeException.class, message,
+ newStackTraceElement("", "f", s1, 1),
+ newStackTraceElement("A", "<init>", s2, 1),
+ newStackTraceElement("", "", cr3.snippet(), 1)));
+ }
+
+ public void throwFromDefaultMethodOfInterface() {
+ String message = "error_message";
+ Snippet s1 = methodKey(assertEval("void f() { throw new RuntimeException(\"" + message + "\"); }"));
+ Snippet s2 = classKey(assertEval("interface A { default void g() { f(); } }"));
+ SnippetEvent cr3 = assertEvalException("new A() { }.g();");
+ assertExceptionMatch(cr3,
+ new ExceptionInfo(RuntimeException.class, message,
+ newStackTraceElement("", "f", s1, 1),
+ newStackTraceElement("A", "g", s2, 1),
+ newStackTraceElement("", "", cr3.snippet(), 1)));
+ }
+
+ public void throwFromLambda() {
+ String message = "lambda";
+ Snippet s1 = varKey(assertEval(
+ "Runnable run = () -> {\n" +
+ " throw new RuntimeException(\"" + message + "\");\n" +
+ "};"
+ ));
+ SnippetEvent cr2 = assertEvalException("run.run();");
+ assertExceptionMatch(cr2,
+ new ExceptionInfo(RuntimeException.class, message,
+ newStackTraceElement("", "lambda$", s1, 2),
+ newStackTraceElement("", "", cr2.snippet(), 1)));
+ }
+
+ public void throwFromAnonymousClass() {
+ String message = "anonymous";
+ Snippet s1 = varKey(assertEval(
+ "Runnable run = new Runnable() {\n" +
+ " public void run() {\n"+
+ " throw new RuntimeException(\"" + message + "\");\n" +
+ " }\n" +
+ "};"
+ ));
+ SnippetEvent cr2 = assertEvalException("run.run();");
+ assertExceptionMatch(cr2,
+ new ExceptionInfo(RuntimeException.class, message,
+ newStackTraceElement("1", "run", s1, 3),
+ newStackTraceElement("", "", cr2.snippet(), 1)));
+ }
+
+ public void throwFromLocalClass() {
+ String message = "local";
+ Snippet s1 = methodKey(assertEval(
+ "void f() {\n" +
+ " class A {\n" +
+ " void f() {\n"+
+ " throw new RuntimeException(\"" + message + "\");\n" +
+ " }\n" +
+ " }\n" +
+ " new A().f();\n" +
+ "}"
+ ));
+ SnippetEvent cr2 = assertEvalException("f();");
+ assertExceptionMatch(cr2,
+ new ExceptionInfo(RuntimeException.class, message,
+ newStackTraceElement("1A", "f", s1, 4),
+ newStackTraceElement("", "f", s1, 7),
+ newStackTraceElement("", "", cr2.snippet(), 1)));
+ }
+
+ @Test(enabled = false) // TODO 8129427
+ public void outOfMemory() {
+ assertEval("import java.util.*;");
+ assertEval("List<byte[]> list = new ArrayList<>();");
+ assertExecuteException("while (true) { list.add(new byte[10000]); }", OutOfMemoryError.class);
+ }
+
+ public void stackOverflow() {
+ assertEval("void f() { f(); }");
+ assertExecuteException("f();", StackOverflowError.class);
+ }
+
+ private StackTraceElement newStackTraceElement(String className, String methodName, Snippet key, int lineNumber) {
+ return new StackTraceElement(className, methodName, "#" + key.id(), lineNumber);
+ }
+
+ private static class ExceptionInfo {
+ public final Class<? extends Throwable> exception;
+ public final String message;
+ public final StackTraceElement[] stackTraceElements;
+
+ public ExceptionInfo(Class<? extends Throwable> exception, String message, StackTraceElement...stackTraceElements) {
+ this.exception = exception;
+ this.message = message;
+ this.stackTraceElements = stackTraceElements.length == 0 ? null : stackTraceElements;
+ }
+ }
+
+ private void assertExecuteException(String input, Class<? extends Throwable> exception) {
+ assertExceptionMatch(assertEvalException(input), new ExceptionInfo(exception, null));
+ }
+
+ private void assertExceptionMatch(SnippetEvent cr, ExceptionInfo exceptionInfo) {
+ assertNotNull(cr.exception(), "Expected exception was not thrown: " + exceptionInfo.exception);
+ if (cr.exception() instanceof EvalException) {
+ EvalException ex = (EvalException) cr.exception();
+ String actualException = ex.getExceptionClassName();
+ String expectedException = exceptionInfo.exception.getCanonicalName();
+ String stackTrace = getStackTrace(ex);
+ String source = cr.snippet().source();
+ assertEquals(actualException, expectedException,
+ String.format("Given \"%s\" expected exception: %s, got: %s%nStack trace:%n%s",
+ source, expectedException, actualException, stackTrace));
+ if (exceptionInfo.message != null) {
+ assertEquals(ex.getMessage(), exceptionInfo.message,
+ String.format("Given \"%s\" expected message: %s, got: %s",
+ source, exceptionInfo.message, ex.getMessage()));
+ }
+ if (exceptionInfo.stackTraceElements != null) {
+ assertStackTrace(ex.getStackTrace(), exceptionInfo.stackTraceElements,
+ String.format("Given \"%s\"%nStack trace:%n%s%n",
+ source, stackTrace));
+ }
+ } else {
+ fail("Unexpected execution exceptionInfo: " + cr.exception());
+ }
+ }
+
+ private void assertStackTrace(StackTraceElement[] actual, StackTraceElement[] expected, String message) {
+ if (actual != expected) {
+ if (actual == null || expected == null) {
+ fail(message);
+ } else {
+ assertEquals(actual.length, expected.length, message + " : arrays do not have the same size");
+ for (int i = 0; i < actual.length; ++i) {
+ StackTraceElement actualElement = actual[i];
+ StackTraceElement expectedElement = expected[i];
+ assertEquals(actualElement.getClassName(), expectedElement.getClassName(), message + " : class names");
+ String expectedMethodName = expectedElement.getMethodName();
+ if (expectedMethodName.startsWith("lambda$")) {
+ assertTrue(actualElement.getMethodName().startsWith("lambda$"), message + " : method names");
+ } else {
+ assertEquals(actualElement.getMethodName(), expectedElement.getMethodName(), message + " : method names");
+ }
+ assertEquals(actualElement.getFileName(), expectedElement.getFileName(), message + " : file names");
+ assertEquals(actualElement.getLineNumber(), expectedElement.getLineNumber(), message + " : line numbers");
+ }
+ }
+ }
+ }
+
+ private String getStackTrace(EvalException ex) {
+ StringWriter st = new StringWriter();
+ ex.printStackTrace(new PrintWriter(st));
+ return st.toString();
+ }
+}