blob: 890a1968b05a6982f406d8b612a694bf79d4eb34 [file] [log] [blame]
/*
* Copyright (C) 2013 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.loganalysis.parser;
import com.android.loganalysis.item.KernelLogItem;
import com.android.loganalysis.item.MiscKernelLogItem;
import com.android.loganalysis.item.SELinuxItem;
import com.android.loganalysis.util.LogPatternUtil;
import junit.framework.TestCase;
import java.util.Arrays;
import java.util.List;
/**
* Unit tests for {@link KernelLogParser}.
*/
public class KernelLogParserTest extends TestCase {
/**
* Test that log lines formatted by last kmsg are able to be parsed.
*/
public void testParseLastKmsg() {
List<String> lines = Arrays.asList(
"[ 0.000000] Start",
"[ 1.000000] Kernel panic",
"[ 2.000000] End");
KernelLogItem kernelLog = new KernelLogParser().parse(lines);
assertNotNull(kernelLog);
assertEquals(0.0, kernelLog.getStartTime(), 0.0000005);
assertEquals(2.0, kernelLog.getStopTime(), 0.0000005);
assertEquals(1, kernelLog.getEvents().size());
assertEquals(1, kernelLog.getMiscEvents(KernelLogParser.KERNEL_RESET).size());
MiscKernelLogItem item = kernelLog.getMiscEvents(KernelLogParser.KERNEL_RESET).get(0);
assertEquals(1.0, item.getEventTime(), 0.0000005);
assertEquals("[ 0.000000] Start", item.getPreamble());
assertEquals("Kernel panic", item.getStack());
}
/**
* Test that log lines formatted by dmsg are able to be parsed.
*/
public void testParseDmesg() {
List<String> lines = Arrays.asList(
"<1>[ 0.000000] Start",
"<1>[ 1.000000] Kernel panic",
"<1>[ 2.000000] End");
KernelLogItem kernelLog = new KernelLogParser().parse(lines);
assertNotNull(kernelLog);
assertEquals(0.0, kernelLog.getStartTime(), 0.0000005);
assertEquals(2.0, kernelLog.getStopTime(), 0.0000005);
assertEquals(1, kernelLog.getEvents().size());
assertEquals(1, kernelLog.getMiscEvents(KernelLogParser.KERNEL_RESET).size());
MiscKernelLogItem item = kernelLog.getMiscEvents(KernelLogParser.KERNEL_RESET).get(0);
assertEquals(1.0, item.getEventTime(), 0.0000005);
assertEquals("<1>[ 0.000000] Start", item.getPreamble());
assertEquals("Kernel panic", item.getStack());
}
/**
* Test that last boot reasons are parsed.
*/
public void testParseLastMessage() {
List<String> lines = Arrays.asList(
"[ 0.000000] Start",
"[ 2.000000] End",
"Last boot reason: hw_reset");
KernelLogItem kernelLog = new KernelLogParser().parse(lines);
assertNotNull(kernelLog);
assertEquals(0.0, kernelLog.getStartTime(), 0.0000005);
assertEquals(2.0, kernelLog.getStopTime(), 0.0000005);
assertEquals(1, kernelLog.getEvents().size());
assertEquals(1, kernelLog.getMiscEvents(KernelLogParser.KERNEL_RESET).size());
MiscKernelLogItem item = kernelLog.getMiscEvents(KernelLogParser.KERNEL_RESET).get(0);
assertEquals(2.0, item.getEventTime(), 0.0000005);
assertEquals("[ 0.000000] Start\n[ 2.000000] End", item.getPreamble());
assertEquals("Last boot reason: hw_reset", item.getStack());
}
/**
* Test that reset reasons don't crash if times are set.
*/
public void testNoPreviousLogs() {
List<String> lines = Arrays.asList(
"Last boot reason: hw_reset");
KernelLogItem kernelLog = new KernelLogParser().parse(lines);
assertNotNull(kernelLog);
assertNull(kernelLog.getStartTime());
assertNull(kernelLog.getStopTime());
assertEquals(1, kernelLog.getEvents().size());
assertEquals(1, kernelLog.getMiscEvents(KernelLogParser.KERNEL_RESET).size());
MiscKernelLogItem item = kernelLog.getMiscEvents(KernelLogParser.KERNEL_RESET).get(0);
assertNull(item.getEventTime());
assertEquals("", item.getPreamble());
assertEquals("Last boot reason: hw_reset", item.getStack());
}
/**
* Test that an empty input returns {@code null}.
*/
public void testEmptyInput() {
KernelLogItem item = new KernelLogParser().parse(Arrays.asList(""));
assertNull(item);
}
/**
* Test that kernel patterns are matched.
*/
public void testPatterns() {
List<String> kernelResetPatterns = Arrays.asList(
"smem: DIAG",
"smsm: AMSS FATAL ERROR",
"kernel BUG at ",
"PVR_K:(Fatal): Debug assertion failed! []",
"Kernel panic",
"BP panicked",
"WROTE DSP RAMDUMP",
"tegra_wdt: last reset due to watchdog timeout",
"tegra_wdt tegra_wdt.0: last reset is due to watchdog timeout.",
"Last reset was MPU Watchdog Timer reset",
"[MODEM_IF] CRASH",
"Last boot reason: kernel_panic",
"Last boot reason: rpm_err",
"Last boot reason: hw_reset",
"Last boot reason: wdog_",
"Last boot reason: tz_err",
"Last boot reason: adsp_err",
"Last boot reason: modem_err",
"Last boot reason: mba_err",
"Last boot reason: watchdog",
"Last boot reason: watchdogr",
"Last boot reason: Watchdog",
"Last boot reason: Panic",
"Last reset was system watchdog timer reset");
LogPatternUtil patternUtil = new KernelLogParser().getLogPatternUtil();
for (String pattern : kernelResetPatterns) {
assertEquals(String.format("Message \"%s\" was not matched.", pattern),
KernelLogParser.KERNEL_RESET, patternUtil.checkMessage(pattern));
}
assertEquals(KernelLogParser.KERNEL_ERROR, patternUtil.checkMessage("Internal error:"));
assertEquals(KernelLogParser.SELINUX_DENIAL, patternUtil.checkMessage(
"avc: denied scontext=0:0:domain:0 "));
}
/**
* Test that an SELinux Denial can be parsed out of a list of log lines.
*/
public void testSelinuxDenialParse() {
final String SELINUX_DENIAL_STACK = "type=1400 audit(1384544483.730:10): avc: denied " +
"{ getattr } for pid=797 comm=\"Binder_5\" path=\"/dev/pts/1\" + " +
"dev=devpts ino=4 scontext=u:r:system_server:s0 " +
"tcontext=u:object_r:devpts:s0 tclass=chr_file";
List<String> lines = Arrays.asList(
"<4>[ 0.000000] Memory policy: ECC disabled, Data cache writealloc",
"<7>[ 7.896355] SELinux: initialized (dev cgroup, type cgroup)" +
", uses genfs_contexts",
"<5>[ 43.399164] " + SELINUX_DENIAL_STACK);
KernelLogItem kernelLog = new KernelLogParser().parse(lines);
assertNotNull(kernelLog);
assertEquals(0.0, kernelLog.getStartTime(), 0.0000005);
assertEquals(43.399164, kernelLog.getStopTime(), 0.0000005);
assertEquals(1, kernelLog.getEvents().size());
assertEquals(1, kernelLog.getMiscEvents(KernelLogParser.SELINUX_DENIAL).size());
assertEquals(1, kernelLog.getSELinuxEvents().size());
MiscKernelLogItem item = kernelLog.getMiscEvents(KernelLogParser.SELINUX_DENIAL).get(0);
assertEquals(43.399164, item.getEventTime(), 0.0000005);
assertEquals(KernelLogParser.SELINUX_DENIAL, item.getCategory());
assertEquals(SELINUX_DENIAL_STACK, item.getStack());
SELinuxItem selinuxItem = kernelLog.getSELinuxEvents().get(0);
assertEquals("system_server", selinuxItem.getSContext());
assertEquals(43.399164, selinuxItem.getEventTime(), 0.0000005);
assertEquals(KernelLogParser.SELINUX_DENIAL, selinuxItem.getCategory());
assertEquals(SELINUX_DENIAL_STACK, selinuxItem.getStack());
}
public void testMantaReset() {
final List<String> lines = Arrays.asList("[ 3281.347296] ---fimc_is_ischain_close(0)",
"[ 3281.432055] fimc_is_scalerc_video_close",
"[ 3281.432270] fimc_is_scalerp_video_close",
"[ 3287.688303] wm8994-codec wm8994-codec: FIFO error",
"",
"No errors detected",
"Last reset was system watchdog timer reset (RST_STAT=0x100000)");
KernelLogItem kernelLog = new KernelLogParser().parse(lines);
assertEquals(1, kernelLog.getEvents().size());
assertEquals(1, kernelLog.getMiscEvents(KernelLogParser.KERNEL_RESET).size());
}
/**
* Test that only the first kernel reset is taken but other signatures can have multiple
*/
public void testMultipleKernelResets() {
final String SELINUX_DENIAL_STACK = "type=1400 audit(1384544483.730:10): avc: denied " +
"{ getattr } for pid=797 comm=\"Binder_5\" path=\"/dev/pts/1\" + " +
"dev=devpts ino=4 scontext=u:r:system_server:s0 " +
"tcontext=u:object_r:devpts:s0 tclass=chr_file";
final List<String> lines = Arrays.asList(
"[ 0.000000] Kernel panic",
"[ 0.000000] Internal error:",
"[ 0.000000] " + SELINUX_DENIAL_STACK,
"[ 1.000000] Kernel panic",
"[ 1.000000] Internal error:",
"[ 1.000000] " + SELINUX_DENIAL_STACK,
"[ 2.000000] Kernel panic",
"[ 2.000000] Internal error:",
"[ 2.000000] " + SELINUX_DENIAL_STACK);
KernelLogItem kernelLog = new KernelLogParser().parse(lines);
assertEquals(7, kernelLog.getEvents().size());
assertEquals(1, kernelLog.getMiscEvents(KernelLogParser.KERNEL_RESET).size());
assertEquals(0.0,
kernelLog.getMiscEvents(KernelLogParser.KERNEL_RESET).get(0).getEventTime());
}
}