1 /* 2 * Copyright (C) 2018 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 package com.android.tradefed.result; 17 18 import com.android.tradefed.device.ITestDevice; 19 import com.android.tradefed.metrics.proto.MetricMeasurement.Metric; 20 21 import org.easymock.EasyMock; 22 import org.junit.Before; 23 import org.junit.Test; 24 import org.junit.runner.RunWith; 25 import org.junit.runners.JUnit4; 26 27 import java.util.HashMap; 28 29 /** Unit tests for {@link LogcatCrashResultForwarder}. */ 30 @RunWith(JUnit4.class) 31 public class LogcatCrashResultForwarderTest { 32 private LogcatCrashResultForwarder mReporter; 33 private ITestInvocationListener mMockListener; 34 private ITestDevice mMockDevice; 35 36 @Before 37 public void setUp() { 38 mMockListener = EasyMock.createMock(ITestInvocationListener.class); 39 mMockDevice = EasyMock.createMock(ITestDevice.class); 40 } 41 42 /** Test if a crash is detected but no crash is found in the logcat. */ 43 @Test 44 @SuppressWarnings("MustBeClosedChecker") 45 public void testCaptureTestCrash_noCrashInLogcat() { 46 mReporter = new LogcatCrashResultForwarder(mMockDevice, mMockListener); 47 TestDescription test = new TestDescription("com.class", "test"); 48 49 mMockListener.testStarted(test, 0L); 50 EasyMock.expect(mMockDevice.getLogcatSince(0L)) 51 .andReturn(new ByteArrayInputStreamSource("".getBytes())); 52 mMockListener.testFailed(test, "instrumentation failed. reason: 'Process crashed.'"); 53 mMockListener.testEnded(test, 5L, new HashMap<String, Metric>()); 54 55 EasyMock.replay(mMockListener, mMockDevice); 56 mReporter.testStarted(test, 0L); 57 mReporter.testFailed(test, "instrumentation failed. reason: 'Process crashed.'"); 58 mReporter.testEnded(test, 5L, new HashMap<String, Metric>()); 59 EasyMock.verify(mMockListener, mMockDevice); 60 } 61 62 /** 63 * Test that if a crash is detected and found in the logcat, we add the extracted information to 64 * the failure. 65 */ 66 @Test 67 @SuppressWarnings("MustBeClosedChecker") 68 public void testCaptureTestCrash_oneCrashingLogcat() { 69 mReporter = new LogcatCrashResultForwarder(mMockDevice, mMockListener); 70 TestDescription test = new TestDescription("com.class", "test"); 71 72 mMockListener.testStarted(test, 0L); 73 String logcat = 74 "03-20 09:57:36.709 11 11 E AndroidRuntime: FATAL EXCEPTION: Thread-2\n" 75 + "03-20 09:57:36.709 11 11 E AndroidRuntime: Process: android.gesture.cts" 76 + ", PID: 11034\n" 77 + "03-20 09:57:36.709 11 11 E AndroidRuntime: java.lang.RuntimeException:" 78 + " Runtime\n" 79 + "03-20 09:57:36.709 11 11 E AndroidRuntime: at android.GestureTest$1" 80 + ".run(GestureTest.java:52)\n" 81 + "03-20 09:57:36.709 11 11 E AndroidRuntime: at java.lang.Thread.run" 82 + "(Thread.java:764)\n" 83 + "03-20 09:57:36.711 11 11 I TestRunner: started: testGetStrokesCount" 84 + "(android.gesture.cts.GestureTest)\n"; 85 86 EasyMock.expect(mMockDevice.getLogcatSince(0L)) 87 .andReturn(new ByteArrayInputStreamSource(logcat.getBytes())); 88 // Some crash was added to the failure 89 mMockListener.testFailed( 90 EasyMock.eq(test), 91 EasyMock.contains( 92 "instrumentation failed. reason: 'Process crashed.'" 93 + "\nCrash Message:Runtime")); 94 mMockListener.testEnded(test, 5L, new HashMap<String, Metric>()); 95 // If a run failure follows, expect it to contain the additional stack too. 96 mMockListener.testRunFailed( 97 EasyMock.contains("Something went wrong.\nCrash Message:Runtime")); 98 99 EasyMock.replay(mMockListener, mMockDevice); 100 mReporter.testStarted(test, 0L); 101 mReporter.testFailed(test, "instrumentation failed. reason: 'Process crashed.'"); 102 mReporter.testEnded(test, 5L, new HashMap<String, Metric>()); 103 mReporter.testRunFailed("Something went wrong."); 104 EasyMock.verify(mMockListener, mMockDevice); 105 } 106 107 /** 108 * Test that if a crash is note detected at testFailed but later found at testRunFailed, we 109 * still add the extracted information to the failure. 110 */ 111 @Test 112 @SuppressWarnings("MustBeClosedChecker") 113 public void testCaptureTestCrash_oneCrashingLogcatAfterTestEnded() { 114 mReporter = new LogcatCrashResultForwarder(mMockDevice, mMockListener); 115 TestDescription test = new TestDescription("com.class", "test"); 116 117 mMockListener.testStarted(test, 0L); 118 String logcat = 119 "03-20 09:57:36.709 11 11 E AndroidRuntime: FATAL EXCEPTION: Thread-2\n" 120 + "03-20 09:57:36.709 11 11 E AndroidRuntime: Process: android.gesture.cts" 121 + ", PID: 11034\n" 122 + "03-20 09:57:36.709 11 11 E AndroidRuntime: java.lang.RuntimeException:" 123 + " Runtime\n" 124 + "03-20 09:57:36.709 11 11 E AndroidRuntime: at android.GestureTest$1" 125 + ".run(GestureTest.java:52)\n" 126 + "03-20 09:57:36.709 11 11 E AndroidRuntime: at java.lang.Thread.run" 127 + "(Thread.java:764)\n" 128 + "03-20 09:57:36.711 11 11 I TestRunner: started: testGetStrokesCount" 129 + "(android.gesture.cts.GestureTest)\n"; 130 131 EasyMock.expect(mMockDevice.getLogcatSince(0L)) 132 .andReturn(new ByteArrayInputStreamSource(logcat.getBytes())); 133 // No crash added at the point of testFailed. 134 mMockListener.testFailed(test, "Something went wrong."); 135 mMockListener.testEnded(test, 5L, new HashMap<String, Metric>()); 136 // If a run failure comes with a crash detected, expect it to contain the additional stack. 137 mMockListener.testRunFailed( 138 EasyMock.contains( 139 "instrumentation failed. reason: 'Process crashed.'" 140 + "\nCrash Message:Runtime")); 141 142 EasyMock.replay(mMockListener, mMockDevice); 143 mReporter.testStarted(test, 0L); 144 mReporter.testFailed(test, "Something went wrong."); 145 mReporter.testEnded(test, 5L, new HashMap<String, Metric>()); 146 mReporter.testRunFailed("instrumentation failed. reason: 'Process crashed.'"); 147 EasyMock.verify(mMockListener, mMockDevice); 148 } 149 } 150