From 1c09a52ef9d363d6ce751e533b11a2ea30219f43 Mon Sep 17 00:00:00 2001 From: Alexey Andreev Date: Mon, 26 Nov 2018 11:40:58 +0300 Subject: [PATCH] Add option to suppress decoding stack when running JUnit tests --- .travis.yml | 2 +- .../org/teavm/junit/HtmlUnitRunStrategy.java | 5 ++- .../org/teavm/junit/RhinoResultParser.java | 30 +++++++++---- .../java/org/teavm/junit/TeaVMTestRunner.java | 45 +++++++++++-------- 4 files changed, 51 insertions(+), 31 deletions(-) diff --git a/.travis.yml b/.travis.yml index efc81cf22..fb2fd3889 100644 --- a/.travis.yml +++ b/.travis.yml @@ -43,7 +43,7 @@ install: - rm -rf tools/idea/idea-artifacts/dependencies script: - - $MVN_CMD -e install -Dteavm.junit.optimized=false -P with-idea -P with-cli -Dteavm.junit.js.runner=none -V + - $MVN_CMD -e install -Dteavm.junit.optimized=false -Dteavm.junit.js.decodeStack=false -P with-idea -P with-cli -Dteavm.junit.js.runner=none -V - BASE_PATH=`pwd` - pushd tests/src/test/js - "export DISPLAY=:99.0" diff --git a/tools/junit/src/main/java/org/teavm/junit/HtmlUnitRunStrategy.java b/tools/junit/src/main/java/org/teavm/junit/HtmlUnitRunStrategy.java index 1d0895004..76478e65f 100644 --- a/tools/junit/src/main/java/org/teavm/junit/HtmlUnitRunStrategy.java +++ b/tools/junit/src/main/java/org/teavm/junit/HtmlUnitRunStrategy.java @@ -67,8 +67,9 @@ class HtmlUnitRunStrategy implements TestRunStrategy { Object[] args = new Object[] { new NativeJavaObject(function, asyncResult, AsyncResult.class) }; page.get().executeJavaScriptFunctionIfPossible(function, function, args, page.get()); - RhinoResultParser.parseResult((Scriptable) asyncResult.getResult(), run.getCallback(), - new File(run.getBaseDirectory(), run.getFileName() + ".teavmdbg")); + boolean decodeStack = Boolean.parseBoolean(System.getProperty(TeaVMTestRunner.JS_DECODE_STACK, "true")); + File debugFile = decodeStack ? new File(run.getBaseDirectory(), run.getFileName() + ".teavmdbg") : null; + RhinoResultParser.parseResult((Scriptable) asyncResult.getResult(), run.getCallback(), debugFile); } private void cleanUp() { diff --git a/tools/junit/src/main/java/org/teavm/junit/RhinoResultParser.java b/tools/junit/src/main/java/org/teavm/junit/RhinoResultParser.java index f040d11d5..49ece5d32 100644 --- a/tools/junit/src/main/java/org/teavm/junit/RhinoResultParser.java +++ b/tools/junit/src/main/java/org/teavm/junit/RhinoResultParser.java @@ -24,6 +24,7 @@ import java.io.InputStream; import java.io.InputStreamReader; import java.io.Reader; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -50,21 +51,30 @@ final class RhinoResultParser { callback.complete(); break; case "exception": { - DebugInformation debugInformation = getDebugInformation(debugFile); + DebugInformation debugInformation = debugFile != null ? getDebugInformation(debugFile) : null; String className = String.valueOf(result.get("className", result)); - String decodedName = debugInformation.getClassNameByJsName(className); - if (decodedName != null) { - className = decodedName; + if (debugInformation != null) { + String decodedName = debugInformation.getClassNameByJsName(className); + if (decodedName != null) { + className = decodedName; + } } String message = String.valueOf(result.get("message", result)); String stack = result.get("stack", result).toString(); - String[] script = getScript(new File(debugFile.getParentFile(), - debugFile.getName().substring(0, debugFile.getName().length() - 9))); - StackTraceElement[] decodedStack = decodeStack(stack, script, debugInformation); - if (decodedStack != null) { + StackTraceElement[] decodedStack = null; + if (debugInformation != null) { + String[] script = getScript(new File(debugFile.getParentFile(), + debugFile.getName().substring(0, debugFile.getName().length() - 9))); + List elements = new ArrayList<>(); + elements.addAll(Arrays.asList(decodeStack(stack, script, debugInformation))); + List currentElements = Arrays.asList(Thread.currentThread().getStackTrace()); + elements.addAll(currentElements.subList(2, currentElements.size())); + decodedStack = elements.toArray(new StackTraceElement[0]); stack = ""; + } else { + stack = "\n" + stack; } Throwable e; @@ -73,7 +83,9 @@ final class RhinoResultParser { } else { e = new RuntimeException(className + ": " + message + stack); } - e.setStackTrace(decodedStack); + if (decodedStack != null) { + e.setStackTrace(decodedStack); + } callback.error(e); break; } diff --git a/tools/junit/src/main/java/org/teavm/junit/TeaVMTestRunner.java b/tools/junit/src/main/java/org/teavm/junit/TeaVMTestRunner.java index 04c4a7980..b2315d6c9 100644 --- a/tools/junit/src/main/java/org/teavm/junit/TeaVMTestRunner.java +++ b/tools/junit/src/main/java/org/teavm/junit/TeaVMTestRunner.java @@ -92,6 +92,7 @@ public class TeaVMTestRunner extends Runner implements Filterable { private static final String JS_RUNNER = "teavm.junit.js.runner"; private static final String THREAD_COUNT = "teavm.junit.js.threads"; private static final String JS_ENABLED = "teavm.junit.js"; + static final String JS_DECODE_STACK = "teavm.junit.js.decodeStack"; private static final String C_ENABLED = "teavm.junit.c"; private static final String WASM_ENABLED = "teavm.junit.wasm"; private static final String C_COMPILER = "teavm.junit.c.compiler"; @@ -552,33 +553,39 @@ public class TeaVMTestRunner extends Runner implements Filterable { private CompileResult compileToJs(Method method, TeaVMTestConfiguration configuration, File path) { + boolean decodeStack = Boolean.parseBoolean(System.getProperty(JS_DECODE_STACK, "true")); DebugInformationBuilder debugEmitter = new DebugInformationBuilder(); Supplier targetSupplier = () -> { JavaScriptTarget target = new JavaScriptTarget(); - target.setDebugEmitter(debugEmitter); + if (decodeStack) { + target.setDebugEmitter(debugEmitter); + } return target; }; - CompilePostProcessor postBuild = (vm, file) -> { - DebugInformation debugInfo = debugEmitter.getDebugInformation(); - File sourceMapsFile = new File(file.getPath() + ".map"); - File debugFile = new File(file.getPath() + ".teavmdbg"); - try { - try (Writer writer = new OutputStreamWriter(new FileOutputStream(file, true), UTF_8)) { - writer.write("\n//# sourceMappingURL="); - writer.write(sourceMapsFile.getName()); - } + CompilePostProcessor postBuild = null; + if (decodeStack) { + postBuild = (vm, file) -> { + DebugInformation debugInfo = debugEmitter.getDebugInformation(); + File sourceMapsFile = new File(file.getPath() + ".map"); + File debugFile = new File(file.getPath() + ".teavmdbg"); + try { + try (Writer writer = new OutputStreamWriter(new FileOutputStream(file, true), UTF_8)) { + writer.write("\n//# sourceMappingURL="); + writer.write(sourceMapsFile.getName()); + } - try (Writer sourceMapsOut = new OutputStreamWriter(new FileOutputStream(sourceMapsFile), UTF_8)) { - debugInfo.writeAsSourceMaps(sourceMapsOut, "", file.getPath()); - } + try (Writer sourceMapsOut = new OutputStreamWriter(new FileOutputStream(sourceMapsFile), UTF_8)) { + debugInfo.writeAsSourceMaps(sourceMapsOut, "", file.getPath()); + } - try (OutputStream out = new FileOutputStream(debugFile)) { - debugInfo.write(out); + try (OutputStream out = new FileOutputStream(debugFile)) { + debugInfo.write(out); + } + } catch (IOException e) { + throw new RuntimeException(e); } - } catch (IOException e) { - throw new RuntimeException(e); - } - }; + }; + } return compileTest(method, configuration, targetSupplier, TestEntryPoint.class.getName(), path, ".js", postBuild); }