changeset 396:1b0f8547b888

7901927: Error reporting should always print the entire exception, not only the message Contributed-by: Jerzy Krolak <j.krolak@gmail.com>
author shade
date Mon, 27 Mar 2017 18:41:27 +0200
parents e8c09609767c
children 794ae5fc5330
files jcstress-core/src/main/java/org/openjdk/jcstress/EmbeddedExecutor.java jcstress-core/src/main/java/org/openjdk/jcstress/infra/runners/Runner.java jcstress-core/src/main/java/org/openjdk/jcstress/util/StringUtils.java jcstress-core/src/test/java/org/openjdk/jcstress/EmbeddedExecutorTest.java jcstress-core/src/test/java/org/openjdk/jcstress/util/StringUtilsTest.java
diffstat 5 files changed, 104 insertions(+), 10 deletions(-) [+]
line wrap: on
line diff
--- a/jcstress-core/src/main/java/org/openjdk/jcstress/EmbeddedExecutor.java	Mon Mar 27 18:35:03 2017 +0200
+++ b/jcstress-core/src/main/java/org/openjdk/jcstress/EmbeddedExecutor.java	Mon Mar 27 18:41:27 2017 +0200
@@ -29,6 +29,7 @@
 import org.openjdk.jcstress.infra.collectors.TestResultCollector;
 import org.openjdk.jcstress.infra.runners.Runner;
 import org.openjdk.jcstress.infra.runners.TestConfig;
+import org.openjdk.jcstress.util.StringUtils;
 
 import java.lang.reflect.Constructor;
 import java.util.concurrent.ExecutorService;
@@ -80,11 +81,11 @@
                 o.run();
             } catch (ClassFormatError | NoClassDefFoundError | NoSuchMethodError | NoSuchFieldError e) {
                 TestResult result = new TestResult(config, Status.API_MISMATCH, 0);
-                result.addAuxData(e.getMessage());
+                result.addAuxData(StringUtils.getStacktrace(e));
                 sink.add(result);
             } catch (Throwable ex) {
                 TestResult result = new TestResult(config, Status.TEST_ERROR, 0);
-                result.addAuxData(ex.getMessage());
+                result.addAuxData(StringUtils.getStacktrace(ex));
                 sink.add(result);
             } finally {
                 if (onFinish != null) {
--- a/jcstress-core/src/main/java/org/openjdk/jcstress/infra/runners/Runner.java	Mon Mar 27 18:35:03 2017 +0200
+++ b/jcstress-core/src/main/java/org/openjdk/jcstress/infra/runners/Runner.java	Mon Mar 27 18:41:27 2017 +0200
@@ -28,10 +28,9 @@
 import org.openjdk.jcstress.infra.collectors.TestResult;
 import org.openjdk.jcstress.infra.collectors.TestResultCollector;
 import org.openjdk.jcstress.util.Counter;
+import org.openjdk.jcstress.util.StringUtils;
 import org.openjdk.jcstress.vm.WhiteBoxSupport;
 
-import java.io.PrintWriter;
-import java.io.StringWriter;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.List;
@@ -107,11 +106,7 @@
     protected void dumpFailure(int iteration, Status status, String message, Throwable aux) {
         messages.add(message);
         TestResult result = prepareResult(iteration, status);
-        StringWriter sw = new StringWriter();
-        PrintWriter pw = new PrintWriter(sw);
-        aux.printStackTrace(pw);
-        pw.close();
-        result.addAuxData(sw.toString());
+        result.addAuxData(StringUtils.getStacktrace(aux));
         collector.add(result);
     }
 
--- a/jcstress-core/src/main/java/org/openjdk/jcstress/util/StringUtils.java	Mon Mar 27 18:35:03 2017 +0200
+++ b/jcstress-core/src/main/java/org/openjdk/jcstress/util/StringUtils.java	Mon Mar 27 18:41:27 2017 +0200
@@ -24,8 +24,9 @@
  */
 package org.openjdk.jcstress.util;
 
+import java.io.PrintWriter;
+import java.io.StringWriter;
 import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.Collection;
 import java.util.List;
 
@@ -101,4 +102,20 @@
         }
         return sb.toString();
     }
+
+    public static String getStacktrace(Throwable throwable) {
+        StringWriter sw = new StringWriter();
+        PrintWriter pw = new PrintWriter(sw);
+        throwable.printStackTrace(pw);
+        pw.close();
+        return sw.toString();
+    }
+
+    public static String getFirstLine(String src) {
+        int endLine = src.indexOf("\n");
+        if (endLine > 0) {
+            return src.substring(0, endLine).trim();
+        }
+        return src;
+    }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jcstress-core/src/test/java/org/openjdk/jcstress/EmbeddedExecutorTest.java	Mon Mar 27 18:41:27 2017 +0200
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2017, 2017, 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.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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 org.openjdk.jcstress;
+
+import junit.framework.Assert;
+import org.junit.Test;
+import org.openjdk.jcstress.infra.Status;
+import org.openjdk.jcstress.infra.TestInfo;
+import org.openjdk.jcstress.infra.collectors.InProcessCollector;
+import org.openjdk.jcstress.infra.collectors.TestResult;
+import org.openjdk.jcstress.infra.runners.TestConfig;
+
+import java.util.Collections;
+
+import static org.openjdk.jcstress.util.StringUtils.getFirstLine;
+
+public class EmbeddedExecutorTest {
+
+    private InProcessCollector sink = new InProcessCollector();
+
+    private EmbeddedExecutor embeddedExecutor = new EmbeddedExecutor(sink);
+
+    @Test
+    public void testReportTestError() {
+        TestConfig config = createSimpleConfigFor("my.missing.ClassName");
+        embeddedExecutor.run(config);
+
+        Assert.assertEquals("Should get exactly one test result", 1, sink.getTestResults().size());
+
+        TestResult testResult = sink.getTestResults().iterator().next();
+        Assert.assertEquals("Should report a test error", Status.TEST_ERROR, testResult.status());
+
+        String errorMessage = testResult.getAuxData().get(0);
+        Assert.assertEquals("Should report the test error reason", "java.lang.ClassNotFoundException: my.missing.ClassName",
+                getFirstLine(errorMessage));
+    }
+
+    private TestConfig createSimpleConfigFor(String runnerClassName) {
+        Options opts = new Options(new String[]{});
+        TestInfo info = new TestInfo("", runnerClassName, "", 4, false);
+        return new TestConfig(opts, info, TestConfig.RunMode.FORKED, 1, Collections.emptyList());
+    }
+
+}
\ No newline at end of file
--- a/jcstress-core/src/test/java/org/openjdk/jcstress/util/StringUtilsTest.java	Mon Mar 27 18:35:03 2017 +0200
+++ b/jcstress-core/src/test/java/org/openjdk/jcstress/util/StringUtilsTest.java	Mon Mar 27 18:41:27 2017 +0200
@@ -15,4 +15,18 @@
         Assert.assertEquals("...", StringUtils.cutoff(s, 3));
     }
 
+    @Test
+    public void testGetStacktrace() {
+        String actual = StringUtils.getStacktrace(new NullPointerException("my message"));
+        String firstLine = StringUtils.getFirstLine(actual);
+
+        Assert.assertEquals("java.lang.NullPointerException: my message", firstLine);
+    }
+
+    @Test
+    public void testGetFirstLine() {
+        Assert.assertEquals("First line", StringUtils.getFirstLine("First line"));
+        Assert.assertEquals("First line", StringUtils.getFirstLine("First line\nsecond line"));
+    }
+
 }