1 /* 2 * Copyright (C) 2016 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package vogar.target; 18 19 import java.util.Arrays; 20 import org.junit.runner.Description; 21 import org.junit.runner.notification.Failure; 22 import org.junit.runner.notification.RunListener; 23 import vogar.Result; 24 import vogar.monitor.TargetMonitor; 25 import vogar.target.junit.JUnitUtils; 26 27 /** 28 * A {@link RunListener} that will notify the vogar main process of the results of the tests. 29 */ 30 public class TargetMonitorRunListener extends RunListener { 31 32 private final TargetMonitor monitor; 33 private Failure failure; 34 35 public TargetMonitorRunListener(TargetMonitor monitor) { 36 this.monitor = monitor; 37 } 38 39 @Override 40 public void testStarted(Description description) throws Exception { 41 failure = null; 42 monitor.outcomeStarted(JUnitUtils.getTestName(description)); 43 } 44 45 @Override 46 public void testFailure(Failure failure) throws Exception { 47 this.failure = failure; 48 } 49 50 @Override 51 public void testFinished(Description description) throws Exception { 52 if (failure == null) { 53 monitor.outcomeFinished(Result.SUCCESS); 54 } else { 55 @SuppressWarnings("ThrowableResultOfMethodCallIgnored") 56 Throwable thrown = failure.getException(); 57 prepareForDisplay(thrown); 58 thrown.printStackTrace(System.out); 59 monitor.outcomeFinished(Result.EXEC_FAILED); 60 } 61 } 62 63 /** 64 * Strip vogar's lines from the stack trace. For example, we'd strip the 65 * first two Assert lines and everything after the testFoo() line in this 66 * stack trace: 67 * 68 * at junit.framework.Assert.fail(Assert.java:198) 69 * at junit.framework.Assert.assertEquals(Assert.java:56) 70 * at junit.framework.Assert.assertEquals(Assert.java:61) 71 * at libcore.java.net.FooTest.testFoo(FooTest.java:124) 72 * at java.lang.reflect.Method.invokeNative(Native Method) 73 * at java.lang.reflect.Method.invoke(Method.java:491) 74 * at vogar.target.junit.Junit$JUnitTest.run(Junit.java:214) 75 * at vogar.target.junit.JUnitRunner$1.call(JUnitRunner.java:112) 76 * at vogar.target.junit.JUnitRunner$1.call(JUnitRunner.java:105) 77 * at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305) 78 * at java.util.concurrent.FutureTask.run(FutureTask.java:137) 79 * at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076) 80 * at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569) 81 * at java.lang.Thread.run(Thread.java:863) 82 */ 83 private static void prepareForDisplay(Throwable t) { 84 StackTraceElement[] stackTraceElements = t.getStackTrace(); 85 boolean foundVogar = false; 86 87 int last = stackTraceElements.length - 1; 88 for (; last >= 0; last--) { 89 String className = stackTraceElements[last].getClassName(); 90 if (className.startsWith("vogar.target")) { 91 foundVogar = true; 92 } else if (foundVogar 93 && !className.startsWith("java.lang.reflect") 94 && !className.startsWith("sun.reflect") 95 && !className.startsWith("junit.framework")) { 96 if (last < stackTraceElements.length) { 97 last++; 98 } 99 break; 100 } 101 } 102 103 int first = 0; 104 for (; first < last; first++) { 105 String className = stackTraceElements[first].getClassName(); 106 if (!className.startsWith("junit.framework")) { 107 break; 108 } 109 } 110 111 if (first > 0) { 112 first--; // retain one assertSomething() line in the trace 113 } 114 115 if (first < last) { 116 t.setStackTrace(Arrays.copyOfRange(stackTraceElements, first, last)); 117 } 118 } 119 } 120