Fix NPE in MonkeyLogParser.
Also, use first crash for monkey log and only set app name/pid if the crash
doesn't already set it.
Bug: 11984522
Change-Id: Ib32e490279005d26b0cd1b15542f296128b6bec7
diff --git a/src/com/android/loganalysis/parser/MonkeyLogParser.java b/src/com/android/loganalysis/parser/MonkeyLogParser.java
index a23bee1..6c5dccb 100644
--- a/src/com/android/loganalysis/parser/MonkeyLogParser.java
+++ b/src/com/android/loganalysis/parser/MonkeyLogParser.java
@@ -83,6 +83,7 @@
private boolean mMatchingJavaCrash = false;
private boolean mMatchingNativeCrash = false;
private boolean mMatchingTraces = false;
+ private boolean mMatchedTrace = false;
private List<String> mBlock = null;
private String mApp = null;
private Integer mPid = null;
@@ -170,8 +171,8 @@
((AnrItem) mMonkeyLog.getCrash()).setTrace(traces.getStack());
}
- mMatchingTraces = false;
- mBlock = null;
+ reset();
+ mMatchedTrace = true;
} else {
mBlock.add(line);
}
@@ -247,27 +248,27 @@
mMonkeyLog.setDroppedCount(DroppedCategory.ROTATIONS, Integer.parseInt(m.group(1)));
}
m = ANR.matcher(line);
- if (m.matches()) {
+ if (mMonkeyLog.getCrash() == null && m.matches()) {
mApp = m.group(1);
mPid = Integer.parseInt(m.group(2));
mBlock = new LinkedList<String>();
mMatchingAnr = true;
}
m = CRASH.matcher(line);
- if (m.matches()) {
+ if (mMonkeyLog.getCrash() == null && m.matches()) {
mApp = m.group(1);
mPid = Integer.parseInt(m.group(2));
mBlock = new LinkedList<String>();
mMatchingCrash = true;
}
m = EMPTY_NATIVE_CRASH.matcher(line);
- if (m.matches()) {
+ if (mMonkeyLog.getCrash() == null && m.matches()) {
MiscLogcatItem crash = new NativeCrashItem();
crash.setStack("");
addCrashAndReset(crash);
}
m = TRACES_START.matcher(line);
- if (m.matches()) {
+ if (!mMatchedTrace && m.matches()) {
mBlock = new LinkedList<String>();
mMatchingTraces = true;
}
@@ -278,18 +279,30 @@
*/
private void addCrashAndReset(MiscLogcatItem crash) {
if (crash != null) {
- crash.setPid(mPid);
- crash.setApp(mApp);
+ if (crash.getPid() == null) {
+ crash.setPid(mPid);
+ }
+ if (crash.getApp() == null) {
+ crash.setApp(mApp);
+ }
mMonkeyLog.setCrash(crash);
}
+ reset();
+ }
+
+ /**
+ * Reset the parser state for crashes.
+ */
+ private void reset() {
+ mApp = null;
+ mPid = null;
mMatchingAnr = false;
mMatchingCrash = false;
mMatchingJavaCrash = false;
mMatchingNativeCrash = false;
+ mMatchingTraces = false;
mBlock = null;
- mApp = null;
- mPid = null;
}
/**
diff --git a/tests/src/com/android/loganalysis/parser/MonkeyLogParserTest.java b/tests/src/com/android/loganalysis/parser/MonkeyLogParserTest.java
index a3b94cb..67bf1ba 100644
--- a/tests/src/com/android/loganalysis/parser/MonkeyLogParserTest.java
+++ b/tests/src/com/android/loganalysis/parser/MonkeyLogParserTest.java
@@ -577,6 +577,114 @@
}
/**
+ * Test that a monkey can be parsed if there is an ANR in the middle of the traces.
+ */
+ public void testParse_malformed_anr() {
+ List<String> lines = Arrays.asList(
+ "# Tuesday, 04/24/2012 05:23:30 PM - device uptime = 216.48: Monkey command used for this test:",
+ "adb shell monkey -p com.google.android.youtube -c android.intent.category.SAMPLE_CODE -c android.intent.category.CAR_DOCK -c android.intent.category.LAUNCHER -c android.intent.category.MONKEY -c android.intent.category.INFO --ignore-security-exceptions --throttle 100 -s 993 -v -v -v 10000 ",
+ "",
+ ":Monkey: seed=993 count=10000",
+ ":AllowPackage: com.google.android.youtube",
+ ":IncludeCategory: android.intent.category.LAUNCHER",
+ ":Switch: #Intent;action=android.intent.action.MAIN;category=android.intent.category.LAUNCHER;launchFlags=0x10200000;component=com.google.android.youtube/.app.honeycomb.Shell%24HomeActivity;end",
+ " // Allowing start of Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] cmp=com.google.android.youtube/.app.honeycomb.Shell$HomeActivity } in package com.google.android.youtube",
+ "Sleeping for 100 milliseconds",
+ ":Sending Key (ACTION_UP): 21 // KEYCODE_DPAD_LEFT",
+ "Sleeping for 100 milliseconds",
+ ":Sending Key (ACTION_DOWN): 22 // KEYCODE_DPAD_RIGHT",
+ ":Sending Key (ACTION_UP): 22 // KEYCODE_DPAD_RIGHT",
+ " //[calendar_time:2012-04-25 00:27:27.155 system_uptime:454996]",
+ " // Sending event #5300",
+ ":Sending Key (ACTION_UP): 19 // KEYCODE_DPAD_UP",
+ "Sleeping for 100 milliseconds",
+ ":Sending Trackball (ACTION_MOVE): 0:(4.0,3.0)",
+ ":Sending Key (ACTION_DOWN): 20 // KEYCODE_DPAD_DOWN",
+ ":Sending Key (ACTION_UP): 20 // KEYCODE_DPAD_DOWN",
+ "// NOT RESPONDING: com.google.android.youtube (pid 0)",
+ "ANR in com.google.android.youtube (com.google.android.youtube/.app.honeycomb.phone.WatchActivity)",
+ "PID: 3301",
+ "Reason: keyDispatchingTimedOut",
+ "Load: 1.0 / 1.05 / 0.6",
+ "CPU usage from 4794ms to -1502ms ago with 99% awake:",
+ " 18% 3301/com.google.android.youtube: 16% user + 2.3% kernel / faults: 268 minor 9 major",
+ " 13% 313/system_server: 9.2% user + 4.4% kernel / faults: 906 minor 3 major",
+ " 10% 117/surfaceflinger: 4.9% user + 5.5% kernel / faults: 1 minor",
+ " 10% 120/mediaserver: 6.8% user + 3.6% kernel / faults: 1189 minor",
+ "34% TOTAL: 19% user + 13% kernel + 0.2% iowait + 1% softirq",
+ "",
+ "procrank:",
+ "// procrank status was 0",
+ "anr traces:",
+ "",
+ "",
+ "----- pid 3301 at 2012-04-25 17:17:08 -----",
+ "Cmd line: com.google.android.youtube",
+ "",
+ "DALVIK THREADS:",
+ "(mutexes: tll=0 tsl=0 tscl=0 ghl=0)",
+ "",
+ "\"main\" prio=5 tid=1 SUSPENDED",
+ " | group=\"main\" sCount=1 dsCount=0 obj=0x00000001 self=0x00000001",
+ " | sysTid=2887 nice=0 sched=0/0 cgrp=foreground handle=0000000001",
+ " | schedstat=( 0 0 0 ) utm=5954 stm=1017 core=0",
+ " at class.method1(Class.java:1)",
+ "// NOT RESPONDING: com.google.android.youtube (pid 3302)",
+ "ANR in com.google.android.youtube (com.google.android.youtube/.app.honeycomb.phone.WatchActivity)",
+ "Reason: keyDispatchingTimedOut",
+ "Load: 1.0 / 1.05 / 0.6",
+ "CPU usage from 4794ms to -1502ms ago with 99% awake:",
+ " 18% 3301/com.google.android.youtube: 16% user + 2.3% kernel / faults: 268 minor 9 major",
+ " 13% 313/system_server: 9.2% user + 4.4% kernel / faults: 906 minor 3 major",
+ " 10% 117/surfaceflinger: 4.9% user + 5.5% kernel / faults: 1 minor",
+ " 10% 120/mediaserver: 6.8% user + 3.6% kernel / faults: 1189 minor",
+ "34% TOTAL: 19% user + 13% kernel + 0.2% iowait + 1% softirq",
+ "",
+ " at class.method2(Class.java:2)",
+ " at class.method2(Class.java:2)",
+ "",
+ "----- end 3301 -----",
+ "// anr traces status was 0",
+ "** Monkey aborted due to error.",
+ "Events injected: 5322",
+ ":Sending rotation degree=0, persist=false",
+ ":Dropped: keys=1 pointers=0 trackballs=0 flips=0 rotations=0",
+ "## Network stats: elapsed time=252942ms (0ms mobile, 252942ms wifi, 0ms not connected)",
+ "** System appears to have crashed at event 5322 of 10000 using seed 993",
+ "",
+ "# Tuesday, 04/24/2012 05:27:44 PM - device uptime = 471.37: Monkey command ran for: 04:14 (mm:ss)",
+ "",
+ "----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------",
+ "");
+
+ MonkeyLogItem monkeyLog = new MonkeyLogParser().parse(lines);
+ assertNotNull(monkeyLog);
+ // FIXME: Add test back once time situation has been worked out.
+ // assertEquals(parseTime("2012-04-24 17:23:30"), monkeyLog.getStartTime());
+ // assertEquals(parseTime("2012-04-24 17:27:44"), monkeyLog.getStopTime());
+ assertEquals(1, monkeyLog.getPackages().size());
+ assertTrue(monkeyLog.getPackages().contains("com.google.android.youtube"));
+ assertEquals(1, monkeyLog.getCategories().size());
+ assertTrue(monkeyLog.getCategories().contains("android.intent.category.LAUNCHER"));
+ assertEquals(100, monkeyLog.getThrottle());
+ assertEquals(993, monkeyLog.getSeed().intValue());
+ assertEquals(10000, monkeyLog.getTargetCount().intValue());
+ assertTrue(monkeyLog.getIgnoreSecurityExceptions());
+ assertEquals(4 * 60 * 1000 + 14 * 1000, monkeyLog.getTotalDuration().longValue());
+ assertEquals(216480, monkeyLog.getStartUptimeDuration().longValue());
+ assertEquals(471370, monkeyLog.getStopUptimeDuration().longValue());
+ assertFalse(monkeyLog.getIsFinished());
+ assertFalse(monkeyLog.getNoActivities());
+ assertEquals(5300, monkeyLog.getIntermediateCount());
+ assertEquals(5322, monkeyLog.getFinalCount().intValue());
+ assertNotNull(monkeyLog.getCrash());
+ assertTrue(monkeyLog.getCrash() instanceof AnrItem);
+ assertEquals("com.google.android.youtube", monkeyLog.getCrash().getApp());
+ assertEquals(3301, monkeyLog.getCrash().getPid().intValue());
+ assertEquals("keyDispatchingTimedOut", ((AnrItem) monkeyLog.getCrash()).getReason());
+ }
+
+ /**
* Test that the other date format can be parsed.
*/
public void testAlternateDateFormat() {