1 /* 2 * Copyright (C) 2012 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.loganalysis.parser; 17 18 import com.android.loganalysis.item.JavaCrashItem; 19 import com.android.loganalysis.item.LogcatItem; 20 import com.android.loganalysis.item.MiscLogcatItem; 21 import com.android.loganalysis.util.ArrayUtil; 22 23 import junit.framework.TestCase; 24 25 import java.text.DateFormat; 26 import java.text.ParseException; 27 import java.text.SimpleDateFormat; 28 import java.util.Arrays; 29 import java.util.Date; 30 import java.util.List; 31 import java.util.regex.Pattern; 32 33 /** 34 * Unit tests for {@link LogcatParserTest}. 35 */ 36 public class LogcatParserTest extends TestCase { 37 38 /** 39 * Test that an ANR is parsed in the log. 40 */ 41 public void testParse_anr() throws ParseException { 42 List<String> lines = Arrays.asList( 43 "04-25 17:17:08.445 312 366 E ActivityManager: ANR (application not responding) in process: com.android.package", 44 "04-25 17:17:08.445 312 366 E ActivityManager: Reason: keyDispatchingTimedOut", 45 "04-25 17:17:08.445 312 366 E ActivityManager: Load: 0.71 / 0.83 / 0.51", 46 "04-25 17:17:08.445 312 366 E ActivityManager: 33% TOTAL: 21% user + 11% kernel + 0.3% iowait"); 47 48 LogcatItem logcat = new LogcatParser("2012").parse(lines); 49 assertNotNull(logcat); 50 assertEquals(parseTime("2012-04-25 17:17:08.445"), logcat.getStartTime()); 51 assertEquals(parseTime("2012-04-25 17:17:08.445"), logcat.getStopTime()); 52 assertEquals(1, logcat.getEvents().size()); 53 assertEquals(1, logcat.getAnrs().size()); 54 assertEquals(312, logcat.getAnrs().get(0).getPid().intValue()); 55 assertEquals(366, logcat.getAnrs().get(0).getTid().intValue()); 56 assertEquals("", logcat.getAnrs().get(0).getLastPreamble()); 57 assertEquals("", logcat.getAnrs().get(0).getProcessPreamble()); 58 assertEquals(parseTime("2012-04-25 17:17:08.445"), logcat.getAnrs().get(0).getEventTime()); 59 } 60 61 /** 62 * Test that an ANR is parsed in the log. 63 */ 64 public void testParse_anr_pid() throws ParseException { 65 List<String> lines = Arrays.asList( 66 "04-25 17:17:08.445 312 366 E ActivityManager: ANR (application not responding) in process: com.android.package", 67 "04-25 17:17:08.445 312 366 E ActivityManager: PID: 1234", 68 "04-25 17:17:08.445 312 366 E ActivityManager: Reason: keyDispatchingTimedOut", 69 "04-25 17:17:08.445 312 366 E ActivityManager: Load: 0.71 / 0.83 / 0.51", 70 "04-25 17:17:08.445 312 366 E ActivityManager: 33% TOTAL: 21% user + 11% kernel + 0.3% iowait"); 71 72 LogcatItem logcat = new LogcatParser("2012").parse(lines); 73 assertNotNull(logcat); 74 assertEquals(parseTime("2012-04-25 17:17:08.445"), logcat.getStartTime()); 75 assertEquals(parseTime("2012-04-25 17:17:08.445"), logcat.getStopTime()); 76 assertEquals(1, logcat.getEvents().size()); 77 assertEquals(1, logcat.getAnrs().size()); 78 assertEquals(1234, logcat.getAnrs().get(0).getPid().intValue()); 79 assertNull(logcat.getAnrs().get(0).getTid()); 80 assertEquals("", logcat.getAnrs().get(0).getLastPreamble()); 81 assertEquals("", logcat.getAnrs().get(0).getProcessPreamble()); 82 assertEquals(parseTime("2012-04-25 17:17:08.445"), logcat.getAnrs().get(0).getEventTime()); 83 } 84 85 /** 86 * Test that Java crashes can be parsed. 87 */ 88 public void testParse_java_crash() throws ParseException { 89 List<String> lines = Arrays.asList( 90 "04-25 09:55:47.799 3064 3082 E AndroidRuntime: java.lang.Exception", 91 "04-25 09:55:47.799 3064 3082 E AndroidRuntime: \tat class.method1(Class.java:1)", 92 "04-25 09:55:47.799 3064 3082 E AndroidRuntime: \tat class.method2(Class.java:2)", 93 "04-25 09:55:47.799 3064 3082 E AndroidRuntime: \tat class.method3(Class.java:3)"); 94 95 LogcatItem logcat = new LogcatParser("2012").parse(lines); 96 assertNotNull(logcat); 97 assertEquals(parseTime("2012-04-25 09:55:47.799"), logcat.getStartTime()); 98 assertEquals(parseTime("2012-04-25 09:55:47.799"), logcat.getStopTime()); 99 assertEquals(1, logcat.getEvents().size()); 100 assertEquals(1, logcat.getJavaCrashes().size()); 101 assertEquals(3064, logcat.getJavaCrashes().get(0).getPid().intValue()); 102 assertEquals(3082, logcat.getJavaCrashes().get(0).getTid().intValue()); 103 assertEquals("", logcat.getJavaCrashes().get(0).getLastPreamble()); 104 assertEquals("", logcat.getJavaCrashes().get(0).getProcessPreamble()); 105 assertEquals(parseTime("2012-04-25 09:55:47.799"), 106 logcat.getJavaCrashes().get(0).getEventTime()); 107 } 108 109 public void testParse_test_exception() { 110 List<String> lines = Arrays.asList( 111 "11-25 19:26:53.581 5832 7008 I TestRunner: ----- begin exception -----", 112 "11-25 19:26:53.589 5832 7008 I TestRunner: ", 113 "11-25 19:26:53.589 5832 7008 I TestRunner: java.util.concurrent.TimeoutException", 114 "11-25 19:26:53.589 5832 7008 I TestRunner: at android.support.test.uiautomator.WaitMixin.wait(WaitMixin.java:49)", 115 "11-25 19:26:53.589 5832 7008 I TestRunner: at android.support.test.uiautomator.WaitMixin.wait(WaitMixin.java:36)", 116 "11-25 19:26:53.589 5832 7008 I TestRunner: at android.support.test.uiautomator.UiDevice.wait(UiDevice.java:169)", 117 "11-25 19:26:53.589 5832 7008 I TestRunner: at com.android.test.uiautomator.common.helpers.MapsHelper.doSearch(MapsHelper.java:87)", 118 "11-25 19:26:53.589 5832 7008 I TestRunner: at com.android.test.uiautomator.aupt.MapsTest.testMaps(MapsTest.java:58)", 119 "11-25 19:26:53.589 5832 7008 I TestRunner: at java.lang.reflect.Method.invoke(Native Method)", 120 "11-25 19:26:53.589 5832 7008 I TestRunner: at java.lang.reflect.Method.invoke(Method.java:372)", 121 "11-25 19:26:53.589 5832 7008 I TestRunner: at android.test.InstrumentationTestCase.runMethod(InstrumentationTestCase.java:214)", 122 "11-25 19:26:53.589 5832 7008 I TestRunner: at android.test.InstrumentationTestCase.runTest(InstrumentationTestCase.java:199)", 123 "11-25 19:26:53.589 5832 7008 I TestRunner: at junit.framework.TestCase.runBare(TestCase.java:134)", 124 "11-25 19:26:53.589 5832 7008 I TestRunner: at junit.framework.TestResult$1.protect(TestResult.java:115)", 125 "11-25 19:26:53.589 5832 7008 I TestRunner: at junit.framework.TestResult.runProtected(TestResult.java:133)", 126 "11-25 19:26:53.589 5832 7008 I TestRunner: at junit.framework.TestResult.run(TestResult.java:118)", 127 "11-25 19:26:53.589 5832 7008 I TestRunner: at junit.framework.TestCase.run(TestCase.java:124)", 128 "11-25 19:26:53.589 5832 7008 I TestRunner: at android.support.test.aupt.AuptTestRunner$AuptPrivateTestRunner.runTest(AuptTestRunner.java:182)", 129 "11-25 19:26:53.589 5832 7008 I TestRunner: at android.test.AndroidTestRunner.runTest(AndroidTestRunner.java:176)", 130 "11-25 19:26:53.589 5832 7008 I TestRunner: at android.test.InstrumentationTestRunner.onStart(InstrumentationTestRunner.java:555)", 131 "11-25 19:26:53.589 5832 7008 I TestRunner: at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:1848)", 132 "11-25 19:26:53.589 5832 7008 I TestRunner: ----- end exception -----" 133 ); 134 135 LogcatParser logcatParser = new LogcatParser("2012"); 136 logcatParser.addJavaCrashTag("I", "TestRunner", LogcatParser.JAVA_CRASH); 137 LogcatItem logcat = logcatParser.parse(lines); 138 assertNotNull(logcat); 139 assertEquals(1, logcat.getEvents().size()); 140 assertEquals(1, logcat.getJavaCrashes().size()); 141 assertEquals(5832, logcat.getJavaCrashes().get(0).getPid().intValue()); 142 assertEquals(7008, logcat.getJavaCrashes().get(0).getTid().intValue()); 143 assertEquals("", logcat.getJavaCrashes().get(0).getLastPreamble()); 144 assertEquals("", logcat.getJavaCrashes().get(0).getProcessPreamble()); 145 assertEquals(LogcatParser.JAVA_CRASH, logcat.getJavaCrashes().get(0).getCategory()); 146 } 147 148 public void testParse_test_exception_with_exras() { 149 List<String> lines = Arrays.asList( 150 "12-06 17:19:18.746 6598 7960 I TestRunner: failed: testYouTube(com.android.test.uiautomator.aupt.YouTubeTest)", 151 "12-06 17:19:18.746 6598 7960 I TestRunner: ----- begin exception -----", 152 "12-06 17:19:18.747 6598 7960 I TestRunner: ", 153 "12-06 17:19:18.747 6598 7960 I TestRunner: java.util.concurrent.TimeoutException", 154 "12-06 17:19:18.747 6598 7960 I TestRunner: at android.support.test.uiautomator.WaitMixin.wait(WaitMixin.java:49)", 155 "12-06 17:19:18.747 6598 7960 I TestRunner: at android.support.test.uiautomator.WaitMixin.wait(WaitMixin.java:36)", 156 "12-06 17:19:18.747 6598 7960 I TestRunner: at android.support.test.uiautomator.UiDevice.wait(UiDevice.java:169)", 157 "12-06 17:19:18.747 6598 7960 I TestRunner: at android.support.test.aupt.AppLauncher.launchApp(AppLauncher.java:127)", 158 "12-06 17:19:18.747 6598 7960 I TestRunner: at com.android.test.uiautomator.common.helpers.YouTubeHelper.open(YouTubeHelper.java:49)", 159 "12-06 17:19:18.747 6598 7960 I TestRunner: at com.android.test.uiautomator.aupt.YouTubeTest.setUp(YouTubeTest.java:44)", 160 "12-06 17:19:18.747 6598 7960 I TestRunner: at junit.framework.TestCase.runBare(TestCase.java:132)", 161 "12-06 17:19:18.747 6598 7960 I TestRunner: at junit.framework.TestResult$1.protect(TestResult.java:115)", 162 "12-06 17:19:18.747 6598 7960 I TestRunner: at junit.framework.TestResult.runProtected(TestResult.java:133)", 163 "12-06 17:19:18.747 6598 7960 I TestRunner: at junit.framework.TestResult.run(TestResult.java:118)", 164 "12-06 17:19:18.747 6598 7960 I TestRunner: at junit.framework.TestCase.run(TestCase.java:124)", 165 "12-06 17:19:18.747 6598 7960 I TestRunner: at android.support.test.aupt.AuptTestRunner$AuptPrivateTestRunner.runTest(AuptTestRunner.java:182)", 166 "12-06 17:19:18.747 6598 7960 I TestRunner: at android.test.AndroidTestRunner.runTest(AndroidTestRunner.java:176)", 167 "12-06 17:19:18.747 6598 7960 I TestRunner: at android.test.InstrumentationTestRunner.onStart(InstrumentationTestRunner.java:555)", 168 "12-06 17:19:18.747 6598 7960 I TestRunner: at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:1851)", 169 "12-06 17:19:18.747 6598 7960 I TestRunner: ----- end exception -----" 170 ); 171 172 LogcatParser logcatParser = new LogcatParser("2012"); 173 logcatParser.addJavaCrashTag("I", "TestRunner", LogcatParser.JAVA_CRASH); 174 LogcatItem logcat = logcatParser.parse(lines); 175 assertNotNull(logcat); 176 assertEquals(1, logcat.getEvents().size()); 177 assertEquals(1, logcat.getJavaCrashes().size()); 178 assertEquals(6598, logcat.getJavaCrashes().get(0).getPid().intValue()); 179 assertEquals(7960, logcat.getJavaCrashes().get(0).getTid().intValue()); 180 assertEquals("", logcat.getJavaCrashes().get(0).getLastPreamble()); 181 assertEquals("", logcat.getJavaCrashes().get(0).getProcessPreamble()); 182 // Check that lines not related to java crash are absent 183 assertFalse(logcat.getJavaCrashes().get(0).getStack().contains("begin exception")); 184 assertFalse(logcat.getJavaCrashes().get(0).getStack().contains("end exception")); 185 assertFalse(logcat.getJavaCrashes().get(0).getStack().contains("failed: testYouTube")); 186 //System.out.println(logcat.getJavaCrashes().get(0).getStack()); 187 } 188 189 /** 190 * Test that Java crashes from system server can be parsed. 191 */ 192 public void testParse_java_crash_system_server() throws ParseException { 193 List<String> lines = Arrays.asList( 194 "04-25 09:55:47.799 3064 3082 E AndroidRuntime: *** FATAL EXCEPTION IN SYSTEM PROCESS: message", 195 "04-25 09:55:47.799 3064 3082 E AndroidRuntime: java.lang.Exception", 196 "04-25 09:55:47.799 3064 3082 E AndroidRuntime: \tat class.method1(Class.java:1)", 197 "04-25 09:55:47.799 3064 3082 E AndroidRuntime: \tat class.method2(Class.java:2)", 198 "04-25 09:55:47.799 3064 3082 E AndroidRuntime: \tat class.method3(Class.java:3)"); 199 200 LogcatItem logcat = new LogcatParser("2012").parse(lines); 201 assertNotNull(logcat); 202 assertEquals(parseTime("2012-04-25 09:55:47.799"), logcat.getStartTime()); 203 assertEquals(parseTime("2012-04-25 09:55:47.799"), logcat.getStopTime()); 204 assertEquals(1, logcat.getEvents().size()); 205 assertEquals(1, logcat.getJavaCrashes().size()); 206 assertEquals("system_server", logcat.getJavaCrashes().get(0).getApp()); 207 assertEquals(3064, logcat.getJavaCrashes().get(0).getPid().intValue()); 208 assertEquals(3082, logcat.getJavaCrashes().get(0).getTid().intValue()); 209 assertEquals("", logcat.getJavaCrashes().get(0).getLastPreamble()); 210 assertEquals("", logcat.getJavaCrashes().get(0).getProcessPreamble()); 211 assertEquals(parseTime("2012-04-25 09:55:47.799"), 212 logcat.getJavaCrashes().get(0).getEventTime()); 213 } 214 215 /** 216 * Test that Java crashes with process and pid can be parsed. 217 */ 218 public void testParse_java_crash_process_pid() throws ParseException { 219 List<String> lines = Arrays.asList( 220 "04-25 09:55:47.799 3064 3082 E AndroidRuntime: FATAL EXCEPTION: main", 221 "04-25 09:55:47.799 3064 3082 E AndroidRuntime: Process: com.android.package, PID: 1234", 222 "04-25 09:55:47.799 3064 3082 E AndroidRuntime: java.lang.Exception", 223 "04-25 09:55:47.799 3064 3082 E AndroidRuntime: \tat class.method1(Class.java:1)", 224 "04-25 09:55:47.799 3064 3082 E AndroidRuntime: \tat class.method2(Class.java:2)", 225 "04-25 09:55:47.799 3064 3082 E AndroidRuntime: \tat class.method3(Class.java:3)"); 226 227 LogcatItem logcat = new LogcatParser("2012").parse(lines); 228 assertNotNull(logcat); 229 assertEquals(parseTime("2012-04-25 09:55:47.799"), logcat.getStartTime()); 230 assertEquals(parseTime("2012-04-25 09:55:47.799"), logcat.getStopTime()); 231 assertEquals(1, logcat.getEvents().size()); 232 assertEquals(1, logcat.getJavaCrashes().size()); 233 assertEquals("com.android.package", logcat.getJavaCrashes().get(0).getApp()); 234 assertEquals(1234, logcat.getJavaCrashes().get(0).getPid().intValue()); 235 assertNull(logcat.getJavaCrashes().get(0).getTid()); 236 assertEquals("", logcat.getJavaCrashes().get(0).getLastPreamble()); 237 assertEquals("", logcat.getJavaCrashes().get(0).getProcessPreamble()); 238 assertEquals(parseTime("2012-04-25 09:55:47.799"), 239 logcat.getJavaCrashes().get(0).getEventTime()); 240 } 241 242 /** 243 * Test that Java crashes with pid can be parsed. 244 */ 245 public void testParse_java_crash_pid() throws ParseException { 246 List<String> lines = Arrays.asList( 247 "04-25 09:55:47.799 3064 3082 E AndroidRuntime: FATAL EXCEPTION: main", 248 "04-25 09:55:47.799 3064 3082 E AndroidRuntime: PID: 1234", 249 "04-25 09:55:47.799 3064 3082 E AndroidRuntime: java.lang.Exception", 250 "04-25 09:55:47.799 3064 3082 E AndroidRuntime: \tat class.method1(Class.java:1)", 251 "04-25 09:55:47.799 3064 3082 E AndroidRuntime: \tat class.method2(Class.java:2)", 252 "04-25 09:55:47.799 3064 3082 E AndroidRuntime: \tat class.method3(Class.java:3)"); 253 254 LogcatItem logcat = new LogcatParser("2012").parse(lines); 255 assertNotNull(logcat); 256 assertEquals(parseTime("2012-04-25 09:55:47.799"), logcat.getStartTime()); 257 assertEquals(parseTime("2012-04-25 09:55:47.799"), logcat.getStopTime()); 258 assertEquals(1, logcat.getEvents().size()); 259 assertEquals(1, logcat.getJavaCrashes().size()); 260 assertNull(logcat.getJavaCrashes().get(0).getApp()); 261 assertEquals(1234, logcat.getJavaCrashes().get(0).getPid().intValue()); 262 assertNull(logcat.getJavaCrashes().get(0).getTid()); 263 assertEquals("", logcat.getJavaCrashes().get(0).getLastPreamble()); 264 assertEquals("", logcat.getJavaCrashes().get(0).getProcessPreamble()); 265 assertEquals(parseTime("2012-04-25 09:55:47.799"), 266 logcat.getJavaCrashes().get(0).getEventTime()); 267 } 268 269 /** 270 * Test that Java crashes with process and pid without stack can be parsed. 271 */ 272 public void testParse_java_crash_empty() throws ParseException { 273 List<String> lines = Arrays.asList( 274 "04-25 09:55:47.799 3064 3082 E AndroidRuntime: FATAL EXCEPTION: main", 275 "04-25 09:55:47.799 3064 3082 E AndroidRuntime: PID: 1234"); 276 277 LogcatItem logcat = new LogcatParser("2012").parse(lines); 278 assertNotNull(logcat); 279 assertEquals(parseTime("2012-04-25 09:55:47.799"), logcat.getStartTime()); 280 assertEquals(parseTime("2012-04-25 09:55:47.799"), logcat.getStopTime()); 281 assertEquals(0, logcat.getEvents().size()); 282 assertEquals(0, logcat.getJavaCrashes().size()); 283 } 284 285 /** 286 * Test that native crashes can be parsed from the info log level. 287 */ 288 public void testParse_native_crash_info() throws ParseException { 289 List<String> lines = Arrays.asList( 290 "04-25 18:33:27.273 115 115 I DEBUG : Build fingerprint: 'product:build:target'", 291 "04-25 18:33:27.273 115 115 I DEBUG : pid: 3112, tid: 3112 >>> com.google.android.browser <<<", 292 "04-25 18:33:27.273 115 115 I DEBUG : signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 00000000"); 293 294 LogcatItem logcat = new LogcatParser("2012").parse(lines); 295 assertNotNull(logcat); 296 assertEquals(parseTime("2012-04-25 18:33:27.273"), logcat.getStartTime()); 297 assertEquals(parseTime("2012-04-25 18:33:27.273"), logcat.getStopTime()); 298 assertEquals(1, logcat.getEvents().size()); 299 assertEquals(1, logcat.getNativeCrashes().size()); 300 assertEquals(3112, logcat.getNativeCrashes().get(0).getPid().intValue()); 301 assertEquals(3112, logcat.getNativeCrashes().get(0).getTid().intValue()); 302 assertEquals("com.google.android.browser", logcat.getNativeCrashes().get(0).getApp()); 303 assertEquals("", logcat.getNativeCrashes().get(0).getLastPreamble()); 304 assertEquals("", logcat.getNativeCrashes().get(0).getProcessPreamble()); 305 assertEquals(parseTime("2012-04-25 18:33:27.273"), 306 logcat.getNativeCrashes().get(0).getEventTime()); 307 } 308 309 /** 310 * Test that native crashes can be parsed from the fatal log level. 311 */ 312 public void testParse_native_crash_fatal() throws ParseException { 313 List<String> lines = Arrays.asList( 314 "04-25 18:33:27.273 115 115 F DEBUG : Build fingerprint: 'product:build:target'", 315 "04-25 18:33:27.273 115 115 F DEBUG : pid: 3112, tid: 3112, name: Name >>> com.google.android.browser <<<", 316 "04-25 18:33:27.273 115 115 F DEBUG : signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 00000000"); 317 318 LogcatItem logcat = new LogcatParser("2012").parse(lines); 319 assertNotNull(logcat); 320 assertEquals(parseTime("2012-04-25 18:33:27.273"), logcat.getStartTime()); 321 assertEquals(parseTime("2012-04-25 18:33:27.273"), logcat.getStopTime()); 322 assertEquals(1, logcat.getEvents().size()); 323 assertEquals(1, logcat.getNativeCrashes().size()); 324 assertEquals(3112, logcat.getNativeCrashes().get(0).getPid().intValue()); 325 assertEquals(3112, logcat.getNativeCrashes().get(0).getTid().intValue()); 326 assertEquals("com.google.android.browser", logcat.getNativeCrashes().get(0).getApp()); 327 assertEquals("", logcat.getNativeCrashes().get(0).getLastPreamble()); 328 assertEquals("", logcat.getNativeCrashes().get(0).getProcessPreamble()); 329 assertEquals(parseTime("2012-04-25 18:33:27.273"), 330 logcat.getNativeCrashes().get(0).getEventTime()); 331 } 332 333 /** 334 * Test that native crashes can be parsed if they have the same pid/tid. 335 */ 336 public void testParse_native_crash_same_pid() throws ParseException { 337 List<String> lines = Arrays.asList( 338 "04-25 18:33:27.273 115 115 I DEBUG : *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***", 339 "04-25 18:33:27.273 115 115 I DEBUG : Build fingerprint: 'product:build:target'", 340 "04-25 18:33:27.273 115 115 I DEBUG : pid: 3112, tid: 3112 >>> com.google.android.browser <<<", 341 "04-25 18:33:27.273 115 115 I DEBUG : signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 00000000", 342 "04-25 18:33:27.273 115 115 I DEBUG : *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***", 343 "04-25 18:33:27.273 115 115 I DEBUG : Build fingerprint: 'product:build:target'", 344 "04-25 18:33:27.273 115 115 I DEBUG : pid: 3113, tid: 3113 >>> com.google.android.browser2 <<<", 345 "04-25 18:33:27.273 115 115 I DEBUG : signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 00000000"); 346 347 LogcatItem logcat = new LogcatParser("2012").parse(lines); 348 assertNotNull(logcat); 349 assertEquals(parseTime("2012-04-25 18:33:27.273"), logcat.getStartTime()); 350 assertEquals(parseTime("2012-04-25 18:33:27.273"), logcat.getStopTime()); 351 assertEquals(2, logcat.getEvents().size()); 352 assertEquals(2, logcat.getNativeCrashes().size()); 353 assertEquals(3112, logcat.getNativeCrashes().get(0).getPid().intValue()); 354 assertEquals(3112, logcat.getNativeCrashes().get(0).getTid().intValue()); 355 assertEquals("com.google.android.browser", logcat.getNativeCrashes().get(0).getApp()); 356 assertEquals(3113, logcat.getNativeCrashes().get(1).getPid().intValue()); 357 assertEquals(3113, logcat.getNativeCrashes().get(1).getTid().intValue()); 358 assertEquals("com.google.android.browser2", logcat.getNativeCrashes().get(1).getApp()); 359 } 360 361 public void testParse_misc_events() throws ParseException { 362 List<String> lines = Arrays.asList( 363 "04-25 18:33:27.273 1676 1821 W AudioTrack: obtainBuffer timed out (is the CPU pegged?) 0x361378 user=0000116a, server=00000000", 364 "04-25 18:33:28.273 7813 7813 E gralloc : GetBufferLock timed out for thread 7813 buffer 0x61 usage 0x200 LockState 1", 365 "04-25 18:33:29.273 395 637 W Watchdog: *** WATCHDOG KILLING SYSTEM PROCESS: null"); 366 367 LogcatItem logcat = new LogcatParser("2012").parse(lines); 368 assertNotNull(logcat); 369 assertEquals(parseTime("2012-04-25 18:33:27.273"), logcat.getStartTime()); 370 assertEquals(parseTime("2012-04-25 18:33:29.273"), logcat.getStopTime()); 371 assertEquals(3, logcat.getEvents().size()); 372 assertEquals(1, logcat.getMiscEvents(LogcatParser.HIGH_CPU_USAGE).size()); 373 assertEquals(1, logcat.getMiscEvents(LogcatParser.HIGH_MEMORY_USAGE).size()); 374 assertEquals(1, logcat.getMiscEvents(LogcatParser.RUNTIME_RESTART).size()); 375 376 MiscLogcatItem item = logcat.getMiscEvents(LogcatParser.HIGH_CPU_USAGE).get(0); 377 378 assertEquals(1676, item.getPid().intValue()); 379 assertEquals(1821, item.getTid().intValue()); 380 assertEquals(parseTime("2012-04-25 18:33:27.273"), item.getEventTime()); 381 382 item = logcat.getMiscEvents(LogcatParser.HIGH_MEMORY_USAGE).get(0); 383 384 assertEquals(7813, item.getPid().intValue()); 385 assertEquals(7813, item.getTid().intValue()); 386 assertEquals(parseTime("2012-04-25 18:33:28.273"), item.getEventTime()); 387 388 item = logcat.getMiscEvents(LogcatParser.RUNTIME_RESTART).get(0); 389 390 assertEquals(395, item.getPid().intValue()); 391 assertEquals(637, item.getTid().intValue()); 392 assertEquals(parseTime("2012-04-25 18:33:29.273"), item.getEventTime()); 393 } 394 395 /** 396 * Test that multiple events can be parsed. 397 */ 398 public void testParse_multiple_events() throws ParseException { 399 List<String> lines = Arrays.asList( 400 "04-25 09:55:47.799 3064 3082 E AndroidRuntime: java.lang.Exception", 401 "04-25 09:55:47.799 3064 3082 E AndroidRuntime: \tat class.method1(Class.java:1)", 402 "04-25 09:55:47.799 3064 3082 E AndroidRuntime: \tat class.method2(Class.java:2)", 403 "04-25 09:55:47.799 3064 3082 E AndroidRuntime: \tat class.method3(Class.java:3)", 404 "04-25 09:55:47.799 3065 3090 E AndroidRuntime: java.lang.Exception", 405 "04-25 09:55:47.799 3065 3090 E AndroidRuntime: \tat class.method1(Class.java:1)", 406 "04-25 09:55:47.799 3065 3090 E AndroidRuntime: \tat class.method2(Class.java:2)", 407 "04-25 09:55:47.799 3065 3090 E AndroidRuntime: \tat class.method3(Class.java:3)", 408 "04-25 17:17:08.445 312 366 E ActivityManager: ANR (application not responding) in process: com.android.package", 409 "04-25 17:17:08.445 312 366 E ActivityManager: Reason: keyDispatchingTimedOut", 410 "04-25 17:17:08.445 312 366 E ActivityManager: Load: 0.71 / 0.83 / 0.51", 411 "04-25 17:17:08.445 312 366 E ActivityManager: 33% TOTAL: 21% user + 11% kernel + 0.3% iowait", 412 "04-25 17:17:08.445 312 366 E ActivityManager: ANR (application not responding) in process: com.android.package", 413 "04-25 17:17:08.445 312 366 E ActivityManager: Reason: keyDispatchingTimedOut", 414 "04-25 17:17:08.445 312 366 E ActivityManager: Load: 0.71 / 0.83 / 0.51", 415 "04-25 17:17:08.445 312 366 E ActivityManager: 33% TOTAL: 21% user + 11% kernel + 0.3% iowait", 416 "04-25 18:33:27.273 115 115 I DEBUG : *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***", 417 "04-25 18:33:27.273 115 115 I DEBUG : Build fingerprint: 'product:build:target'", 418 "04-25 18:33:27.273 115 115 I DEBUG : pid: 3112, tid: 3112 >>> com.google.android.browser <<<", 419 "04-25 18:33:27.273 115 115 I DEBUG : signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 00000000", 420 "04-25 18:33:27.273 117 117 I DEBUG : *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***", 421 "04-25 18:33:27.273 117 117 I DEBUG : Build fingerprint: 'product:build:target'", 422 "04-25 18:33:27.273 117 117 I DEBUG : pid: 3113, tid: 3113 >>> com.google.android.browser <<<", 423 "04-25 18:33:27.273 117 117 I DEBUG : signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 00000000"); 424 425 426 LogcatItem logcat = new LogcatParser("2012").parse(lines); 427 assertNotNull(logcat); 428 assertEquals(parseTime("2012-04-25 09:55:47.799"), logcat.getStartTime()); 429 assertEquals(parseTime("2012-04-25 18:33:27.273"), logcat.getStopTime()); 430 assertEquals(6, logcat.getEvents().size()); 431 assertEquals(2, logcat.getAnrs().size()); 432 assertEquals(2, logcat.getJavaCrashes().size()); 433 assertEquals(2, logcat.getNativeCrashes().size()); 434 435 assertEquals(312, logcat.getAnrs().get(0).getPid().intValue()); 436 assertEquals(366, logcat.getAnrs().get(0).getTid().intValue()); 437 assertEquals(parseTime("2012-04-25 17:17:08.445"), logcat.getAnrs().get(0).getEventTime()); 438 439 assertEquals(312, logcat.getAnrs().get(1).getPid().intValue()); 440 assertEquals(366, logcat.getAnrs().get(1).getTid().intValue()); 441 assertEquals(parseTime("2012-04-25 17:17:08.445"), logcat.getAnrs().get(1).getEventTime()); 442 443 assertEquals(3064, logcat.getJavaCrashes().get(0).getPid().intValue()); 444 assertEquals(3082, logcat.getJavaCrashes().get(0).getTid().intValue()); 445 assertEquals( 446 parseTime("2012-04-25 09:55:47.799"), 447 logcat.getJavaCrashes().get(0).getEventTime()); 448 449 assertEquals(3065, logcat.getJavaCrashes().get(1).getPid().intValue()); 450 assertEquals(3090, logcat.getJavaCrashes().get(1).getTid().intValue()); 451 assertEquals( 452 parseTime("2012-04-25 09:55:47.799"), 453 logcat.getJavaCrashes().get(1).getEventTime()); 454 455 assertEquals(3112, logcat.getNativeCrashes().get(0).getPid().intValue()); 456 assertEquals(3112, logcat.getNativeCrashes().get(0).getTid().intValue()); 457 assertEquals( 458 parseTime("2012-04-25 18:33:27.273"), 459 logcat.getNativeCrashes().get(0).getEventTime()); 460 461 assertEquals(3113, logcat.getNativeCrashes().get(1).getPid().intValue()); 462 assertEquals(3113, logcat.getNativeCrashes().get(1).getTid().intValue()); 463 assertEquals( 464 parseTime("2012-04-25 18:33:27.273"), 465 logcat.getNativeCrashes().get(1).getEventTime()); 466 } 467 468 /** Test that including extra uid column still parses the logs. */ 469 public void testParse_uid() throws ParseException { 470 List<String> lines = 471 Arrays.asList( 472 "04-25 09:55:47.799 wifi 3064 3082 E AndroidRuntime: java.lang.Exception", 473 "04-25 09:55:47.799 wifi 3064 3082 E AndroidRuntime: \tat class.method1(Class.java:1)", 474 "04-25 09:55:47.799 wifi 3064 3082 E AndroidRuntime: \tat class.method2(Class.java:2)", 475 "04-25 09:55:47.799 wifi 3064 3082 E AndroidRuntime: \tat class.method3(Class.java:3)", 476 "04-25 09:55:47.799 wifi 3065 3090 E AndroidRuntime: java.lang.Exception", 477 "04-25 09:55:47.799 wifi 3065 3090 E AndroidRuntime: \tat class.method1(Class.java:1)", 478 "04-25 09:55:47.799 wifi 3065 3090 E AndroidRuntime: \tat class.method2(Class.java:2)", 479 "04-25 09:55:47.799 wifi 3065 3090 E AndroidRuntime: \tat class.method3(Class.java:3)", 480 "04-25 17:17:08.445 1337 312 366 E ActivityManager: ANR (application not responding) in process: com.android.package", 481 "04-25 17:17:08.445 1337 312 366 E ActivityManager: Reason: keyDispatchingTimedOut", 482 "04-25 17:17:08.445 1337 312 366 E ActivityManager: Load: 0.71 / 0.83 / 0.51", 483 "04-25 17:17:08.445 1337 312 366 E ActivityManager: 33% TOTAL: 21% user + 11% kernel + 0.3% iowait", 484 "04-25 17:17:08.445 1337 312 366 E ActivityManager: ANR (application not responding) in process: com.android.package", 485 "04-25 17:17:08.445 1337 312 366 E ActivityManager: Reason: keyDispatchingTimedOut", 486 "04-25 17:17:08.445 1337 312 366 E ActivityManager: Load: 0.71 / 0.83 / 0.51", 487 "04-25 17:17:08.445 1337 312 366 E ActivityManager: 33% TOTAL: 21% user + 11% kernel + 0.3% iowait", 488 "04-25 18:33:27.273 wifi123 115 115 I DEBUG : *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***", 489 "04-25 18:33:27.273 wifi123 115 115 I DEBUG : Build fingerprint: 'product:build:target'", 490 "04-25 18:33:27.273 wifi123 115 115 I DEBUG : pid: 3112, tid: 3112 >>> com.google.android.browser <<<", 491 "04-25 18:33:27.273 wifi123 115 115 I DEBUG : signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 00000000", 492 "04-25 18:33:27.273 wifi123 117 117 I DEBUG : *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***", 493 "04-25 18:33:27.273 wifi123 117 117 I DEBUG : Build fingerprint: 'product:build:target'", 494 "04-25 18:33:27.273 wifi123 117 117 I DEBUG : pid: 3113, tid: 3113 >>> com.google.android.browser <<<", 495 "04-25 18:33:27.273 wifi123 117 117 I DEBUG : signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 00000000"); 496 497 498 LogcatItem logcat = new LogcatParser("2012").parse(lines); 499 assertNotNull(logcat); 500 assertEquals(parseTime("2012-04-25 09:55:47.799"), logcat.getStartTime()); 501 assertEquals(parseTime("2012-04-25 18:33:27.273"), logcat.getStopTime()); 502 assertEquals(6, logcat.getEvents().size()); 503 assertEquals(2, logcat.getAnrs().size()); 504 assertEquals(2, logcat.getJavaCrashes().size()); 505 assertEquals(2, logcat.getNativeCrashes().size()); 506 507 assertEquals(312, logcat.getAnrs().get(0).getPid().intValue()); 508 assertEquals(366, logcat.getAnrs().get(0).getTid().intValue()); 509 assertEquals(parseTime("2012-04-25 17:17:08.445"), logcat.getAnrs().get(0).getEventTime()); 510 511 assertEquals(312, logcat.getAnrs().get(1).getPid().intValue()); 512 assertEquals(366, logcat.getAnrs().get(1).getTid().intValue()); 513 assertEquals(parseTime("2012-04-25 17:17:08.445"), logcat.getAnrs().get(1).getEventTime()); 514 515 assertEquals(3064, logcat.getJavaCrashes().get(0).getPid().intValue()); 516 assertEquals(3082, logcat.getJavaCrashes().get(0).getTid().intValue()); 517 assertEquals(parseTime("2012-04-25 09:55:47.799"), 518 logcat.getJavaCrashes().get(0).getEventTime()); 519 520 assertEquals(3065, logcat.getJavaCrashes().get(1).getPid().intValue()); 521 assertEquals(3090, logcat.getJavaCrashes().get(1).getTid().intValue()); 522 assertEquals(parseTime("2012-04-25 09:55:47.799"), 523 logcat.getJavaCrashes().get(1).getEventTime()); 524 525 assertEquals(3112, logcat.getNativeCrashes().get(0).getPid().intValue()); 526 assertEquals(3112, logcat.getNativeCrashes().get(0).getTid().intValue()); 527 assertEquals(parseTime("2012-04-25 18:33:27.273"), 528 logcat.getNativeCrashes().get(0).getEventTime()); 529 530 assertEquals(3113, logcat.getNativeCrashes().get(1).getPid().intValue()); 531 assertEquals(3113, logcat.getNativeCrashes().get(1).getTid().intValue()); 532 assertEquals(parseTime("2012-04-25 18:33:27.273"), 533 logcat.getNativeCrashes().get(1).getEventTime()); 534 } 535 536 /** 537 * Test that multiple java crashes and native crashes can be parsed even when interleaved. 538 */ 539 public void testParse_multiple_events_interleaved() throws ParseException { 540 List<String> lines = Arrays.asList( 541 "04-25 09:55:47.799 3064 3082 E AndroidRuntime: java.lang.Exception", 542 "04-25 09:55:47.799 3065 3090 E AndroidRuntime: java.lang.Exception", 543 "04-25 09:55:47.799 115 115 I DEBUG : *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***", 544 "04-25 09:55:47.799 117 117 I DEBUG : *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***", 545 "04-25 09:55:47.799 3064 3082 E AndroidRuntime: \tat class.method1(Class.java:1)", 546 "04-25 09:55:47.799 3065 3090 E AndroidRuntime: \tat class.method1(Class.java:1)", 547 "04-25 09:55:47.799 115 115 I DEBUG : Build fingerprint: 'product:build:target'", 548 "04-25 09:55:47.799 117 117 I DEBUG : Build fingerprint: 'product:build:target'", 549 "04-25 09:55:47.799 3064 3082 E AndroidRuntime: \tat class.method2(Class.java:2)", 550 "04-25 09:55:47.799 3065 3090 E AndroidRuntime: \tat class.method2(Class.java:2)", 551 "04-25 09:55:47.799 115 115 I DEBUG : pid: 3112, tid: 3112 >>> com.google.android.browser <<<", 552 "04-25 09:55:47.799 117 117 I DEBUG : pid: 3113, tid: 3113 >>> com.google.android.browser <<<", 553 "04-25 09:55:47.799 3064 3082 E AndroidRuntime: \tat class.method3(Class.java:3)", 554 "04-25 09:55:47.799 3065 3090 E AndroidRuntime: \tat class.method3(Class.java:3)", 555 "04-25 09:55:47.799 115 115 I DEBUG : signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 00000000", 556 "04-25 09:55:47.799 117 117 I DEBUG : signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 00000000"); 557 558 LogcatItem logcat = new LogcatParser("2012").parse(lines); 559 assertNotNull(logcat); 560 assertEquals(parseTime("2012-04-25 09:55:47.799"), logcat.getStartTime()); 561 assertEquals(parseTime("2012-04-25 09:55:47.799"), logcat.getStopTime()); 562 assertEquals(4, logcat.getEvents().size()); 563 assertEquals(0, logcat.getAnrs().size()); 564 assertEquals(2, logcat.getJavaCrashes().size()); 565 assertEquals(2, logcat.getNativeCrashes().size()); 566 567 assertEquals(3064, logcat.getJavaCrashes().get(0).getPid().intValue()); 568 assertEquals(3082, logcat.getJavaCrashes().get(0).getTid().intValue()); 569 assertEquals(parseTime("2012-04-25 09:55:47.799"), 570 logcat.getJavaCrashes().get(0).getEventTime()); 571 572 assertEquals(3065, logcat.getJavaCrashes().get(1).getPid().intValue()); 573 assertEquals(3090, logcat.getJavaCrashes().get(1).getTid().intValue()); 574 assertEquals(parseTime("2012-04-25 09:55:47.799"), 575 logcat.getJavaCrashes().get(1).getEventTime()); 576 577 assertEquals(3112, logcat.getNativeCrashes().get(0).getPid().intValue()); 578 assertEquals(3112, logcat.getNativeCrashes().get(0).getTid().intValue()); 579 assertEquals(parseTime("2012-04-25 09:55:47.799"), 580 logcat.getNativeCrashes().get(0).getEventTime()); 581 582 assertEquals(3113, logcat.getNativeCrashes().get(1).getPid().intValue()); 583 assertEquals(3113, logcat.getNativeCrashes().get(1).getTid().intValue()); 584 assertEquals(parseTime("2012-04-25 09:55:47.799"), 585 logcat.getNativeCrashes().get(1).getEventTime()); 586 } 587 588 /** 589 * Test that the preambles are set correctly. 590 */ 591 public void testParse_preambles() throws ParseException { 592 List<String> lines = Arrays.asList( 593 "04-25 09:15:47.799 123 3082 I tag: message 1", 594 "04-25 09:20:47.799 3064 3082 I tag: message 2", 595 "04-25 09:25:47.799 345 3082 I tag: message 3", 596 "04-25 09:30:47.799 3064 3082 I tag: message 4", 597 "04-25 09:35:47.799 456 3082 I tag: message 5", 598 "04-25 09:40:47.799 3064 3082 I tag: message 6", 599 "04-25 09:45:47.799 567 3082 I tag: message 7", 600 "04-25 09:50:47.799 3064 3082 I tag: message 8", 601 "04-25 09:55:47.799 3064 3082 E AndroidRuntime: java.lang.Exception", 602 "04-25 09:55:47.799 3064 3082 E AndroidRuntime: \tat class.method1(Class.java:1)", 603 "04-25 09:55:47.799 3064 3082 E AndroidRuntime: \tat class.method2(Class.java:2)", 604 "04-25 09:55:47.799 3064 3082 E AndroidRuntime: \tat class.method3(Class.java:3)"); 605 606 List<String> expectedLastPreamble = Arrays.asList( 607 "04-25 09:15:47.799 123 3082 I tag: message 1", 608 "04-25 09:20:47.799 3064 3082 I tag: message 2", 609 "04-25 09:25:47.799 345 3082 I tag: message 3", 610 "04-25 09:30:47.799 3064 3082 I tag: message 4", 611 "04-25 09:35:47.799 456 3082 I tag: message 5", 612 "04-25 09:40:47.799 3064 3082 I tag: message 6", 613 "04-25 09:45:47.799 567 3082 I tag: message 7", 614 "04-25 09:50:47.799 3064 3082 I tag: message 8"); 615 616 List<String> expectedProcPreamble = Arrays.asList( 617 "04-25 09:20:47.799 3064 3082 I tag: message 2", 618 "04-25 09:30:47.799 3064 3082 I tag: message 4", 619 "04-25 09:40:47.799 3064 3082 I tag: message 6", 620 "04-25 09:50:47.799 3064 3082 I tag: message 8"); 621 622 LogcatItem logcat = new LogcatParser("2012").parse(lines); 623 assertNotNull(logcat); 624 assertEquals(parseTime("2012-04-25 09:15:47.799"), logcat.getStartTime()); 625 assertEquals(parseTime("2012-04-25 09:55:47.799"), logcat.getStopTime()); 626 assertEquals(1, logcat.getEvents().size()); 627 assertEquals(1, logcat.getJavaCrashes().size()); 628 assertEquals(3064, logcat.getJavaCrashes().get(0).getPid().intValue()); 629 assertEquals(3082, logcat.getJavaCrashes().get(0).getTid().intValue()); 630 assertEquals(ArrayUtil.join("\n", expectedLastPreamble), 631 logcat.getJavaCrashes().get(0).getLastPreamble()); 632 assertEquals(ArrayUtil.join("\n", expectedProcPreamble), 633 logcat.getJavaCrashes().get(0).getProcessPreamble()); 634 assertEquals(parseTime("2012-04-25 09:55:47.799"), 635 logcat.getJavaCrashes().get(0).getEventTime()); 636 } 637 638 /** 639 * Test that events while the device is rebooting are ignored. 640 */ 641 public void testParse_reboot() throws ParseException { 642 List<String> lines = Arrays.asList( 643 "04-25 09:15:47.799 123 3082 I ShutdownThread: Rebooting, reason: null", 644 "04-25 09:55:47.799 3064 3082 E AndroidRuntime: java.lang.Exception", 645 "04-25 09:55:47.799 3064 3082 E AndroidRuntime: \tat class.method1(Class.java:1)", 646 "04-25 09:55:47.799 3064 3082 E AndroidRuntime: \tat class.method2(Class.java:2)", 647 "04-25 09:55:47.799 3064 3082 E AndroidRuntime: \tat class.method3(Class.java:3)"); 648 649 LogcatItem logcat = new LogcatParser("2012").parse(lines); 650 assertNotNull(logcat); 651 assertEquals(parseTime("2012-04-25 09:15:47.799"), logcat.getStartTime()); 652 assertEquals(parseTime("2012-04-25 09:55:47.799"), logcat.getStopTime()); 653 assertEquals(0, logcat.getEvents().size()); 654 } 655 656 /** 657 * Test that events while the device is rebooting are ignored, but devices after the reboot are 658 * captured. 659 */ 660 public void testParse_reboot_resume() throws ParseException { 661 List<String> lines = Arrays.asList( 662 "04-25 09:15:47.799 123 3082 I ShutdownThread: Rebooting, reason: null", 663 "04-25 09:55:47.799 3064 3082 E AndroidRuntime: java.lang.Exception", 664 "04-25 09:55:47.799 3064 3082 E AndroidRuntime: \tat class.method1(Class.java:1)", 665 "04-25 09:55:47.799 3064 3082 E AndroidRuntime: \tat class.method2(Class.java:2)", 666 "04-25 09:55:47.799 3064 3082 E AndroidRuntime: \tat class.method3(Class.java:3)", 667 "logcat interrupted. May see duplicated content in log.--------- beginning of /dev/log/main", 668 "04-25 09:59:47.799 3064 3082 E AndroidRuntime: java.lang.Exception2", 669 "04-25 09:59:47.799 3064 3082 E AndroidRuntime: \tat class.method1(Class.java:1)", 670 "04-25 09:59:47.799 3064 3082 E AndroidRuntime: \tat class.method2(Class.java:2)", 671 "04-25 09:59:47.799 3064 3082 E AndroidRuntime: \tat class.method3(Class.java:3)"); 672 673 674 LogcatItem logcat = new LogcatParser("2012").parse(lines); 675 assertNotNull(logcat); 676 assertEquals(parseTime("2012-04-25 09:15:47.799"), logcat.getStartTime()); 677 assertEquals(parseTime("2012-04-25 09:59:47.799"), logcat.getStopTime()); 678 assertEquals(1, logcat.getEvents().size()); 679 assertEquals("java.lang.Exception2", logcat.getJavaCrashes().get(0).getException()); 680 681 lines = Arrays.asList( 682 "04-25 09:15:47.799 123 3082 I ShutdownThread: Rebooting, reason: null", 683 "04-25 09:55:47.799 3064 3082 E AndroidRuntime: java.lang.Exception", 684 "04-25 09:55:47.799 3064 3082 E AndroidRuntime: \tat class.method1(Class.java:1)", 685 "04-25 09:55:47.799 3064 3082 E AndroidRuntime: \tat class.method2(Class.java:2)", 686 "04-25 09:55:47.799 3064 3082 E AndroidRuntime: \tat class.method3(Class.java:3)", 687 "logcat interrupted. May see duplicated content in log.--------- beginning of main", 688 "04-25 09:59:47.799 3064 3082 E AndroidRuntime: java.lang.Exception2", 689 "04-25 09:59:47.799 3064 3082 E AndroidRuntime: \tat class.method1(Class.java:1)", 690 "04-25 09:59:47.799 3064 3082 E AndroidRuntime: \tat class.method2(Class.java:2)", 691 "04-25 09:59:47.799 3064 3082 E AndroidRuntime: \tat class.method3(Class.java:3)"); 692 693 694 logcat = new LogcatParser("2012").parse(lines); 695 assertNotNull(logcat); 696 assertEquals(parseTime("2012-04-25 09:15:47.799"), logcat.getStartTime()); 697 assertEquals(parseTime("2012-04-25 09:59:47.799"), logcat.getStopTime()); 698 assertEquals(1, logcat.getEvents().size()); 699 assertEquals("java.lang.Exception2", logcat.getJavaCrashes().get(0).getException()); 700 } 701 702 /** 703 * Test that the time logcat format can be parsed. 704 */ 705 public void testParse_time() throws ParseException { 706 List<String> lines = Arrays.asList( 707 "04-25 09:55:47.799 E/AndroidRuntime(3064): java.lang.Exception", 708 "04-25 09:55:47.799 E/AndroidRuntime(3064): \tat class.method1(Class.java:1)", 709 "04-25 09:55:47.799 E/AndroidRuntime(3064): \tat class.method2(Class.java:2)", 710 "04-25 09:55:47.799 E/AndroidRuntime(3064): \tat class.method3(Class.java:3)"); 711 712 LogcatItem logcat = new LogcatParser("2012").parse(lines); 713 assertNotNull(logcat); 714 assertEquals(parseTime("2012-04-25 09:55:47.799"), logcat.getStartTime()); 715 assertEquals(parseTime("2012-04-25 09:55:47.799"), logcat.getStopTime()); 716 assertEquals(1, logcat.getEvents().size()); 717 assertEquals(1, logcat.getJavaCrashes().size()); 718 assertEquals(3064, logcat.getJavaCrashes().get(0).getPid().intValue()); 719 assertNull(logcat.getJavaCrashes().get(0).getTid()); 720 assertEquals(parseTime("2012-04-25 09:55:47.799"), 721 logcat.getJavaCrashes().get(0).getEventTime()); 722 } 723 724 /** 725 * Test that we can add and find custom patterns that match based on logcat Tags only. 726 */ 727 public void testAddPattern_byTagOnly() { 728 List<String> lines = Arrays.asList( 729 "04-25 18:33:28.273 7813 7813 E HelloTag: Hello everyone!!!1", 730 "04-25 18:33:29.273 395 637 I Watchdog: find me!", 731 "04-25 18:33:39.273 395 637 W Watchdog: find me!"); 732 733 LogcatParser parser = new LogcatParser("2012"); 734 assertNotNull(parser); 735 parser.addPattern(null, null, "HelloTag", "HelloCategory"); 736 parser.addPattern(null, null, "Watchdog", "WatchdogCategory"); 737 LogcatItem logcat = parser.parse(lines); 738 assertNotNull(logcat); 739 740 /* verify that we find the HelloTag entry */ 741 List<MiscLogcatItem> matchedEvents = logcat.getMiscEvents("HelloCategory"); 742 assertEquals(1, matchedEvents.size()); 743 assertEquals("HelloTag", matchedEvents.get(0).getTag()); 744 745 /* verify that we find both Watchdog entries */ 746 matchedEvents = logcat.getMiscEvents("WatchdogCategory"); 747 assertEquals(2, matchedEvents.size()); 748 assertEquals("Watchdog", matchedEvents.get(0).getTag()); 749 } 750 751 /** 752 * Test that we can add and find custom patterns that match based on Level AND Tag. 753 */ 754 public void testAddPattern_byLevelAndTagOnly() { 755 List<String> lines = Arrays.asList( 756 "04-25 18:33:28.273 7813 7813 E HelloTag: GetBufferLock timed out for thread 7813 buffer 0x61 usage 0x200 LockState 1", 757 "04-25 18:33:29.273 395 637 I Watchdog: Info", 758 "04-25 18:33:29.273 395 637 W Watchdog: Warning"); 759 760 LogcatParser parser = new LogcatParser("2012"); 761 assertNotNull(parser); 762 parser.addPattern(null, "I", "Watchdog", "WatchdogCategory"); 763 LogcatItem logcat = parser.parse(lines); 764 assertNotNull(logcat); 765 766 List<MiscLogcatItem> matchedEvents = logcat.getMiscEvents("WatchdogCategory"); 767 assertEquals(1, matchedEvents.size()); 768 assertEquals("Watchdog", matchedEvents.get(0).getTag()); 769 assertEquals("Info", matchedEvents.get(0).getStack()); 770 } 771 772 /** 773 * Test that we can add and find custom patterns that match based on Level, Tag, AND Message. 774 */ 775 public void testAddPattern_byLevelTagAndMessageOnly() { 776 List<String> lines = Arrays.asList( 777 "04-25 18:33:29.273 395 637 W Watchdog: I'm the one you need to find!", 778 "04-25 18:33:29.273 395 637 W Watchdog: my message doesn't match.", 779 "04-25 18:33:29.273 395 637 I Watchdog: my Level doesn't match, try and find me!", 780 "04-25 18:33:29.273 395 637 W NotMe: my Tag doesn't match, try and find me!"); 781 782 LogcatParser parser = new LogcatParser("2012"); 783 assertNotNull(parser); 784 parser.addPattern(Pattern.compile(".*find*."), "W", "Watchdog", "WatchdogCategory"); 785 LogcatItem logcat = parser.parse(lines); 786 assertNotNull(logcat); 787 788 /* verify that we find the only entry that matches based on Level, Tag, AND Message */ 789 List<MiscLogcatItem> matchedEvents = logcat.getMiscEvents("WatchdogCategory"); 790 assertEquals(1, matchedEvents.size()); 791 assertEquals("Watchdog", matchedEvents.get(0).getTag()); 792 assertEquals("I'm the one you need to find!", matchedEvents.get(0).getStack()); 793 } 794 795 public void testFatalException() { 796 List<String> lines = Arrays.asList( 797 "06-05 06:14:51.529 1712 1712 D AndroidRuntime: Calling main entry com.android.commands.input.Input", 798 "06-05 06:14:51.709 1712 1712 E AndroidRuntime: *** FATAL EXCEPTION IN SYSTEM PROCESS: main", 799 "06-05 06:14:51.709 1712 1712 E AndroidRuntime: java.lang.NullPointerException", 800 "06-05 06:14:51.709 1712 1712 E AndroidRuntime: \tat android.hardware.input.InputManager.injectInputEvent(InputManager.java:641)", 801 "06-05 06:14:51.709 1712 1712 E AndroidRuntime: \tat com.android.commands.input.Input.injectKeyEvent(Input.java:233)", 802 "06-05 06:14:51.709 1712 1712 E AndroidRuntime: \tat com.android.commands.input.Input.sendKeyEvent(Input.java:184)", 803 "06-05 06:14:51.709 1712 1712 E AndroidRuntime: \tat com.android.commands.input.Input.run(Input.java:96)", 804 "06-05 06:14:51.709 1712 1712 E AndroidRuntime: \tat com.android.commands.input.Input.main(Input.java:59)", 805 "06-05 06:14:51.709 1712 1712 E AndroidRuntime: \tat com.android.internal.os.RuntimeInit.nativeFinishInit(Native Method)", 806 "06-05 06:14:51.709 1712 1712 E AndroidRuntime: \tat com.android.internal.os.RuntimeInit.main(RuntimeInit.java:243)", 807 "06-05 06:14:51.709 1712 1712 E AndroidRuntime: \tat dalvik.system.NativeStart.main(Native Method)"); 808 LogcatParser parser = new LogcatParser("2014"); 809 LogcatItem logcat = parser.parse(lines); 810 assertEquals(1, logcat.getJavaCrashes().size()); 811 JavaCrashItem crash = logcat.getJavaCrashes().get(0); 812 assertEquals("com.android.commands.input.Input", crash.getApp()); 813 } 814 815 /** 816 * Test that an empty input returns {@code null}. 817 */ 818 public void testEmptyInput() { 819 LogcatItem item = new LogcatParser().parse(Arrays.asList("")); 820 assertNull(item); 821 } 822 823 /** 824 * Test that after clearing a parser, reusing it produces a new LogcatItem instead of 825 * appending to the previous one. 826 */ 827 public void testClear() { 828 List<String> lines = Arrays.asList( 829 "04-25 18:33:28.273 7813 7813 E HelloTag: GetBufferLock timed out for thread 7813 buffer 0x61 usage 0x200 LockState 1", 830 "04-25 18:33:28.273 7813 7813 E GoodbyeTag: GetBufferLock timed out for thread 7813 buffer 0x61 usage 0x200 LockState 1" 831 ); 832 LogcatParser parser = new LogcatParser(); 833 LogcatItem l1 = parser.parse(lines.subList(0, 1)); 834 parser.clear(); 835 LogcatItem l2 = parser.parse(lines.subList(1, 2)); 836 assertEquals(l1.getEvents().size(), 1); 837 assertEquals(l2.getEvents().size(), 1); 838 assertFalse(l1.getEvents().get(0).getTag().equals(l2.getEvents().get(0).getTag())); 839 } 840 841 private Date parseTime(String timeStr) throws ParseException { 842 DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS"); 843 return formatter.parse(timeStr); 844 } 845 } 846