From fa3c4f07e261cae20cf4bd5e4927b22e6c00d157 Mon Sep 17 00:00:00 2001 From: Julien Desprez Date: Thu, 1 Apr 2021 13:22:41 -0700 Subject: Rename tests dir to javatests It's more bazel friendly Test: unit tests Bug: 183980865 Change-Id: Ia0f5c883a306f6fbdc89a91d8c020ce33e455357 --- javatests/.classpath | 9 + javatests/.project | 17 + javatests/Android.bp | 32 + javatests/Android.mk | 25 + .../loganalysis/item/BatteryDischargeItemTest.java | 56 ++ .../loganalysis/item/BatteryUsageItemTest.java | 53 ++ .../item/DumpsysPackageStatsItemTest.java | 52 ++ .../loganalysis/item/DvmLockSampleItemTest.java | 57 ++ .../android/loganalysis/item/GenericItemTest.java | 266 +++++++ .../loganalysis/item/InterruptItemTest.java | 53 ++ .../loganalysis/item/LocationDumpsItemTest.java | 81 ++ .../android/loganalysis/item/MemInfoItemTest.java | 52 ++ .../loganalysis/item/MonkeyLogItemTest.java | 67 ++ .../android/loganalysis/item/ProcrankItemTest.java | 60 ++ .../loganalysis/item/SmartMonkeyLogItemTest.java | 52 ++ .../loganalysis/item/SystemPropsItemTest.java | 52 ++ .../com/android/loganalysis/item/TopItemTest.java | 41 + .../android/loganalysis/item/WakelockItemTest.java | 63 ++ .../parser/AbstractSectionParserTest.java | 98 +++ .../parser/ActivityServiceParserTest.java | 59 ++ .../android/loganalysis/parser/AnrParserTest.java | 164 ++++ .../BatteryDischargeStatsInfoParserTest.java | 164 ++++ .../parser/BatteryStatsDetailedInfoParserTest.java | 131 ++++ .../parser/BatteryStatsSummaryInfoParserTest.java | 109 +++ .../loganalysis/parser/BatteryUsageParserTest.java | 56 ++ .../loganalysis/parser/BugreportParserTest.java | 766 +++++++++++++++++++ .../parser/CompactMemInfoParserTest.java | 205 +++++ .../loganalysis/parser/CpuInfoParserTest.java | 54 ++ .../loganalysis/parser/DmesgParserTest.java | 317 ++++++++ .../parser/DumpsysBatteryStatsParserTest.java | 153 ++++ .../parser/DumpsysPackageStatsParserTest.java | 60 ++ .../loganalysis/parser/DumpsysParserTest.java | 143 ++++ .../parser/DumpsysProcStatsParserTest.java | 48 ++ .../parser/DumpsysProcessMeminfoParserTest.java | 104 +++ .../parser/DumpsysWifiStatsParserTest.java | 103 +++ .../parser/DvmLockSampleParserTest.java | 46 ++ .../loganalysis/parser/EventsLogParserTest.java | 260 +++++++ .../loganalysis/parser/GfxInfoParserTest.java | 358 +++++++++ .../loganalysis/parser/InterruptParserTest.java | 62 ++ .../loganalysis/parser/JavaCrashParserTest.java | 151 ++++ .../loganalysis/parser/KernelLogParserTest.java | 342 +++++++++ .../parser/LocationServiceParserTest.java | 89 +++ .../loganalysis/parser/LogcatParserTest.java | 845 +++++++++++++++++++++ .../loganalysis/parser/MemHealthParserTest.java | 184 +++++ .../loganalysis/parser/MemInfoParserTest.java | 64 ++ .../loganalysis/parser/MonkeyLogParserTest.java | 786 +++++++++++++++++++ .../loganalysis/parser/NativeCrashParserTest.java | 192 +++++ .../loganalysis/parser/ProcessUsageParserTest.java | 78 ++ .../loganalysis/parser/ProcrankParserTest.java | 105 +++ .../loganalysis/parser/QtaguidParserTest.java | 73 ++ .../parser/SmartMonkeyLogParserTest.java | 147 ++++ .../loganalysis/parser/SystemPropsParserTest.java | 75 ++ .../loganalysis/parser/TimingsLogParserTest.java | 354 +++++++++ .../android/loganalysis/parser/TopParserTest.java | 83 ++ .../loganalysis/parser/TraceFormatParserTest.java | 227 ++++++ .../loganalysis/parser/TracesParserTest.java | 167 ++++ .../loganalysis/parser/WakelockParserTest.java | 127 ++++ .../loganalysis/rule/InterruptRuleTest.java | 101 +++ .../loganalysis/rule/LocationUsageRuleTest.java | 100 +++ .../loganalysis/rule/ProcessUsageRuleTest.java | 111 +++ .../android/loganalysis/rule/WakelockRuleTest.java | 108 +++ .../loganalysis/rule/WifiStatsRuleTest.java | 103 +++ .../android/loganalysis/util/ArrayUtilTest.java | 68 ++ .../loganalysis/util/LogPatternUtilTest.java | 57 ++ .../android/loganalysis/util/LogTailUtilTest.java | 66 ++ .../android/loganalysis/util/RegexTrieTest.java | 284 +++++++ .../util/config/ArgsOptionParserTest.java | 629 +++++++++++++++ .../loganalysis/util/config/OptionSetterTest.java | 828 ++++++++++++++++++++ .../util/config/OptionUpdateRuleTest.java | 88 +++ tests/.classpath | 9 - tests/.project | 17 - tests/Android.bp | 32 - tests/Android.mk | 25 - .../loganalysis/item/BatteryDischargeItemTest.java | 56 -- .../loganalysis/item/BatteryUsageItemTest.java | 53 -- .../item/DumpsysPackageStatsItemTest.java | 52 -- .../loganalysis/item/DvmLockSampleItemTest.java | 57 -- .../android/loganalysis/item/GenericItemTest.java | 266 ------- .../loganalysis/item/InterruptItemTest.java | 53 -- .../loganalysis/item/LocationDumpsItemTest.java | 81 -- .../android/loganalysis/item/MemInfoItemTest.java | 52 -- .../loganalysis/item/MonkeyLogItemTest.java | 67 -- .../android/loganalysis/item/ProcrankItemTest.java | 60 -- .../loganalysis/item/SmartMonkeyLogItemTest.java | 52 -- .../loganalysis/item/SystemPropsItemTest.java | 52 -- .../com/android/loganalysis/item/TopItemTest.java | 41 - .../android/loganalysis/item/WakelockItemTest.java | 63 -- .../parser/AbstractSectionParserTest.java | 98 --- .../parser/ActivityServiceParserTest.java | 59 -- .../android/loganalysis/parser/AnrParserTest.java | 164 ---- .../BatteryDischargeStatsInfoParserTest.java | 164 ---- .../parser/BatteryStatsDetailedInfoParserTest.java | 131 ---- .../parser/BatteryStatsSummaryInfoParserTest.java | 109 --- .../loganalysis/parser/BatteryUsageParserTest.java | 56 -- .../loganalysis/parser/BugreportParserTest.java | 766 ------------------- .../parser/CompactMemInfoParserTest.java | 205 ----- .../loganalysis/parser/CpuInfoParserTest.java | 54 -- .../loganalysis/parser/DmesgParserTest.java | 317 -------- .../parser/DumpsysBatteryStatsParserTest.java | 153 ---- .../parser/DumpsysPackageStatsParserTest.java | 60 -- .../loganalysis/parser/DumpsysParserTest.java | 143 ---- .../parser/DumpsysProcStatsParserTest.java | 48 -- .../parser/DumpsysProcessMeminfoParserTest.java | 104 --- .../parser/DumpsysWifiStatsParserTest.java | 103 --- .../parser/DvmLockSampleParserTest.java | 46 -- .../loganalysis/parser/EventsLogParserTest.java | 260 ------- .../loganalysis/parser/GfxInfoParserTest.java | 358 --------- .../loganalysis/parser/InterruptParserTest.java | 62 -- .../loganalysis/parser/JavaCrashParserTest.java | 151 ---- .../loganalysis/parser/KernelLogParserTest.java | 342 --------- .../parser/LocationServiceParserTest.java | 89 --- .../loganalysis/parser/LogcatParserTest.java | 845 --------------------- .../loganalysis/parser/MemHealthParserTest.java | 184 ----- .../loganalysis/parser/MemInfoParserTest.java | 64 -- .../loganalysis/parser/MonkeyLogParserTest.java | 786 ------------------- .../loganalysis/parser/NativeCrashParserTest.java | 192 ----- .../loganalysis/parser/ProcessUsageParserTest.java | 78 -- .../loganalysis/parser/ProcrankParserTest.java | 105 --- .../loganalysis/parser/QtaguidParserTest.java | 73 -- .../parser/SmartMonkeyLogParserTest.java | 147 ---- .../loganalysis/parser/SystemPropsParserTest.java | 75 -- .../loganalysis/parser/TimingsLogParserTest.java | 354 --------- .../android/loganalysis/parser/TopParserTest.java | 83 -- .../loganalysis/parser/TraceFormatParserTest.java | 227 ------ .../loganalysis/parser/TracesParserTest.java | 167 ---- .../loganalysis/parser/WakelockParserTest.java | 127 ---- .../loganalysis/rule/InterruptRuleTest.java | 101 --- .../loganalysis/rule/LocationUsageRuleTest.java | 100 --- .../loganalysis/rule/ProcessUsageRuleTest.java | 111 --- .../android/loganalysis/rule/WakelockRuleTest.java | 108 --- .../loganalysis/rule/WifiStatsRuleTest.java | 103 --- .../android/loganalysis/util/ArrayUtilTest.java | 68 -- .../loganalysis/util/LogPatternUtilTest.java | 57 -- .../android/loganalysis/util/LogTailUtilTest.java | 66 -- .../android/loganalysis/util/RegexTrieTest.java | 284 ------- .../util/config/ArgsOptionParserTest.java | 629 --------------- .../loganalysis/util/config/OptionSetterTest.java | 828 -------------------- .../util/config/OptionUpdateRuleTest.java | 88 --- 138 files changed, 11180 insertions(+), 11180 deletions(-) create mode 100644 javatests/.classpath create mode 100644 javatests/.project create mode 100644 javatests/Android.bp create mode 100644 javatests/Android.mk create mode 100644 javatests/src/com/android/loganalysis/item/BatteryDischargeItemTest.java create mode 100644 javatests/src/com/android/loganalysis/item/BatteryUsageItemTest.java create mode 100644 javatests/src/com/android/loganalysis/item/DumpsysPackageStatsItemTest.java create mode 100644 javatests/src/com/android/loganalysis/item/DvmLockSampleItemTest.java create mode 100644 javatests/src/com/android/loganalysis/item/GenericItemTest.java create mode 100644 javatests/src/com/android/loganalysis/item/InterruptItemTest.java create mode 100644 javatests/src/com/android/loganalysis/item/LocationDumpsItemTest.java create mode 100644 javatests/src/com/android/loganalysis/item/MemInfoItemTest.java create mode 100644 javatests/src/com/android/loganalysis/item/MonkeyLogItemTest.java create mode 100644 javatests/src/com/android/loganalysis/item/ProcrankItemTest.java create mode 100644 javatests/src/com/android/loganalysis/item/SmartMonkeyLogItemTest.java create mode 100644 javatests/src/com/android/loganalysis/item/SystemPropsItemTest.java create mode 100644 javatests/src/com/android/loganalysis/item/TopItemTest.java create mode 100644 javatests/src/com/android/loganalysis/item/WakelockItemTest.java create mode 100644 javatests/src/com/android/loganalysis/parser/AbstractSectionParserTest.java create mode 100644 javatests/src/com/android/loganalysis/parser/ActivityServiceParserTest.java create mode 100644 javatests/src/com/android/loganalysis/parser/AnrParserTest.java create mode 100644 javatests/src/com/android/loganalysis/parser/BatteryDischargeStatsInfoParserTest.java create mode 100644 javatests/src/com/android/loganalysis/parser/BatteryStatsDetailedInfoParserTest.java create mode 100644 javatests/src/com/android/loganalysis/parser/BatteryStatsSummaryInfoParserTest.java create mode 100644 javatests/src/com/android/loganalysis/parser/BatteryUsageParserTest.java create mode 100644 javatests/src/com/android/loganalysis/parser/BugreportParserTest.java create mode 100644 javatests/src/com/android/loganalysis/parser/CompactMemInfoParserTest.java create mode 100644 javatests/src/com/android/loganalysis/parser/CpuInfoParserTest.java create mode 100644 javatests/src/com/android/loganalysis/parser/DmesgParserTest.java create mode 100644 javatests/src/com/android/loganalysis/parser/DumpsysBatteryStatsParserTest.java create mode 100644 javatests/src/com/android/loganalysis/parser/DumpsysPackageStatsParserTest.java create mode 100644 javatests/src/com/android/loganalysis/parser/DumpsysParserTest.java create mode 100644 javatests/src/com/android/loganalysis/parser/DumpsysProcStatsParserTest.java create mode 100644 javatests/src/com/android/loganalysis/parser/DumpsysProcessMeminfoParserTest.java create mode 100644 javatests/src/com/android/loganalysis/parser/DumpsysWifiStatsParserTest.java create mode 100644 javatests/src/com/android/loganalysis/parser/DvmLockSampleParserTest.java create mode 100644 javatests/src/com/android/loganalysis/parser/EventsLogParserTest.java create mode 100644 javatests/src/com/android/loganalysis/parser/GfxInfoParserTest.java create mode 100644 javatests/src/com/android/loganalysis/parser/InterruptParserTest.java create mode 100644 javatests/src/com/android/loganalysis/parser/JavaCrashParserTest.java create mode 100644 javatests/src/com/android/loganalysis/parser/KernelLogParserTest.java create mode 100644 javatests/src/com/android/loganalysis/parser/LocationServiceParserTest.java create mode 100644 javatests/src/com/android/loganalysis/parser/LogcatParserTest.java create mode 100644 javatests/src/com/android/loganalysis/parser/MemHealthParserTest.java create mode 100644 javatests/src/com/android/loganalysis/parser/MemInfoParserTest.java create mode 100644 javatests/src/com/android/loganalysis/parser/MonkeyLogParserTest.java create mode 100644 javatests/src/com/android/loganalysis/parser/NativeCrashParserTest.java create mode 100644 javatests/src/com/android/loganalysis/parser/ProcessUsageParserTest.java create mode 100644 javatests/src/com/android/loganalysis/parser/ProcrankParserTest.java create mode 100644 javatests/src/com/android/loganalysis/parser/QtaguidParserTest.java create mode 100644 javatests/src/com/android/loganalysis/parser/SmartMonkeyLogParserTest.java create mode 100644 javatests/src/com/android/loganalysis/parser/SystemPropsParserTest.java create mode 100644 javatests/src/com/android/loganalysis/parser/TimingsLogParserTest.java create mode 100644 javatests/src/com/android/loganalysis/parser/TopParserTest.java create mode 100644 javatests/src/com/android/loganalysis/parser/TraceFormatParserTest.java create mode 100644 javatests/src/com/android/loganalysis/parser/TracesParserTest.java create mode 100644 javatests/src/com/android/loganalysis/parser/WakelockParserTest.java create mode 100644 javatests/src/com/android/loganalysis/rule/InterruptRuleTest.java create mode 100644 javatests/src/com/android/loganalysis/rule/LocationUsageRuleTest.java create mode 100644 javatests/src/com/android/loganalysis/rule/ProcessUsageRuleTest.java create mode 100644 javatests/src/com/android/loganalysis/rule/WakelockRuleTest.java create mode 100644 javatests/src/com/android/loganalysis/rule/WifiStatsRuleTest.java create mode 100644 javatests/src/com/android/loganalysis/util/ArrayUtilTest.java create mode 100644 javatests/src/com/android/loganalysis/util/LogPatternUtilTest.java create mode 100644 javatests/src/com/android/loganalysis/util/LogTailUtilTest.java create mode 100644 javatests/src/com/android/loganalysis/util/RegexTrieTest.java create mode 100644 javatests/src/com/android/loganalysis/util/config/ArgsOptionParserTest.java create mode 100644 javatests/src/com/android/loganalysis/util/config/OptionSetterTest.java create mode 100644 javatests/src/com/android/loganalysis/util/config/OptionUpdateRuleTest.java delete mode 100644 tests/.classpath delete mode 100644 tests/.project delete mode 100644 tests/Android.bp delete mode 100644 tests/Android.mk delete mode 100644 tests/src/com/android/loganalysis/item/BatteryDischargeItemTest.java delete mode 100644 tests/src/com/android/loganalysis/item/BatteryUsageItemTest.java delete mode 100644 tests/src/com/android/loganalysis/item/DumpsysPackageStatsItemTest.java delete mode 100644 tests/src/com/android/loganalysis/item/DvmLockSampleItemTest.java delete mode 100644 tests/src/com/android/loganalysis/item/GenericItemTest.java delete mode 100644 tests/src/com/android/loganalysis/item/InterruptItemTest.java delete mode 100644 tests/src/com/android/loganalysis/item/LocationDumpsItemTest.java delete mode 100644 tests/src/com/android/loganalysis/item/MemInfoItemTest.java delete mode 100644 tests/src/com/android/loganalysis/item/MonkeyLogItemTest.java delete mode 100644 tests/src/com/android/loganalysis/item/ProcrankItemTest.java delete mode 100644 tests/src/com/android/loganalysis/item/SmartMonkeyLogItemTest.java delete mode 100644 tests/src/com/android/loganalysis/item/SystemPropsItemTest.java delete mode 100644 tests/src/com/android/loganalysis/item/TopItemTest.java delete mode 100644 tests/src/com/android/loganalysis/item/WakelockItemTest.java delete mode 100644 tests/src/com/android/loganalysis/parser/AbstractSectionParserTest.java delete mode 100644 tests/src/com/android/loganalysis/parser/ActivityServiceParserTest.java delete mode 100644 tests/src/com/android/loganalysis/parser/AnrParserTest.java delete mode 100644 tests/src/com/android/loganalysis/parser/BatteryDischargeStatsInfoParserTest.java delete mode 100644 tests/src/com/android/loganalysis/parser/BatteryStatsDetailedInfoParserTest.java delete mode 100644 tests/src/com/android/loganalysis/parser/BatteryStatsSummaryInfoParserTest.java delete mode 100644 tests/src/com/android/loganalysis/parser/BatteryUsageParserTest.java delete mode 100644 tests/src/com/android/loganalysis/parser/BugreportParserTest.java delete mode 100644 tests/src/com/android/loganalysis/parser/CompactMemInfoParserTest.java delete mode 100644 tests/src/com/android/loganalysis/parser/CpuInfoParserTest.java delete mode 100644 tests/src/com/android/loganalysis/parser/DmesgParserTest.java delete mode 100644 tests/src/com/android/loganalysis/parser/DumpsysBatteryStatsParserTest.java delete mode 100644 tests/src/com/android/loganalysis/parser/DumpsysPackageStatsParserTest.java delete mode 100644 tests/src/com/android/loganalysis/parser/DumpsysParserTest.java delete mode 100644 tests/src/com/android/loganalysis/parser/DumpsysProcStatsParserTest.java delete mode 100644 tests/src/com/android/loganalysis/parser/DumpsysProcessMeminfoParserTest.java delete mode 100644 tests/src/com/android/loganalysis/parser/DumpsysWifiStatsParserTest.java delete mode 100644 tests/src/com/android/loganalysis/parser/DvmLockSampleParserTest.java delete mode 100644 tests/src/com/android/loganalysis/parser/EventsLogParserTest.java delete mode 100644 tests/src/com/android/loganalysis/parser/GfxInfoParserTest.java delete mode 100644 tests/src/com/android/loganalysis/parser/InterruptParserTest.java delete mode 100644 tests/src/com/android/loganalysis/parser/JavaCrashParserTest.java delete mode 100644 tests/src/com/android/loganalysis/parser/KernelLogParserTest.java delete mode 100644 tests/src/com/android/loganalysis/parser/LocationServiceParserTest.java delete mode 100644 tests/src/com/android/loganalysis/parser/LogcatParserTest.java delete mode 100644 tests/src/com/android/loganalysis/parser/MemHealthParserTest.java delete mode 100644 tests/src/com/android/loganalysis/parser/MemInfoParserTest.java delete mode 100644 tests/src/com/android/loganalysis/parser/MonkeyLogParserTest.java delete mode 100644 tests/src/com/android/loganalysis/parser/NativeCrashParserTest.java delete mode 100644 tests/src/com/android/loganalysis/parser/ProcessUsageParserTest.java delete mode 100644 tests/src/com/android/loganalysis/parser/ProcrankParserTest.java delete mode 100644 tests/src/com/android/loganalysis/parser/QtaguidParserTest.java delete mode 100644 tests/src/com/android/loganalysis/parser/SmartMonkeyLogParserTest.java delete mode 100644 tests/src/com/android/loganalysis/parser/SystemPropsParserTest.java delete mode 100644 tests/src/com/android/loganalysis/parser/TimingsLogParserTest.java delete mode 100644 tests/src/com/android/loganalysis/parser/TopParserTest.java delete mode 100644 tests/src/com/android/loganalysis/parser/TraceFormatParserTest.java delete mode 100644 tests/src/com/android/loganalysis/parser/TracesParserTest.java delete mode 100644 tests/src/com/android/loganalysis/parser/WakelockParserTest.java delete mode 100644 tests/src/com/android/loganalysis/rule/InterruptRuleTest.java delete mode 100644 tests/src/com/android/loganalysis/rule/LocationUsageRuleTest.java delete mode 100644 tests/src/com/android/loganalysis/rule/ProcessUsageRuleTest.java delete mode 100644 tests/src/com/android/loganalysis/rule/WakelockRuleTest.java delete mode 100644 tests/src/com/android/loganalysis/rule/WifiStatsRuleTest.java delete mode 100644 tests/src/com/android/loganalysis/util/ArrayUtilTest.java delete mode 100644 tests/src/com/android/loganalysis/util/LogPatternUtilTest.java delete mode 100644 tests/src/com/android/loganalysis/util/LogTailUtilTest.java delete mode 100644 tests/src/com/android/loganalysis/util/RegexTrieTest.java delete mode 100644 tests/src/com/android/loganalysis/util/config/ArgsOptionParserTest.java delete mode 100644 tests/src/com/android/loganalysis/util/config/OptionSetterTest.java delete mode 100644 tests/src/com/android/loganalysis/util/config/OptionUpdateRuleTest.java diff --git a/javatests/.classpath b/javatests/.classpath new file mode 100644 index 0000000..55aa5dd --- /dev/null +++ b/javatests/.classpath @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/javatests/.project b/javatests/.project new file mode 100644 index 0000000..f4a1c0b --- /dev/null +++ b/javatests/.project @@ -0,0 +1,17 @@ + + + loganalysis-tests + + + + + + org.eclipse.jdt.core.javabuilder + + + + + + org.eclipse.jdt.core.javanature + + diff --git a/javatests/Android.bp b/javatests/Android.bp new file mode 100644 index 0000000..fae1c13 --- /dev/null +++ b/javatests/Android.bp @@ -0,0 +1,32 @@ +// 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 { + default_applicable_licenses: ["Android-Apache-2.0"], +} + +java_test_host { + name: "loganalysis-tests", + defaults: ["tradefed_defaults"], + + // Only compile source java files in this lib. + srcs: ["src/**/*.java"], + + static_libs: [ + "loganalysis", + "json-prebuilt", + "junit", + "guava", + ], +} diff --git a/javatests/Android.mk b/javatests/Android.mk new file mode 100644 index 0000000..e3958cd --- /dev/null +++ b/javatests/Android.mk @@ -0,0 +1,25 @@ +# 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. + +LOCAL_PATH := $(call my-dir) + +# makefile rules to copy jars to HOST_OUT/tradefed +# so tradefed.sh can automatically add to classpath + +DEST_JAR := $(HOST_OUT)/tradefed/loganalysis-tests.jar +$(DEST_JAR): $(call intermediates-dir-for,JAVA_LIBRARIES,loganalysis-tests,HOST)/javalib.jar + $(copy-file-to-new-target) + +# this dependency ensure the above rule will be executed if module is built +$(HOST_OUT_JAVA_LIBRARIES)/loganalysis-tests.jar : $(DEST_JAR) diff --git a/javatests/src/com/android/loganalysis/item/BatteryDischargeItemTest.java b/javatests/src/com/android/loganalysis/item/BatteryDischargeItemTest.java new file mode 100644 index 0000000..5e27eb2 --- /dev/null +++ b/javatests/src/com/android/loganalysis/item/BatteryDischargeItemTest.java @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2015 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.item; + +import com.android.loganalysis.item.BatteryDischargeItem.BatteryDischargeInfoItem; + +import junit.framework.TestCase; + +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + +import java.util.Calendar; + +/** + * Unit test for {@link BatteryDischargeItem}. + */ +public class BatteryDischargeItemTest extends TestCase { + + /** + * Test that {@link BatteryDischargeItem#toJson()} returns correctly. + */ + public void testToJson() throws JSONException { + BatteryDischargeItem item = new BatteryDischargeItem(); + item.addBatteryDischargeInfo(Calendar.getInstance(),25, 95); + + // Convert to JSON string and back again + JSONObject output = new JSONObject(item.toJson().toString()); + + assertTrue(output.has(BatteryDischargeItem.BATTERY_DISCHARGE)); + assertTrue(output.get(BatteryDischargeItem.BATTERY_DISCHARGE) instanceof JSONArray); + + JSONArray dischargeInfo = output.getJSONArray(BatteryDischargeItem.BATTERY_DISCHARGE); + + assertEquals(1, dischargeInfo.length()); + assertTrue(dischargeInfo.getJSONObject(0).has(BatteryDischargeInfoItem.BATTERY_LEVEL)); + assertTrue(dischargeInfo.getJSONObject(0).has( + BatteryDischargeInfoItem.DISCHARGE_ELAPSED_TIME)); + assertTrue(dischargeInfo.getJSONObject(0).has( + BatteryDischargeInfoItem.CLOCK_TIME_OF_DISCHARGE)); + + } +} diff --git a/javatests/src/com/android/loganalysis/item/BatteryUsageItemTest.java b/javatests/src/com/android/loganalysis/item/BatteryUsageItemTest.java new file mode 100644 index 0000000..b44a432 --- /dev/null +++ b/javatests/src/com/android/loganalysis/item/BatteryUsageItemTest.java @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2015 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.item; + +import com.android.loganalysis.item.BatteryUsageItem.BatteryUsageInfoItem; + +import junit.framework.TestCase; + +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + +/** + * Unit test for {@link BatteryUsageItem}. + */ +public class BatteryUsageItemTest extends TestCase { + + /** + * Test that {@link BatteryUsageItem#toJson()} returns correctly. + */ + public void testToJson() throws JSONException { + BatteryUsageItem item = new BatteryUsageItem(); + item.addBatteryUsage("Cell standby", 2925); + item.addBatteryUsage("Uid u0a71", 68.1); + // Convert to JSON string and back again + JSONObject output = new JSONObject(item.toJson().toString()); + + assertTrue(output.has(BatteryUsageItem.BATTERY_CAPACITY)); + assertTrue(output.get(BatteryUsageItem.BATTERY_USAGE) instanceof JSONArray); + + JSONArray usage = output.getJSONArray(BatteryUsageItem.BATTERY_USAGE); + + assertEquals(2, usage.length()); + assertTrue(usage.getJSONObject(0).has(BatteryUsageInfoItem.NAME)); + assertTrue(usage.getJSONObject(0).has(BatteryUsageInfoItem.USAGE)); + + assertTrue(usage.getJSONObject(1).has(BatteryUsageInfoItem.NAME)); + assertTrue(usage.getJSONObject(1).has(BatteryUsageInfoItem.USAGE)); + } +} diff --git a/javatests/src/com/android/loganalysis/item/DumpsysPackageStatsItemTest.java b/javatests/src/com/android/loganalysis/item/DumpsysPackageStatsItemTest.java new file mode 100644 index 0000000..dd60500 --- /dev/null +++ b/javatests/src/com/android/loganalysis/item/DumpsysPackageStatsItemTest.java @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2017 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.item; + +import junit.framework.TestCase; + +import org.json.JSONException; +import org.json.JSONObject; + +/** Unit test for {@link DumpsysPackageStatsItem}. */ +public class DumpsysPackageStatsItemTest extends TestCase { + + /** Test that {@link DumpsysPackageStatsItem#toJson()} returns correctly. */ + public void testToJson() throws JSONException { + DumpsysPackageStatsItem item = new DumpsysPackageStatsItem(); + + item.put("com.google.android.calculator", new AppVersionItem(73000302, "7.3 (3821978)")); + item.put( + "com.google.android.googlequicksearchbox", + new AppVersionItem(300734793, "6.16.35.26.arm64")); + + // Convert to JSON string and back again + JSONObject output = new JSONObject(item.toJson().toString()); + + assertTrue(output.has(DumpsysPackageStatsItem.APP_VERSIONS)); + + JSONObject appVersionsJson = output.getJSONObject(DumpsysPackageStatsItem.APP_VERSIONS); + + assertEquals(2, appVersionsJson.length()); + final JSONObject calcAppVersionJson = + appVersionsJson.getJSONObject("com.google.android.calculator"); + assertEquals(73000302, calcAppVersionJson.getInt(AppVersionItem.VERSION_CODE)); + assertEquals("7.3 (3821978)", calcAppVersionJson.getString(AppVersionItem.VERSION_NAME)); + final JSONObject gsaAppVersionJson = + appVersionsJson.getJSONObject("com.google.android.googlequicksearchbox"); + assertEquals(300734793, gsaAppVersionJson.getInt(AppVersionItem.VERSION_CODE)); + assertEquals("6.16.35.26.arm64", gsaAppVersionJson.getString(AppVersionItem.VERSION_NAME)); + } +} diff --git a/javatests/src/com/android/loganalysis/item/DvmLockSampleItemTest.java b/javatests/src/com/android/loganalysis/item/DvmLockSampleItemTest.java new file mode 100644 index 0000000..5d6054e --- /dev/null +++ b/javatests/src/com/android/loganalysis/item/DvmLockSampleItemTest.java @@ -0,0 +1,57 @@ +/* + * 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.item; + +import junit.framework.TestCase; + +import org.json.JSONException; +import org.json.JSONObject; + +/** + * Unit test for {@link DvmLockSampleItem}. + */ +public class DvmLockSampleItemTest extends TestCase { + /** + * Test that {@link DvmLockSampleItem#toJson()} returns correctly. + */ + public void testToJson() throws JSONException { + DvmLockSampleItem item = new DvmLockSampleItem(); + + item.setAttribute(DvmLockSampleItem.PROCESS_NAME, "android.support.test.aupt"); + item.setAttribute(DvmLockSampleItem.SENSITIVITY_FLAG, false); + item.setAttribute(DvmLockSampleItem.WAITING_THREAD_NAME, "Instr: android.support.test.aupt"); + item.setAttribute(DvmLockSampleItem.WAIT_TIME, 75); + item.setAttribute(DvmLockSampleItem.WAITING_SOURCE_FILE, "AccessibilityCache.java"); + item.setAttribute(DvmLockSampleItem.WAITING_SOURCE_LINE, 256); + item.setAttribute(DvmLockSampleItem.OWNER_FILE_NAME, "-"); + item.setAttribute(DvmLockSampleItem.OWNER_ACQUIRE_SOURCE_LINE, 96); + item.setAttribute(DvmLockSampleItem.SAMPLE_PERCENTAGE, 15); + + // Convert to JSON string and back again + JSONObject output = new JSONObject(item.toJson().toString()); + + // Assert that each field is the expected value + assertEquals("android.support.test.aupt", output.get(DvmLockSampleItem.PROCESS_NAME)); + assertEquals(false, output.get(DvmLockSampleItem.SENSITIVITY_FLAG)); + assertEquals("Instr: android.support.test.aupt", output.get(DvmLockSampleItem.WAITING_THREAD_NAME)); + assertEquals(75, output.get(DvmLockSampleItem.WAIT_TIME)); + assertEquals("AccessibilityCache.java", output.get(DvmLockSampleItem.WAITING_SOURCE_FILE)); + assertEquals(256, output.get(DvmLockSampleItem.WAITING_SOURCE_LINE)); + assertEquals("-", output.get(DvmLockSampleItem.OWNER_FILE_NAME)); + assertEquals(96, output.get(DvmLockSampleItem.OWNER_ACQUIRE_SOURCE_LINE)); + assertEquals(15, output.get(DvmLockSampleItem.SAMPLE_PERCENTAGE)); + } +} diff --git a/javatests/src/com/android/loganalysis/item/GenericItemTest.java b/javatests/src/com/android/loganalysis/item/GenericItemTest.java new file mode 100644 index 0000000..e9ea31f --- /dev/null +++ b/javatests/src/com/android/loganalysis/item/GenericItemTest.java @@ -0,0 +1,266 @@ +/* + * Copyright (C) 2011 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.item; + +import junit.framework.TestCase; + +import org.json.JSONException; +import org.json.JSONObject; + +import java.util.Arrays; +import java.util.Date; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +/** + * Unit test for {@link GenericItem}. + */ +public class GenericItemTest extends TestCase { + private static final Set ATTRIBUTES = new HashSet(Arrays.asList( + "integer", "string")); + + private String mStringAttribute = "String"; + private Integer mIntegerAttribute = 1; + + /** Empty item with no attributes set */ + private GenericItem mEmptyItem1; + /** Empty item with no attributes set */ + private GenericItem mEmptyItem2; + /** Item with only the string attribute set */ + private GenericItem mStringItem; + /** Item with only the integer attribute set */ + private GenericItem mIntegerItem; + /** Item with both attributes set, product of mStringItem and mIntegerItem */ + private GenericItem mFullItem1; + /** Item with both attributes set, product of mStringItem and mIntegerItem */ + private GenericItem mFullItem2; + /** Item that is inconsistent with the others */ + private GenericItem mInconsistentItem; + + @Override + public void setUp() { + mEmptyItem1 = new GenericItem(ATTRIBUTES); + mEmptyItem2 = new GenericItem(ATTRIBUTES); + mStringItem = new GenericItem(ATTRIBUTES); + mStringItem.setAttribute("string", mStringAttribute); + mIntegerItem = new GenericItem(ATTRIBUTES); + mIntegerItem.setAttribute("integer", mIntegerAttribute); + mFullItem1 = new GenericItem(ATTRIBUTES); + mFullItem1.setAttribute("string", mStringAttribute); + mFullItem1.setAttribute("integer", mIntegerAttribute); + mFullItem2 = new GenericItem(ATTRIBUTES); + mFullItem2.setAttribute("string", mStringAttribute); + mFullItem2.setAttribute("integer", mIntegerAttribute); + mInconsistentItem = new GenericItem(ATTRIBUTES); + mInconsistentItem.setAttribute("string", "gnirts"); + mInconsistentItem.setAttribute("integer", 2); + } + + /** + * Test for {@link GenericItem#mergeAttributes(IItem, Set)}. + */ + public void testMergeAttributes() throws ConflictingItemException { + Map attributes; + + attributes = mEmptyItem1.mergeAttributes(mEmptyItem1, ATTRIBUTES); + assertNull(attributes.get("string")); + assertNull(attributes.get("integer")); + + attributes = mEmptyItem1.mergeAttributes(mEmptyItem2, ATTRIBUTES); + assertNull(attributes.get("string")); + assertNull(attributes.get("integer")); + + attributes = mEmptyItem2.mergeAttributes(mEmptyItem1, ATTRIBUTES); + assertNull(attributes.get("string")); + assertNull(attributes.get("integer")); + + attributes = mEmptyItem1.mergeAttributes(mStringItem, ATTRIBUTES); + assertEquals(mStringAttribute, attributes.get("string")); + assertNull(attributes.get("integer")); + + attributes = mStringItem.mergeAttributes(mEmptyItem1, ATTRIBUTES); + assertEquals(mStringAttribute, attributes.get("string")); + assertNull(attributes.get("integer")); + + attributes = mIntegerItem.mergeAttributes(mStringItem, ATTRIBUTES); + assertEquals(mStringAttribute, attributes.get("string")); + assertEquals(mIntegerAttribute, attributes.get("integer")); + + attributes = mEmptyItem1.mergeAttributes(mFullItem1, ATTRIBUTES); + assertEquals(mStringAttribute, attributes.get("string")); + assertEquals(mIntegerAttribute, attributes.get("integer")); + + attributes = mFullItem1.mergeAttributes(mEmptyItem1, ATTRIBUTES); + assertEquals(mStringAttribute, attributes.get("string")); + assertEquals(mIntegerAttribute, attributes.get("integer")); + + attributes = mFullItem1.mergeAttributes(mFullItem2, ATTRIBUTES); + assertEquals(mStringAttribute, attributes.get("string")); + assertEquals(mIntegerAttribute, attributes.get("integer")); + + try { + mFullItem1.mergeAttributes(mInconsistentItem, ATTRIBUTES); + fail("Expecting a ConflictingItemException"); + } catch (ConflictingItemException e) { + // Expected + } + } + + /** + * Test for {@link GenericItem#isConsistent(IItem)}. + */ + public void testIsConsistent() { + assertTrue(mEmptyItem1.isConsistent(mEmptyItem1)); + assertFalse(mEmptyItem1.isConsistent(null)); + assertTrue(mEmptyItem1.isConsistent(mEmptyItem2)); + assertTrue(mEmptyItem2.isConsistent(mEmptyItem1)); + assertTrue(mEmptyItem1.isConsistent(mStringItem)); + assertTrue(mStringItem.isConsistent(mEmptyItem1)); + assertTrue(mIntegerItem.isConsistent(mStringItem)); + assertTrue(mEmptyItem1.isConsistent(mFullItem1)); + assertTrue(mFullItem1.isConsistent(mEmptyItem1)); + assertTrue(mFullItem1.isConsistent(mFullItem2)); + assertFalse(mFullItem1.isConsistent(mInconsistentItem)); + } + + /** Test {@link GenericItem#equals(Object)}. */ + @SuppressWarnings("SelfEquals") + public void testEquals() { + assertTrue(mEmptyItem1.equals(mEmptyItem1)); + assertFalse(mEmptyItem1.equals(null)); + assertTrue(mEmptyItem1.equals(mEmptyItem2)); + assertTrue(mEmptyItem2.equals(mEmptyItem1)); + assertFalse(mEmptyItem1.equals(mStringItem)); + assertFalse(mStringItem.equals(mEmptyItem1)); + assertFalse(mIntegerItem.equals(mStringItem)); + assertFalse(mEmptyItem1.equals(mFullItem1)); + assertFalse(mFullItem1.equals(mEmptyItem1)); + assertTrue(mFullItem1.equals(mFullItem2)); + assertFalse(mFullItem1.equals(mInconsistentItem)); + } + + /** + * Test for {@link GenericItem#setAttribute(String, Object)} and + * {@link GenericItem#getAttribute(String)}. + */ + public void testAttributes() { + GenericItem item = new GenericItem(ATTRIBUTES); + + assertNull(item.getAttribute("string")); + assertNull(item.getAttribute("integer")); + + item.setAttribute("string", mStringAttribute); + item.setAttribute("integer", mIntegerAttribute); + + assertEquals(mStringAttribute, item.getAttribute("string")); + assertEquals(mIntegerAttribute, item.getAttribute("integer")); + + item.setAttribute("string", null); + item.setAttribute("integer", null); + + assertNull(item.getAttribute("string")); + assertNull(item.getAttribute("integer")); + + try { + item.setAttribute("object", new Object()); + fail("Failed to throw IllegalArgumentException"); + } catch (IllegalArgumentException e) { + // Expected because "object" is not "string" or "integer". + } + } + + /** + * Test for {@link GenericItem#areEqual(Object, Object)} + */ + public void testAreEqual() { + assertTrue(GenericItem.areEqual(null, null)); + assertTrue(GenericItem.areEqual("test", "test")); + assertFalse(GenericItem.areEqual(null, "test")); + assertFalse(GenericItem.areEqual("test", null)); + assertFalse(GenericItem.areEqual("test", "")); + } + + /** + * Test for {@link GenericItem#areConsistent(Object, Object)} + */ + public void testAreConsistent() { + assertTrue(GenericItem.areConsistent(null, null)); + assertTrue(GenericItem.areConsistent("test", "test")); + assertTrue(GenericItem.areConsistent(null, "test")); + assertTrue(GenericItem.areConsistent("test", null)); + assertFalse(GenericItem.areConsistent("test", "")); + } + + /** + * Test for {@link GenericItem#mergeObjects(Object, Object)} + */ + public void testMergeObjects() throws ConflictingItemException { + assertNull(GenericItem.mergeObjects(null, null)); + assertEquals("test", GenericItem.mergeObjects("test", "test")); + assertEquals("test", GenericItem.mergeObjects(null, "test")); + assertEquals("test", GenericItem.mergeObjects("test", null)); + + try { + assertEquals("test", GenericItem.mergeObjects("test", "")); + fail("Expected ConflictingItemException to be thrown"); + } catch (ConflictingItemException e) { + // Expected because "test" conflicts with "". + } + } + + /** + * Test that {@link GenericItem#toJson()} returns correctly. + */ + public void testToJson() throws JSONException { + GenericItem item = new GenericItem(new HashSet(Arrays.asList( + "string", "date", "object", "integer", "long", "float", "double", "item", "null"))); + Date date = new Date(); + Object object = new Object(); + NativeCrashItem subItem = new NativeCrashItem(); + + item.setAttribute("string", "foo"); + item.setAttribute("date", date); + item.setAttribute("object", object); + item.setAttribute("integer", 0); + item.setAttribute("long", 1L); + item.setAttribute("float", 2.5f); + item.setAttribute("double", 3.5); + item.setAttribute("item", subItem); + item.setAttribute("null", null); + + // Convert to JSON string and back again + JSONObject output = new JSONObject(item.toJson().toString()); + + assertTrue(output.has("string")); + assertEquals("foo", output.get("string")); + assertTrue(output.has("date")); + assertEquals(date.toString(), output.get("date")); + assertTrue(output.has("object")); + assertEquals(object.toString(), output.get("object")); + assertTrue(output.has("integer")); + assertEquals(0, output.get("integer")); + assertTrue(output.has("long")); + assertEquals(1, output.get("long")); + assertTrue(output.has("float")); + assertEquals(2.5, output.get("float")); + assertTrue(output.has("double")); + assertEquals(3.5, output.get("double")); + assertTrue(output.has("item")); + assertTrue(output.get("item") instanceof JSONObject); + assertFalse(output.has("null")); + } +} diff --git a/javatests/src/com/android/loganalysis/item/InterruptItemTest.java b/javatests/src/com/android/loganalysis/item/InterruptItemTest.java new file mode 100644 index 0000000..9e9df61 --- /dev/null +++ b/javatests/src/com/android/loganalysis/item/InterruptItemTest.java @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2015 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.item; + + +import com.android.loganalysis.item.InterruptItem.InterruptInfoItem; + +import junit.framework.TestCase; + +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + +/** + * Unit test for {@link InterruptItem}. + */ +public class InterruptItemTest extends TestCase { + + /** + * Test that {@link InterruptItem#toJson()} returns correctly. + */ + public void testToJson() throws JSONException { + InterruptItem item = new InterruptItem(); + item.addInterrupt("smd-modem",25, InterruptItem.InterruptCategory.ALARM_INTERRUPT); + + // Convert to JSON string and back again + JSONObject output = new JSONObject(item.toJson().toString()); + + assertTrue(output.has(InterruptItem.INTERRUPTS)); + assertTrue(output.get(InterruptItem.INTERRUPTS) instanceof JSONArray); + + JSONArray interruptsInfo = output.getJSONArray(InterruptItem.INTERRUPTS); + + assertEquals(1, interruptsInfo.length()); + assertTrue(interruptsInfo.getJSONObject(0).has(InterruptInfoItem.NAME)); + assertTrue(interruptsInfo.getJSONObject(0).has(InterruptInfoItem.CATEGORY)); + assertTrue(interruptsInfo.getJSONObject(0).has(InterruptInfoItem.INTERRUPT_COUNT)); + + } +} diff --git a/javatests/src/com/android/loganalysis/item/LocationDumpsItemTest.java b/javatests/src/com/android/loganalysis/item/LocationDumpsItemTest.java new file mode 100644 index 0000000..a96bc0d --- /dev/null +++ b/javatests/src/com/android/loganalysis/item/LocationDumpsItemTest.java @@ -0,0 +1,81 @@ +/* + * Copyright (C) 2016 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.item; + +import com.android.loganalysis.item.LocationDumpsItem.LocationInfoItem; + +import junit.framework.TestCase; + +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + +/** + * Unit test for {@link LocationDumpsItem}. + */ +public class LocationDumpsItemTest extends TestCase { + + /** + * Test that {@link LocationDumpsItem#toJson()} returns correctly. + */ + public void testToJson() throws JSONException { + LocationDumpsItem item = new LocationDumpsItem(); + item.addLocationClient("com.google.android.gms", 500, 60, 1000, "PRIORITY_ACCURACY", 45); + item.addLocationClient("com.google.android.maps", 0, 0, 0, "PRIORITY_ACCURACY", 55); + + // Convert to JSON string and back again + JSONObject output = new JSONObject(item.toJson().toString()); + + assertTrue(output.has(LocationDumpsItem.LOCATION_CLIENTS)); + assertTrue(output.get(LocationDumpsItem.LOCATION_CLIENTS) instanceof JSONArray); + + JSONArray locationClients = output.getJSONArray(LocationDumpsItem.LOCATION_CLIENTS); + + assertEquals(2, locationClients.length()); + assertTrue(locationClients.getJSONObject(0).has(LocationInfoItem.PACKAGE)); + assertTrue(locationClients.getJSONObject(0).has(LocationInfoItem.EFFECTIVE_INTERVAL)); + assertTrue(locationClients.getJSONObject(0).has(LocationInfoItem.MIN_INTERVAL)); + assertTrue(locationClients.getJSONObject(0).has(LocationInfoItem.MAX_INTERVAL)); + assertTrue(locationClients.getJSONObject(0).has(LocationInfoItem.REQUEST_PRIORITY)); + assertTrue(locationClients.getJSONObject(0).has(LocationInfoItem.LOCATION_DURATION)); + + assertTrue(locationClients.getJSONObject(1).has(LocationInfoItem.PACKAGE)); + assertTrue(locationClients.getJSONObject(1).has(LocationInfoItem.EFFECTIVE_INTERVAL)); + assertTrue(locationClients.getJSONObject(1).has(LocationInfoItem.MIN_INTERVAL)); + assertTrue(locationClients.getJSONObject(1).has(LocationInfoItem.MAX_INTERVAL)); + assertTrue(locationClients.getJSONObject(1).has(LocationInfoItem.REQUEST_PRIORITY)); + assertTrue(locationClients.getJSONObject(1).has(LocationInfoItem.LOCATION_DURATION)); + } + + /** + * Test that {@link LocationDumpsItem#getLocationClients()} returns correctly. + */ + public void testGetLocationDumps() { + LocationDumpsItem item = new LocationDumpsItem(); + item.addLocationClient("com.google.android.gms", 500, 60, 1000, "PRIORITY_ACCURACY", 45); + + assertEquals(item.getLocationClients().size(), 1); + LocationInfoItem client = item.getLocationClients().iterator().next(); + assertNotNull(client); + assertEquals(client.getPackage(), "com.google.android.gms"); + assertEquals(client.getEffectiveInterval(), 500); + assertEquals(client.getMinInterval(), 60); + assertEquals(client.getMaxInterval(), 1000); + assertEquals(client.getPriority(), "PRIORITY_ACCURACY"); + assertEquals(client.getDuration(), 45); + } + +} diff --git a/javatests/src/com/android/loganalysis/item/MemInfoItemTest.java b/javatests/src/com/android/loganalysis/item/MemInfoItemTest.java new file mode 100644 index 0000000..7f25fe3 --- /dev/null +++ b/javatests/src/com/android/loganalysis/item/MemInfoItemTest.java @@ -0,0 +1,52 @@ +/* + * 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.item; + +import junit.framework.TestCase; + +import org.json.JSONException; +import org.json.JSONObject; + +/** + * Unit test for {@link MemInfoItem}. + */ +public class MemInfoItemTest extends TestCase { + + /** + * Test that {@link MemInfoItem#toJson()} returns correctly. + */ + public void testToJson() throws JSONException { + MemInfoItem item = new MemInfoItem(); + item.put("foo", 123l); + item.put("bar", 456l); + item.setText("foo: 123 kB\nbar: 456 kB"); + + // Convert to JSON string and back again + JSONObject output = new JSONObject(item.toJson().toString()); + + assertTrue(output.has(MemInfoItem.LINES)); + assertTrue(output.get(MemInfoItem.LINES) instanceof JSONObject); + assertTrue(output.has(MemInfoItem.TEXT)); + assertEquals("foo: 123 kB\nbar: 456 kB", output.get(MemInfoItem.TEXT)); + + JSONObject lines = output.getJSONObject(MemInfoItem.LINES); + + assertEquals(2, lines.length()); + + assertEquals(123, lines.get("foo")); + assertEquals(456, lines.get("bar")); + } +} diff --git a/javatests/src/com/android/loganalysis/item/MonkeyLogItemTest.java b/javatests/src/com/android/loganalysis/item/MonkeyLogItemTest.java new file mode 100644 index 0000000..cc2867c --- /dev/null +++ b/javatests/src/com/android/loganalysis/item/MonkeyLogItemTest.java @@ -0,0 +1,67 @@ +/* + * 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.item; + +import junit.framework.TestCase; + +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + +/** + * Unit test for {@link MonkeyLogItem}. + */ +public class MonkeyLogItemTest extends TestCase { + /** + * Test that {@link MonkeyLogItem#toJson()} returns correctly. + */ + public void testToJson() throws JSONException { + MonkeyLogItem item = new MonkeyLogItem(); + item.addCategory("category1"); + item.addCategory("category2"); + item.addPackage("package1"); + item.addPackage("package2"); + item.addPackage("package3"); + + // Convert to JSON string and back again + JSONObject output = new JSONObject(item.toJson().toString()); + + assertTrue(output.has(MonkeyLogItem.CATEGORIES)); + assertTrue(output.get(MonkeyLogItem.CATEGORIES) instanceof JSONArray); + + JSONArray categories = output.getJSONArray(MonkeyLogItem.CATEGORIES); + + assertEquals(2, categories.length()); + assertTrue(in("category1", categories)); + assertTrue(in("category2", categories)); + + JSONArray packages = output.getJSONArray(MonkeyLogItem.PACKAGES); + + assertEquals(3, packages.length()); + assertTrue(in("package1", packages)); + assertTrue(in("package2", packages)); + assertTrue(in("package3", packages)); + } + + private boolean in(String value, JSONArray array) throws JSONException { + for (int i = 0; i < array.length(); i++) { + if (value.equals(array.get(i))) { + return true; + } + } + return false; + } +} diff --git a/javatests/src/com/android/loganalysis/item/ProcrankItemTest.java b/javatests/src/com/android/loganalysis/item/ProcrankItemTest.java new file mode 100644 index 0000000..7f5d309 --- /dev/null +++ b/javatests/src/com/android/loganalysis/item/ProcrankItemTest.java @@ -0,0 +1,60 @@ +/* + * 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.item; + +import junit.framework.TestCase; + +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + +/** + * Unit test for {@link ProcrankItem}. + */ +public class ProcrankItemTest extends TestCase { + + /** + * Test that {@link ProcrankItem#toJson()} returns correctly. + */ + public void testToJson() throws JSONException { + ProcrankItem item = new ProcrankItem(); + item.addProcrankLine(0, "process0", 1, 2, 3, 4); + item.addProcrankLine(5, "process1", 6, 7, 8, 9); + item.setText("foo\nbar"); + + // Convert to JSON string and back again + JSONObject output = new JSONObject(item.toJson().toString()); + + assertTrue(output.has(ProcrankItem.LINES)); + assertTrue(output.get(ProcrankItem.LINES) instanceof JSONArray); + assertTrue(output.has(ProcrankItem.TEXT)); + assertEquals("foo\nbar", output.get(ProcrankItem.TEXT)); + + JSONArray lines = output.getJSONArray(ProcrankItem.LINES); + + assertEquals(2, lines.length()); + assertTrue(lines.get(0) instanceof JSONObject); + + JSONObject line = lines.getJSONObject(0); + + assertEquals(0, line.get(ProcrankItem.PID)); + assertEquals("process0", line.get(ProcrankItem.PROCESS_NAME)); + assertEquals(1, line.get(ProcrankItem.VSS)); + assertEquals(2, line.get(ProcrankItem.RSS)); + assertEquals(3, line.get(ProcrankItem.PSS)); + assertEquals(4, line.get(ProcrankItem.USS)); + } +} diff --git a/javatests/src/com/android/loganalysis/item/SmartMonkeyLogItemTest.java b/javatests/src/com/android/loganalysis/item/SmartMonkeyLogItemTest.java new file mode 100644 index 0000000..4dd5597 --- /dev/null +++ b/javatests/src/com/android/loganalysis/item/SmartMonkeyLogItemTest.java @@ -0,0 +1,52 @@ +/* + * 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.item; + +import junit.framework.TestCase; + +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + +import java.util.Date; + +/** + * Unit test for {@link SmartMonkeyLogItem}. + */ +public class SmartMonkeyLogItemTest extends TestCase { + /** + * Test that {@link SmartMonkeyLogItem#toJson()} returns correctly. + */ + public void testToJson() throws JSONException { + SmartMonkeyLogItem item = new SmartMonkeyLogItem(); + item.addApplication("application1"); + item.addPackage("package1"); + item.addAnrTime(new Date()); + item.addCrashTime(new Date()); + + // Convert to JSON string and back again + JSONObject output = new JSONObject(item.toJson().toString()); + + assertTrue(output.has(SmartMonkeyLogItem.APPLICATIONS)); + assertTrue(output.get(SmartMonkeyLogItem.APPLICATIONS) instanceof JSONArray); + assertTrue(output.has(SmartMonkeyLogItem.PACKAGES)); + assertTrue(output.get(SmartMonkeyLogItem.PACKAGES) instanceof JSONArray); + assertTrue(output.has(SmartMonkeyLogItem.ANR_TIMES)); + assertTrue(output.get(SmartMonkeyLogItem.ANR_TIMES) instanceof JSONArray); + assertTrue(output.has(SmartMonkeyLogItem.CRASH_TIMES)); + assertTrue(output.get(SmartMonkeyLogItem.CRASH_TIMES) instanceof JSONArray); + } +} diff --git a/javatests/src/com/android/loganalysis/item/SystemPropsItemTest.java b/javatests/src/com/android/loganalysis/item/SystemPropsItemTest.java new file mode 100644 index 0000000..b9b6675 --- /dev/null +++ b/javatests/src/com/android/loganalysis/item/SystemPropsItemTest.java @@ -0,0 +1,52 @@ +/* + * 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.item; + +import junit.framework.TestCase; + +import org.json.JSONException; +import org.json.JSONObject; + +/** + * Unit test for {@link SystemPropsItem}. + */ +public class SystemPropsItemTest extends TestCase { + + /** + * Test that {@link SystemPropsItem#toJson()} returns correctly. + */ + public void testToJson() throws JSONException { + SystemPropsItem item = new SystemPropsItem(); + item.put("foo", "123"); + item.put("bar", "456"); + item.setText("[foo]: [123]\n[bar]: [456]"); + + // Convert to JSON string and back again + JSONObject output = new JSONObject(item.toJson().toString()); + + assertTrue(output.has(SystemPropsItem.LINES)); + assertTrue(output.get(SystemPropsItem.LINES) instanceof JSONObject); + assertTrue(output.has(SystemPropsItem.TEXT)); + assertEquals("[foo]: [123]\n[bar]: [456]", output.get(SystemPropsItem.TEXT)); + + JSONObject lines = output.getJSONObject(SystemPropsItem.LINES); + + assertEquals(2, lines.length()); + + assertEquals("123", lines.get("foo")); + assertEquals("456", lines.get("bar")); + } +} diff --git a/javatests/src/com/android/loganalysis/item/TopItemTest.java b/javatests/src/com/android/loganalysis/item/TopItemTest.java new file mode 100644 index 0000000..2df01d0 --- /dev/null +++ b/javatests/src/com/android/loganalysis/item/TopItemTest.java @@ -0,0 +1,41 @@ +/* + * 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.item; + +import junit.framework.TestCase; + +import org.json.JSONException; +import org.json.JSONObject; + +/** + * Unit test for {@link TopItem}. + */ +public class TopItemTest extends TestCase { + + /** + * Test that {@link TopItem#toJson()} returns correctly. + */ + public void testToJson() throws JSONException { + TopItem item = new TopItem(); + item.setText("User 20%, System 20%, IOW 5%, IRQ 3%"); + + // Convert to JSON string and back again + JSONObject output = new JSONObject(item.toJson().toString()); + + assertTrue(output.has(TopItem.TEXT)); + assertEquals("User 20%, System 20%, IOW 5%, IRQ 3%", output.get(TopItem.TEXT)); + } +} diff --git a/javatests/src/com/android/loganalysis/item/WakelockItemTest.java b/javatests/src/com/android/loganalysis/item/WakelockItemTest.java new file mode 100644 index 0000000..f570a7b --- /dev/null +++ b/javatests/src/com/android/loganalysis/item/WakelockItemTest.java @@ -0,0 +1,63 @@ +/* + * Copyright (C) 2015 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.item; + +import com.android.loganalysis.item.WakelockItem.WakelockInfoItem; + +import junit.framework.TestCase; + +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + +/** + * Unit test for {@link WakelockItem}. + */ +public class WakelockItemTest extends TestCase { + + /** + * Test that {@link WakelockItem#toJson()} returns correctly. + */ + public void testToJson() throws JSONException { + WakelockItem item = new WakelockItem(); + item.addWakeLock("screen","u100", 150000, 25, + WakelockItem.WakeLockCategory.PARTIAL_WAKELOCK); + item.addWakeLock("wlan_rx", 150000, 25, + WakelockItem.WakeLockCategory.KERNEL_WAKELOCK); + + // Convert to JSON string and back again + JSONObject output = new JSONObject(item.toJson().toString()); + + assertTrue(output.has(WakelockItem.WAKELOCKS)); + assertTrue(output.get(WakelockItem.WAKELOCKS) instanceof JSONArray); + + JSONArray wakelockInfo = output.getJSONArray(WakelockItem.WAKELOCKS); + + assertEquals(2, wakelockInfo.length()); + assertTrue(wakelockInfo.getJSONObject(0).has(WakelockInfoItem.NAME)); + assertTrue(wakelockInfo.getJSONObject(0).has(WakelockInfoItem.PROCESS_UID)); + assertTrue(wakelockInfo.getJSONObject(0).has(WakelockInfoItem.HELD_TIME)); + assertTrue(wakelockInfo.getJSONObject(0).has(WakelockInfoItem.LOCKED_COUNT)); + assertTrue(wakelockInfo.getJSONObject(0).has(WakelockInfoItem.CATEGORY)); + + assertTrue(wakelockInfo.getJSONObject(1).has(WakelockInfoItem.NAME)); + assertFalse(wakelockInfo.getJSONObject(1).has(WakelockInfoItem.PROCESS_UID)); + assertTrue(wakelockInfo.getJSONObject(1).has(WakelockInfoItem.HELD_TIME)); + assertTrue(wakelockInfo.getJSONObject(1).has(WakelockInfoItem.LOCKED_COUNT)); + assertTrue(wakelockInfo.getJSONObject(1).has(WakelockInfoItem.CATEGORY)); + + } +} diff --git a/javatests/src/com/android/loganalysis/parser/AbstractSectionParserTest.java b/javatests/src/com/android/loganalysis/parser/AbstractSectionParserTest.java new file mode 100644 index 0000000..1092d0e --- /dev/null +++ b/javatests/src/com/android/loganalysis/parser/AbstractSectionParserTest.java @@ -0,0 +1,98 @@ +/* + * Copyright (C) 2011 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.IItem; + +import junit.framework.TestCase; + +import java.util.ArrayList; +import java.util.List; + +/** + * Unit tests for {@link AbstractSectionParser} + */ +public class AbstractSectionParserTest extends TestCase { + AbstractSectionParser mParser = null; + + @Override + public void setUp() throws Exception { + super.setUp(); + mParser = new AbstractSectionParser() { + @Override + public IItem parse(List lines) { + for (String line : lines) { + parseLine(line); + } + commit(); + return null; + } + }; + } + + private static class FakeBlockParser implements IParser { + private String mExpected = null; + private int mCalls = 0; + + public FakeBlockParser(String expected) { + mExpected = expected; + } + + public int getCalls() { + return mCalls; + } + + @Override + public IItem parse(List input) { + assertEquals(1, input.size()); + assertEquals("parseBlock() got unexpected input!", mExpected, input.get(0)); + mCalls += 1; + return null; + } + } + + /** + * Verifies that {@link AbstractSectionParser} switches between parsers as expected + */ + public void testSwitchParsers() { + final String lineFormat = "howdy, parser %d!"; + final String linePattern = "I spy %d candles"; + final int nParsers = 4; + FakeBlockParser[] parsers = new FakeBlockParser[nParsers]; + final List lines = new ArrayList(2*nParsers); + + for (int i = 0; i < nParsers; ++i) { + String line = String.format(lineFormat, i); + FakeBlockParser parser = new FakeBlockParser(line); + mParser.addSectionParser(parser, String.format(linePattern, i)); + parsers[i] = parser; + + // add the parser trigger + lines.add(String.format(linePattern, i)); + // and then add the line that the parser is expecting + lines.add(String.format(lineFormat, i)); + } + + mParser.parse(lines); + + // Verify that all the parsers were run + for (int i = 0; i < nParsers; ++i) { + assertEquals(String.format("Parser %d has wrong call count!", i), 1, + parsers[i].getCalls()); + } + } +} + diff --git a/javatests/src/com/android/loganalysis/parser/ActivityServiceParserTest.java b/javatests/src/com/android/loganalysis/parser/ActivityServiceParserTest.java new file mode 100644 index 0000000..57aff9a --- /dev/null +++ b/javatests/src/com/android/loganalysis/parser/ActivityServiceParserTest.java @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2016 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.ActivityServiceItem; + +import junit.framework.TestCase; + +import java.util.Arrays; +import java.util.List; + +/** + * Unit tests for {@link ActivityServiceParser} + */ +public class ActivityServiceParserTest extends TestCase { + + /** + * Test that normal input is parsed. + */ + public void testActivityServiceParser() { + List inputBlock = Arrays.asList( + "SERVICE com.google.android.gms/" + + "com.google.android.location.internal.GoogleLocationManagerService f4c9e9d " + + "pid=1494", + "Client:", + " nothing to dump", + "Location Request History By Package:", + "Interval effective/min/max 1/0/0[s] Duration: 140[minutes] " + + "[com.google.android.gms, PRIORITY_NO_POWER, UserLocationProducer] " + + "Num requests: 2 Active: true", + "Interval effective/min/max 284/285/3600[s] Duration: 140[minutes] " + + "[com.google.android.googlequicksearchbox, PRIORITY_BALANCED_POWER_ACCURACY] " + + "Num requests: 5 Active: true", + "FLP WakeLock Count:", + "SERVICE com.android.server.telecom/.components.BluetoothPhoneService 98ab pid=802", + "Interval effective/min/max 1/0/0[s] Duration: 140[minutes] " + + "[com.google.android.gms, PRIORITY_NO_POWER, UserLocationProducer] " + + "Num requests: 2 Active: true", + ""); + + ActivityServiceItem activityService = new ActivityServiceParser().parse(inputBlock); + assertNotNull(activityService.getLocationDumps()); + assertEquals(activityService.getLocationDumps().getLocationClients().size(), 2); + } +} + diff --git a/javatests/src/com/android/loganalysis/parser/AnrParserTest.java b/javatests/src/com/android/loganalysis/parser/AnrParserTest.java new file mode 100644 index 0000000..e6afe80 --- /dev/null +++ b/javatests/src/com/android/loganalysis/parser/AnrParserTest.java @@ -0,0 +1,164 @@ +/* + * Copyright (C) 2012 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.AnrItem; +import com.android.loganalysis.util.ArrayUtil; + +import junit.framework.TestCase; + +import java.util.Arrays; +import java.util.List; + +/** + * Unit tests for {@link AnrParser}. + */ +public class AnrParserTest extends TestCase { + + /** + * Test that ANRs are parsed for the header "ANR (application not responding) in process: app" + */ + public void testParse_application_not_responding() { + List lines = Arrays.asList( + "ANR (application not responding) in process: com.android.package", + "Reason: keyDispatchingTimedOut", + "Load: 0.71 / 0.83 / 0.51", + "CPU usage from 4357ms to -1434ms ago:", + " 22% 3378/com.android.package: 19% user + 3.6% kernel / faults: 73 minor 1 major", + " 16% 312/system_server: 12% user + 4.1% kernel / faults: 1082 minor 6 major", + "33% TOTAL: 21% user + 11% kernel + 0.3% iowait", + "CPU usage from 907ms to 1431ms later:", + " 14% 121/mediaserver: 11% user + 3.7% kernel / faults: 17 minor", + " 3.7% 183/AudioOut_2: 3.7% user + 0% kernel", + " 12% 312/system_server: 5.5% user + 7.4% kernel / faults: 6 minor", + " 5.5% 366/InputDispatcher: 0% user + 5.5% kernel", + "18% TOTAL: 11% user + 7.5% kernel"); + + AnrItem anr = new AnrParser().parse(lines); + assertNotNull(anr); + assertEquals("com.android.package", anr.getApp()); + assertEquals("keyDispatchingTimedOut", anr.getReason()); + assertEquals(0.71, anr.getLoad(AnrItem.LoadCategory.LOAD_1)); + assertEquals(0.83, anr.getLoad(AnrItem.LoadCategory.LOAD_5)); + assertEquals(0.51, anr.getLoad(AnrItem.LoadCategory.LOAD_15)); + assertEquals(33.0, anr.getCpuUsage(AnrItem.CpuUsageCategory.TOTAL)); + assertEquals(21.0, anr.getCpuUsage(AnrItem.CpuUsageCategory.USER)); + assertEquals(11.0, anr.getCpuUsage(AnrItem.CpuUsageCategory.KERNEL)); + assertEquals(0.3, anr.getCpuUsage(AnrItem.CpuUsageCategory.IOWAIT)); + assertEquals(ArrayUtil.join("\n", lines), anr.getStack()); + } + + /** + * Test that ANRs are parsed for the header "ANR in app" + */ + public void testParse_anr_in_app() { + List lines = Arrays.asList( + "ANR in com.android.package", + "Reason: keyDispatchingTimedOut", + "Load: 0.71 / 0.83 / 0.51", + "CPU usage from 4357ms to -1434ms ago:", + " 22% 3378/com.android.package: 19% user + 3.6% kernel / faults: 73 minor 1 major", + " 16% 312/system_server: 12% user + 4.1% kernel / faults: 1082 minor 6 major", + "33% TOTAL: 21% user + 11% kernel + 0.3% iowait", + "CPU usage from 907ms to 1431ms later:", + " 14% 121/mediaserver: 11% user + 3.7% kernel / faults: 17 minor", + " 3.7% 183/AudioOut_2: 3.7% user + 0% kernel", + " 12% 312/system_server: 5.5% user + 7.4% kernel / faults: 6 minor", + " 5.5% 366/InputDispatcher: 0% user + 5.5% kernel", + "18% TOTAL: 11% user + 7.5% kernel"); + + AnrItem anr = new AnrParser().parse(lines); + assertNotNull(anr); + assertEquals("com.android.package", anr.getApp()); + assertEquals("keyDispatchingTimedOut", anr.getReason()); + assertEquals(0.71, anr.getLoad(AnrItem.LoadCategory.LOAD_1)); + assertEquals(0.83, anr.getLoad(AnrItem.LoadCategory.LOAD_5)); + assertEquals(0.51, anr.getLoad(AnrItem.LoadCategory.LOAD_15)); + assertEquals(33.0, anr.getCpuUsage(AnrItem.CpuUsageCategory.TOTAL)); + assertEquals(21.0, anr.getCpuUsage(AnrItem.CpuUsageCategory.USER)); + assertEquals(11.0, anr.getCpuUsage(AnrItem.CpuUsageCategory.KERNEL)); + assertEquals(0.3, anr.getCpuUsage(AnrItem.CpuUsageCategory.IOWAIT)); + assertEquals(ArrayUtil.join("\n", lines), anr.getStack()); + } + + /** + * Test that ANRs are parsed for the header "ANR in app (class/package)" + */ + public void testParse_anr_in_app_class_package() { + List lines = Arrays.asList( + "ANR in com.android.package (com.android.package/.Activity)", + "Reason: keyDispatchingTimedOut", + "Load: 0.71 / 0.83 / 0.51", + "CPU usage from 4357ms to -1434ms ago:", + " 22% 3378/com.android.package: 19% user + 3.6% kernel / faults: 73 minor 1 major", + " 16% 312/system_server: 12% user + 4.1% kernel / faults: 1082 minor 6 major", + "33% TOTAL: 21% user + 11% kernel + 0.3% iowait", + "CPU usage from 907ms to 1431ms later:", + " 14% 121/mediaserver: 11% user + 3.7% kernel / faults: 17 minor", + " 3.7% 183/AudioOut_2: 3.7% user + 0% kernel", + " 12% 312/system_server: 5.5% user + 7.4% kernel / faults: 6 minor", + " 5.5% 366/InputDispatcher: 0% user + 5.5% kernel", + "18% TOTAL: 11% user + 7.5% kernel"); + + AnrItem anr = new AnrParser().parse(lines); + assertNotNull(anr); + assertEquals("com.android.package", anr.getApp()); + assertEquals("keyDispatchingTimedOut", anr.getReason()); + assertEquals(0.71, anr.getLoad(AnrItem.LoadCategory.LOAD_1)); + assertEquals(0.83, anr.getLoad(AnrItem.LoadCategory.LOAD_5)); + assertEquals(0.51, anr.getLoad(AnrItem.LoadCategory.LOAD_15)); + assertEquals(33.0, anr.getCpuUsage(AnrItem.CpuUsageCategory.TOTAL)); + assertEquals(21.0, anr.getCpuUsage(AnrItem.CpuUsageCategory.USER)); + assertEquals(11.0, anr.getCpuUsage(AnrItem.CpuUsageCategory.KERNEL)); + assertEquals(0.3, anr.getCpuUsage(AnrItem.CpuUsageCategory.IOWAIT)); + assertEquals(ArrayUtil.join("\n", lines), anr.getStack()); + } + + /** + * Test that ANRs with PID are parsed. + */ + public void testParse_anr_in_app_class_package_pid() { + List lines = Arrays.asList( + "ANR in com.android.package (com.android.package/.Activity)", + "PID: 1234", + "Reason: keyDispatchingTimedOut", + "Load: 0.71 / 0.83 / 0.51", + "CPU usage from 4357ms to -1434ms ago:", + " 22% 3378/com.android.package: 19% user + 3.6% kernel / faults: 73 minor 1 major", + " 16% 312/system_server: 12% user + 4.1% kernel / faults: 1082 minor 6 major", + "33% TOTAL: 21% user + 11% kernel + 0.3% iowait", + "CPU usage from 907ms to 1431ms later:", + " 14% 121/mediaserver: 11% user + 3.7% kernel / faults: 17 minor", + " 3.7% 183/AudioOut_2: 3.7% user + 0% kernel", + " 12% 312/system_server: 5.5% user + 7.4% kernel / faults: 6 minor", + " 5.5% 366/InputDispatcher: 0% user + 5.5% kernel", + "18% TOTAL: 11% user + 7.5% kernel"); + + AnrItem anr = new AnrParser().parse(lines); + assertNotNull(anr); + assertEquals("com.android.package", anr.getApp()); + assertEquals("keyDispatchingTimedOut", anr.getReason()); + assertEquals(1234, anr.getPid().intValue()); + assertEquals(0.71, anr.getLoad(AnrItem.LoadCategory.LOAD_1)); + assertEquals(0.83, anr.getLoad(AnrItem.LoadCategory.LOAD_5)); + assertEquals(0.51, anr.getLoad(AnrItem.LoadCategory.LOAD_15)); + assertEquals(33.0, anr.getCpuUsage(AnrItem.CpuUsageCategory.TOTAL)); + assertEquals(21.0, anr.getCpuUsage(AnrItem.CpuUsageCategory.USER)); + assertEquals(11.0, anr.getCpuUsage(AnrItem.CpuUsageCategory.KERNEL)); + assertEquals(0.3, anr.getCpuUsage(AnrItem.CpuUsageCategory.IOWAIT)); + assertEquals(ArrayUtil.join("\n", lines), anr.getStack()); + } +} diff --git a/javatests/src/com/android/loganalysis/parser/BatteryDischargeStatsInfoParserTest.java b/javatests/src/com/android/loganalysis/parser/BatteryDischargeStatsInfoParserTest.java new file mode 100644 index 0000000..691810c --- /dev/null +++ b/javatests/src/com/android/loganalysis/parser/BatteryDischargeStatsInfoParserTest.java @@ -0,0 +1,164 @@ +/* + * Copyright (C) 2016 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.BatteryDischargeStatsInfoItem; + +import junit.framework.TestCase; + +import java.util.Arrays; +import java.util.List; + +/** + * Unit tests for {@link BatteryDischargeStatsInfoParser} + */ +public class BatteryDischargeStatsInfoParserTest extends TestCase { + + /** + * Test that normal input is parsed correctly. + */ + public void testBatteryDischargeStats() { + List input = Arrays.asList( + " #0: +4m53s738ms to 0 (screen-on, power-save-off, device-idle-off)", + " #1: +4m5s586ms to 1 (screen-on, power-save-off, device-idle-off)", + " #2: +3m0s157ms to 2 (screen-on, power-save-off, device-idle-off)", + " #3: +2m52s243ms to 3 (screen-on, power-save-off, device-idle-off)", + " #4: +2m27s599ms to 4 (screen-on, power-save-off, device-idle-off)", + " #5: +5m0s172ms to 5 (screen-on, power-save-off, device-idle-off)", + " #6: +2m21s664ms to 6 (screen-on, power-save-off, device-idle-off)", + " #7: +5m18s811ms to 7 (screen-on, power-save-off, device-idle-off)", + " #8: +3m35s622ms to 8 (screen-on, power-save-off, device-idle-off)", + " #9: +4m52s605ms to 9 (screen-on, power-save-off, device-idle-off)", + " #10: +4m46s779ms to 10 (screen-on, power-save-off, device-idle-off)", + " #11: +4m0s200ms to 11 (screen-on, power-save-off, device-idle-off)", + " #12: +4m44s941ms to 12 (screen-on, power-save-off, device-idle-off)", + " #13: +3m31s163ms to 13 (screen-on, power-save-off, device-idle-off)", + " #14: +4m17s293ms to 14 (screen-on, power-save-off, device-idle-off)", + " #15: +3m11s584ms to 15 (screen-on, power-save-off, device-idle-off)", + " #16: +5m52s923ms to 16 (screen-on, power-save-off, device-idle-off)", + " #17: +3m7s34ms to 17 (screen-on, power-save-off, device-idle-off)", + " #18: +5m59s810ms to 18 (screen-on, power-save-off, device-idle-off)", + " #19: +6m15s275ms to 19 (screen-on, power-save-off, device-idle-off)", + " #20: +4m0s55ms to 20 (screen-on, power-save-off, device-idle-off)", + " #21: +5m21s911ms to 21 (screen-on, power-save-off, device-idle-off)", + " #22: +4m0s171ms to 22 (screen-on, power-save-off, device-idle-off)", + " #23: +5m22s820ms to 23 (screen-on, power-save-off, device-idle-off)", + " #24: +3m44s752ms to 24 (screen-on, power-save-off, device-idle-off)", + " #25: +4m15s130ms to 25 (screen-on, power-save-off, device-idle-off)", + " #26: +3m48s654ms to 26 (screen-on, power-save-off, device-idle-off)", + " #27: +5m0s294ms to 27 (screen-on, power-save-off, device-idle-off)", + " #28: +3m11s169ms to 28 (screen-on, power-save-off, device-idle-off)", + " #29: +4m48s194ms to 29 (screen-on, power-save-off, device-idle-off)", + " #30: +5m0s319ms to 30 (screen-on, power-save-off, device-idle-off)", + " #31: +2m42s209ms to 31 (screen-on, power-save-off, device-idle-off)", + " #32: +5m29s187ms to 32 (screen-on, power-save-off, device-idle-off)", + " #33: +3m32s392ms to 33 (screen-on, power-save-off, device-idle-off)", + " #34: +5m27s578ms to 34 (screen-on, power-save-off, device-idle-off)", + " #35: +3m47s37ms to 35 (screen-on, power-save-off, device-idle-off)", + " #36: +5m18s916ms to 36 (screen-on, power-save-off, device-idle-off)", + " #37: +2m54s111ms to 37 (screen-on, power-save-off, device-idle-off)", + " #38: +6m32s480ms to 38 (screen-on, power-save-off, device-idle-off)", + " #39: +5m24s906ms to 39 (screen-on, power-save-off, device-idle-off)", + " #40: +3m2s451ms to 40 (screen-on, power-save-off, device-idle-off)", + " #41: +6m29s762ms to 41 (screen-on, power-save-off, device-idle-off)", + " #42: +3m31s933ms to 42 (screen-on, power-save-off, device-idle-off)", + " #43: +4m58s520ms to 43 (screen-on, power-save-off, device-idle-off)", + " #44: +4m31s130ms to 44 (screen-on, power-save-off, device-idle-off)", + " #45: +5m28s870ms to 45 (screen-on, power-save-off, device-idle-off)", + " #46: +3m54s809ms to 46 (screen-on, power-save-off, device-idle-off)", + " #47: +5m5s105ms to 47 (screen-on, power-save-off, device-idle-off)", + " #48: +3m50s427ms to 48 (screen-on, power-save-off, device-idle-off)", + " #49: +6m0s344ms to 49 (screen-on, power-save-off, device-idle-off)", + " #50: +5m2s952ms to 50 (screen-on, power-save-off, device-idle-off)", + " #51: +3m6s120ms to 51 (screen-on, power-save-off, device-idle-off)", + " #52: +5m34s839ms to 52 (screen-on, power-save-off, device-idle-off)", + " #53: +2m33s473ms to 53 (screen-on, power-save-off, device-idle-off)", + " #54: +4m51s873ms to 54 (screen-on, power-save-off, device-idle-off)", + " #55: +3m30s41ms to 55 (screen-on, power-save-off, device-idle-off)", + " #56: +4m29s879ms to 56 (screen-on, power-save-off, device-idle-off)", + " #57: +3m41s722ms to 57 (screen-on, power-save-off, device-idle-off)", + " #58: +4m29s72ms to 58 (screen-on, power-save-off, device-idle-off)", + " #59: +4m49s351ms to 59 (screen-on, power-save-off, device-idle-off)", + " #60: +3m51s605ms to 60 (screen-on, power-save-off, device-idle-off)", + " #61: +5m8s334ms to 61 (screen-on, power-save-off, device-idle-off)", + " #62: +2m53s153ms to 62 (screen-on, power-save-off, device-idle-off)", + " #63: +6m0s234ms to 63 (screen-on, power-save-off, device-idle-off)", + " #64: +3m20s345ms to 64 (screen-on, power-save-off, device-idle-off)", + " #65: +5m46s211ms to 65 (screen-on, power-save-off, device-idle-off)", + " #66: +3m40s147ms to 66 (screen-on, power-save-off, device-idle-off)", + " #67: +5m14s559ms to 67 (screen-on, power-save-off, device-idle-off)", + " #68: +4m0s183ms to 68 (screen-on, power-save-off, device-idle-off)", + " #69: +5m23s334ms to 69 (screen-on, power-save-off, device-idle-off)", + " #70: +5m45s493ms to 70 (screen-on, power-save-off, device-idle-off)", + " #71: +4m0s179ms to 71 (screen-on, power-save-off, device-idle-off)", + " #72: +5m45s462ms to 72 (screen-on, power-save-off, device-idle-off)", + " #73: +3m10s449ms to 73 (screen-on, power-save-off, device-idle-off)", + " #74: +6m29s370ms to 74 (screen-on, power-save-off, device-idle-off)", + " #75: +3m20s414ms to 75 (screen-on, power-save-off, device-idle-off)", + " #76: +5m10s462ms to 76 (screen-on, power-save-off, device-idle-off)", + " #77: +4m20s500ms to 77 (screen-on, power-save-off, device-idle-off)", + " #78: +5m39s504ms to 78 (screen-on, power-save-off, device-idle-off)", + " #79: +5m59s819ms to 79 (screen-on, power-save-off, device-idle-off)", + " #80: +3m0s126ms to 80 (screen-on, power-save-off, device-idle-off)", + " #81: +6m20s912ms to 81 (screen-on, power-save-off, device-idle-off)", + " #82: +4m0s199ms to 82 (screen-on, power-save-off, device-idle-off)", + " #83: +5m23s470ms to 83 (screen-on, power-save-off, device-idle-off)", + " #84: +3m15s368ms to 84 (screen-on, power-save-off, device-idle-off)", + " #85: +6m18s625ms to 85 (screen-on, power-save-off, device-idle-off)", + " #86: +3m41s417ms to 86 (screen-on, power-save-off, device-idle-off)", + " #87: +5m32s257ms to 87 (screen-on, power-save-off, device-idle-off)", + " #88: +4m0s212ms to 88 (screen-on, power-save-off, device-idle-off)", + " #89: +5m41s218ms to 89 (screen-on, power-save-off, device-idle-off)", + " #90: +5m46s333ms to 90 (screen-on, power-save-off, device-idle-off)", + " #91: +3m58s362ms to 91 (screen-on, power-save-off, device-idle-off)", + " #92: +5m1s593ms to 92 (screen-on, power-save-off, device-idle-off)", + " #93: +4m47s33ms to 93 (screen-on, power-save-off, device-idle-off)", + " #94: +6m0s417ms to 94 (screen-on, power-save-off, device-idle-off)", + " #95: +3m9s77ms to 95 (screen-on, power-save-off, device-idle-off)", + " #96: +7m0s308ms to 96 (screen-on, power-save-off, device-idle-off)", + " #97: +3m29s741ms to 97 (screen-on, power-save-off, device-idle-off)", + " #98: +7m12s748ms to 98 (screen-on, power-save-off, device-idle-off)", + " Estimated screen on time: 7h 36m 13s 0ms "); + + BatteryDischargeStatsInfoItem infoItem = new BatteryDischargeStatsInfoParser().parse(input); + assertEquals(99, infoItem.getDischargePercentage()); + assertEquals(27099330, infoItem.getDischargeDuration()); + assertEquals(27207848, infoItem.getProjectedBatteryLife()); + } + + /** + * Test that input with only a few discharge stats. + */ + public void testBatteryDischargeStatsWithTop5Percentages() { + List input = Arrays.asList( + " #95: +3m9s77ms to 95 (screen-on, power-save-off, device-idle-off)", + " #96: +7m0s308ms to 96 (screen-on, power-save-off, device-idle-off)", + " #97: +3m29s741ms to 97 (screen-on, power-save-off, device-idle-off)", + " #98: +7m12s748ms to 98 (screen-on, power-save-off, device-idle-off)", + " Estimated screen on time: 7h 36m 13s 0ms "); + + BatteryDischargeStatsInfoItem infoItem = new BatteryDischargeStatsInfoParser().parse(input); + + try { + infoItem.getProjectedBatteryLife(); + fail("Projected battery life is expected to be undefined when there are not enough" + + " samples of battery discharge below 95 percent."); + } catch (NullPointerException e) { + // NullPointerException expected. + } + } +} diff --git a/javatests/src/com/android/loganalysis/parser/BatteryStatsDetailedInfoParserTest.java b/javatests/src/com/android/loganalysis/parser/BatteryStatsDetailedInfoParserTest.java new file mode 100644 index 0000000..b176fa2 --- /dev/null +++ b/javatests/src/com/android/loganalysis/parser/BatteryStatsDetailedInfoParserTest.java @@ -0,0 +1,131 @@ +/* + * Copyright (C) 2015 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.BatteryStatsDetailedInfoItem; + +import junit.framework.TestCase; + +import java.util.Arrays; +import java.util.List; + +/** + * Unit tests for {@link BatteryStatsDetailedInfoParser} + */ +public class BatteryStatsDetailedInfoParserTest extends TestCase { + + /** + * Test that normal input is parsed. + */ + public void testBatteryStatsDetailedInfoParser() { + List inputBlock = Arrays.asList( + " Time on battery: 2h 21m 5s 622ms (12.0%) realtime, 7m 54s 146ms (0.7%) uptime", + " Time on battery screen off: 2h 5m 55s 3ms (1%) realtime, 7m 4s 5ms (7%) uptime", + " Total run time: 19h 38m 43s 650ms realtime, 17h 25m 32s 175ms uptime", + " All kernel wake locks:", + " Kernel Wake lock PowerManagerService.WakeLocks: 1h 3m 50s 5ms (8 times) realtime", + " Kernel Wake lock event0-2656 : 3m 49s 268ms (2399 times) realtime", + " Kernel Wake lock wlan_wd_wake: 3m 34s 639ms (1751 times) realtime", + " Kernel Wake lock wlan_rx_wake: 3m 19s 887ms (225 times) realtime", + " Kernel Wake lock wlan_tx_wake: 2m 19s 887ms (225 times) realtime", + " Kernel Wake lock tx_wake: 1m 19s 887ms (225 times) realtime", + " ", + " All partial wake locks:", + " Wake lock u0a7 NlpWakeLock: 8m 13s 203ms (1479 times) realtime", + " Wake lock u0a7 NlpCollectorWakeLock: 6m 29s 18ms (238 times) realtime", + " Wake lock u0a7 GCM_CONN_ALARM: 6m 8s 587ms (239 times) realtime", + " Wake lock 1000 *alarm*: 5m 11s 316ms (1469 times) realtime", + " Wake lock u10 xxx: 4m 11s 316ms (1469 times) realtime", + " Wake lock u30 cst: 2m 11s 316ms (1469 times) realtime", + " ", + " All wakeup reasons:", + " Wakeup reason 200:qcom,smd-rpm:222:fc4: 11m 49s 332ms (0 times) realtime", + " Wakeup reason 200:qcom,smd-rpm: 48s 45ms (0 times) realtime", + " Wakeup reason 2:qcom,smd-rpm:2:f0.qm,mm:22:fc4mi: 3s 417ms (0 times) realtime", + " Wakeup reason 188:qcom,smd-adsp:200:qcom,smd-rpm: 1s 656ms (0 times) realtime", + " Wakeup reason 58:qcom,smsm-modem:2:qcom,smd-rpm: 6m 16s 1ms (5 times) realtime", + " Wakeup reason 57:qcom,smd-modem:200:qcom,smd-rpm: 40s 995ms (0 times) realtime", + " Wakeup reason unknown: 8s 455ms (0 times) realtime", + " Wakeup reason 9:bcmsdh_sdmmc:2:qcomd-rpm:240:mso: 8m 5s 9ms (0 times) realtime", + " ", + " 0:", + " User activity: 2 other", + " Wake lock SCREEN_FROZEN realtime", + " Sensor 0: 9s 908ms realtime (1 times)", + " Sensor 1: 9s 997ms realtime (1 times)", + " Foreground for: 2h 21m 5s 622ms", + " Apk android:", + " 24 wakeup alarms", + " u0a9:", + " Mobile network: 8.1KB received, 1.6KB sent (packets 291 received, 342 sent)", + " Mobile radio active: 3m 43s 890ms (34.2%) 39x @ 354 mspp", + " Sensor 2: 12m 13s 15ms realtime (5 times)", + " Sensor 32: (not used)", + " Sensor 35: (not used)"); + + BatteryStatsDetailedInfoItem stats = new BatteryStatsDetailedInfoParser().parse(inputBlock); + + assertEquals(8465622, stats.getTimeOnBattery()); + assertEquals(910619, stats.getScreenOnTime()); + assertNotNull(stats.getWakelockItem()); + assertNotNull(stats.getInterruptItem()); + assertNotNull(stats.getProcessUsageItem()); + } + + /** + * Test with missing wakelock section + */ + public void testMissingWakelockSection() { + List inputBlock = Arrays.asList( + " Time on battery: 2h 21m 5s 622ms (12.0%) realtime, 7m 54s 146ms (0.7%) uptime", + " Time on battery screen off: 2h 5m 55s 3ms (1%) realtime, 7m 4s 5ms (7%) uptime", + " Total run time: 19h 38m 43s 650ms realtime, 17h 25m 32s 175ms uptime", + " All wakeup reasons:", + " Wakeup reason 200:qcom,smd-rpm:222:fc4: 11m 49s 332ms (0 times) realtime", + " Wakeup reason 200:qcom,smd-rpm: 48s 45ms (0 times) realtime", + " Wakeup reason 2:qcom,smd-rpm:2:f0.qm,mm:22:fc4mi: 3s 417ms (0 times) realtime", + " Wakeup reason 188:qcom,smd-adsp:200:qcom,smd-rpm: 1s 656ms (0 times) realtime", + " Wakeup reason 58:qcom,smsm-modem:2:qcom,smd-rpm: 6m 16s 1ms (5 times) realtime", + " Wakeup reason 57:qcom,smd-modem:200:qcom,smd-rpm: 40s 995ms (0 times) realtime", + " Wakeup reason unknown: 8s 455ms (0 times) realtime", + " Wakeup reason 9:bcmsdh_sdmmc:2:qcomd-rpm:240:mso: 8m 5s 9ms (0 times) realtime", + " ", + " 0:", + " User activity: 2 other", + " Wake lock SCREEN_FROZEN realtime", + " Sensor 0: 9s 908ms realtime (1 times)", + " Sensor 1: 9s 997ms realtime (1 times)", + " Foreground for: 2h 21m 5s 622ms", + " Apk android:", + " 24 wakeup alarms", + " u0a9:", + " Mobile network: 8.1KB received, 1.6KB sent (packets 291 received, 342 sent)", + " Mobile radio active: 3m 43s 890ms (34.2%) 39x @ 354 mspp", + " Sensor 2: 12m 13s 15ms realtime (5 times)", + " Sensor 32: (not used)", + " Sensor 35: (not used)"); + BatteryStatsDetailedInfoItem stats = new BatteryStatsDetailedInfoParser().parse(inputBlock); + + assertEquals(8465622, stats.getTimeOnBattery()); + assertEquals(910619, stats.getScreenOnTime()); + + assertNull(stats.getWakelockItem()); + + assertNotNull(stats.getInterruptItem()); + assertNotNull(stats.getProcessUsageItem()); + } +} + diff --git a/javatests/src/com/android/loganalysis/parser/BatteryStatsSummaryInfoParserTest.java b/javatests/src/com/android/loganalysis/parser/BatteryStatsSummaryInfoParserTest.java new file mode 100644 index 0000000..c6ba381 --- /dev/null +++ b/javatests/src/com/android/loganalysis/parser/BatteryStatsSummaryInfoParserTest.java @@ -0,0 +1,109 @@ +/* + * Copyright (C) 2015 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.BatteryStatsSummaryInfoItem; + +import junit.framework.TestCase; + +import java.util.Arrays; +import java.util.GregorianCalendar; +import java.util.List; +import java.util.TimeZone; + +/** + * Unit tests for {@link BatteryStatsSummaryInfoParser} + */ +public class BatteryStatsSummaryInfoParserTest extends TestCase { + + /** + * Test that normal input is parsed. + */ + public void testBatteryStatsSummaryInfoParser() { + List inputBlock = Arrays.asList( + "Battery History (37% used, 95KB used of 256KB, 166 strings using 15KB):", + " 0 (9) RESET:TIME: 2014-12-09-11-33-29", + " +1s067ms (1) 100 c0500020 -wifi_full_lock -wifi_scan", + " +3s297ms (2) 100 80400020 -wake_lock -screen", + " +30m02s075ms (1) 100 c0500020 wifi_signal_strength=4 wifi_suppl=completed", + " +30m03s012ms (2) 099 c0500020 temp=306 volt=4217", + " +33m48s967ms (1) 099 f8400020 +wifi_scan", + " +33m49s335ms (2) 098 f0400020 temp=324 -wifi_scan", + " +1h07m27s735ms (1) 098 80400020 -wake_lock", + " +1h07m27s950ms (2) 097 c0400020", + " +1h07m29s000ms (2) 097 c0400020 -sync=u0a41:\"gmail-ls/com.google/a@g", + " +1h25m34s877ms (2) 097 00400020 -running wake_reason=0:200:qcom,smd-rpm", + " +1h25m41s948ms (2) 096 80400020 wifi_suppl=associated", + " +2h13m40s055ms (1) 096 00400018 -running", + " +2h13m40s570ms (2) 095 c0400008 temp=304 volt=4167", + " +2h56m50s792ms (1) 095 80400020 -wake_lock", + " +2h56m50s967ms (2) 094 00400020 temp=317 -running", + " +3h38m57s986ms (2) 094 80400020 +running wake_reason=0:289:bcmsdh_sdmmc", + " +3h38m58s241ms (2) 093 00400020 temp=327 -running", + " +3h56m33s329ms (1) 093 00400020 -running -wake_lock", + " +3h56m43s245ms (2) 092 00400020 -running", + " +4h13m00s551ms (1) 092 00400020 -running -wake_lock", + " +4h13m24s250ms (2) 091 00400020 -running", + " +4h34m52s233ms (2) 091 80400020 +running wake_reason=0:289:bcmsdh_sdmmc", + " +4h34m52s485ms (3) 090 00400020 -running wake_reason=0:200:qcom,smd-rpm", + " +4h57m20s644ms (1) 090 00400020 -running", + " +4h57m38s484ms (2) 089 00400020 -running", + " +5h20m58s226ms (1) 089 80400020 +running wifi_suppl=associated", + " +5h21m03s909ms (1) 088 80400020 -wake_lock -wifi_full_lock", + " +5h40m38s169ms (2) 088 c0500020 +top=u0a19:com.google.android.googlequick", + " +5h40m38s479ms (2) 087 c0500020 volt=4036", + " +6h16m45s248ms (2) 087 d0440020 -sync=u0a41:gmail-ls/com.google/avellore@go", + " +6h16m45s589ms (2) 086 d0440020 volt=4096", + " +6h52m43s316ms (1) 086 80400020 -wake_lock", + " +6h53m18s952ms (2) 085 c0400020", + " +7h24m02s415ms (1) 085 80400020 -wake_lock", + " +7h24m02s904ms (3) 084 c0400020 volt=4105 +wake_lock=u0a7:NlpWakeLock", + " +7h29m10s379ms (1) 084 00400020 -running -wake_lock", + " +7h29m11s841ms (2) 083 00400020 temp=317 volt=4047 -running", + " +7h41m08s963ms (1) 083 00400020 -running", + " +7h41m20s494ms (2) 082 00400020 temp=300 -running", + " +7h54m57s288ms (1) 082 52441420 -running", + " +7h55m00s801ms (1) 081 52441420 -running", + " +8h02m18s594ms (1) 081 50440020 -running", + " +8h02m23s493ms (2) 080 50440020 temp=313 -running"); + + BatteryStatsSummaryInfoItem summary = new BatteryStatsSummaryInfoParser().parse(inputBlock); + + assertEquals("The battery dropped a level 24 mins on average", + summary.getBatteryDischargeRate()); + + // Get the current timezone short name (PST, GMT) to properly output the time as expected. + String timezone = + new GregorianCalendar().getTimeZone().getDisplayName(false, TimeZone.SHORT); + assertEquals( + String.format( + "The peak discharge time was during Tue Dec 09 16:31:07 %s 2014 to " + + "Tue Dec 09 19:35:52 %s 2014 where battery dropped from 89 to 80", + timezone, timezone), + summary.getPeakDischargeTime()); + } + + public void testNoBatteryDischarge() { + List inputBlock = Arrays.asList( + "Battery History (37% used, 95KB used of 256KB, 166 strings using 15KB):", + " 0 (9) RESET:TIME: 2014-12-09-11-33-29"); + BatteryStatsSummaryInfoItem summary = new BatteryStatsSummaryInfoParser().parse(inputBlock); + + assertEquals("The battery did not discharge", summary.getBatteryDischargeRate()); + assertEquals("The battery did not discharge", summary.getPeakDischargeTime()); + } +} + diff --git a/javatests/src/com/android/loganalysis/parser/BatteryUsageParserTest.java b/javatests/src/com/android/loganalysis/parser/BatteryUsageParserTest.java new file mode 100644 index 0000000..20a9a2e --- /dev/null +++ b/javatests/src/com/android/loganalysis/parser/BatteryUsageParserTest.java @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2015 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.BatteryUsageItem; + +import junit.framework.TestCase; + +import java.util.Arrays; +import java.util.List; + +/** + * Unit tests for {@link BatteryUsageParser} + */ +public class BatteryUsageParserTest extends TestCase { + + private static final double EPSILON = 1e-3; + /** + * Test that normal input is parsed. + */ + public void testBatteryUsageParser() { + List inputBlock = Arrays.asList( + " Capacity: 3220, Computed drain: 11.0, actual drain: 0", + " Screen: 8.93", + " Idle: 1.23", + " Uid 0: 0.281", + " Uid u0a36: 0.200", + " Uid 1000: 0.165", + " Uid 1013: 0.0911", + " Uid u0a16: 0.0441"); + + BatteryUsageItem usage = new BatteryUsageParser().parse(inputBlock); + + assertEquals(3220, usage.getBatteryCapacity()); + assertEquals(7, usage.getBatteryUsage().size()); + + assertEquals("Screen", usage.getBatteryUsage().get(0).getName()); + assertEquals(8.93, usage.getBatteryUsage().get(0).getUsage(), EPSILON); + assertEquals("Uid u0a16", usage.getBatteryUsage().get(6).getName()); + assertEquals(0.0441, usage.getBatteryUsage().get(6).getUsage()); + } +} + diff --git a/javatests/src/com/android/loganalysis/parser/BugreportParserTest.java b/javatests/src/com/android/loganalysis/parser/BugreportParserTest.java new file mode 100644 index 0000000..5f3fc10 --- /dev/null +++ b/javatests/src/com/android/loganalysis/parser/BugreportParserTest.java @@ -0,0 +1,766 @@ +/* + * Copyright (C) 2011 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.BugreportItem; +import com.android.loganalysis.item.IItem; +import com.android.loganalysis.item.MiscKernelLogItem; +import com.android.loganalysis.util.ArrayUtil; + +import junit.framework.TestCase; + +import java.text.DateFormat; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Arrays; +import java.util.Date; +import java.util.List; + +/** + * Unit tests for {@link BugreportParser} + */ +public class BugreportParserTest extends TestCase { + + /** + * Test that a bugreport can be parsed. + */ + public void testParse() throws ParseException { + List lines = + Arrays.asList( + "========================================================", + "== dumpstate: 2012-04-25 20:45:10", + "========================================================", + "------ SECTION ------", + "", + "------ MEMORY INFO (/proc/meminfo) ------", + "MemTotal: 353332 kB", + "MemFree: 65420 kB", + "Buffers: 20800 kB", + "Cached: 86204 kB", + "SwapCached: 0 kB", + "", + "------ CPU INFO (top -n 1 -d 1 -m 30 -t) ------", + "", + "User 3%, System 3%, IOW 0%, IRQ 0%", + "User 33 + Nice 0 + Sys 32 + Idle 929 + IOW 0 + IRQ 0 + SIRQ 0 = 994", + "", + "------ PROCRANK (procrank) ------", + " PID Vss Rss Pss Uss cmdline", + " 178 87136K 81684K 52829K 50012K system_server", + " 1313 78128K 77996K 48603K 45812K com.google.android.apps.maps", + " 3247 61652K 61492K 33122K 30972K com.android.browser", + " ------ ------ ------", + " 203624K 163604K TOTAL", + "RAM: 731448K total, 415804K free, 9016K buffers, 108548K cached", + "[procrank: 1.6s elapsed]", + "", + "------ KERNEL LOG (dmesg) ------", + "<6>[ 0.000000] Initializing cgroup subsys cpu", + "<3>[ 1.000000] benign message", + "", + "", + "------ SYSTEM LOG (logcat -v threadtime -d *:v) ------", + "04-25 09:55:47.799 3064 3082 E AndroidRuntime: java.lang.Exception", + "04-25 09:55:47.799 3064 3082 E AndroidRuntime: \tat class.method1(Class.java:1)", + "04-25 09:55:47.799 3064 3082 E AndroidRuntime: \tat class.method2(Class.java:2)", + "04-25 09:55:47.799 3064 3082 E AndroidRuntime: \tat class.method3(Class.java:3)", + "04-25 17:17:08.445 312 366 E ActivityManager: ANR (application not responding) in process: com.android.package", + "04-25 17:17:08.445 312 366 E ActivityManager: Reason: keyDispatchingTimedOut", + "04-25 17:17:08.445 312 366 E ActivityManager: Load: 0.71 / 0.83 / 0.51", + "04-25 17:17:08.445 312 366 E ActivityManager: 33% TOTAL: 21% user + 11% kernel + 0.3% iowait", + "04-25 18:33:27.273 115 115 I DEBUG : *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***", + "04-25 18:33:27.273 115 115 I DEBUG : Build fingerprint: 'product:build:target'", + "04-25 18:33:27.273 115 115 I DEBUG : pid: 3112, tid: 3112 >>> com.google.android.browser <<<", + "04-25 18:33:27.273 115 115 I DEBUG : signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 00000000", + "", + "------ SYSTEM PROPERTIES ------", + "[dalvik.vm.dexopt-flags]: [m=y]", + "[dalvik.vm.heapgrowthlimit]: [48m]", + "[dalvik.vm.heapsize]: [256m]", + "[gsm.version.ril-impl]: [android moto-ril-multimode 1.0]", + "", + "------ LAST KMSG (/proc/last_kmsg) ------", + "[ 0.000000] Initializing cgroup subsys cpu", + "[ 16.203491] benign message", + "", + "------ SECTION ------", + "", + "------ VM TRACES AT LAST ANR (/data/anr/traces.txt: 2012-04-25 17:17:08) ------", + "", + "", + "----- pid 2887 at 2012-04-25 17:17:08 -----", + "Cmd line: com.android.package", + "", + "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)", + " at class.method2(Class.java:2)", + " at class.method2(Class.java:2)", + "", + "----- end 2887 -----", + "", + "------ SECTION ------", + "", + "------ DUMPSYS (dumpsys) ------", + "DUMP OF SERVICE batterystats:", + "Battery History (0% used, 1636 used of 256KB, 15 strings using 794):", + " 0 (15) RESET:TIME: 1970-01-10-06-23-28", + " +45s702ms (2) 001 80080000 volt=4187", + " +1m15s525ms (2) 001 80080000 temp=299 volt=4155", + "Statistics since last charged:", + " Time on battery: 1h 5m 2s 4ms (9%) realtime, 1h 5m 2s 4ms (9%) uptime", + " Time on battery screen off: 1h 4m 5s 8ms (9%) realtime, 1h 4m 5s 8ms (9%) uptime", + " All kernel wake locks:", + " Kernel Wake lock PowerManagerService.WakeLocks: 5m 10s 6ms (2 times) realtime", + " Kernel Wake lock msm_serial_hs_rx: 2m 13s 612ms (258 times) realtime", + "", + " All partial wake locks:", + " Wake lock 1001 ProxyController: 1h 4m 47s 565ms (4 times) realtime", + " Wake lock 1013 AudioMix: 1s 979ms (3 times) realtime", + "", + " All wakeup reasons:", + " Wakeup reason 2:bcmsdh_sdmmc:2:qcom,smd:2:msmgio: 1m 5s 4ms (2 times) realtime", + " Wakeup reason 2:qcom,smd-rpm:2:fc4c.qcom,spmi: 7m 1s 914ms (7 times) realtime", + "", + "DUMP OF SERVICE package:", + "Package [com.google.android.calculator] (e075c9d):", + " userId=10071", + " secondaryCpuAbi=null", + " versionCode=73000302 minSdk=10000 targetSdk=10000", + " versionName=7.3 (3821978)", + " splits=[base]", + "========================================================", + "== Running Application Services", + "========================================================", + "------ APP SERVICES (dumpsys activity service all) ------", + "SERVICE com.google.android.gms/" + + "com.google.android.location.internal.GoogleLocationManagerService f4c9d pid=14", + " Location Request History By Package:", + "Interval effective/min/max 1/0/0[s] Duration: 140[minutes] [" + + "com.google.android.gms, PRIORITY_NO_POWER, UserLocationProducer] " + + "Num requests: 2 Active: true", + "Interval effective/min/max 284/285/3600[s] Duration: 140[minutes] " + + "[com.google.android.googlequicksearchbox, PRIORITY_BALANCED_POWER_ACCURACY] " + + "Num requests: 5 Active: true"); + + BugreportItem bugreport = new BugreportParser().parse(lines); + assertNotNull(bugreport); + assertEquals(parseTime("2012-04-25 20:45:10.000"), bugreport.getTime()); + + assertNotNull(bugreport.getMemInfo()); + assertEquals(5, bugreport.getMemInfo().size()); + + assertNotNull(bugreport.getTop()); + assertEquals(994, bugreport.getTop().getTotal()); + + assertNotNull(bugreport.getProcrank()); + assertEquals(3, bugreport.getProcrank().getPids().size()); + + assertNotNull(bugreport.getKernelLog()); + assertEquals(1.0, bugreport.getKernelLog().getStopTime(), 0.000005); + + assertNotNull(bugreport.getSystemLog()); + assertEquals(parseTime("2012-04-25 09:55:47.799"), bugreport.getSystemLog().getStartTime()); + assertEquals(parseTime("2012-04-25 18:33:27.273"), bugreport.getSystemLog().getStopTime()); + assertEquals(3, bugreport.getSystemLog().getEvents().size()); + assertEquals(1, bugreport.getSystemLog().getAnrs().size()); + assertNotNull(bugreport.getSystemLog().getAnrs().get(0).getTrace()); + + assertNotNull(bugreport.getLastKmsg()); + assertEquals(16.203491, bugreport.getLastKmsg().getStopTime(), 0.000005); + + assertNotNull(bugreport.getSystemProps()); + assertEquals(4, bugreport.getSystemProps().size()); + + assertNotNull(bugreport.getDumpsys()); + assertNotNull(bugreport.getDumpsys().getBatteryStats()); + assertNotNull(bugreport.getDumpsys().getPackageStats()); + + assertNotNull(bugreport.getActivityService()); + assertNotNull(bugreport.getActivityService().getLocationDumps().getLocationClients()); + assertEquals(bugreport.getActivityService().getLocationDumps().getLocationClients().size(), + 2); + } + + /** + * Test that the logcat year is set correctly from the bugreport timestamp. + */ + public void testParse_set_logcat_year() throws ParseException { + List lines = Arrays.asList( + "========================================================", + "== dumpstate: 1999-01-01 02:03:04", + "========================================================", + "------ SYSTEM LOG (logcat -v threadtime -d *:v) ------", + "01-01 01:02:03.000 1 1 I TAG : message", + "01-01 01:02:04.000 1 1 I TAG : message", + ""); + + BugreportItem bugreport = new BugreportParser().parse(lines); + assertNotNull(bugreport); + assertEquals(parseTime("1999-01-01 02:03:04.000"), bugreport.getTime()); + assertNotNull(bugreport.getSystemLog()); + assertEquals(parseTime("1999-01-01 01:02:03.000"), bugreport.getSystemLog().getStartTime()); + assertEquals(parseTime("1999-01-01 01:02:04.000"), bugreport.getSystemLog().getStopTime()); + } + + /** + * Test that the command line is parsed + */ + public void testParse_command_line() { + List lines = Arrays.asList("Command line:"); + BugreportItem bugreport = new BugreportParser().parse(lines); + assertTrue(bugreport.getCommandLine().isEmpty()); + + lines = Arrays.asList("Command line: key=value"); + bugreport = new BugreportParser().parse(lines); + assertEquals(1, bugreport.getCommandLine().size()); + assertEquals("value", bugreport.getCommandLine().get("key")); + + lines = Arrays.asList("Command line: key1=value1 key2=value2"); + bugreport = new BugreportParser().parse(lines); + assertEquals(2, bugreport.getCommandLine().size()); + assertEquals("value1", bugreport.getCommandLine().get("key1")); + assertEquals("value2", bugreport.getCommandLine().get("key2")); + + // Test a bad strings + lines = Arrays.asList("Command line: key1=value=withequals key2= "); + bugreport = new BugreportParser().parse(lines); + assertEquals(2, bugreport.getCommandLine().size()); + assertEquals("value=withequals", bugreport.getCommandLine().get("key1")); + assertEquals("", bugreport.getCommandLine().get("key2")); + + lines = Arrays.asList("Command line: key1=value1 nonkey key2="); + bugreport = new BugreportParser().parse(lines); + assertEquals(3, bugreport.getCommandLine().size()); + assertEquals("value1", bugreport.getCommandLine().get("key1")); + assertEquals("", bugreport.getCommandLine().get("key2")); + assertNull(bugreport.getCommandLine().get("nonkey")); + } + + /** + * Test that a normal boot triggers a normal boot event and no unknown reason. + */ + public void testParse_bootreason_kernel_good() { + List lines = Arrays.asList( + "========================================================", + "== dumpstate: 1999-01-01 02:03:04", + "========================================================", + "Command line: androidboot.bootreason=reboot", + ""); + BugreportItem bugreport = new BugreportParser().parse(lines); + assertNotNull(bugreport.getLastKmsg()); + assertEquals(1, bugreport.getLastKmsg().getEvents().size()); + assertEquals("Last boot reason: reboot", + bugreport.getLastKmsg().getEvents().get(0).getStack()); + assertEquals("NORMAL_REBOOT", bugreport.getLastKmsg().getEvents().get(0).getCategory()); + } + + /** + * Test that a kernel reset boot triggers a kernel reset event and no unknown reason. + */ + public void testParse_bootreason_kernel_bad() { + List lines = Arrays.asList( + "========================================================", + "== dumpstate: 1999-01-01 02:03:04", + "========================================================", + "Command line: androidboot.bootreason=hw_reset", + ""); + BugreportItem bugreport = new BugreportParser().parse(lines); + assertNotNull(bugreport.getLastKmsg()); + assertEquals(1, bugreport.getLastKmsg().getEvents().size()); + assertEquals("Last boot reason: hw_reset", + bugreport.getLastKmsg().getEvents().get(0).getStack()); + assertEquals("KERNEL_RESET", bugreport.getLastKmsg().getEvents().get(0).getCategory()); + } + + /** + * Test that a normal boot triggers a normal boot event and no unknown reason. + */ + public void testParse_bootreason_prop_good() { + List lines = Arrays.asList( + "========================================================", + "== dumpstate: 1999-01-01 02:03:04", + "========================================================", + "------ SYSTEM PROPERTIES ------", + "[ro.boot.bootreason]: [reboot]", + ""); + BugreportItem bugreport = new BugreportParser().parse(lines); + assertNotNull(bugreport.getLastKmsg()); + assertEquals(1, bugreport.getLastKmsg().getEvents().size()); + assertEquals("Last boot reason: reboot", + bugreport.getLastKmsg().getEvents().get(0).getStack()); + assertEquals("NORMAL_REBOOT", bugreport.getLastKmsg().getEvents().get(0).getCategory()); + } + + /** + * Test that a kernel reset boot triggers a kernel reset event and no unknown reason. + */ + public void testParse_bootreason_prop_bad() { + List lines = Arrays.asList( + "========================================================", + "== dumpstate: 1999-01-01 02:03:04", + "========================================================", + "------ SYSTEM PROPERTIES ------", + "[ro.boot.bootreason]: [hw_reset]", + ""); + BugreportItem bugreport = new BugreportParser().parse(lines); + assertNotNull(bugreport.getLastKmsg()); + assertEquals(1, bugreport.getLastKmsg().getEvents().size()); + assertEquals("Last boot reason: hw_reset", + bugreport.getLastKmsg().getEvents().get(0).getStack()); + assertEquals("KERNEL_RESET", bugreport.getLastKmsg().getEvents().get(0).getCategory()); + assertEquals("", bugreport.getLastKmsg().getEvents().get(0).getPreamble()); + assertEquals(0.0, bugreport.getLastKmsg().getEvents().get(0).getEventTime()); + assertEquals(0.0, bugreport.getLastKmsg().getStartTime()); + assertEquals(0.0, bugreport.getLastKmsg().getStopTime()); + } + + /** + * Test that a kernel panic in the last kmsg and a kernel panic only triggers one kernel reset. + */ + public void testParse_bootreason_duplicate() { + List lines = Arrays.asList( + "========================================================", + "== dumpstate: 1999-01-01 02:03:04", + "========================================================", + "Command line: androidboot.bootreason=hw_reset", + "------ SYSTEM PROPERTIES ------", + "[ro.boot.bootreason]: [hw_reset]", + "", + "------ LAST KMSG (/proc/last_kmsg) ------", + "[ 0.000000] Initializing cgroup subsys cpu", + "[ 16.203491] Kernel panic", + ""); + BugreportItem bugreport = new BugreportParser().parse(lines); + assertNotNull(bugreport.getLastKmsg()); + assertEquals(1, bugreport.getLastKmsg().getEvents().size()); + assertEquals("Kernel panic", bugreport.getLastKmsg().getEvents().get(0).getStack()); + assertEquals("KERNEL_RESET", bugreport.getLastKmsg().getEvents().get(0).getCategory()); + } + + /** + * Test that the trace is set correctly if there is only one ANR. + */ + public void testSetAnrTrace_single() { + List lines = Arrays.asList( + "========================================================", + "== dumpstate: 2012-04-25 20:45:10", + "========================================================", + "------ SYSTEM LOG (logcat -v threadtime -d *:v) ------", + "04-25 17:17:08.445 312 366 E ActivityManager: ANR (application not responding) in process: com.android.package", + "04-25 17:17:08.445 312 366 E ActivityManager: Reason: keyDispatchingTimedOut", + "04-25 17:17:08.445 312 366 E ActivityManager: Load: 0.71 / 0.83 / 0.51", + "04-25 17:17:08.445 312 366 E ActivityManager: 33% TOTAL: 21% user + 11% kernel + 0.3% iowait", + "", + "------ VM TRACES AT LAST ANR (/data/anr/traces.txt: 2012-04-25 17:17:08) ------", + "", + "----- pid 2887 at 2012-04-25 17:17:08 -----", + "Cmd line: com.android.package", + "", + "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)", + " at class.method2(Class.java:2)", + " at class.method2(Class.java:2)", + "", + "----- end 2887 -----", + ""); + + List expectedStack = Arrays.asList( + "\"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)", + " at class.method2(Class.java:2)", + " at class.method2(Class.java:2)"); + + BugreportItem bugreport = new BugreportParser().parse(lines); + + assertNotNull(bugreport.getSystemLog()); + assertEquals(1, bugreport.getSystemLog().getAnrs().size()); + assertEquals(ArrayUtil.join("\n", expectedStack), + bugreport.getSystemLog().getAnrs().get(0).getTrace()); + } + + /** + * Test that the trace is set correctly if there are multiple ANRs. + */ + public void testSetAnrTrace_multiple() { + List lines = Arrays.asList( + "========================================================", + "== dumpstate: 2012-04-25 20:45:10", + "========================================================", + "------ SYSTEM LOG (logcat -v threadtime -d *:v) ------", + "04-25 17:17:08.445 312 366 E ActivityManager: ANR (application not responding) in process: com.android.package", + "04-25 17:17:08.445 312 366 E ActivityManager: Reason: keyDispatchingTimedOut", + "04-25 17:17:08.445 312 366 E ActivityManager: Load: 0.71 / 0.83 / 0.51", + "04-25 17:17:08.445 312 366 E ActivityManager: 33% TOTAL: 21% user + 11% kernel + 0.3% iowait", + "04-25 17:18:08.445 312 366 E ActivityManager: ANR (application not responding) in process: com.android.package", + "04-25 17:18:08.445 312 366 E ActivityManager: Reason: keyDispatchingTimedOut", + "04-25 17:18:08.445 312 366 E ActivityManager: Load: 0.71 / 0.83 / 0.51", + "04-25 17:18:08.445 312 366 E ActivityManager: 33% TOTAL: 21% user + 11% kernel + 0.3% iowait", + "04-25 17:19:08.445 312 366 E ActivityManager: ANR (application not responding) in process: com.android.different.pacakge", + "04-25 17:19:08.445 312 366 E ActivityManager: Reason: keyDispatchingTimedOut", + "04-25 17:19:08.445 312 366 E ActivityManager: Load: 0.71 / 0.83 / 0.51", + "04-25 17:19:08.445 312 366 E ActivityManager: 33% TOTAL: 21% user + 11% kernel + 0.3% iowait", + "", + "------ VM TRACES AT LAST ANR (/data/anr/traces.txt: 2012-04-25 17:18:08) ------", + "", + "----- pid 2887 at 2012-04-25 17:17:08 -----", + "Cmd line: com.android.package", + "", + "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)", + " at class.method2(Class.java:2)", + " at class.method2(Class.java:2)", + "", + "----- end 2887 -----", + ""); + + List expectedStack = Arrays.asList( + "\"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)", + " at class.method2(Class.java:2)", + " at class.method2(Class.java:2)"); + + BugreportItem bugreport = new BugreportParser().parse(lines); + + assertNotNull(bugreport.getSystemLog()); + assertEquals(3, bugreport.getSystemLog().getAnrs().size()); + assertNull(bugreport.getSystemLog().getAnrs().get(0).getTrace()); + assertEquals(ArrayUtil.join("\n", expectedStack), + bugreport.getSystemLog().getAnrs().get(1).getTrace()); + assertNull(bugreport.getSystemLog().getAnrs().get(2).getTrace()); + } + + /** + * Test that the trace is set correctly if there is not traces file. + */ + public void testSetAnrTrace_no_traces() { + List lines = Arrays.asList( + "========================================================", + "== dumpstate: 2012-04-25 20:45:10", + "========================================================", + "------ SYSTEM LOG (logcat -v threadtime -d *:v) ------", + "04-25 17:17:08.445 312 366 E ActivityManager: ANR (application not responding) in process: com.android.package", + "04-25 17:17:08.445 312 366 E ActivityManager: Reason: keyDispatchingTimedOut", + "04-25 17:17:08.445 312 366 E ActivityManager: Load: 0.71 / 0.83 / 0.51", + "04-25 17:17:08.445 312 366 E ActivityManager: 33% TOTAL: 21% user + 11% kernel + 0.3% iowait", + "", + "*** NO ANR VM TRACES FILE (/data/anr/traces.txt): No such file or directory", + ""); + + BugreportItem bugreport = new BugreportParser().parse(lines); + + assertNotNull(bugreport.getSystemLog()); + assertEquals(1, bugreport.getSystemLog().getAnrs().size()); + assertNull(bugreport.getSystemLog().getAnrs().get(0).getTrace()); + } + + /** + * Add a test that ensures that the "new" style of stack dumping works. Traces aren't written to + * a global trace file. Instead, each ANR event is written to a separate trace file (note the + * "/data/anr/anr_4376042170248254515" instead of "/data/anr/traces.txt"). + */ + public void testAnrTraces_not_global_traceFile() { + List lines = + Arrays.asList( + "========================================================", + "== dumpstate: 2017-06-12 16:46:29", + "========================================================", + "------ SYSTEM LOG (logcat -v threadtime -v printable -v uid -d *:v) ------", + "--------- beginning of main ", + "02-18 04:26:31.829 logd 468 468 W auditd : type=2000 audit(0.0:1): initialized", + "02-18 04:26:33.783 logd 468 468 I auditd : type=1403 audit(0.0:2): policy loaded auid=4294967295 ses=4294967295", + "02-18 04:26:33.783 logd 468 468 W auditd : type=1404 audit(0.0:3): enforcing=1 old_enforcing=0 auid=4294967295 ses=4294967295", + "06-12 16:45:47.426 1000 1050 1124 E ActivityManager: ANR in com.example.android.helloactivity (com.example.android.helloactivity/.HelloActivity)", + "06-12 16:45:47.426 1000 1050 1124 E ActivityManager: PID: 7176", + "06-12 16:45:47.426 1000 1050 1124 E ActivityManager: Reason: Input dispatching timed out (Waiting because no window has focus but there is a focused application that may eventually add a window when it finishes starting up.)", + "06-12 16:45:47.426 1000 1050 1124 E ActivityManager: Load: 6.85 / 7.07 / 5.31", + "06-12 16:45:47.426 1000 1050 1124 E ActivityManager: CPU usage from 235647ms to 0ms ago (2017-06-12 16:41:49.415 to 2017-06-12 16:45:45.062):", + "06-12 16:45:47.426 1000 1050 1124 E ActivityManager: 7.7% 1848/com.ustwo.lwp: 4% user + 3.7% kernel / faults: 157 minor", + "06-12 16:45:47.426 1000 1050 1124 E ActivityManager: 7.7% 2536/com.google.android.googlequicksearchbox:search: 5.6% user + 2.1% kernel / faults: 195 minor", + "06-12 16:45:47.426 1000 1050 1124 E ActivityManager: 7.2% 1050/system_server: 4.5% user + 2.6% kernel / faults: 27117 minor ", + "06-12 16:45:47.426 1000 1050 1124 E ActivityManager: 5.3% 489/surfaceflinger: 2.9% user + 2.3% kernel / faults: 15 minor ", + "", + "------ VM TRACES AT LAST ANR (/data/anr/anr_4376042170248254515: 2017-06-12 16:45:47) ------", + "", + "----- pid 7176 at 2017-06-12 16:45:45 -----", + "Cmd line: com.example.android.helloactivity", + "", + "DALVIK THREADS:", + "(mutexes: tll=0 tsl=0 tscl=0 ghl=0)", + "", + "\"main\" daemon prio=5 tid=5 Waiting", + " | group=\"system\" sCount=1 dsCount=0 flags=1 obj=0x140805e8 self=0x7caf4bf400", + " | sysTid=7184 nice=4 cgrp=default sched=0/0 handle=0x7c9b4e44f0", + " | state=S schedstat=( 507031 579062 19 ) utm=0 stm=0 core=3 HZ=100", + " | stack=0x7c9b3e2000-0x7c9b3e4000 stackSize=1037KB", + " | held mutexes=", + " at java.lang.Object.wait(Native method)", + " - waiting on <0x0281f7b7> (a java.lang.Class)", + " at java.lang.Daemons$ReferenceQueueDaemon.runInternal(Daemons.java:178)", + " - locked <0x0281f7b7> (a java.lang.Class)", + " at java.lang.Daemons$Daemon.run(Daemons.java:103)", + " at java.lang.Thread.run(Thread.java:764)", + "", + "----- end 7176 -----"); + + // NOTE: The parser only extracts the main thread from the traces. + List expectedStack = + Arrays.asList( + "\"main\" daemon prio=5 tid=5 Waiting", + " | group=\"system\" sCount=1 dsCount=0 flags=1 obj=0x140805e8 self=0x7caf4bf400", + " | sysTid=7184 nice=4 cgrp=default sched=0/0 handle=0x7c9b4e44f0", + " | state=S schedstat=( 507031 579062 19 ) utm=0 stm=0 core=3 HZ=100", + " | stack=0x7c9b3e2000-0x7c9b3e4000 stackSize=1037KB", + " | held mutexes=", + " at java.lang.Object.wait(Native method)", + " - waiting on <0x0281f7b7> (a java.lang.Class)", + " at java.lang.Daemons$ReferenceQueueDaemon.runInternal(Daemons.java:178)", + " - locked <0x0281f7b7> (a java.lang.Class)", + " at java.lang.Daemons$Daemon.run(Daemons.java:103)", + " at java.lang.Thread.run(Thread.java:764)"); + + BugreportItem bugreport = new BugreportParser().parse(lines); + assertNotNull(bugreport.getSystemLog()); + assertEquals(1, bugreport.getSystemLog().getAnrs().size()); + assertEquals( + ArrayUtil.join("\n", expectedStack), + bugreport.getSystemLog().getAnrs().get(0).getTrace()); + } + + /** + * Test that missing sections in bugreport are set to {@code null}, not empty {@link IItem}s. + */ + public void testNoSections() { + List lines = Arrays.asList( + "========================================================", + "== dumpstate: 2012-04-25 20:45:10", + "========================================================"); + + BugreportItem bugreport = new BugreportParser().parse(lines); + assertNotNull(bugreport); + assertNull(bugreport.getDumpsys()); + assertNull(bugreport.getKernelLog()); + assertNull(bugreport.getMemInfo()); + assertNull(bugreport.getProcrank()); + assertNull(bugreport.getSystemLog()); + assertNull(bugreport.getSystemProps()); + assertNull(bugreport.getTop()); + assertNotNull(bugreport.getLastKmsg()); + List events = bugreport.getLastKmsg().getMiscEvents( + KernelLogParser.KERNEL_RESET); + assertEquals(events.size(), 1); + assertEquals(events.get(0).getStack(), "Unknown reason"); + + lines = Arrays.asList( + "========================================================", + "== dumpstate: 2012-04-25 20:45:10", + "========================================================", + "", + "------ DUMPSYS (dumpsys) ------", + "", + "------ KERNEL LOG (dmesg) ------", + "", + "------ LAST KMSG (/proc/last_kmsg) ------", + "", + "------ MEMORY INFO (/proc/meminfo) ------", + "", + "------ PROCRANK (procrank) ------", + "", + "------ SYSTEM LOG (logcat -v threadtime -d *:v) ------", + "", + "------ SYSTEM PROPERTIES ------", + "", + "------ CPU INFO (top -n 1 -d 1 -m 30 -t) ------", + ""); + + bugreport = new BugreportParser().parse(lines); + assertNotNull(bugreport); + assertNotNull(bugreport.getDumpsys()); + assertNull(bugreport.getKernelLog()); + assertNull(bugreport.getMemInfo()); + assertNull(bugreport.getProcrank()); + assertNull(bugreport.getSystemLog()); + assertNull(bugreport.getSystemProps()); + assertNull(bugreport.getTop()); + assertNotNull(bugreport.getLastKmsg()); + events = bugreport.getLastKmsg().getMiscEvents(KernelLogParser.KERNEL_RESET); + assertEquals(events.size(), 1); + assertEquals(events.get(0).getStack(), "Unknown reason"); + } + + /** + * Test that section headers are correctly parsed. + */ + public void testSectionHeader() { + List lines = + Arrays.asList( + "========================================================", + "== dumpstate: 2012-04-25 20:45:10", + "========================================================", + "------ DUMPSYS (dumpsys) ------", + "DUMP OF SERVICE SurfaceFlinger:", + "--DrmDisplayCompositor[0]: num_frames=1456 num_ms=475440 fps=3.06243", + "---- DrmDisplayCompositor Layers: num=3", + "------ DrmDisplayCompositor Layer: plane=17 crtc=20 crtc[x/y/w/h]=0/0/2560/1800", + "------ DrmDisplayCompositor Layer: plane=21 disabled", + "------ DrmDisplayCompositor Layer: plane=22 disabled", + "DUMP OF SERVICE batterystats:", + "Battery History (0% used, 1636 used of 256KB, 15 strings using 794):", + " 0 (15) RESET:TIME: 1970-01-10-06-23-28", + " +45s702ms (2) 001 80080000 volt=4187", + " +1m15s525ms (2) 001 80080000 temp=299 volt=4155", + "Statistics since last charged:", + " Time on battery: 1h 5m 2s 4ms (9%) realtime, 1h 5m 2s 4ms (9%) uptime", + " Time on battery screen off: 1h 4m 5s 8ms (9%) realtime, 1h 4m 5s 8ms (9%) uptime", + " All kernel wake locks:", + " Kernel Wake lock PowerManagerService.WakeLocks: 5m 10s 6ms (2 times) realtime", + " Kernel Wake lock msm_serial_hs_rx: 2m 13s 612ms (258 times) realtime", + "", + " All partial wake locks:", + " Wake lock 1001 ProxyController: 1h 4m 47s 565ms (4 times) realtime", + " Wake lock 1013 AudioMix: 1s 979ms (3 times) realtime", + "", + " All wakeup reasons:", + " Wakeup reason 2:bcmsdh_sdmmc:2:qcom,smd:2:msmgio: 1m 5s 4ms (2 times) realtime", + " Wakeup reason 2:qcom,smd-rpm:2:fc4c.qcom,spmi: 7m 1s 914ms (7 times) realtime", + "DUMP OF SERVICE package:", + "Package [com.google.android.calculator] (e075c9d):", + " use rId=10071", + " secondaryCpuAbi=null", + " versionCode=73000302 minSdk=10000 targetSdk=10000", + " versionName=7.3 (3821978)", + " splits=[base]", + "DUMP OF SERVICE procstats:", + "COMMITTED STATS FROM 2015-09-30-07-44-54:", + " * system / 1000 / v23:", + " TOTAL: 100% (118MB-118MB-118MB/71MB-71MB-71MB over 1)", + " Persistent: 100% (118MB-118MB-118MB/71MB-71MB-71MB over 1)", + " * com.android.phone / 1001 / v23:", + " TOTAL: 6.7%", + " Persistent: 6.7%", + ""); + BugreportItem bugreport = new BugreportParser().parse(lines); + assertNotNull(bugreport.getDumpsys()); + assertNotNull(bugreport.getDumpsys().getBatteryStats()); + assertNotNull(bugreport.getDumpsys().getPackageStats()); + assertNotNull(bugreport.getDumpsys().getProcStats()); + } + + /** + * Test that an empty input returns {@code null}. + */ + public void testEmptyInput() { + BugreportItem item = new BugreportParser().parse(Arrays.asList("")); + assertNull(item); + } + + /** + * Test that app names from logcat events are populated by matching the logcat PIDs with the + * PIDs from the logcat. + */ + public void testSetAppsFromProcrank() { + List lines = Arrays.asList( + "========================================================", + "== dumpstate: 2012-04-25 20:45:10", + "========================================================", + "------ PROCRANK (procrank) ------", + " PID Vss Rss Pss Uss cmdline", + " 3064 87136K 81684K 52829K 50012K com.android.package1", + " 3066 87136K 81684K 52829K 50012K com.android.package2", + " ------ ------ ------", + " 203624K 163604K TOTAL", + "RAM: 731448K total, 415804K free, 9016K buffers, 108548K cached", + "[procrank: 1.6s elapsed]", + "------ SYSTEM LOG (logcat -v threadtime -d *:v) ------", + "04-25 09:55:47.799 3064 3082 E AndroidRuntime: java.lang.Exception", + "04-25 09:55:47.799 3064 3082 E AndroidRuntime: \tat class.method1(Class.java:1)", + "04-25 09:55:47.799 3064 3082 E AndroidRuntime: \tat class.method2(Class.java:2)", + "04-25 09:55:47.799 3064 3082 E AndroidRuntime: \tat class.method3(Class.java:3)", + "04-25 09:55:47.799 3065 3083 E AndroidRuntime: java.lang.Exception", + "04-25 09:55:47.799 3065 3083 E AndroidRuntime: \tat class.method1(Class.java:1)", + "04-25 09:55:47.799 3065 3083 E AndroidRuntime: \tat class.method2(Class.java:2)", + "04-25 09:55:47.799 3065 3083 E AndroidRuntime: \tat class.method3(Class.java:3)", + "04-25 09:55:47.799 3065 3084 E AndroidRuntime: FATAL EXCEPTION: main", + "04-25 09:55:47.799 3066 3084 E AndroidRuntime: Process: com.android.package3, PID: 1234", + "04-25 09:55:47.799 3066 3084 E AndroidRuntime: java.lang.Exception", + "04-25 09:55:47.799 3066 3084 E AndroidRuntime: \tat class.method1(Class.java:1)", + "04-25 09:55:47.799 3066 3084 E AndroidRuntime: \tat class.method2(Class.java:2)", + "04-25 09:55:47.799 3066 3084 E AndroidRuntime: \tat class.method3(Class.java:3)"); + + BugreportItem bugreport = new BugreportParser().parse(lines); + assertNotNull(bugreport.getSystemLog()); + assertEquals(3, bugreport.getSystemLog().getJavaCrashes().size()); + assertEquals("com.android.package1", + bugreport.getSystemLog().getJavaCrashes().get(0).getApp()); + assertNull(bugreport.getSystemLog().getJavaCrashes().get(1).getApp()); + assertEquals("com.android.package3", + bugreport.getSystemLog().getJavaCrashes().get(2).getApp()); + } + + /** + * Some Android devices refer to SYSTEM LOG as MAIN LOG. Check that parser recognizes this + * alternate syntax. + */ + public void testSystemLogAsMainLog() { + List lines = Arrays.asList( + "------ MAIN LOG (logcat -b main -b system -v threadtime -d *:v) ------", + "--------- beginning of /dev/log/system", + "12-11 19:48:07.945 1484 1508 D BatteryService: update start"); + BugreportItem bugreport = new BugreportParser().parse(lines); + assertNotNull(bugreport.getSystemLog()); + } + + /** + * Some Android devices refer to SYSTEM LOG as MAIN AND SYSTEM LOG. Check that parser + * recognizes this alternate syntax. + */ + public void testSystemAndMainLog() { + List lines = Arrays.asList( + "------ MAIN AND SYSTEM LOG (logcat -b main -b system -v threadtime -d *:v) ------", + "--------- beginning of /dev/log/system", + "12-17 15:15:12.877 1994 2019 D UiModeManager: updateConfigurationLocked: "); + BugreportItem bugreport = new BugreportParser().parse(lines); + assertNotNull(bugreport.getSystemLog()); + } + + private Date parseTime(String timeStr) throws ParseException { + DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS"); + return formatter.parse(timeStr); + } +} diff --git a/javatests/src/com/android/loganalysis/parser/CompactMemInfoParserTest.java b/javatests/src/com/android/loganalysis/parser/CompactMemInfoParserTest.java new file mode 100644 index 0000000..ed4b39b --- /dev/null +++ b/javatests/src/com/android/loganalysis/parser/CompactMemInfoParserTest.java @@ -0,0 +1,205 @@ +/* + * Copyright (C) 2014 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.CompactMemInfoItem; + +import junit.framework.TestCase; + +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + +import java.util.Arrays; +import java.util.List; + +public class CompactMemInfoParserTest extends TestCase { + + public void testSingleProcLineWithSwapHasActivities() { + List input = Arrays.asList("proc,cached,com.google.android.youtube1,2964,19345,1005,a"); + + CompactMemInfoItem item = new CompactMemInfoParser().parse(input); + + assertEquals(1, item.getPids().size()); + assertEquals("com.google.android.youtube1", item.getName(2964)); + assertEquals(19345, item.getPss(2964)); + assertEquals(1005, item.getSwap(2964)); + assertEquals("cached", item.getType(2964)); + assertEquals(true, item.hasActivities(2964)); + } + + public void testSingleProcLineWithoutSwapHasActivities() { + List input = Arrays.asList("proc,cached,com.google.android.youtube,2964,19345,a"); + + CompactMemInfoItem item = new CompactMemInfoParser().parse(input); + + assertEquals(1, item.getPids().size()); + assertEquals("com.google.android.youtube", item.getName(2964)); + assertEquals(19345, item.getPss(2964)); + assertEquals(0, item.getSwap(2964)); + assertEquals("cached", item.getType(2964)); + assertEquals(true, item.hasActivities(2964)); + } + + + public void testSingleProcLineWithoutSwapNoActivities() { + List input = Arrays.asList("proc,cached,com.google.android.youtube,2964,19345,e"); + + CompactMemInfoItem item = new CompactMemInfoParser().parse(input); + + assertEquals(1, item.getPids().size()); + assertEquals("com.google.android.youtube", item.getName(2964)); + assertEquals(19345, item.getPss(2964)); + assertEquals(0, item.getSwap(2964)); + assertEquals("cached", item.getType(2964)); + assertEquals(false, item.hasActivities(2964)); + } + + public void testSingleLostRamLine() { + List input = Arrays.asList("lostram,1005"); + CompactMemInfoItem item = new CompactMemInfoParser().parse(input); + assertEquals(1005, item.getLostRam()); + } + + public void testSingleRamLine() { + List input = Arrays.asList("ram,2866484,1221694,1112777"); + CompactMemInfoItem item = new CompactMemInfoParser().parse(input); + assertEquals(1221694, item.getFreeRam()); + } + + public void testSingleZramLine() { + List input = Arrays.asList("zram,5800,520908,491632"); + CompactMemInfoItem item = new CompactMemInfoParser().parse(input); + assertEquals(5800, item.getTotalZram()); + assertEquals(491632, item.getFreeSwapZram()); + } + + public void testSingleTuningLine() { + // With specific configuration + List input1 = Arrays.asList("tuning,192,512,322560,high-end-gfx"); + CompactMemInfoItem item1 = new CompactMemInfoParser().parse(input1); + assertEquals(322560, item1.getTuningLevel()); + // Without specific configuration + List input2 = Arrays.asList("tuning,193,513,322561"); + CompactMemInfoItem item2 = new CompactMemInfoParser().parse(input2); + assertEquals(322561, item2.getTuningLevel()); + } + + public void testSomeMalformedLines() { + List input = + Arrays.asList( + "proc,cached,com.google.android.youtube,a,b,e", + "proc,cached,com.google.android.youtube,2964,c,e", + "proc,cached,com.google.android.youtube,2964,e", + "proc,cached,com.google.android.youtube,2964,19345,a,e", + "lostram,a,1000", + "lostram,1000,a", + "ram,123,345", + "ram,123,345,abc", + "ram,123,345,456,678", + "ram,123,345,456,abc", + "zram,123,345", + "zram,123,345,abc", + "zram,123,345,456,678", + "zram,123,345,456,abc", + "tuning,123,345", + "tuning,123,345,abc"); + + CompactMemInfoItem item = new CompactMemInfoParser().parse(input); + + assertEquals(0, item.getPids().size()); + } + + public void testMultipleLines() { + List input = + Arrays.asList( + "proc,cached,com.google.android.youtube,2964,19345,123,e", + "proc,cached,com.google.android.apps.plus,2877,9604,N/A,e", + "proc,cached,com.google.android.apps.magazines,2009,20111,N/A,e", + "proc,cached,com.google.android.apps.walletnfcrel,10790,11164,100,e", + "proc,cached,com.google.android.incallui,3410,9491,N/A,e", + "lostram,1005", + "ram,2866484,1221694,1112777", + "zram,5800,520908,491632", + "tuning,193,513,322561"); + + CompactMemInfoItem item = new CompactMemInfoParser().parse(input); + + assertEquals(5, item.getPids().size()); + assertEquals("com.google.android.youtube", item.getName(2964)); + assertEquals(19345, item.getPss(2964)); + assertEquals(123, item.getSwap(2964)); + assertEquals("cached", item.getType(2964)); + assertEquals(false, item.hasActivities(2964)); + + assertEquals(1005, item.getLostRam()); + assertEquals(1221694, item.getFreeRam()); + assertEquals(5800, item.getTotalZram()); + assertEquals(491632, item.getFreeSwapZram()); + assertEquals(322561, item.getTuningLevel()); + } + + public void testSkipNonProcLines() { + // Skip lines which does not start with proc + + List input = Arrays.asList( + "oom,cached,141357", + "proc,cached,com.google.android.youtube,2964,19345,54321,e", + "proc,cached,com.google.android.apps.plus,2877,9604,4321,e", + "proc,cached,com.google.android.apps.magazines,2009,20111,321,e", + "proc,cached,com.google.android.apps.walletnfcrel,10790,11164,21,e", + "proc,cached,com.google.android.incallui,3410,9491,1,e", + "cat,Native,63169"); + + CompactMemInfoItem item = new CompactMemInfoParser().parse(input); + + assertEquals(5, item.getPids().size()); + assertEquals("com.google.android.youtube", item.getName(2964)); + assertEquals(19345, item.getPss(2964)); + assertEquals(54321, item.getSwap(2964)); + assertEquals("cached", item.getType(2964)); + assertEquals(false, item.hasActivities(2964)); + } + + public void testJson() throws JSONException { + List input = + Arrays.asList( + "oom,cached,141357", + "proc,cached,com.google.android.youtube,2964,19345,N/A,e", + "proc,cached,com.google.android.apps.plus,2877,9604,50,e", + "proc,cached,com.google.android.apps.magazines,2009,20111,100,e", + "proc,cached,com.google.android.apps.walletnfcrel,10790,11164,0,e", + "proc,cached,com.google.android.incallui,3410,9491,500,e", + "lostram,1005", + "ram,2866484,1221694,1112777", + "zram,5800,520908,491632", + "tuning,193,513,322561", + "cat,Native,63169"); + + CompactMemInfoItem item = new CompactMemInfoParser().parse(input); + JSONObject json = item.toJson(); + assertNotNull(json); + + JSONArray processes = json.getJSONArray("processes"); + assertEquals(5, processes.length()); + + assertEquals(1005, (long)json.get("lostRam")); + assertEquals(1221694, (long) json.get("freeRam")); + assertEquals(5800, (long) json.get("totalZram")); + assertEquals(491632, (long) json.get("freeSwapZram")); + assertEquals(322561, (long) json.get("tuningLevel")); + } +} diff --git a/javatests/src/com/android/loganalysis/parser/CpuInfoParserTest.java b/javatests/src/com/android/loganalysis/parser/CpuInfoParserTest.java new file mode 100644 index 0000000..196f6a2 --- /dev/null +++ b/javatests/src/com/android/loganalysis/parser/CpuInfoParserTest.java @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2015 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.CpuInfoItem; + +import junit.framework.TestCase; + +import java.util.Arrays; +import java.util.List; + +public class CpuInfoParserTest extends TestCase { + + public void testSingleLine() { + List input = Arrays.asList(" 0.1% 170/surfaceflinger: 0% user + 0% kernel"); + + CpuInfoItem item = new CpuInfoParser().parse(input); + + assertEquals(1, item.getPids().size()); + assertEquals("surfaceflinger", item.getName(170)); + assertEquals(0.1, item.getPercent(170), 0.0001); + } + + public void testMultipleLines() { + List input = Arrays.asList( + "CPU usage from 35935ms to 26370ms ago:", + " 57% 489/system_server: 37% user + 20% kernel / faults: 39754 minor 57 major", + " 34% 853/com.google.android.leanbacklauncher: 30% user + 4.6% kernel / faults: 7838 minor 14 major", + " 15% 19463/com.google.android.videos: 11% user + 3.3% kernel / faults: 21603 minor 141 major", + " 8.2% 170/surfaceflinger: 3.4% user + 4.8% kernel / faults: 1 minor"); + CpuInfoItem item = new CpuInfoParser().parse(input); + + assertEquals(4, item.getPids().size()); + assertEquals("system_server", item.getName(489)); + assertEquals(57.0, item.getPercent(489), 0.0001); + assertEquals("surfaceflinger", item.getName(170)); + assertEquals(8.2, item.getPercent(170), 0.0001); + } + +} + diff --git a/javatests/src/com/android/loganalysis/parser/DmesgParserTest.java b/javatests/src/com/android/loganalysis/parser/DmesgParserTest.java new file mode 100644 index 0000000..e4ea7af --- /dev/null +++ b/javatests/src/com/android/loganalysis/parser/DmesgParserTest.java @@ -0,0 +1,317 @@ +/* + * Copyright (C) 2016 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.DmesgActionInfoItem; +import com.android.loganalysis.item.DmesgItem; +import com.android.loganalysis.item.DmesgServiceInfoItem; +import com.android.loganalysis.item.DmesgStageInfoItem; +import com.android.loganalysis.item.DmesgModuleInfoItem; +import java.io.BufferedReader; +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStreamReader; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import junit.framework.TestCase; + +/** + * Unit tests for {@link DmesgParser}. + */ +public class DmesgParserTest extends TestCase { + + private static final String BOOT_ANIMATION = "bootanim"; + private static final String NETD = "netd"; + private static final String FOO = "foo"; + private static final String BAR = "bar"; + private static final String TOTAL_MODULE = "TOTAL_MODULE"; + private static final String[] LINES = + new String[] { + "[ 0.370107] init: Loading module /lib/modules/foo.ko with args ''", + "[ 0.372497] init: Loaded kernel module /lib/modules/foo.ko", + "[ 0.372500] init: Loading module /lib/modules/bar.ko with args ''", + "[ 1.115467] init: Loaded 198 kernel modules took 748 ms", + "[ 2.471163] init: Wait for property 'apexd.status=ready' took 403ms", + "[ 3.786943] ueventd: Coldboot took 0.701291 seconds", + "[ 22.962730] init: starting service 'bootanim'...", + "[ 23.252321] init: starting service 'netd'...", + "[ 29.331069] ipa-wan ipa_wwan_ioctl:1428 dev(rmnet_data0) register to IPA", + "[ 32.182592] ueventd: fixup /sys/devices/virtual/input/poll_delay 0 1004 660", + "[ 35.642666] SELinux: initialized (dev fuse, type fuse), uses genfs_contexts", + "[ 39.855818] init: Service 'bootanim' (pid 588) exited with status 0", + "[ 41.665818] init: init first stage started!", + "[ 44.942872] init: processing action (early-init) from (/init.rc:13)", + "[ 47.233446] init: processing action (set_mmap_rnd_bits) from (:0)", + "[ 47.240083] init: processing action (set_kptr_restrict) from (:0)", + "[ 47.245778] init: processing action (keychord_init) from (:0)", + "[ 52.361049] init: processing action (persist.sys.usb.config=* boot) from" + + " (:0)", + "[ 52.361108] init: processing action (enable_property_trigger) from (:0)", + "[ 52.361313] init: processing action (security.perf_harden=1) from" + + " (/init.rc:677)", + "[ 52.361495] init: processing action (ro.debuggable=1) from (/init.rc:700)", + "[ 58.298293] init: processing action (sys.boot_completed=1)", + "[ 59.331069] ipa-wan ipa_wwan_ioctl:1428 dev(rmnet_data0) register to IPA", + "[ 62.182592] ueventd: fixup /sys/devices/virtual/input/poll_delay 0 1004 660", + "[ 65.642666] SELinux: initialized (dev fuse, type fuse), uses genfs_contexts", + "[ 69.855818] init: Service 'bootanim' (pid 588) exited with status 0" + }; + + private static final Map EXPECTED_SERVICE_INFO_ITEMS = + getExpectedServiceInfoItems(); + + private static final List EXPECTED_STAGE_INFO_ITEMS = + getExpectedStageInfoItems(); + + private static final List EXPECTED_ACTION_INFO_ITEMS = + getExpectedActionInfoItems(); + + private static final Map EXPECTED_MODULE_INFO_ITEMS = + getExpectedModuleInfoItems(); + + /** + * Test for empty dmesg logs passed to the DmesgParser + */ + public void testEmptyDmesgLog() throws IOException { + String[] lines = new String[] {""}; + try (BufferedReader bufferedReader = new BufferedReader(new InputStreamReader( + new ByteArrayInputStream(String.join("\n", lines).getBytes())))) { + DmesgParser dmesgParser = new DmesgParser(); + dmesgParser.parseInfo(bufferedReader); + assertEquals("Service info items list should be empty", 0, + dmesgParser.getServiceInfoItems().size()); + } + } + + /** + * Test for complete dmesg logs passed as list of strings + */ + public void testCompleteDmesgLog_passedAsList() { + + DmesgParser dmesgParser = new DmesgParser(); + DmesgItem actualDmesgItem = dmesgParser.parse(Arrays.asList(LINES)); + + assertEquals("Service info items list size should be 2", 2, + dmesgParser.getServiceInfoItems().size()); + assertEquals("Stage info items list size should be 3",3, + dmesgParser.getStageInfoItems().size()); + assertEquals("Action info items list size should be 9",9, + dmesgParser.getActionInfoItems().size()); + assertEquals( + "Module info items list size should be 3", + 3, + dmesgParser.getModuleInfoItems().size()); + + assertEquals(EXPECTED_SERVICE_INFO_ITEMS, actualDmesgItem.getServiceInfoItems()); + assertEquals(EXPECTED_STAGE_INFO_ITEMS, actualDmesgItem.getStageInfoItems()); + assertEquals(EXPECTED_ACTION_INFO_ITEMS, actualDmesgItem.getActionInfoItems()); + assertEquals(EXPECTED_MODULE_INFO_ITEMS, actualDmesgItem.getModuleInfoItems()); + } + + /** + * Test for complete dmesg logs passed as buffered input + */ + public void testCompleteDmesgLog_passedAsBufferedInput() throws IOException { + try (BufferedReader bufferedReader = new BufferedReader(new InputStreamReader( + new ByteArrayInputStream(String.join("\n", LINES).getBytes())))) { + DmesgParser dmesgParser = new DmesgParser(); + dmesgParser.parseInfo(bufferedReader); + assertEquals("Service info items list size should be 2", 2, + dmesgParser.getServiceInfoItems().size()); + assertEquals("Stage info items list size should be 3", 3, + dmesgParser.getStageInfoItems().size()); + assertEquals("Action info items list size should be 9",9, + dmesgParser.getActionInfoItems().size()); + assertEquals( + "Module info items list size should be 3", + 3, + dmesgParser.getModuleInfoItems().size()); + } + } + + /** + * Test service which logs both the start and end time + */ + public void testCompleteServiceInfo() { + DmesgParser dmesgParser = new DmesgParser(); + for (String line : LINES) { + dmesgParser.parseServiceInfo(line); + } + + assertEquals("There should be two service infos", 2, + dmesgParser.getServiceInfoItems().size()); + assertEquals(EXPECTED_SERVICE_INFO_ITEMS, dmesgParser.getServiceInfoItems()); + } + + /** + * Test service which logs only the start time + */ + public void testStartServiceInfo() { + DmesgParser dmesgParser = new DmesgParser(); + for (String line : LINES) { + dmesgParser.parseServiceInfo(line); + } + List serviceInfoItems = new ArrayList<>( + dmesgParser.getServiceInfoItems().values()); + assertEquals("There should be exactly two service infos", 2, serviceInfoItems.size()); + assertEquals("Service name is not bootanim", BOOT_ANIMATION, + serviceInfoItems.get(0).getServiceName()); + assertEquals("Service name is not netd", NETD, serviceInfoItems.get(1).getServiceName()); + } + + /** + * Test multiple service info parsed correctly and stored in the same order logged in + * the file. + */ + public void testMultipleServiceInfo() { + DmesgParser dmesgParser = new DmesgParser(); + for (String line : LINES) { + dmesgParser.parseServiceInfo(line); + } + assertEquals("There should be exactly two service info", 2, + dmesgParser.getServiceInfoItems().size()); + assertEquals(EXPECTED_SERVICE_INFO_ITEMS, dmesgParser.getServiceInfoItems()); + } + + /** + * Test invalid patterns on the start and exit service logs + */ + public void testInvalidServiceLogs() { + // Added space at the end of the start and exit of service logs to make it invalid + String[] lines = new String[] { + "[ 22.962730] init: starting service 'bootanim'... ", + "[ 23.252321] init: starting service 'netd'... ", + "[ 29.331069] ipa-wan ipa_wwan_ioctl:1428 dev(rmnet_data0) register to IPA", + "[ 32.182592] ueventd: fixup /sys/devices/virtual/input/poll_delay 0 1004 660", + "[ 35.642666] SELinux: initialized (dev fuse, type fuse), uses genfs_contexts", + "[ 39.855818] init: Service 'bootanim' (pid 588) exited with status 0 "}; + DmesgParser dmesgParser = new DmesgParser(); + for (String line : lines) { + dmesgParser.parseServiceInfo(line); + } + List serviceInfoItems = new ArrayList<>( + dmesgParser.getServiceInfoItems().values()); + assertEquals("No service info should be available", 0, serviceInfoItems.size()); + } + + /** + * Test init stages' start time logs + */ + public void testCompleteStageInfo() { + DmesgParser dmesgParser = new DmesgParser(); + for (String line : LINES) { + dmesgParser.parseStageInfo(line); + } + List stageInfoItems = dmesgParser.getStageInfoItems(); + assertEquals(3, stageInfoItems.size()); + assertEquals(EXPECTED_STAGE_INFO_ITEMS, stageInfoItems); + } + + /** Test processing action start time logs */ + public void testCompleteActionInfo() { + DmesgParser dmesgParser = new DmesgParser(); + for (String line : LINES) { + dmesgParser.parseActionInfo(line); + } + List actualActionInfoItems = dmesgParser.getActionInfoItems(); + assertEquals(9, actualActionInfoItems.size()); + assertEquals(EXPECTED_ACTION_INFO_ITEMS, actualActionInfoItems); + } + + /** Test incomplete module loaded pattern */ + public void testIncompleteModuleInfo() { + DmesgParser dmesgParser = new DmesgParser(); + for (String line : LINES) { + dmesgParser.parseModuleInfo(line); + } + List actualModuleInfoItems = + new ArrayList<>(dmesgParser.getModuleInfoItems().values()); + assertEquals(EXPECTED_MODULE_INFO_ITEMS, dmesgParser.getModuleInfoItems()); + assertEquals(3, actualModuleInfoItems.size()); + assertEquals( + "Duration should be -1L", + Long.valueOf(-1L), + actualModuleInfoItems.get(0).getModuleDuration()); + } + + private static List getExpectedActionInfoItems() { + return Arrays.asList( + new DmesgActionInfoItem("/init.rc:13", "early-init", 44942L), + new DmesgActionInfoItem(":0", "set_mmap_rnd_bits", 47233L), + new DmesgActionInfoItem(":0", "set_kptr_restrict", 47240L), + new DmesgActionInfoItem(":0", "keychord_init", 47245L), + new DmesgActionInfoItem( + ":0", "persist.sys.usb.config=* boot", 52361L), + new DmesgActionInfoItem(":0", "enable_property_trigger", 52361L), + new DmesgActionInfoItem("/init.rc:677", "security.perf_harden=1", 52361L), + new DmesgActionInfoItem("/init.rc:700", "ro.debuggable=1", 52361L), + new DmesgActionInfoItem(null, "sys.boot_completed=1", 58298L)); + } + + private static List getExpectedStageInfoItems() { + return Arrays.asList( + new DmesgStageInfoItem("init_Wait for property 'apexd.status=ready'", null, 403L), + new DmesgStageInfoItem("ueventd_Coldboot", null, 701L), + new DmesgStageInfoItem("first", 41665L, null)); + } + + private static Map getExpectedServiceInfoItems() { + Map serviceInfoItemsMap = new HashMap<>(); + DmesgServiceInfoItem bootanimServiceInfoItem = new DmesgServiceInfoItem(); + bootanimServiceInfoItem.setServiceName(BOOT_ANIMATION); + bootanimServiceInfoItem.setStartTime(22962L); + bootanimServiceInfoItem.setEndTime(69855L); + + DmesgServiceInfoItem netdServiceInfoItem = new DmesgServiceInfoItem(); + netdServiceInfoItem.setServiceName(NETD); + netdServiceInfoItem.setStartTime(23252L); + + serviceInfoItemsMap.put(BOOT_ANIMATION, bootanimServiceInfoItem); + serviceInfoItemsMap.put(NETD, netdServiceInfoItem); + + return serviceInfoItemsMap; + } + + private static Map getExpectedModuleInfoItems() { + Map moduleInfoItemsMap = new HashMap<>(); + DmesgModuleInfoItem fooModuleInfo = new DmesgModuleInfoItem(); + fooModuleInfo.setModuleName(FOO); + fooModuleInfo.setStartTime(370L); + fooModuleInfo.setEndTime(372L); + + DmesgModuleInfoItem barModuleInfo = new DmesgModuleInfoItem(); + barModuleInfo.setModuleName(BAR); + barModuleInfo.setStartTime(372L); + + DmesgModuleInfoItem totalInfoItem = new DmesgModuleInfoItem(); + totalInfoItem.setModuleName(TOTAL_MODULE); + totalInfoItem.setModuleCount("198"); + totalInfoItem.setModuleDuration(748L); + + moduleInfoItemsMap.put(FOO, fooModuleInfo); + moduleInfoItemsMap.put(BAR, barModuleInfo); + moduleInfoItemsMap.put(TOTAL_MODULE, totalInfoItem); + + return moduleInfoItemsMap; + } +} diff --git a/javatests/src/com/android/loganalysis/parser/DumpsysBatteryStatsParserTest.java b/javatests/src/com/android/loganalysis/parser/DumpsysBatteryStatsParserTest.java new file mode 100644 index 0000000..e96491a --- /dev/null +++ b/javatests/src/com/android/loganalysis/parser/DumpsysBatteryStatsParserTest.java @@ -0,0 +1,153 @@ +/* + * Copyright (C) 2015 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.DumpsysBatteryStatsItem; + +import junit.framework.TestCase; + +import java.util.Arrays; +import java.util.List; + +/** + * Unit tests for {@link DumpsysBatteryStatsParser} + */ +public class DumpsysBatteryStatsParserTest extends TestCase { + + /** + * Test that normal input is parsed. + */ + public void testBatteryStatsParser() { + List inputBlock = Arrays.asList( + "Battery History (37% used, 95KB used of 256KB, 166 strings using 15KB):", + " 0 (9) RESET:TIME: 2014-12-09-11-33-29", + " +1s067ms (1) 100 c0500020 -wifi_full_lock -wifi_scan", + " +3s297ms (2) 100 80400020 -wake_lock -screen", + " +30m02s075ms (1) 100 c0500020 wifi_signal_strength=4 wifi_suppl=completed", + " +30m03s012ms (2) 099 c0500020 temp=306 volt=4217", + " +33m48s967ms (1) 099 f8400020 +wifi_scan", + " +33m49s335ms (2) 098 f0400020 temp=324 -wifi_scan", + "Statistics since last charge:", + " Time on battery: 2h 21m 5s 622ms (12.0%) realtime, 7m 54s 146ms (0.7%) uptime", + " Time on battery screen off: 2h 5m 55s 3ms (1%) realtime, 7m 4s 5ms (7%) uptime", + " Total run time: 19h 38m 43s 650ms realtime, 17h 25m 32s 175ms uptime", + " All kernel wake locks:", + " Kernel Wake lock PowerManagerService.WakeLocks: 1h 3m 50s 5ms (8 times) realtime", + " Kernel Wake lock event0-2656 : 3m 49s 268ms (2399 times) realtime", + " Kernel Wake lock wlan_wd_wake: 3m 34s 639ms (1751 times) realtime", + " Kernel Wake lock wlan_rx_wake: 3m 19s 887ms (225 times) realtime", + " Kernel Wake lock wlan_tx_wake: 2m 19s 887ms (225 times) realtime", + " Kernel Wake lock tx_wake: 1m 19s 887ms (225 times) realtime", + " ", + " All partial wake locks:", + " Wake lock u0a7 NlpWakeLock: 8m 13s 203ms (1479 times) realtime", + " Wake lock u0a7 NlpCollectorWakeLock: 6m 29s 18ms (238 times) realtime", + " Wake lock u0a7 GCM_CONN_ALARM: 6m 8s 587ms (239 times) realtime", + " Wake lock 1000 *alarm*: 5m 11s 316ms (1469 times) realtime", + " Wake lock u10 xxx: 4m 11s 316ms (1469 times) realtime", + " Wake lock u30 cst: 2m 11s 316ms (1469 times) realtime", + " ", + " All wakeup reasons:", + " Wakeup reason 200:qcom,smd-rpm:222:fc4: 11m 49s 332ms (0 times) realtime", + " Wakeup reason 200:qcom,smd-rpm: 48s 45ms (0 times) realtime", + " Wakeup reason 2:qcom,smd-rpm:2:f0.qm,mm:22:fc4mi: 3s 417ms (0 times) realtime", + " Wakeup reason 188:qcom,smd-adsp:200:qcom,smd-rpm: 1s 656ms (0 times) realtime", + " Wakeup reason 58:qcom,smsm-modem:2:qcom,smd-rpm: 6m 16s 1ms (5 times) realtime", + " Wakeup reason 57:qcom,smd-modem:200:qcom,smd-rpm: 40s 995ms (0 times) realtime", + " Wakeup reason unknown: 8s 455ms (0 times) realtime", + " Wakeup reason 9:bcmsdh_sdmmc:2:qcomd-rpm:240:mso: 8m 5s 9ms (0 times) realtime", + " ", + " 0:", + " User activity: 2 other", + " Wake lock SCREEN_FROZEN realtime", + " Sensor 0: 9s 908ms realtime (1 times)", + " Sensor 1: 9s 997ms realtime (1 times)", + " Foreground for: 2h 21m 5s 622ms", + " Apk android:", + " 24 wakeup alarms", + " u0a9:", + " Mobile network: 8.1KB received, 1.6KB sent (packets 291 received, 342 sent)", + " Mobile radio active: 3m 43s 890ms (34.2%) 39x @ 354 mspp", + " Sensor 2: 12m 13s 15ms realtime (5 times)", + " Sensor 32: (not used)", + " Sensor 35: (not used)"); + + DumpsysBatteryStatsItem batteryStats = new DumpsysBatteryStatsParser().parse(inputBlock); + assertNotNull(batteryStats.getBatteryStatsSummaryItem()); + assertNotNull(batteryStats.getDetailedBatteryStatsItem()); + } + + public void testBatteryStatsWithNoKB() { + List inputBlock = Arrays.asList( + "Battery History (37% used, 95 used of 256KB, 166 strings using 15):", + " 0 (9) RESET:TIME: 2014-12-09-11-33-29", + " +1s067ms (1) 100 c0500020 -wifi_full_lock -wifi_scan", + " +3s297ms (2) 100 80400020 -wake_lock -screen", + " +30m02s075ms (1) 100 c0500020 wifi_signal_strength=4 wifi_suppl=completed", + " +30m03s012ms (2) 099 c0500020 temp=306 volt=4217", + " +33m48s967ms (1) 099 f8400020 +wifi_scan", + " +33m49s335ms (2) 098 f0400020 temp=324 -wifi_scan", + "Statistics since last charge:", + " Time on battery: 2h 21m 5s 622ms (12.0%) realtime, 7m 54s 146ms (0.7%) uptime", + " Time on battery screen off: 2h 5m 55s 3ms (1%) realtime, 7m 4s 5ms (7%) uptime", + " Total run time: 19h 38m 43s 650ms realtime, 17h 25m 32s 175ms uptime", + " All kernel wake locks:", + " Kernel Wake lock PowerManagerService.WakeLocks: 1h 3m 50s 5ms (8 times) realtime", + " Kernel Wake lock event0-2656 : 3m 49s 268ms (2399 times) realtime", + " Kernel Wake lock wlan_wd_wake: 3m 34s 639ms (1751 times) realtime", + " Kernel Wake lock wlan_rx_wake: 3m 19s 887ms (225 times) realtime", + " Kernel Wake lock wlan_tx_wake: 2m 19s 887ms (225 times) realtime", + " Kernel Wake lock tx_wake: 1m 19s 887ms (225 times) realtime", + " ", + " All partial wake locks:", + " Wake lock u0a7 NlpWakeLock: 8m 13s 203ms (1479 times) realtime", + " Wake lock u0a7 NlpCollectorWakeLock: 6m 29s 18ms (238 times) realtime", + " Wake lock u0a7 GCM_CONN_ALARM: 6m 8s 587ms (239 times) realtime", + " Wake lock 1000 *alarm*: 5m 11s 316ms (1469 times) realtime", + " Wake lock u10 xxx: 4m 11s 316ms (1469 times) realtime", + " Wake lock u30 cst: 2m 11s 316ms (1469 times) realtime", + " ", + " All wakeup reasons:", + " Wakeup reason 200:qcom,smd-rpm:222:fc4: 11m 49s 332ms (0 times) realtime", + " Wakeup reason 200:qcom,smd-rpm: 48s 45ms (0 times) realtime", + " Wakeup reason 2:qcom,smd-rpm:2:f0.qm,mm:22:fc4mi: 3s 417ms (0 times) realtime", + " Wakeup reason 188:qcom,smd-adsp:200:qcom,smd-rpm: 1s 656ms (0 times) realtime", + " Wakeup reason 58:qcom,smsm-modem:2:qcom,smd-rpm: 6m 16s 1ms (5 times) realtime", + " Wakeup reason 57:qcom,smd-modem:200:qcom,smd-rpm: 40s 995ms (0 times) realtime", + " Wakeup reason unknown: 8s 455ms (0 times) realtime", + " Wakeup reason 9:bcmsdh_sdmmc:2:qcomd-rpm:240:mso: 8m 5s 9ms (0 times) realtime", + " ", + " 0:", + " User activity: 2 other", + " Wake lock SCREEN_FROZEN realtime", + " Sensor 0: 9s 908ms realtime (1 times)", + " Sensor 1: 9s 997ms realtime (1 times)", + " Foreground for: 2h 21m 5s 622ms", + " Apk android:", + " 24 wakeup alarms", + " u0a9:", + " Mobile network: 8.1KB received, 1.6KB sent (packets 291 received, 342 sent)", + " Mobile radio active: 3m 43s 890ms (34.2%) 39x @ 354 mspp", + " Sensor 2: 12m 13s 15ms realtime (5 times)", + " Sensor 32: (not used)", + " Sensor 35: (not used)"); + + DumpsysBatteryStatsItem batteryStats = new DumpsysBatteryStatsParser().parse(inputBlock); + assertNotNull(batteryStats.getBatteryStatsSummaryItem()); + assertNotNull(batteryStats.getDetailedBatteryStatsItem()); + } +} + diff --git a/javatests/src/com/android/loganalysis/parser/DumpsysPackageStatsParserTest.java b/javatests/src/com/android/loganalysis/parser/DumpsysPackageStatsParserTest.java new file mode 100644 index 0000000..ee15b78 --- /dev/null +++ b/javatests/src/com/android/loganalysis/parser/DumpsysPackageStatsParserTest.java @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2017 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.AppVersionItem; +import com.android.loganalysis.item.DumpsysPackageStatsItem; + +import junit.framework.TestCase; + +import java.util.Arrays; +import java.util.List; + +/** Unit tests for {@link DumpsysPackageStatsParser} */ +public class DumpsysPackageStatsParserTest extends TestCase { + + /** Test that normal input is parsed. */ + public void testDumpsysPackageStatsParser() { + List inputBlock = + Arrays.asList( + "DUMP OF SERVICE package:", + "Package [com.google.android.calculator] (e075c9d):", + " userId=10071", + " secondaryCpuAbi=null", + " versionCode=73000302 minSdk=10000 targetSdk=10000", + " versionName=7.3 (3821978)", + " splits=[base]", + " Package [com.google.android.googlequicksearchbox] (607929e):", + " userId=10037", + " pkg=Package{af43294 com.google.android.googlequicksearchbox}", + " versionCode=300734793 minSdk=10000 targetSdk=10000", + " versionName=6.16.35.26.arm64", + " apkSigningVersion=2"); + + final DumpsysPackageStatsItem packagestats = + new DumpsysPackageStatsParser().parse(inputBlock); + assertEquals(2, packagestats.size()); + assertNotNull(packagestats.get("com.google.android.calculator")); + final AppVersionItem calculator = packagestats.get("com.google.android.calculator"); + assertEquals(73000302, calculator.getVersionCode()); + assertEquals("7.3 (3821978)", calculator.getVersionName()); + assertNotNull(packagestats.get("com.google.android.googlequicksearchbox")); + final AppVersionItem googlequicksearchbox = + packagestats.get("com.google.android.googlequicksearchbox"); + assertEquals(300734793, googlequicksearchbox.getVersionCode()); + assertEquals("6.16.35.26.arm64", googlequicksearchbox.getVersionName()); + } +} diff --git a/javatests/src/com/android/loganalysis/parser/DumpsysParserTest.java b/javatests/src/com/android/loganalysis/parser/DumpsysParserTest.java new file mode 100644 index 0000000..020c724 --- /dev/null +++ b/javatests/src/com/android/loganalysis/parser/DumpsysParserTest.java @@ -0,0 +1,143 @@ +/* + * Copyright (C) 2015 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.DumpsysItem; + +import junit.framework.TestCase; + +import java.util.Arrays; +import java.util.List; + +/** + * Unit tests for {@link DumpsysParser} + */ +public class DumpsysParserTest extends TestCase { + + /** + * Test that normal input is parsed. + */ + public void testDumpsysParser() { + List inputBlock = + Arrays.asList( + "DUMP OF SERVICE batterystats:", + "Battery History (37% used, 95KB used of 256KB, 166 strings using 15KB):", + " 0 (9) RESET:TIME: 2014-12-09-11-33-29", + " +1s067ms (1) 100 c0500020 -wifi_full_lock -wifi_scan", + " +3s297ms (2) 100 80400020 -wake_lock -screen", + " +30m02s075ms (1) 100 c0500020 wifi_signal_strength=4 wifi_suppl=completed", + " +30m03s012ms (2) 099 c0500020 temp=306 volt=4217", + " +33m48s967ms (1) 099 f8400020 +wifi_scan", + " +33m49s335ms (2) 098 f0400020 temp=324 -wifi_scan", + "Statistics since last charge:", + " Time on battery: 2h 21m 5s 622ms (12.0%) realtime, 7m 54s 146ms (0.7%) uptime", + " Time on battery screen off: 2h 5m 55s 3ms (1%) realtime, 7m 4s 5ms (7%) uptime", + " Total run time: 19h 38m 43s 650ms realtime, 17h 25m 32s 175ms uptime", + " All kernel wake locks:", + " Kernel Wake lock PowerManagerService.WakeLocks: 1h 3m 50s 5ms (8 times) realtime", + " Kernel Wake lock event0-2656 : 3m 49s 268ms (2399 times) realtime", + " Kernel Wake lock wlan_wd_wake: 3m 34s 639ms (1751 times) realtime", + " Kernel Wake lock wlan_rx_wake: 3m 19s 887ms (225 times) realtime", + " Kernel Wake lock wlan_tx_wake: 2m 19s 887ms (225 times) realtime", + " Kernel Wake lock tx_wake: 1m 19s 887ms (225 times) realtime", + " ", + " All partial wake locks:", + " Wake lock u0a7 NlpWakeLock: 8m 13s 203ms (1479 times) realtime", + " Wake lock u0a7 NlpCollectorWakeLock: 6m 29s 18ms (238 times) realtime", + " Wake lock u0a7 GCM_CONN_ALARM: 6m 8s 587ms (239 times) realtime", + " Wake lock 1000 *alarm*: 5m 11s 316ms (1469 times) realtime", + " Wake lock u10 xxx: 4m 11s 316ms (1469 times) realtime", + " Wake lock u30 cst: 2m 11s 316ms (1469 times) realtime", + " ", + " All wakeup reasons:", + " Wakeup reason 200:qcom,smd-rpm:222:fc4: 11m 49s 332ms (0 times) realtime", + " Wakeup reason 200:qcom,smd-rpm: 48s 45ms (0 times) realtime", + " Wakeup reason 2:qcom,smd-rpm:2:f0.qm,mm:22:fc4mi: 3s 417ms (0 times) realtime", + " Wakeup reason 188:qcom,smd-adsp:200:qcom,smd-rpm: 1s 656ms (0 times) realtime", + " Wakeup reason 58:qcom,smsm-modem:2:qcom,smd-rpm: 6m 16s 1ms (5 times) realtime", + " Wakeup reason 57:qcom,smd-modem:200:qcom,smd-rpm: 40s 995ms (0 times) realtime", + " Wakeup reason unknown: 8s 455ms (0 times) realtime", + " Wakeup reason 9:bcmsdh_sdmmc:2:qcomd-rpm:240:mso: 8m 5s 9ms (0 times) realtime", + " ", + " 0:", + " User activity: 2 other", + " Wake lock SCREEN_FROZEN realtime", + " Sensor 0: 9s 908ms realtime (1 times)", + " Sensor 1: 9s 997ms realtime (1 times)", + " Foreground for: 2h 21m 5s 622ms", + " Apk android:", + " 24 wakeup alarms", + " u0a9:", + " Mobile network: 8.1KB received, 1.6KB sent (packets 291 received, 342 sent)", + " Mobile radio active: 3m 43s 890ms (34.2%) 39x @ 354 mspp", + " Sensor 2: 12m 13s 15ms realtime (5 times)", + " Sensor 32: (not used)", + " Sensor 35: (not used)", + "DUMP OF SERVICE package:", + "Package [com.google.android.calculator] (e075c9d):", + " userId=10071", + " secondaryCpuAbi=null", + " versionCode=73000302 minSdk=10000 targetSdk=10000", + " versionName=7.3 (3821978)", + " splits=[base]", + "Package [com.google.android.googlequicksearchbox] (607929e):", + " userId=10037", + " pkg=Package{af43294 com.google.android.googlequicksearchbox}", + " versionCode=300734793 minSdk=10000 targetSdk=10000", + " versionName=6.16.35.26.arm64", + " apkSigningVersion=2", + "DUMP OF SERVICE procstats:", + "COMMITTED STATS FROM 2015-03-20-02-01-02 (checked in):", + " * com.android.systemui / u0a22 / v22:", + " TOTAL: 100% (159MB-160MB-161MB/153MB-153MB-154MB over 13)", + " Persistent: 100% (159MB-160MB-161MB/153MB-153MB-154MB over 13)", + " * com.google.process.gapps / u0a9 / v22:", + " TOTAL: 100% (22MB-24MB-25MB/18MB-19MB-20MB over 13)", + " Imp Fg: 100% (22MB-24MB-25MB/18MB-19MB-20MB over 13)", + "DUMP OF SERVICE wifi:", + "Wi-Fi is enabled", + "rec[0]: time=10-09 00:25:16.737 processed=DefaultState org=DeviceActiveState " + + "dest= what=155654(0x26006)", + "mScreenOff true", + " rec[0]: time=10-08 16:49:55.034 processed=WatchdogEnabledState org=OnlineState " + + "dest=OnlineWatchState what=135170(0x21002)", + "rec[30]: time=10-08 13:06:50.379 processed=DriverStartedState org=ConnectedState " + + "dest= what=131143(0x20047) (1)CMD_START_SCAN rt=4720806/7884852 10013 51 " + + "ic=0 proc(ms):14 onGoing full started:1444334810368,11 cnt=24 rssi=-127 f=-1 " + + "sc=0 link=-1 tx=1.5, 1.7, 0.0 rx=8.4 fiv=20000 [on:3266 tx:65 rx:556 " + + "period:1268] from screen [on:266962 period:266959]", + "rec[357]: time=10-08 13:10:13.199 processed=DriverStartedState org=ConnectedState " + + "dest= what=131143(0x20047) (-2)CMD_START_SCAN rt=4923625/8087671 10013 " + + "175 ic=0 proc(ms):2 onGoing full started:1444335011199,1999 cnt=24 rssi=-127 " + + "f=-1 sc=0 link=-1 tx=8.4, 1.7, 0.0 rx=6.7 fiv=20000 [on:0 tx:0 rx:0 period:990]" + + "from screen [on:467747 period:469779]", + "WifiConfigStore - Log Begin ----", + "10-08 11:09:14.653 - Event [IFNAME=wlan0 CTRL-EVENT-SCAN-STARTED ]", + "10-08 13:06:29.489 - Event [IFNAME=wlan0 CTRL-EVENT-DISCONNECTED " + + "bssid=9c:1c:12:c3:d0:72 reason=0]", + "10-08 13:06:22.280 - Event [IFNAME=wlan0 CTRL-EVENT-SCAN-STARTED ]", + "10-08 13:06:25.363 - Event [IFNAME=wlan0 CTRL-EVENT-SCAN-STARTED ]", + "10-08 13:08:15.018 - Event [IFNAME=wlan0 CTRL-EVENT-DISCONNECTED " + + "bssid=9c:1c:12:e8:72:d2 reason=3 locally_generated=1]", + "10-08 13:08:15.324 - wlan0: 442:IFNAME=wlan0 ENABLE_NETWORK 0 -> true"); + + DumpsysItem dumpsys = new DumpsysParser().parse(inputBlock); + assertNotNull(dumpsys.getBatteryStats()); + assertNotNull(dumpsys.getPackageStats()); + assertNotNull(dumpsys.getProcStats()); + assertNotNull(dumpsys.getWifiStats()); + } +} diff --git a/javatests/src/com/android/loganalysis/parser/DumpsysProcStatsParserTest.java b/javatests/src/com/android/loganalysis/parser/DumpsysProcStatsParserTest.java new file mode 100644 index 0000000..27bb7a4 --- /dev/null +++ b/javatests/src/com/android/loganalysis/parser/DumpsysProcStatsParserTest.java @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2015 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.DumpsysProcStatsItem; + +import junit.framework.TestCase; + +import java.util.Arrays; +import java.util.List; + +/** + * Unit tests for {@link DumpsysProcStatsParser} + */ +public class DumpsysProcStatsParserTest extends TestCase { + + /** + * Test that normal input is parsed. + */ + public void testDumpsysProcStatsParser() { + List inputBlock = Arrays.asList( + "COMMITTED STATS FROM 2015-03-20-02-01-02 (checked in):", + " * com.android.systemui / u0a22 / v22:", + " TOTAL: 100% (159MB-160MB-161MB/153MB-153MB-154MB over 13)", + " Persistent: 100% (159MB-160MB-161MB/153MB-153MB-154MB over 13)", + " * com.google.process.gapps / u0a9 / v22:", + " TOTAL: 100% (22MB-24MB-25MB/18MB-19MB-20MB over 13)", + " Imp Fg: 100% (22MB-24MB-25MB/18MB-19MB-20MB over 13)"); + + DumpsysProcStatsItem procstats = new DumpsysProcStatsParser().parse(inputBlock); + assertEquals("com.android.systemui", procstats.get("u0a22")); + assertEquals("com.google.process.gapps", procstats.get("u0a9")); + } +} + diff --git a/javatests/src/com/android/loganalysis/parser/DumpsysProcessMeminfoParserTest.java b/javatests/src/com/android/loganalysis/parser/DumpsysProcessMeminfoParserTest.java new file mode 100644 index 0000000..b7042d3 --- /dev/null +++ b/javatests/src/com/android/loganalysis/parser/DumpsysProcessMeminfoParserTest.java @@ -0,0 +1,104 @@ +/* + * Copyright (C) 2018 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 static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; + +import com.android.loganalysis.item.DumpsysProcessMeminfoItem; + +import org.junit.Test; + +import java.util.Arrays; +import java.util.List; + +/** Unit tests for {@link DumpsysProcessMeminfoParser} */ +public class DumpsysProcessMeminfoParserTest { + private static final String TEST_INPUT = + "time,28506638,177086152\n" + + "4,938,system_server,11,22,N/A,44,0,0,N/A,0,0,0,N/A,0,27613,14013,176602," + + "218228,0,0,122860,122860,1512,1412,5740,8664,0,0,154924,154924,27568," + + "13972,11916,53456,0,0,123008,123008,0,0,0,0,0,0,0,0,Dalvik Other,3662,0," + + "104,0,3660,0,0,0,Stack,1576,0,8,0,1576,0,0,0,Cursor,0,0,0,0,0,0,0,0," + + "Ashmem,156,0,20,0,148,0,0,0,Gfx dev,100,0,48,0,76,0,0,0,Other dev,116,0," + + "164,0,0,96,0,0,.so mmap,7500,2680,3984,21864,904,2680,0,0,.jar mmap,0,0,0," + + "0,0,0,0,0,.apk mmap,72398,71448,0,11736,0,71448,0,0,.ttf mmap,0,0,0,0,0,0," + + "0,0,.dex mmap,76874,46000,0,83644,40,46000,0,0,.oat mmap,8127,2684,64," + + "26652,0,2684,0,0,.art mmap,1991,48,972,10004,1544,48,0,0,Other mmap,137,0," + + "44,1024,4,52,0,0,EGL mtrack,0,0,0,0,0,0,0,0,GL mtrack,111,222,333,444,555," + + "666,777,888,"; + + private static final String INVALID_TEST_INPUT = "RANDOM,TEST,DATA\n234235345345"; + + // Test that normal input is parsed + @Test + public void testDumpsysProcessMeminfoParser() { + List inputBlock = Arrays.asList(TEST_INPUT.split("\n")); + DumpsysProcessMeminfoItem dump = new DumpsysProcessMeminfoParser().parse(inputBlock); + assertEquals(938, dump.getPid()); + assertEquals("system_server", dump.getProcessName()); + assertEquals( + Long.valueOf(11L), + dump.get(DumpsysProcessMeminfoItem.NATIVE).get(DumpsysProcessMeminfoItem.MAX)); + assertEquals( + Long.valueOf(22L), + dump.get(DumpsysProcessMeminfoItem.DALVIK).get(DumpsysProcessMeminfoItem.MAX)); + assertFalse( + dump.get(DumpsysProcessMeminfoItem.OTHER) + .containsKey(DumpsysProcessMeminfoItem.MAX)); + assertEquals( + Long.valueOf(44L), + dump.get(DumpsysProcessMeminfoItem.TOTAL).get(DumpsysProcessMeminfoItem.MAX)); + assertEquals( + Long.valueOf(218228L), + dump.get(DumpsysProcessMeminfoItem.TOTAL).get(DumpsysProcessMeminfoItem.PSS)); + assertEquals( + Long.valueOf(3662L), dump.get("Dalvik Other").get(DumpsysProcessMeminfoItem.PSS)); + assertEquals(Long.valueOf(111L), dump.get("GL mtrack").get(DumpsysProcessMeminfoItem.PSS)); + assertEquals( + Long.valueOf(222L), + dump.get("GL mtrack").get(DumpsysProcessMeminfoItem.SWAPPABLE_PSS)); + assertEquals( + Long.valueOf(333L), + dump.get("GL mtrack").get(DumpsysProcessMeminfoItem.SHARED_DIRTY)); + assertEquals( + Long.valueOf(444L), + dump.get("GL mtrack").get(DumpsysProcessMeminfoItem.SHARED_CLEAN)); + assertEquals( + Long.valueOf(555L), + dump.get("GL mtrack").get(DumpsysProcessMeminfoItem.PRIVATE_DIRTY)); + assertEquals( + Long.valueOf(666L), + dump.get("GL mtrack").get(DumpsysProcessMeminfoItem.PRIVATE_CLEAN)); + assertEquals( + Long.valueOf(777L), + dump.get("GL mtrack").get(DumpsysProcessMeminfoItem.SWAPPED_OUT)); + assertEquals( + Long.valueOf(888L), + dump.get("GL mtrack").get(DumpsysProcessMeminfoItem.SWAPPED_OUT_PSS)); + } + + // Test that the parser does not crash on invalid input and returns empty data + @Test + public void testDumpsysProcessMeminfoParserInvalid() { + List inputBlock = Arrays.asList(INVALID_TEST_INPUT.split("\n")); + DumpsysProcessMeminfoItem dump = new DumpsysProcessMeminfoParser().parse(inputBlock); + assertNull(dump.getProcessName()); + assertTrue(dump.get(DumpsysProcessMeminfoItem.TOTAL).isEmpty()); + } +} diff --git a/javatests/src/com/android/loganalysis/parser/DumpsysWifiStatsParserTest.java b/javatests/src/com/android/loganalysis/parser/DumpsysWifiStatsParserTest.java new file mode 100644 index 0000000..f52e432 --- /dev/null +++ b/javatests/src/com/android/loganalysis/parser/DumpsysWifiStatsParserTest.java @@ -0,0 +1,103 @@ +/* + * Copyright (C) 2016 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.DumpsysWifiStatsItem; + +import junit.framework.TestCase; + +import java.util.Arrays; +import java.util.List; + +/** + * Unit tests for {@link DumpsysWifiStatsParser} + */ +public class DumpsysWifiStatsParserTest extends TestCase { + + /** + * Test that normal input is parsed. + */ + public void testDumpsysWifiStatsParser() { + List inputBlock = Arrays.asList( + "Wi-Fi is enabled", + "rec[0]: time=10-09 00:25:16.737 processed=DefaultState org=DeviceActiveState " + + "dest= what=155654(0x26006)", + "mScreenOff true", + " rec[0]: time=10-08 16:49:55.034 processed=WatchdogEnabledState org=OnlineState " + + "dest=OnlineWatchState what=135170(0x21002)", + "rec[30]: time=10-08 13:06:50.379 processed=DriverStartedState org=ConnectedState " + + "dest= what=131143(0x20047) (1)CMD_START_SCAN rt=4720806/7884852 10013 51 " + + "ic=0 proc(ms):14 onGoing full started:1444334810368,11 cnt=24 rssi=-127 f=-1 " + + "sc=0 link=-1 tx=1.5, 1.7, 0.0 rx=8.4 fiv=20000 [on:3266 tx:65 rx:556 " + + "period:1268] from screen [on:266962 period:266959]", + "rec[357]: time=10-08 13:10:13.199 processed=DriverStartedState org=ConnectedState " + + "dest= what=131143(0x20047) (-2)CMD_START_SCAN rt=4923625/8087671 10013 " + + "175 ic=0 proc(ms):2 onGoing full started:1444335011199,1999 cnt=24 rssi=-127 " + + "f=-1 sc=0 link=-1 tx=8.4, 1.7, 0.0 rx=6.7 fiv=20000 [on:0 tx:0 rx:0 period:990] " + + "from screen [on:467747 period:469779]", + "WifiConfigStore - Log Begin ----", + "10-08 11:09:14.653 - Event [IFNAME=wlan0 CTRL-EVENT-SCAN-STARTED ]", + "10-08 13:06:29.489 - Event [IFNAME=wlan0 CTRL-EVENT-DISCONNECTED " + + "bssid=9c:1c:12:c3:d0:72 reason=0]", + "10-08 13:06:22.280 - Event [IFNAME=wlan0 CTRL-EVENT-SCAN-STARTED ]", + "10-08 13:06:25.363 - Event [IFNAME=wlan0 CTRL-EVENT-SCAN-STARTED ]", + "10-08 13:08:15.018 - Event [IFNAME=wlan0 CTRL-EVENT-DISCONNECTED " + + "bssid=9c:1c:12:e8:72:d2 reason=3 locally_generated=1]", + "10-08 13:08:15.324 - wlan0: 442:IFNAME=wlan0 ENABLE_NETWORK 0 -> true", + "01-21 13:17:23.1 - Event [IFNAME=wlan0 Trying to associate with SSID 'WL-power']", + "01-21 13:18:23.1 - Event [IFNAME=wlan0 Trying to associate with SSID 'WL-power']", + "01-21 13:18:23.1 - Event [IFNAME=wlan0 Trying to associate with SSID 'WL-power']"); + + DumpsysWifiStatsItem wifiStats = new DumpsysWifiStatsParser().parse(inputBlock); + assertEquals(2, wifiStats.getNumWifiDisconnects()); + assertEquals(3, wifiStats.getNumWifiScans()); + assertEquals(3, wifiStats.getNumWifiAssociations()); + } + + /** + * Test that input with no wifi disconnect and wifi scans. + */ + public void testDumpsysWifiStatsParser_no_wifi_scan_disconnect() { + List inputBlock = Arrays.asList( + "Wi-Fi is enabled", + "rec[0]: time=10-09 00:25:16.737 processed=DefaultState org=DeviceActiveState " + + "dest= what=155654(0x26006)", + "mScreenOff true", + " rec[0]: time=10-08 16:49:55.034 processed=WatchdogEnabledState org=OnlineState " + + "dest=OnlineWatchState what=135170(0x21002)", + "rec[30]: time=10-08 13:06:50.379 processed=DriverStartedState org=ConnectedState " + + "dest= what=131143(0x20047) (1)CMD_START_SCAN rt=4720806/7884852 10013 51 " + + "ic=0 proc(ms):14 onGoing full started:1444334810368,11 cnt=24 rssi=-127 f=-1 " + + "sc=0 link=-1 tx=1.5, 1.7, 0.0 rx=8.4 fiv=20000 [on:3266 tx:65 rx:556 " + + "period:1268] from screen [on:266962 period:266959]", + "rec[357]: time=10-08 13:10:13.199 processed=DriverStartedState org=ConnectedState " + + "dest= what=131143(0x20047) (-2)CMD_START_SCAN rt=4923625/8087671 10013 " + + "175 ic=0 proc(ms):2 onGoing full started:1444335011199,1999 cnt=24 rssi=-127 " + + "f=-1 sc=0 link=-1 tx=8.4, 1.7, 0.0 rx=6.7 fiv=20000 [on:0 tx:0 rx:0 period:990]" + + "from screen [on:467747 period:469779]", + "WifiConfigStore - Log Begin ----", + "10-08 13:07:37.777 - wlan0: 384:IFNAME=wlan0 ENABLE_NETWORK 4 -> true", + "10-08 13:07:37.789 - wlan0: 388:IFNAME=wlan0 SAVE_CONFIG -> true", + "10-08 13:08:15.065 - wlan0: 427:IFNAME=wlan0 SET ps 1 -> true", + "10-08 13:08:15.179 - wlan0: 432:IFNAME=wlan0 SET pno 1 -> true"); + + DumpsysWifiStatsItem wifiStats = new DumpsysWifiStatsParser().parse(inputBlock); + assertEquals(0, wifiStats.getNumWifiDisconnects()); + assertEquals(0, wifiStats.getNumWifiScans()); + assertEquals(0, wifiStats.getNumWifiAssociations()); + } +} + diff --git a/javatests/src/com/android/loganalysis/parser/DvmLockSampleParserTest.java b/javatests/src/com/android/loganalysis/parser/DvmLockSampleParserTest.java new file mode 100644 index 0000000..cb85999 --- /dev/null +++ b/javatests/src/com/android/loganalysis/parser/DvmLockSampleParserTest.java @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2014 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.DvmLockSampleItem; +import com.android.loganalysis.parser.DvmLockSampleParser; + +import junit.framework.TestCase; +import java.util.Arrays; +import java.util.List; + +public class DvmLockSampleParserTest extends TestCase { + + /** + * Sanity-check our DVM lock line parser against a single log line + */ + public void testSingleDvmLine() { + List input = Arrays.asList( + "[android.support.test.aupt,0,Instr: android.support.test.aupt,75," + + "AccessibilityCache.java,256,-,96,15]"); + + DvmLockSampleItem item = new DvmLockSampleParser().parse(input); + assertEquals("android.support.test.aupt", item.getAttribute(DvmLockSampleItem.PROCESS_NAME)); + assertEquals(Boolean.FALSE, item.getAttribute(DvmLockSampleItem.SENSITIVITY_FLAG)); + assertEquals("Instr: android.support.test.aupt", item.getAttribute(DvmLockSampleItem.WAITING_THREAD_NAME)); + assertEquals(75, item.getAttribute(DvmLockSampleItem.WAIT_TIME)); + assertEquals("AccessibilityCache.java", item.getAttribute(DvmLockSampleItem.WAITING_SOURCE_FILE)); + assertEquals(256, item.getAttribute(DvmLockSampleItem.WAITING_SOURCE_LINE)); + assertEquals("AccessibilityCache.java", item.getAttribute(DvmLockSampleItem.OWNER_FILE_NAME)); + assertEquals(96, item.getAttribute(DvmLockSampleItem.OWNER_ACQUIRE_SOURCE_LINE)); + assertEquals(15, item.getAttribute(DvmLockSampleItem.SAMPLE_PERCENTAGE)); + } +} diff --git a/javatests/src/com/android/loganalysis/parser/EventsLogParserTest.java b/javatests/src/com/android/loganalysis/parser/EventsLogParserTest.java new file mode 100644 index 0000000..6956d16 --- /dev/null +++ b/javatests/src/com/android/loganalysis/parser/EventsLogParserTest.java @@ -0,0 +1,260 @@ +/* + * Copyright (C) 2016 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.LatencyItem; +import com.android.loganalysis.item.TransitionDelayItem; + +import junit.framework.TestCase; + +import java.io.BufferedReader; +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileWriter; +import java.io.IOException; +import java.io.InputStreamReader; +import java.util.Arrays; +import java.util.List; + +/** + * Unit tests for {@link EventsLogParser}. + */ +public class EventsLogParserTest extends TestCase { + + private File mTempFile = null; + + @Override + protected void tearDown() throws Exception { + mTempFile.delete(); + } + + /** + * Test for empty events logs passed to the transition delay parser + */ + public void testEmptyEventsLog() throws IOException { + List lines = Arrays.asList(""); + List transitionItems = + new EventsLogParser().parseTransitionDelayInfo(readInputBuffer(getTempFile(lines))); + assertEquals("Transition Delay items list should be empty", 0,transitionItems.size()); + } + + /** + * Test for no transition delay info in the events log + */ + public void testNoTransitionDelayInfo() throws IOException { + List lines = Arrays + .asList( + "08-25 12:56:15.850 1152 8968 I am_focused_stack: [0,0,1,appDied setFocusedActivity]", + "08-25 12:56:15.850 1152 8968 I wm_task_moved: [6,1,1]", + "08-25 12:56:15.852 1152 8968 I am_focused_activity: [0,com.google.android.apps.nexuslauncher/.NexusLauncherActivity,appDied]", + "08-25 12:56:15.852 1152 8968 I wm_task_removed: [27,removeTask]", + "08-25 12:56:15.852 1152 8968 I wm_stack_removed: 1"); + List transitionItems = + new EventsLogParser().parseTransitionDelayInfo(readInputBuffer(getTempFile(lines))); + assertEquals("Transition Delay items list should be empty", 0, + transitionItems.size()); + } + + /** + * Test for Cold launch transition delay and starting window delay info + */ + public void testValidColdTransitionDelay() throws IOException { + List lines = Arrays + .asList("09-18 23:56:19.376 1140 1221 I sysui_multi_action: [319,51,321,50,322,190,325,670,757,761,758,7,759,1,806,com.google.android.calculator,871,com.android.calculator2.Calculator,904,com.google.android.apps.nexuslauncher,905,0,945,41]", + "09-18 23:56:19.376 1140 1221 I sysui_multi_action: [319,51,321,50,322,190,325,670,757,761,758,7,759,1,806,com.google.android.calculator,871,com.android.calculator2.Calculator,905,0,945,41]"); + List transitionItems = + new EventsLogParser().parseTransitionDelayInfo(readInputBuffer(getTempFile(lines))); + assertEquals("Startinng Window Delay items list should have two item", 2, + transitionItems.size()); + assertEquals("Component name not parsed correctly", + "com.google.android.calculator/com.android.calculator2.Calculator", + transitionItems.get(0).getComponentName()); + assertEquals("Transition delay is not parsed correctly", Long.valueOf(51), + transitionItems.get(0).getTransitionDelay()); + assertEquals("Starting window delay is not parsed correctly", Long.valueOf(50), + transitionItems.get(0).getStartingWindowDelay()); + assertEquals("Date and time is not parsed correctly", "09-18 23:56:19.376", + transitionItems.get(0).getDateTime()); + } + + /** + * Test for Hot launch transition delay and starting window delay info + */ + public void testValidHotTransitionDelay() throws IOException { + List lines = Arrays + .asList("09-18 23:56:19.376 1140 1221 I sysui_multi_action: [319,51,321,50,322,190,325,670,757,761,758,7,759,1,806,com.google.android.calculator,871,com.android.calculator2.Calculator,904,com.google.android.apps.nexuslauncher,905,0]", + "09-18 23:56:19.376 1140 1221 I sysui_multi_action: [319,51,321,50,322,190,325,670,757,761,758,7,759,1,806,com.google.android.calculator,871,com.android.calculator2.Calculator,905,0]", + "09-19 02:26:30.182 1143 1196 I sysui_multi_action: [319,87,322,75,325,212,757,761,758,9,759,2,806,com.google.android.apps.nexuslauncher,871,com.google.android.apps.nexuslauncher.NexusLauncherActivity,904,com.google.android.apps.nexuslauncher,905,0]", + "09-19 02:26:30.182 1143 1196 I sysui_multi_action: [319,87,322,75,325,212,757,761,758,9,759,2,806,com.google.android.apps.nexuslauncher,871,com.google.android.apps.nexuslauncher.NexusLauncherActivity,905,0]"); + List transitionItems = + new EventsLogParser().parseTransitionDelayInfo(readInputBuffer(getTempFile(lines))); + assertEquals("Transition Delay items list should have four item", 4, + transitionItems.size()); + assertEquals("Component name not parsed correctly", + "com.google.android.calculator/com.android.calculator2.Calculator", + transitionItems.get(0).getComponentName()); + assertEquals("Transition delay is not parsed correctly", Long.valueOf(51), + transitionItems.get(0).getTransitionDelay()); + assertEquals("Date is not parsed correctly", "09-18 23:56:19.376", + transitionItems.get(0).getDateTime()); + } + + /** + * Test for same app transition delay items order after parsing from the events log + */ + public void testTransitionDelayOrder() throws IOException { + List lines = Arrays + .asList("09-18 23:56:19.376 1140 1221 I sysui_multi_action: [319,51,321,59,322,190,325,670,757,761,758,7,759,1,806,com.google.android.calculator,871,com.android.calculator2.Calculator,904,com.google.android.apps.nexuslauncher,905,0,945,41]", + "09-18 23:59:18.380 1140 1221 I sysui_multi_action: [319,55,321,65,322,190,325,670,757,761,758,7,759,1,806,com.google.android.calculator,871,com.android.calculator2.Calculator,905,0,945,41]"); + List transitionItems = + new EventsLogParser().parseTransitionDelayInfo(readInputBuffer(getTempFile(lines))); + assertEquals("Transition Delay items list should have two items", 2, + transitionItems.size()); + assertEquals("Transition delay for the first item is not set correct", Long.valueOf(59), + transitionItems.get(0).getStartingWindowDelay()); + assertEquals("Transition delay for the second item is not set correct", Long.valueOf(65), + transitionItems.get(1).getStartingWindowDelay()); + } + + /** + * Test for two different different apps transition delay items + */ + public void testDifferentAppTransitionDelay() throws IOException { + List lines = Arrays + .asList("09-18 23:56:19.376 1140 1221 I sysui_multi_action: [319,51,321,50,322,190,325,670,757,761,758,7,759,1,806,com.google.android.calculator,871,com.android.calculator2.Calculator,904,com.google.android.apps.nexuslauncher,905,0]", + "09-19 02:26:30.182 1143 1196 I sysui_multi_action: [319,87,322,75,325,212,757,761,758,9,759,2,806,com.google.android.apps.nexuslauncher,871,com.google.android.apps.nexuslauncher.NexusLauncherActivity,904,com.google.android.apps.nexuslauncher,905,0]"); + List transitionItems = + new EventsLogParser().parseTransitionDelayInfo(readInputBuffer(getTempFile(lines))); + assertEquals("Transition Delay items list should have two items", 2, + transitionItems.size()); + assertEquals("Calculator is not the first transition delay item", + "com.google.android.calculator/com.android.calculator2.Calculator", + transitionItems.get(0).getComponentName()); + assertEquals("Maps is not the second transition delay item", + "com.google.android.apps.nexuslauncher/" + + "com.google.android.apps.nexuslauncher.NexusLauncherActivity", + transitionItems.get(1).getComponentName()); + } + + /** + * Test for invalid transition delay items pattern having different code. + */ + public void testInvalidTransitionPattern() throws IOException { + List lines = Arrays + .asList("01-02 08:11:58.691 934 986 I sysui_multi_action: a[319,48,322,82,325,84088,757,761,758,9,759,4,807,com.google.android.calculator,871,com.android.calculator2.Calculator,905,0]", + "01-02 08:12:03.639 934 970 I sysui_multi_action: [757,803,799,window_time_0,802,5]", + "01-02 08:12:10.849 934 986 I sysui_multi_action: 319,42,321,59,322,208,325,84100,757,761,758,9,759,4,806,com.google.android.apps.maps,871,com.google.android.maps.MapsActivity,905,0]", + "01-02 08:12:16.895 1446 1446 I sysui_multi_action: [757,803,799,overview_trigger_nav_btn,802,1]", + "01-02 08:12:16.895 1446 1446 I sysui_multi_action: [757,803,799,overview_source_app,802,1]", + "01-02 08:12:16.895 1446 1446 I sysui_multi_action: [757,804,799,overview_source_app_index,801,8,802,1]"); + List transitionItems = + new EventsLogParser().parseTransitionDelayInfo(readInputBuffer(getTempFile(lines))); + assertEquals("Transition Delay items list should be empty", 0, + transitionItems.size()); + } + + /** + * Test for valid latency item + */ + public void testValidLatencyInfo() throws IOException { + List lines = Arrays + .asList("08-25 13:01:19.412 1152 9031 I am_restart_activity: [com.google.android.gm/.ConversationListActivityGmail,0,85290699,38]", + "08-25 13:01:19.437 1152 1226 I sysui_action: [321,85]", + "08-25 13:01:19.437 1152 1226 I sysui_action: [320,1]", + "08-25 13:01:19.437 1152 1226 I sysui_action: [319,85]", + "08-25 12:56:15.850 1152 8968 I am_focused_stack: [0,0,1,appDied setFocusedActivity]", + "09-19 11:53:16.893 1080 1160 I sysui_latency: [1,50]"); + List latencyItems = + new EventsLogParser().parseLatencyInfo(readInputBuffer(getTempFile(lines))); + assertEquals("One latency item should present in the list", 1, latencyItems.size()); + assertEquals("Action Id is not correct", 1, latencyItems.get(0).getActionId()); + assertEquals("Delay is not correct", 50L, latencyItems.get(0).getDelay()); + } + + /** + * Test for empty delay info + */ + public void testInvalidLatencyInfo() throws IOException { + List lines = Arrays + .asList("08-25 13:01:19.412 1152 9031 I am_restart_activity: [com.google.android.gm/.ConversationListActivityGmail,0,85290699,38]", + "08-25 13:01:19.437 1152 1226 I sysui_action: [321,85]", + "08-25 13:01:19.437 1152 1226 I sysui_action: [320,1]", + "08-25 13:01:19.437 1152 1226 I sysui_action: [319,85]", + "08-25 12:56:15.850 1152 8968 I am_focused_stack: [0,0,1,appDied setFocusedActivity]", + "09-19 11:53:16.893 1080 1160 I sysui_latency: [1]"); + List latencyItems = + new EventsLogParser().parseLatencyInfo(readInputBuffer(getTempFile(lines))); + assertEquals("Latency items list should be empty", 0, latencyItems.size()); + } + + /** + * Test for empty latency info + */ + public void testEmptyLatencyInfo() throws IOException { + List lines = Arrays + .asList("08-25 13:01:19.412 1152 9031 I am_restart_activity: [com.google.android.gm/.ConversationListActivityGmail,0,85290699,38]", + "08-25 13:01:19.437 1152 1226 I sysui_action: [321,85]", + "08-25 13:01:19.437 1152 1226 I sysui_action: [320,1]", + "08-25 13:01:19.437 1152 1226 I sysui_action: [319,85]", + "08-25 12:56:15.850 1152 8968 I am_focused_stack: [0,0,1,appDied setFocusedActivity]", + "09-19 11:53:16.893 1080 1160 I sysui_latency: []"); + List latencyItems = + new EventsLogParser().parseLatencyInfo(readInputBuffer(getTempFile(lines))); + assertEquals("Latency items list should be empty", 0, latencyItems.size()); + } + + + /** + * Test for order of the latency items + */ + public void testLatencyInfoOrder() throws IOException { + List lines = Arrays + .asList("09-19 11:53:16.893 1080 1160 I sysui_latency: [1,50]", + "08-25 13:01:19.437 1152 1226 I sysui_action: [321,85]", + "08-25 13:01:19.437 1152 1226 I sysui_action: [320,1]", + "08-25 13:01:19.437 1152 1226 I sysui_action: [319,85]", + "08-25 12:56:15.850 1152 8968 I am_focused_stack: [0,0,1,appDied setFocusedActivity]", + "09-19 11:53:16.893 1080 1160 I sysui_latency: [2,100]"); + List latencyItems = + new EventsLogParser().parseLatencyInfo(readInputBuffer(getTempFile(lines))); + assertEquals("Latency list should have 2 items", 2, latencyItems.size()); + assertEquals("First latency id is not 1", 1, latencyItems.get(0).getActionId()); + assertEquals("Second latency id is not 2", 2, latencyItems.get(1).getActionId()); + } + + /** + * Write list of strings to file and use it for testing. + */ + public File getTempFile(List sampleEventsLogs) throws IOException { + mTempFile = File.createTempFile("events_logcat", ".txt"); + BufferedWriter out = new BufferedWriter(new FileWriter(mTempFile)); + for (String line : sampleEventsLogs) { + out.write(line); + out.newLine(); + } + out.close(); + return mTempFile; + } + + /** + * Reader to read the input from the given temp file + */ + public BufferedReader readInputBuffer(File tempFile) throws IOException { + return (new BufferedReader(new InputStreamReader(new FileInputStream(tempFile)))); + } +} diff --git a/javatests/src/com/android/loganalysis/parser/GfxInfoParserTest.java b/javatests/src/com/android/loganalysis/parser/GfxInfoParserTest.java new file mode 100644 index 0000000..fcd053b --- /dev/null +++ b/javatests/src/com/android/loganalysis/parser/GfxInfoParserTest.java @@ -0,0 +1,358 @@ +/* + * Copyright (C) 2015 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.GfxInfoItem; + +import junit.framework.TestCase; + +import java.util.Arrays; +import java.util.List; + +public class GfxInfoParserTest extends TestCase { + + /** + * Tests gfxinfo output from M with single process. + */ + public void testSingleProcess() { + List input = Arrays.asList( + "** Graphics info for pid 853 [com.google.android.leanbacklauncher] **", + "", + "Stats since: 13370233957ns", + "Total frames rendered: 20391", + "Janky frames: 785 (3.85%)", + "90th percentile: 9ms", + "95th percentile: 14ms", + "99th percentile: 32ms", + "Number Missed Vsync: 155", + "Number High input latency: 0", + "Number Slow UI thread: 469", + "Number Slow bitmap uploads: 65", + "Number Slow issue draw commands: 153", + "", + "Caches:", + "Current memory usage / total memory usage (bytes):", + " TextureCache 16055224 / 50331648", + " LayerCache 0 / 33554432 (numLayers = 0)", + " Layers total 0 (numLayers = 0)", + " RenderBufferCache 0 / 2097152", + " GradientCache 0 / 838860", + " PathCache 0 / 25165824", + " TessellationCache 1048296 / 1048576", + " TextDropShadowCache 0 / 4194304", + " PatchCache 0 / 131072", + " FontRenderer 0 A8 524288 / 524288", + " FontRenderer 0 RGBA 0 / 0", + " FontRenderer 0 total 524288 / 524288", + "Other:", + " FboCache 0 / 0", + "Total memory usage:", + " 17627808 bytes, 16.81 MB", + "", + "Profile data in ms:", + "", + "\tcom.google.android.leanbacklauncher/com.google.android.leanbacklauncher.MainActivity/android.view.ViewRootImpl@8dc465 (visibility=8)", + "Stats since: 13370233957ns", + "Total frames rendered: 20391", + "Janky frames: 785 (3.85%)", + "90th percentile: 9ms", + "95th percentile: 14ms", + "99th percentile: 32ms", + "Number Missed Vsync: 155", + "Number High input latency: 0", + "Number Slow UI thread: 469", + "Number Slow bitmap uploads: 65", + "Number Slow issue draw commands: 153", + "", + "View hierarchy:", + "", + " com.google.android.leanbacklauncher/com.google.android.leanbacklauncher.MainActivity/android.view.ViewRootImpl@8dc465", + " 220 views, 177.61 kB of display lists", + "", + "", + "Total ViewRootImpl: 1", + "Total Views: 220", + "Total DisplayList: 177.61 kB"); + + GfxInfoItem item = new GfxInfoParser().parse(input); + + assertEquals(1, item.getPids().size()); + assertEquals("com.google.android.leanbacklauncher", item.getName(853)); + assertEquals(20391, item.getTotalFrames(853)); + assertEquals(785, item.getJankyFrames(853)); + assertEquals(9, item.getPrecentile90(853)); + assertEquals(14, item.getPrecentile95(853)); + assertEquals(32, item.getPrecentile99(853)); + } + + /** + * Test gfxinfo output from M with multiple processes. + */ + public void testMultipleProcesses() { + List input = Arrays.asList( + "Applications Graphics Acceleration Info:", + "Uptime: 6127679 Realtime: 6127679", + "", + "** Graphics info for pid 844 [com.google.android.leanbacklauncher] **", + "", + "Stats since: 12167093145ns", + "Total frames rendered: 1690", + "Janky frames: 125 (7.40%)", + "90th percentile: 13ms", + "95th percentile: 19ms", + "99th percentile: 48ms", + "Number Missed Vsync: 17", + "Number High input latency: 0", + "Number Slow UI thread: 32", + "Number Slow bitmap uploads: 20", + "Number Slow issue draw commands: 67", + "", + "Caches:", + "Current memory usage / total memory usage (bytes):", + " TextureCache 16550096 / 50331648", + " LayerCache 0 / 33554432 (numLayers = 0)", + " Layers total 0 (numLayers = 0)", + " RenderBufferCache 0 / 2097152", + " GradientCache 0 / 838860", + " PathCache 0 / 25165824", + " TessellationCache 350424 / 1048576", + " TextDropShadowCache 0 / 4194304", + " PatchCache 0 / 131072", + " FontRenderer 0 A8 524288 / 524288", + " FontRenderer 0 RGBA 0 / 0", + " FontRenderer 0 total 524288 / 524288", + "Other:", + " FboCache 0 / 0", + "Total memory usage:", + " 17424808 bytes, 16.62 MB", + "", + "Profile data in ms:", + "", + "\tcom.google.android.leanbacklauncher/com.google.android.leanbacklauncher.MainActivity/android.view.ViewRootImpl@178d02b (visibility=0)", + "Stats since: 12167093145ns", + "Total frames rendered: 1690", + "Janky frames: 125 (7.40%)", + "90th percentile: 13ms", + "95th percentile: 19ms", + "99th percentile: 48ms", + "Number Missed Vsync: 17", + "Number High input latency: 0", + "Number Slow UI thread: 32", + "Number Slow bitmap uploads: 20", + "Number Slow issue draw commands: 67", + "", + "View hierarchy:", + "", + " com.google.android.leanbacklauncher/com.google.android.leanbacklauncher.MainActivity/android.view.ViewRootImpl@178d02b", + " 221 views, 207.24 kB of display lists", + "", + "", + "Total ViewRootImpl: 1", + "Total Views: 221", + "Total DisplayList: 207.24 kB", + "", + "", + "** Graphics info for pid 1881 [com.android.vending] **", + "", + "Stats since: 6092969986095ns", + "Total frames rendered: 693", + "Janky frames: 62 (8.95%)", + "90th percentile: 16ms", + "95th percentile: 26ms", + "99th percentile: 81ms", + "Number Missed Vsync: 17", + "Number High input latency: 0", + "Number Slow UI thread: 30", + "Number Slow bitmap uploads: 4", + "Number Slow issue draw commands: 13", + "", + "Caches:", + "Current memory usage / total memory usage (bytes):", + " TextureCache 7369504 / 50331648", + " LayerCache 0 / 33554432 (numLayers = 0)", + " Layers total 0 (numLayers = 0)", + " RenderBufferCache 0 / 2097152", + " GradientCache 0 / 838860", + " PathCache 0 / 25165824", + " TessellationCache 0 / 1048576", + " TextDropShadowCache 0 / 4194304", + " PatchCache 0 / 131072", + " FontRenderer 0 A8 524288 / 524288", + " FontRenderer 0 RGBA 0 / 0", + " FontRenderer 0 total 524288 / 524288", + "Other:", + " FboCache 0 / 0", + "Total memory usage:", + " 7893792 bytes, 7.53 MB", + "", + "Profile data in ms:", + "", + "\tcom.android.vending/com.google.android.finsky.activities.MainActivity/android.view.ViewRootImpl@5bd0cb2 (visibility=8)", + "Stats since: 6092969986095ns", + "Total frames rendered: 693", + "Janky frames: 62 (8.95%)", + "90th percentile: 16ms", + "95th percentile: 26ms", + "99th percentile: 81ms", + "Number Missed Vsync: 17", + "Number High input latency: 0", + "Number Slow UI thread: 30", + "Number Slow bitmap uploads: 4", + "Number Slow issue draw commands: 13", + "", + "View hierarchy:", + "", + " com.android.vending/com.google.android.finsky.activities.MainActivity/android.view.ViewRootImpl@5bd0cb2", + " 195 views, 157.71 kB of display lists", + "", + "", + "Total ViewRootImpl: 1", + "Total Views: 195", + "Total DisplayList: 157.71 kB", + "", + "", + "** Graphics info for pid 2931 [com.google.android.videos] **", + "", + "Stats since: 6039768250261ns", + "Total frames rendered: 107", + "Janky frames: 42 (39.25%)", + "90th percentile: 48ms", + "95th percentile: 65ms", + "99th percentile: 113ms", + "Number Missed Vsync: 9", + "Number High input latency: 0", + "Number Slow UI thread: 28", + "Number Slow bitmap uploads: 8", + "Number Slow issue draw commands: 20", + "", + "Caches:", + "Current memory usage / total memory usage (bytes):", + " TextureCache 7880000 / 50331648", + " LayerCache 0 / 33554432 (numLayers = 0)", + " Layers total 0 (numLayers = 0)", + " RenderBufferCache 0 / 2097152", + " GradientCache 0 / 838860", + " PathCache 0 / 25165824", + " TessellationCache 0 / 1048576", + " TextDropShadowCache 0 / 4194304", + " PatchCache 0 / 131072", + " FontRenderer 0 A8 524288 / 524288", + " FontRenderer 0 RGBA 0 / 0", + " FontRenderer 0 total 524288 / 524288", + "Other:", + " FboCache 0 / 0", + "Total memory usage:", + " 8404288 bytes, 8.01 MB", + "", + "Profile data in ms:", + "", + "\tcom.google.android.videos/com.google.android.videos.pano.activity.PanoHomeActivity/android.view.ViewRootImpl@3d96e69 (visibility=8)", + "Stats since: 6039768250261ns", + "Total frames rendered: 107", + "Janky frames: 42 (39.25%)", + "90th percentile: 48ms", + "95th percentile: 65ms", + "99th percentile: 113ms", + "Number Missed Vsync: 9", + "Number High input latency: 0", + "Number Slow UI thread: 28", + "Number Slow bitmap uploads: 8", + "Number Slow issue draw commands: 20", + "", + "View hierarchy:", + "", + " com.google.android.videos/com.google.android.videos.pano.activity.PanoHomeActivity/android.view.ViewRootImpl@3d96e69", + " 219 views, 173.57 kB of display lists", + "", + "", + "Total ViewRootImpl: 1", + "Total Views: 219", + "Total DisplayList: 173.57 kB"); + + GfxInfoItem item = new GfxInfoParser().parse(input); + + assertEquals(3, item.getPids().size()); + assertEquals("com.google.android.leanbacklauncher", item.getName(844)); + assertEquals(1690, item.getTotalFrames(844)); + assertEquals(125, item.getJankyFrames(844)); + assertEquals(13, item.getPrecentile90(844)); + assertEquals(19, item.getPrecentile95(844)); + assertEquals(48, item.getPrecentile99(844)); + assertEquals("com.android.vending", item.getName(1881)); + assertEquals(693, item.getTotalFrames(1881)); + assertEquals(62, item.getJankyFrames(1881)); + assertEquals(16, item.getPrecentile90(1881)); + assertEquals(26, item.getPrecentile95(1881)); + assertEquals(81, item.getPrecentile99(1881)); + assertEquals("com.google.android.videos", item.getName(2931)); + assertEquals(107, item.getTotalFrames(2931)); + assertEquals(42, item.getJankyFrames(2931)); + assertEquals(48, item.getPrecentile90(2931)); + assertEquals(65, item.getPrecentile95(2931)); + assertEquals(113, item.getPrecentile99(2931)); + } + + /** + * Test gfxinfo output from L with single process. + * In L, gfxinfo does not contain Jank number information. + * This method tests that GfxInfoParser silently ignores such outputs. + */ + public void testSingleProcessInL() { + List input = Arrays.asList( + "** Graphics info for pid 1924 [com.google.android.leanbacklauncher] **", + "", + "Caches:", + "Current memory usage / total memory usage (bytes):", + " TextureCache 19521592 / 50331648", + " LayerCache 14745600 / 50331648 (numLayers = 5)", + " Layer size 512x512; isTextureLayer()=0; texid=392 fbo=0; refs=1", + " Layer size 512x448; isTextureLayer()=0; texid=377 fbo=0; refs=1", + " Layer size 1920x832; isTextureLayer()=0; texid=360 fbo=0; refs=1", + " Layer size 1920x512; isTextureLayer()=0; texid=14 fbo=0; refs=1", + " Layer size 1920x320; isTextureLayer()=0; texid=393 fbo=0; refs=1", + " Layers total 14745600 (numLayers = 5)", + " RenderBufferCache 0 / 8388608", + " GradientCache 0 / 1048576", + " PathCache 3370264 / 33554432", + " TessellationCache 194928 / 1048576", + " TextDropShadowCache 0 / 6291456", + " PatchCache 0 / 131072", + " FontRenderer 0 A8 1048576 / 1048576", + " FontRenderer 0 RGBA 0 / 0", + " FontRenderer 0 total 1048576 / 1048576", + "Other:", + " FboCache 0 / 0", + "Total memory usage:", + " 38880960 bytes, 37.08 MB", + "", + "Profile data in ms:", + "", + "\tcom.google.android.leanbacklauncher/com.google.android.leanbacklauncher.MainActivity/android.view.ViewRootImpl@355a7923 (visibility=0)", + "View hierarchy:", + "", + " com.google.android.leanbacklauncher/com.google.android.leanbacklauncher.MainActivity/android.view.ViewRootImpl@355a7923", + " 142 views, 136.96 kB of display lists", + "", + "", + "Total ViewRootImpl: 1", + "Total Views: 142", + "Total DisplayList: 136.96 kB"); + + GfxInfoItem item = new GfxInfoParser().parse(input); + + assertEquals(0, item.getPids().size()); + } +} diff --git a/javatests/src/com/android/loganalysis/parser/InterruptParserTest.java b/javatests/src/com/android/loganalysis/parser/InterruptParserTest.java new file mode 100644 index 0000000..d45f3af --- /dev/null +++ b/javatests/src/com/android/loganalysis/parser/InterruptParserTest.java @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2015 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.InterruptItem; + +import junit.framework.TestCase; + +import java.util.Arrays; +import java.util.List; + +/** + * Unit tests for {@link InterruptParser} + */ +public class InterruptParserTest extends TestCase { + + /** + * Test that normal input is parsed. + */ + public void testInterruptParser() { + List inputBlock = Arrays.asList( + " Wakeup reason 200:qcom,smd-rpm:222:fc4: 11m 49s 332ms (0 times) realtime", + " Wakeup reason 200:qcom,smd-rpm: 48s 45ms (0 times) realtime", + " Wakeup reason 2:qcom,smd-rpm:2:f0.qm,mm:22:fc4mi: 3s 417ms (0 times) realtime", + " Wakeup reason 188:qcom,smd-adsp:200:qcom,smd-rpm: 1s 656ms (0 times) realtime", + " Wakeup reason 58:qcom,smsm-modem:2:qcom,smd-rpm: 6m 16s 1ms (5 times) realtime", + " Wakeup reason 57:qcom,smd-modem:200:qcom,smd-rpm: 40s 995ms (0 times) realtime", + " Wakeup reason unknown: 8s 455ms (0 times) realtime", + " Wakeup reason 9:bcmsdh_sdmmc:2:qcomd-rpm:240:mso: 8m 5s 9ms (0 times) realtime"); + + InterruptItem interrupt = new InterruptParser().parse(inputBlock); + + assertEquals(1, interrupt.getInterrupts( + InterruptItem.InterruptCategory.WIFI_INTERRUPT).size()); + + assertEquals("9:bcmsdh_sdmmc:2:qcomd-rpm:240:mso", interrupt.getInterrupts( + InterruptItem.InterruptCategory.WIFI_INTERRUPT).get(0).getName()); + + assertEquals(2, interrupt.getInterrupts( + InterruptItem.InterruptCategory.MODEM_INTERRUPT).size()); + + assertEquals(5, interrupt.getInterrupts(InterruptItem.InterruptCategory.MODEM_INTERRUPT). + get(0).getInterruptCount()); + + } +} + diff --git a/javatests/src/com/android/loganalysis/parser/JavaCrashParserTest.java b/javatests/src/com/android/loganalysis/parser/JavaCrashParserTest.java new file mode 100644 index 0000000..a7d06b3 --- /dev/null +++ b/javatests/src/com/android/loganalysis/parser/JavaCrashParserTest.java @@ -0,0 +1,151 @@ +/* + * Copyright (C) 2012 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.JavaCrashItem; +import com.android.loganalysis.util.ArrayUtil; + +import junit.framework.TestCase; + +import java.util.Arrays; +import java.util.List; + +/** + * Unit tests for {@link JavaCrashParser}. + */ +public class JavaCrashParserTest extends TestCase { + + /** + * Test that Java crashes are parsed with no message. + */ + public void testParse_no_message() { + List lines = Arrays.asList( + "java.lang.Exception", + "\tat class.method1(Class.java:1)", + "\tat class.method2(Class.java:2)", + "\tat class.method3(Class.java:3)"); + + JavaCrashItem jc = new JavaCrashParser().parse(lines); + assertNotNull(jc); + assertEquals("java.lang.Exception", jc.getException()); + assertNull(jc.getMessage()); + assertEquals(ArrayUtil.join("\n", lines), jc.getStack()); + } + + /** + * Test that Java crashes are parsed with a message. + */ + public void testParse_message() { + List lines = Arrays.asList( + "java.lang.Exception: This is the message", + "\tat class.method1(Class.java:1)", + "\tat class.method2(Class.java:2)", + "\tat class.method3(Class.java:3)"); + + JavaCrashItem jc = new JavaCrashParser().parse(lines); + assertNotNull(jc); + assertEquals("java.lang.Exception", jc.getException()); + assertEquals("This is the message", jc.getMessage()); + assertEquals(ArrayUtil.join("\n", lines), jc.getStack()); + } + + /** + * Test that Java crashes are parsed if the message spans multiple lines. + */ + public void testParse_multiline_message() { + List lines = Arrays.asList( + "java.lang.Exception: This message", + "is many lines", + "long.", + "\tat class.method1(Class.java:1)", + "\tat class.method2(Class.java:2)", + "\tat class.method3(Class.java:3)"); + + JavaCrashItem jc = new JavaCrashParser().parse(lines); + assertNotNull(jc); + assertEquals("java.lang.Exception", jc.getException()); + assertEquals("This message\nis many lines\nlong.", jc.getMessage()); + assertEquals(ArrayUtil.join("\n", lines), jc.getStack()); + } + + /** + * Test that caused by sections of Java crashes are parsed, with no message or single or + * multiline messages. + */ + public void testParse_caused_by() { + List lines = Arrays.asList( + "java.lang.Exception: This is the message", + "\tat class.method1(Class.java:1)", + "\tat class.method2(Class.java:2)", + "\tat class.method3(Class.java:3)", + "Caused by: java.lang.Exception", + "\tat class.method4(Class.java:4)", + "Caused by: java.lang.Exception: This is the caused by message", + "\tat class.method5(Class.java:5)", + "Caused by: java.lang.Exception: This is a multiline", + "caused by message", + "\tat class.method6(Class.java:6)"); + + JavaCrashItem jc = new JavaCrashParser().parse(lines); + assertNotNull(jc); + assertEquals("java.lang.Exception", jc.getException()); + assertEquals("This is the message", jc.getMessage()); + assertEquals(ArrayUtil.join("\n", lines), jc.getStack()); + } + + /** + * Test that the Java crash is cutoff if an unexpected line is handled. + */ + public void testParse_cutoff() { + List lines = Arrays.asList( + "java.lang.Exception: This is the message", + "\tat class.method1(Class.java:1)", + "\tat class.method2(Class.java:2)", + "\tat class.method3(Class.java:3)", + "Invalid line", + "java.lang.Exception: This is the message"); + + JavaCrashItem jc = new JavaCrashParser().parse(lines); + assertNotNull(jc); + assertEquals("java.lang.Exception", jc.getException()); + assertEquals("This is the message", jc.getMessage()); + assertEquals(ArrayUtil.join("\n", lines.subList(0, lines.size()-2)), jc.getStack()); + } + + /** + * Tests that only parts between the markers are parsed. + */ + public void testParse_begin_end_markers() { + List lines = Arrays.asList( + "error: this message has begin and end", + "----- begin exception -----", + "java.lang.Exception: This message", + "is many lines", + "long.", + "\tat class.method1(Class.java:1)", + "\tat class.method2(Class.java:2)", + "\tat class.method3(Class.java:3)", + "----- end exception -----"); + + JavaCrashItem jc = new JavaCrashParser().parse(lines); + assertNotNull(jc); + assertEquals("java.lang.Exception", jc.getException()); + assertEquals("This message\nis many lines\nlong.", jc.getMessage()); + assertNotNull(jc.getStack()); + assertFalse(jc.getStack().contains("begin exception")); + assertFalse(jc.getStack().contains("end exception")); + } +} diff --git a/javatests/src/com/android/loganalysis/parser/KernelLogParserTest.java b/javatests/src/com/android/loganalysis/parser/KernelLogParserTest.java new file mode 100644 index 0000000..159a90e --- /dev/null +++ b/javatests/src/com/android/loganalysis/parser/KernelLogParserTest.java @@ -0,0 +1,342 @@ +/* + * 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.LowMemoryKillerItem; +import com.android.loganalysis.item.MiscKernelLogItem; +import com.android.loganalysis.item.PageAllocationFailureItem; +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 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 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 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 unknown last boot reasons are parsed. + */ + public void testParseUnknownLastMessage() { + List lines = Arrays.asList( + "[ 0.000000] Start", + "[ 2.000000] End", + "Last boot reason: unknown failure"); + + 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()); + assertNotNull(item.getStack()); + } + + public void testParseKnownGoodLastMessage() { + List lines = Arrays.asList( + "[ 0.000000] Start", + "[ 2.000000] End", + "Last boot reason: reboot"); + + KernelLogItem kernelLog = new KernelLogParser().parse(lines); + assertNotNull(kernelLog); + assertEquals(0.0, kernelLog.getStartTime(), 0.0000005); + assertEquals(2.0, kernelLog.getStopTime(), 0.0000005); + assertEquals(0, kernelLog.getEvents().size()); + } + + /** + * Test that reset reasons don't crash if times are set. + */ + public void testNoPreviousLogs() { + List 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 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 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(2, 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()); + } + + /** + * Test that an LowMemoryKiller event can be parsed out of a list of log lines. + */ + public void testLowMemoryKillerParse() { + final String LMK_MESSAGE = "Killing '.qcrilmsgtunnel' (3699), adj 100,"; + List 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", + "<3>[ 43.399164] " + LMK_MESSAGE); + KernelLogItem kernelLog = new KernelLogParser().parse(lines); + + assertNotNull(kernelLog); + assertEquals(0.0, kernelLog.getStartTime(), 0.0000005); + assertEquals(43.399164, kernelLog.getStopTime(), 0.0000005); + assertEquals(2, kernelLog.getEvents().size()); + assertEquals(1, kernelLog.getMiscEvents(KernelLogParser.LOW_MEMORY_KILLER).size()); + assertEquals(1, kernelLog.getLowMemoryKillerEvents().size()); + + MiscKernelLogItem miscItem = kernelLog.getMiscEvents(KernelLogParser.LOW_MEMORY_KILLER) + .get(0); + assertEquals(43.399164, miscItem.getEventTime(), 0.0000005); + assertEquals(KernelLogParser.LOW_MEMORY_KILLER, miscItem.getCategory()); + assertEquals(LMK_MESSAGE, miscItem.getStack()); + + LowMemoryKillerItem lmkItem = kernelLog.getLowMemoryKillerEvents().get(0); + assertEquals(KernelLogParser.LOW_MEMORY_KILLER, lmkItem.getCategory()); + assertEquals(3699, lmkItem.getPid()); + assertEquals(".qcrilmsgtunnel", lmkItem.getProcessName()); + assertEquals(100, lmkItem.getAdjustment()); + assertEquals(LMK_MESSAGE, lmkItem.getStack()); + } + + /** + * Test that page allocation failures can be parsed out of a list of log lines. + */ + public void testPageAllocationFailureParse() { + final String ALLOC_FAILURE = "page allocation failure: order:3, mode:0x10c0d0"; + List 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", + "<3>[ 43.399164] " + ALLOC_FAILURE); + KernelLogItem kernelLog = new KernelLogParser().parse(lines); + + assertNotNull(kernelLog); + assertEquals(0.0, kernelLog.getStartTime(), 0.0000005); + assertEquals(43.399164, kernelLog.getStopTime(), 0.0000005); + assertEquals(2, kernelLog.getEvents().size()); + assertEquals(1, kernelLog.getMiscEvents(KernelLogParser.PAGE_ALLOC_FAILURE).size()); + assertEquals(1, kernelLog.getPageAllocationFailureEvents().size()); + + MiscKernelLogItem miscItem = kernelLog.getMiscEvents(KernelLogParser.PAGE_ALLOC_FAILURE) + .get(0); + assertEquals(43.399164, miscItem.getEventTime(), 0.0000005); + assertEquals(KernelLogParser.PAGE_ALLOC_FAILURE, miscItem.getCategory()); + assertEquals(ALLOC_FAILURE, miscItem.getStack()); + + PageAllocationFailureItem failItem = kernelLog.getPageAllocationFailureEvents().get(0); + assertEquals(KernelLogParser.PAGE_ALLOC_FAILURE, failItem.getCategory()); + assertEquals(3, failItem.getOrder()); + assertEquals(ALLOC_FAILURE, failItem.getStack()); + } + + public void testMantaReset() { + final List 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 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()); + } +} diff --git a/javatests/src/com/android/loganalysis/parser/LocationServiceParserTest.java b/javatests/src/com/android/loganalysis/parser/LocationServiceParserTest.java new file mode 100644 index 0000000..fc58e45 --- /dev/null +++ b/javatests/src/com/android/loganalysis/parser/LocationServiceParserTest.java @@ -0,0 +1,89 @@ +/* + * Copyright (C) 2016 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.LocationDumpsItem; +import com.android.loganalysis.item.LocationDumpsItem.LocationInfoItem; + +import junit.framework.TestCase; + +import java.util.Arrays; +import java.util.List; + +/** + * Unit tests for {@link LocationServiceParser} + */ +public class LocationServiceParserTest extends TestCase { + + /** + * Test that normal input is parsed. + */ + public void testLocationClientsSize() { + List inputBlock = Arrays.asList( + " Location Request History By Package:", + " Interval effective/min/max 1/0/0[s] Duration: 140[minutes] " + + "[com.google.android.gms, PRIORITY_NO_POWER, UserLocationProducer] " + + "Num requests: 2 Active: true", + " Interval effective/min/max 284/285/3600[s] Duration: 140[minutes] " + + "[com.google.android.googlequicksearchbox, PRIORITY_BALANCED_POWER_ACCURACY] " + + "Num requests: 5 Active: true", + " Interval effective/min/max 0/0/0[s] Duration: 0[minutes] " + + "[com.google.android.apps.walletnfcrel, PRIORITY_BALANCED_POWER_ACCURACY] " + + "Num requests: 1 Active: false", + " ", + " FLP WakeLock Count"); + + LocationDumpsItem locationClients = new LocationServiceParser().parse(inputBlock); + assertNotNull(locationClients.getLocationClients()); + assertEquals(locationClients.getLocationClients().size(), 3); + } + + /** + * Test that normal input is parsed. + */ + public void testLocationClientParser() { + List inputBlock = Arrays.asList( + " Location Request History By Package:", + " Interval effective/min/max 1/0/0[s] Duration: 140[minutes] " + + "[com.google.android.gms, PRIORITY_NO_POWER, UserLocationProducer] " + + "Num requests: 2 Active: true"); + + LocationDumpsItem locationClients = new LocationServiceParser().parse(inputBlock); + assertNotNull(locationClients.getLocationClients()); + LocationInfoItem client = locationClients.getLocationClients().iterator().next(); + assertEquals(client.getPackage(), "com.google.android.gms"); + assertEquals(client.getEffectiveInterval(), 1); + assertEquals(client.getMinInterval(), 0); + assertEquals(client.getMaxInterval(), 0); + assertEquals(client.getPriority(), "PRIORITY_NO_POWER"); + assertEquals(client.getDuration(), 140); + } + + /** + * Test that invalid input is parsed. + */ + public void testLocationClientParserInvalidInput() { + List inputBlock = Arrays.asList( + " Location Request History By Package:", + " Interval effective/min/max 1/0/0[s] Duration: 140[minutes] " + + "[com.google.android.gms PRIORITY_NO_POWER UserLocationProducer] " + + "Num requests: 2 Active: true"); + LocationDumpsItem locationClients = new LocationServiceParser().parse(inputBlock); + assertEquals(locationClients.getLocationClients().size(), 0); + } + +} + diff --git a/javatests/src/com/android/loganalysis/parser/LogcatParserTest.java b/javatests/src/com/android/loganalysis/parser/LogcatParserTest.java new file mode 100644 index 0000000..1d4f72c --- /dev/null +++ b/javatests/src/com/android/loganalysis/parser/LogcatParserTest.java @@ -0,0 +1,845 @@ +/* + * Copyright (C) 2012 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.JavaCrashItem; +import com.android.loganalysis.item.LogcatItem; +import com.android.loganalysis.item.MiscLogcatItem; +import com.android.loganalysis.util.ArrayUtil; + +import junit.framework.TestCase; + +import java.text.DateFormat; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Arrays; +import java.util.Date; +import java.util.List; +import java.util.regex.Pattern; + +/** + * Unit tests for {@link LogcatParserTest}. + */ +public class LogcatParserTest extends TestCase { + + /** + * Test that an ANR is parsed in the log. + */ + public void testParse_anr() throws ParseException { + List lines = Arrays.asList( + "04-25 17:17:08.445 312 366 E ActivityManager: ANR (application not responding) in process: com.android.package", + "04-25 17:17:08.445 312 366 E ActivityManager: Reason: keyDispatchingTimedOut", + "04-25 17:17:08.445 312 366 E ActivityManager: Load: 0.71 / 0.83 / 0.51", + "04-25 17:17:08.445 312 366 E ActivityManager: 33% TOTAL: 21% user + 11% kernel + 0.3% iowait"); + + LogcatItem logcat = new LogcatParser("2012").parse(lines); + assertNotNull(logcat); + assertEquals(parseTime("2012-04-25 17:17:08.445"), logcat.getStartTime()); + assertEquals(parseTime("2012-04-25 17:17:08.445"), logcat.getStopTime()); + assertEquals(1, logcat.getEvents().size()); + assertEquals(1, logcat.getAnrs().size()); + assertEquals(312, logcat.getAnrs().get(0).getPid().intValue()); + assertEquals(366, logcat.getAnrs().get(0).getTid().intValue()); + assertEquals("", logcat.getAnrs().get(0).getLastPreamble()); + assertEquals("", logcat.getAnrs().get(0).getProcessPreamble()); + assertEquals(parseTime("2012-04-25 17:17:08.445"), logcat.getAnrs().get(0).getEventTime()); + } + + /** + * Test that an ANR is parsed in the log. + */ + public void testParse_anr_pid() throws ParseException { + List lines = Arrays.asList( + "04-25 17:17:08.445 312 366 E ActivityManager: ANR (application not responding) in process: com.android.package", + "04-25 17:17:08.445 312 366 E ActivityManager: PID: 1234", + "04-25 17:17:08.445 312 366 E ActivityManager: Reason: keyDispatchingTimedOut", + "04-25 17:17:08.445 312 366 E ActivityManager: Load: 0.71 / 0.83 / 0.51", + "04-25 17:17:08.445 312 366 E ActivityManager: 33% TOTAL: 21% user + 11% kernel + 0.3% iowait"); + + LogcatItem logcat = new LogcatParser("2012").parse(lines); + assertNotNull(logcat); + assertEquals(parseTime("2012-04-25 17:17:08.445"), logcat.getStartTime()); + assertEquals(parseTime("2012-04-25 17:17:08.445"), logcat.getStopTime()); + assertEquals(1, logcat.getEvents().size()); + assertEquals(1, logcat.getAnrs().size()); + assertEquals(1234, logcat.getAnrs().get(0).getPid().intValue()); + assertNull(logcat.getAnrs().get(0).getTid()); + assertEquals("", logcat.getAnrs().get(0).getLastPreamble()); + assertEquals("", logcat.getAnrs().get(0).getProcessPreamble()); + assertEquals(parseTime("2012-04-25 17:17:08.445"), logcat.getAnrs().get(0).getEventTime()); + } + + /** + * Test that Java crashes can be parsed. + */ + public void testParse_java_crash() throws ParseException { + List lines = Arrays.asList( + "04-25 09:55:47.799 3064 3082 E AndroidRuntime: java.lang.Exception", + "04-25 09:55:47.799 3064 3082 E AndroidRuntime: \tat class.method1(Class.java:1)", + "04-25 09:55:47.799 3064 3082 E AndroidRuntime: \tat class.method2(Class.java:2)", + "04-25 09:55:47.799 3064 3082 E AndroidRuntime: \tat class.method3(Class.java:3)"); + + LogcatItem logcat = new LogcatParser("2012").parse(lines); + assertNotNull(logcat); + assertEquals(parseTime("2012-04-25 09:55:47.799"), logcat.getStartTime()); + assertEquals(parseTime("2012-04-25 09:55:47.799"), logcat.getStopTime()); + assertEquals(1, logcat.getEvents().size()); + assertEquals(1, logcat.getJavaCrashes().size()); + assertEquals(3064, logcat.getJavaCrashes().get(0).getPid().intValue()); + assertEquals(3082, logcat.getJavaCrashes().get(0).getTid().intValue()); + assertEquals("", logcat.getJavaCrashes().get(0).getLastPreamble()); + assertEquals("", logcat.getJavaCrashes().get(0).getProcessPreamble()); + assertEquals(parseTime("2012-04-25 09:55:47.799"), + logcat.getJavaCrashes().get(0).getEventTime()); + } + + public void testParse_test_exception() { + List lines = Arrays.asList( + "11-25 19:26:53.581 5832 7008 I TestRunner: ----- begin exception -----", + "11-25 19:26:53.589 5832 7008 I TestRunner: ", + "11-25 19:26:53.589 5832 7008 I TestRunner: java.util.concurrent.TimeoutException", + "11-25 19:26:53.589 5832 7008 I TestRunner: at android.support.test.uiautomator.WaitMixin.wait(WaitMixin.java:49)", + "11-25 19:26:53.589 5832 7008 I TestRunner: at android.support.test.uiautomator.WaitMixin.wait(WaitMixin.java:36)", + "11-25 19:26:53.589 5832 7008 I TestRunner: at android.support.test.uiautomator.UiDevice.wait(UiDevice.java:169)", + "11-25 19:26:53.589 5832 7008 I TestRunner: at com.android.test.uiautomator.common.helpers.MapsHelper.doSearch(MapsHelper.java:87)", + "11-25 19:26:53.589 5832 7008 I TestRunner: at com.android.test.uiautomator.aupt.MapsTest.testMaps(MapsTest.java:58)", + "11-25 19:26:53.589 5832 7008 I TestRunner: at java.lang.reflect.Method.invoke(Native Method)", + "11-25 19:26:53.589 5832 7008 I TestRunner: at java.lang.reflect.Method.invoke(Method.java:372)", + "11-25 19:26:53.589 5832 7008 I TestRunner: at android.test.InstrumentationTestCase.runMethod(InstrumentationTestCase.java:214)", + "11-25 19:26:53.589 5832 7008 I TestRunner: at android.test.InstrumentationTestCase.runTest(InstrumentationTestCase.java:199)", + "11-25 19:26:53.589 5832 7008 I TestRunner: at junit.framework.TestCase.runBare(TestCase.java:134)", + "11-25 19:26:53.589 5832 7008 I TestRunner: at junit.framework.TestResult$1.protect(TestResult.java:115)", + "11-25 19:26:53.589 5832 7008 I TestRunner: at junit.framework.TestResult.runProtected(TestResult.java:133)", + "11-25 19:26:53.589 5832 7008 I TestRunner: at junit.framework.TestResult.run(TestResult.java:118)", + "11-25 19:26:53.589 5832 7008 I TestRunner: at junit.framework.TestCase.run(TestCase.java:124)", + "11-25 19:26:53.589 5832 7008 I TestRunner: at android.support.test.aupt.AuptTestRunner$AuptPrivateTestRunner.runTest(AuptTestRunner.java:182)", + "11-25 19:26:53.589 5832 7008 I TestRunner: at android.test.AndroidTestRunner.runTest(AndroidTestRunner.java:176)", + "11-25 19:26:53.589 5832 7008 I TestRunner: at android.test.InstrumentationTestRunner.onStart(InstrumentationTestRunner.java:555)", + "11-25 19:26:53.589 5832 7008 I TestRunner: at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:1848)", + "11-25 19:26:53.589 5832 7008 I TestRunner: ----- end exception -----" + ); + + LogcatParser logcatParser = new LogcatParser("2012"); + logcatParser.addJavaCrashTag("I", "TestRunner", LogcatParser.JAVA_CRASH); + LogcatItem logcat = logcatParser.parse(lines); + assertNotNull(logcat); + assertEquals(1, logcat.getEvents().size()); + assertEquals(1, logcat.getJavaCrashes().size()); + assertEquals(5832, logcat.getJavaCrashes().get(0).getPid().intValue()); + assertEquals(7008, logcat.getJavaCrashes().get(0).getTid().intValue()); + assertEquals("", logcat.getJavaCrashes().get(0).getLastPreamble()); + assertEquals("", logcat.getJavaCrashes().get(0).getProcessPreamble()); + assertEquals(LogcatParser.JAVA_CRASH, logcat.getJavaCrashes().get(0).getCategory()); + } + + public void testParse_test_exception_with_exras() { + List lines = Arrays.asList( + "12-06 17:19:18.746 6598 7960 I TestRunner: failed: testYouTube(com.android.test.uiautomator.aupt.YouTubeTest)", + "12-06 17:19:18.746 6598 7960 I TestRunner: ----- begin exception -----", + "12-06 17:19:18.747 6598 7960 I TestRunner: ", + "12-06 17:19:18.747 6598 7960 I TestRunner: java.util.concurrent.TimeoutException", + "12-06 17:19:18.747 6598 7960 I TestRunner: at android.support.test.uiautomator.WaitMixin.wait(WaitMixin.java:49)", + "12-06 17:19:18.747 6598 7960 I TestRunner: at android.support.test.uiautomator.WaitMixin.wait(WaitMixin.java:36)", + "12-06 17:19:18.747 6598 7960 I TestRunner: at android.support.test.uiautomator.UiDevice.wait(UiDevice.java:169)", + "12-06 17:19:18.747 6598 7960 I TestRunner: at android.support.test.aupt.AppLauncher.launchApp(AppLauncher.java:127)", + "12-06 17:19:18.747 6598 7960 I TestRunner: at com.android.test.uiautomator.common.helpers.YouTubeHelper.open(YouTubeHelper.java:49)", + "12-06 17:19:18.747 6598 7960 I TestRunner: at com.android.test.uiautomator.aupt.YouTubeTest.setUp(YouTubeTest.java:44)", + "12-06 17:19:18.747 6598 7960 I TestRunner: at junit.framework.TestCase.runBare(TestCase.java:132)", + "12-06 17:19:18.747 6598 7960 I TestRunner: at junit.framework.TestResult$1.protect(TestResult.java:115)", + "12-06 17:19:18.747 6598 7960 I TestRunner: at junit.framework.TestResult.runProtected(TestResult.java:133)", + "12-06 17:19:18.747 6598 7960 I TestRunner: at junit.framework.TestResult.run(TestResult.java:118)", + "12-06 17:19:18.747 6598 7960 I TestRunner: at junit.framework.TestCase.run(TestCase.java:124)", + "12-06 17:19:18.747 6598 7960 I TestRunner: at android.support.test.aupt.AuptTestRunner$AuptPrivateTestRunner.runTest(AuptTestRunner.java:182)", + "12-06 17:19:18.747 6598 7960 I TestRunner: at android.test.AndroidTestRunner.runTest(AndroidTestRunner.java:176)", + "12-06 17:19:18.747 6598 7960 I TestRunner: at android.test.InstrumentationTestRunner.onStart(InstrumentationTestRunner.java:555)", + "12-06 17:19:18.747 6598 7960 I TestRunner: at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:1851)", + "12-06 17:19:18.747 6598 7960 I TestRunner: ----- end exception -----" + ); + + LogcatParser logcatParser = new LogcatParser("2012"); + logcatParser.addJavaCrashTag("I", "TestRunner", LogcatParser.JAVA_CRASH); + LogcatItem logcat = logcatParser.parse(lines); + assertNotNull(logcat); + assertEquals(1, logcat.getEvents().size()); + assertEquals(1, logcat.getJavaCrashes().size()); + assertEquals(6598, logcat.getJavaCrashes().get(0).getPid().intValue()); + assertEquals(7960, logcat.getJavaCrashes().get(0).getTid().intValue()); + assertEquals("", logcat.getJavaCrashes().get(0).getLastPreamble()); + assertEquals("", logcat.getJavaCrashes().get(0).getProcessPreamble()); + // Check that lines not related to java crash are absent + assertFalse(logcat.getJavaCrashes().get(0).getStack().contains("begin exception")); + assertFalse(logcat.getJavaCrashes().get(0).getStack().contains("end exception")); + assertFalse(logcat.getJavaCrashes().get(0).getStack().contains("failed: testYouTube")); + //System.out.println(logcat.getJavaCrashes().get(0).getStack()); + } + + /** + * Test that Java crashes from system server can be parsed. + */ + public void testParse_java_crash_system_server() throws ParseException { + List lines = Arrays.asList( + "04-25 09:55:47.799 3064 3082 E AndroidRuntime: *** FATAL EXCEPTION IN SYSTEM PROCESS: message", + "04-25 09:55:47.799 3064 3082 E AndroidRuntime: java.lang.Exception", + "04-25 09:55:47.799 3064 3082 E AndroidRuntime: \tat class.method1(Class.java:1)", + "04-25 09:55:47.799 3064 3082 E AndroidRuntime: \tat class.method2(Class.java:2)", + "04-25 09:55:47.799 3064 3082 E AndroidRuntime: \tat class.method3(Class.java:3)"); + + LogcatItem logcat = new LogcatParser("2012").parse(lines); + assertNotNull(logcat); + assertEquals(parseTime("2012-04-25 09:55:47.799"), logcat.getStartTime()); + assertEquals(parseTime("2012-04-25 09:55:47.799"), logcat.getStopTime()); + assertEquals(1, logcat.getEvents().size()); + assertEquals(1, logcat.getJavaCrashes().size()); + assertEquals("system_server", logcat.getJavaCrashes().get(0).getApp()); + assertEquals(3064, logcat.getJavaCrashes().get(0).getPid().intValue()); + assertEquals(3082, logcat.getJavaCrashes().get(0).getTid().intValue()); + assertEquals("", logcat.getJavaCrashes().get(0).getLastPreamble()); + assertEquals("", logcat.getJavaCrashes().get(0).getProcessPreamble()); + assertEquals(parseTime("2012-04-25 09:55:47.799"), + logcat.getJavaCrashes().get(0).getEventTime()); + } + + /** + * Test that Java crashes with process and pid can be parsed. + */ + public void testParse_java_crash_process_pid() throws ParseException { + List lines = Arrays.asList( + "04-25 09:55:47.799 3064 3082 E AndroidRuntime: FATAL EXCEPTION: main", + "04-25 09:55:47.799 3064 3082 E AndroidRuntime: Process: com.android.package, PID: 1234", + "04-25 09:55:47.799 3064 3082 E AndroidRuntime: java.lang.Exception", + "04-25 09:55:47.799 3064 3082 E AndroidRuntime: \tat class.method1(Class.java:1)", + "04-25 09:55:47.799 3064 3082 E AndroidRuntime: \tat class.method2(Class.java:2)", + "04-25 09:55:47.799 3064 3082 E AndroidRuntime: \tat class.method3(Class.java:3)"); + + LogcatItem logcat = new LogcatParser("2012").parse(lines); + assertNotNull(logcat); + assertEquals(parseTime("2012-04-25 09:55:47.799"), logcat.getStartTime()); + assertEquals(parseTime("2012-04-25 09:55:47.799"), logcat.getStopTime()); + assertEquals(1, logcat.getEvents().size()); + assertEquals(1, logcat.getJavaCrashes().size()); + assertEquals("com.android.package", logcat.getJavaCrashes().get(0).getApp()); + assertEquals(1234, logcat.getJavaCrashes().get(0).getPid().intValue()); + assertNull(logcat.getJavaCrashes().get(0).getTid()); + assertEquals("", logcat.getJavaCrashes().get(0).getLastPreamble()); + assertEquals("", logcat.getJavaCrashes().get(0).getProcessPreamble()); + assertEquals(parseTime("2012-04-25 09:55:47.799"), + logcat.getJavaCrashes().get(0).getEventTime()); + } + + /** + * Test that Java crashes with pid can be parsed. + */ + public void testParse_java_crash_pid() throws ParseException { + List lines = Arrays.asList( + "04-25 09:55:47.799 3064 3082 E AndroidRuntime: FATAL EXCEPTION: main", + "04-25 09:55:47.799 3064 3082 E AndroidRuntime: PID: 1234", + "04-25 09:55:47.799 3064 3082 E AndroidRuntime: java.lang.Exception", + "04-25 09:55:47.799 3064 3082 E AndroidRuntime: \tat class.method1(Class.java:1)", + "04-25 09:55:47.799 3064 3082 E AndroidRuntime: \tat class.method2(Class.java:2)", + "04-25 09:55:47.799 3064 3082 E AndroidRuntime: \tat class.method3(Class.java:3)"); + + LogcatItem logcat = new LogcatParser("2012").parse(lines); + assertNotNull(logcat); + assertEquals(parseTime("2012-04-25 09:55:47.799"), logcat.getStartTime()); + assertEquals(parseTime("2012-04-25 09:55:47.799"), logcat.getStopTime()); + assertEquals(1, logcat.getEvents().size()); + assertEquals(1, logcat.getJavaCrashes().size()); + assertNull(logcat.getJavaCrashes().get(0).getApp()); + assertEquals(1234, logcat.getJavaCrashes().get(0).getPid().intValue()); + assertNull(logcat.getJavaCrashes().get(0).getTid()); + assertEquals("", logcat.getJavaCrashes().get(0).getLastPreamble()); + assertEquals("", logcat.getJavaCrashes().get(0).getProcessPreamble()); + assertEquals(parseTime("2012-04-25 09:55:47.799"), + logcat.getJavaCrashes().get(0).getEventTime()); + } + + /** + * Test that Java crashes with process and pid without stack can be parsed. + */ + public void testParse_java_crash_empty() throws ParseException { + List lines = Arrays.asList( + "04-25 09:55:47.799 3064 3082 E AndroidRuntime: FATAL EXCEPTION: main", + "04-25 09:55:47.799 3064 3082 E AndroidRuntime: PID: 1234"); + + LogcatItem logcat = new LogcatParser("2012").parse(lines); + assertNotNull(logcat); + assertEquals(parseTime("2012-04-25 09:55:47.799"), logcat.getStartTime()); + assertEquals(parseTime("2012-04-25 09:55:47.799"), logcat.getStopTime()); + assertEquals(0, logcat.getEvents().size()); + assertEquals(0, logcat.getJavaCrashes().size()); + } + + /** + * Test that native crashes can be parsed from the info log level. + */ + public void testParse_native_crash_info() throws ParseException { + List lines = Arrays.asList( + "04-25 18:33:27.273 115 115 I DEBUG : Build fingerprint: 'product:build:target'", + "04-25 18:33:27.273 115 115 I DEBUG : pid: 3112, tid: 3112 >>> com.google.android.browser <<<", + "04-25 18:33:27.273 115 115 I DEBUG : signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 00000000"); + + LogcatItem logcat = new LogcatParser("2012").parse(lines); + assertNotNull(logcat); + assertEquals(parseTime("2012-04-25 18:33:27.273"), logcat.getStartTime()); + assertEquals(parseTime("2012-04-25 18:33:27.273"), logcat.getStopTime()); + assertEquals(1, logcat.getEvents().size()); + assertEquals(1, logcat.getNativeCrashes().size()); + assertEquals(3112, logcat.getNativeCrashes().get(0).getPid().intValue()); + assertEquals(3112, logcat.getNativeCrashes().get(0).getTid().intValue()); + assertEquals("com.google.android.browser", logcat.getNativeCrashes().get(0).getApp()); + assertEquals("", logcat.getNativeCrashes().get(0).getLastPreamble()); + assertEquals("", logcat.getNativeCrashes().get(0).getProcessPreamble()); + assertEquals(parseTime("2012-04-25 18:33:27.273"), + logcat.getNativeCrashes().get(0).getEventTime()); + } + + /** + * Test that native crashes can be parsed from the fatal log level. + */ + public void testParse_native_crash_fatal() throws ParseException { + List lines = Arrays.asList( + "04-25 18:33:27.273 115 115 F DEBUG : Build fingerprint: 'product:build:target'", + "04-25 18:33:27.273 115 115 F DEBUG : pid: 3112, tid: 3112, name: Name >>> com.google.android.browser <<<", + "04-25 18:33:27.273 115 115 F DEBUG : signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 00000000"); + + LogcatItem logcat = new LogcatParser("2012").parse(lines); + assertNotNull(logcat); + assertEquals(parseTime("2012-04-25 18:33:27.273"), logcat.getStartTime()); + assertEquals(parseTime("2012-04-25 18:33:27.273"), logcat.getStopTime()); + assertEquals(1, logcat.getEvents().size()); + assertEquals(1, logcat.getNativeCrashes().size()); + assertEquals(3112, logcat.getNativeCrashes().get(0).getPid().intValue()); + assertEquals(3112, logcat.getNativeCrashes().get(0).getTid().intValue()); + assertEquals("com.google.android.browser", logcat.getNativeCrashes().get(0).getApp()); + assertEquals("", logcat.getNativeCrashes().get(0).getLastPreamble()); + assertEquals("", logcat.getNativeCrashes().get(0).getProcessPreamble()); + assertEquals(parseTime("2012-04-25 18:33:27.273"), + logcat.getNativeCrashes().get(0).getEventTime()); + } + + /** + * Test that native crashes can be parsed if they have the same pid/tid. + */ + public void testParse_native_crash_same_pid() throws ParseException { + List lines = Arrays.asList( + "04-25 18:33:27.273 115 115 I DEBUG : *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***", + "04-25 18:33:27.273 115 115 I DEBUG : Build fingerprint: 'product:build:target'", + "04-25 18:33:27.273 115 115 I DEBUG : pid: 3112, tid: 3112 >>> com.google.android.browser <<<", + "04-25 18:33:27.273 115 115 I DEBUG : signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 00000000", + "04-25 18:33:27.273 115 115 I DEBUG : *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***", + "04-25 18:33:27.273 115 115 I DEBUG : Build fingerprint: 'product:build:target'", + "04-25 18:33:27.273 115 115 I DEBUG : pid: 3113, tid: 3113 >>> com.google.android.browser2 <<<", + "04-25 18:33:27.273 115 115 I DEBUG : signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 00000000"); + + LogcatItem logcat = new LogcatParser("2012").parse(lines); + assertNotNull(logcat); + assertEquals(parseTime("2012-04-25 18:33:27.273"), logcat.getStartTime()); + assertEquals(parseTime("2012-04-25 18:33:27.273"), logcat.getStopTime()); + assertEquals(2, logcat.getEvents().size()); + assertEquals(2, logcat.getNativeCrashes().size()); + assertEquals(3112, logcat.getNativeCrashes().get(0).getPid().intValue()); + assertEquals(3112, logcat.getNativeCrashes().get(0).getTid().intValue()); + assertEquals("com.google.android.browser", logcat.getNativeCrashes().get(0).getApp()); + assertEquals(3113, logcat.getNativeCrashes().get(1).getPid().intValue()); + assertEquals(3113, logcat.getNativeCrashes().get(1).getTid().intValue()); + assertEquals("com.google.android.browser2", logcat.getNativeCrashes().get(1).getApp()); + } + + public void testParse_misc_events() throws ParseException { + List lines = Arrays.asList( + "04-25 18:33:27.273 1676 1821 W AudioTrack: obtainBuffer timed out (is the CPU pegged?) 0x361378 user=0000116a, server=00000000", + "04-25 18:33:28.273 7813 7813 E gralloc : GetBufferLock timed out for thread 7813 buffer 0x61 usage 0x200 LockState 1", + "04-25 18:33:29.273 395 637 W Watchdog: *** WATCHDOG KILLING SYSTEM PROCESS: null"); + + LogcatItem logcat = new LogcatParser("2012").parse(lines); + assertNotNull(logcat); + assertEquals(parseTime("2012-04-25 18:33:27.273"), logcat.getStartTime()); + assertEquals(parseTime("2012-04-25 18:33:29.273"), logcat.getStopTime()); + assertEquals(3, logcat.getEvents().size()); + assertEquals(1, logcat.getMiscEvents(LogcatParser.HIGH_CPU_USAGE).size()); + assertEquals(1, logcat.getMiscEvents(LogcatParser.HIGH_MEMORY_USAGE).size()); + assertEquals(1, logcat.getMiscEvents(LogcatParser.RUNTIME_RESTART).size()); + + MiscLogcatItem item = logcat.getMiscEvents(LogcatParser.HIGH_CPU_USAGE).get(0); + + assertEquals(1676, item.getPid().intValue()); + assertEquals(1821, item.getTid().intValue()); + assertEquals(parseTime("2012-04-25 18:33:27.273"), item.getEventTime()); + + item = logcat.getMiscEvents(LogcatParser.HIGH_MEMORY_USAGE).get(0); + + assertEquals(7813, item.getPid().intValue()); + assertEquals(7813, item.getTid().intValue()); + assertEquals(parseTime("2012-04-25 18:33:28.273"), item.getEventTime()); + + item = logcat.getMiscEvents(LogcatParser.RUNTIME_RESTART).get(0); + + assertEquals(395, item.getPid().intValue()); + assertEquals(637, item.getTid().intValue()); + assertEquals(parseTime("2012-04-25 18:33:29.273"), item.getEventTime()); + } + + /** + * Test that multiple events can be parsed. + */ + public void testParse_multiple_events() throws ParseException { + List lines = Arrays.asList( + "04-25 09:55:47.799 3064 3082 E AndroidRuntime: java.lang.Exception", + "04-25 09:55:47.799 3064 3082 E AndroidRuntime: \tat class.method1(Class.java:1)", + "04-25 09:55:47.799 3064 3082 E AndroidRuntime: \tat class.method2(Class.java:2)", + "04-25 09:55:47.799 3064 3082 E AndroidRuntime: \tat class.method3(Class.java:3)", + "04-25 09:55:47.799 3065 3090 E AndroidRuntime: java.lang.Exception", + "04-25 09:55:47.799 3065 3090 E AndroidRuntime: \tat class.method1(Class.java:1)", + "04-25 09:55:47.799 3065 3090 E AndroidRuntime: \tat class.method2(Class.java:2)", + "04-25 09:55:47.799 3065 3090 E AndroidRuntime: \tat class.method3(Class.java:3)", + "04-25 17:17:08.445 312 366 E ActivityManager: ANR (application not responding) in process: com.android.package", + "04-25 17:17:08.445 312 366 E ActivityManager: Reason: keyDispatchingTimedOut", + "04-25 17:17:08.445 312 366 E ActivityManager: Load: 0.71 / 0.83 / 0.51", + "04-25 17:17:08.445 312 366 E ActivityManager: 33% TOTAL: 21% user + 11% kernel + 0.3% iowait", + "04-25 17:17:08.445 312 366 E ActivityManager: ANR (application not responding) in process: com.android.package", + "04-25 17:17:08.445 312 366 E ActivityManager: Reason: keyDispatchingTimedOut", + "04-25 17:17:08.445 312 366 E ActivityManager: Load: 0.71 / 0.83 / 0.51", + "04-25 17:17:08.445 312 366 E ActivityManager: 33% TOTAL: 21% user + 11% kernel + 0.3% iowait", + "04-25 18:33:27.273 115 115 I DEBUG : *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***", + "04-25 18:33:27.273 115 115 I DEBUG : Build fingerprint: 'product:build:target'", + "04-25 18:33:27.273 115 115 I DEBUG : pid: 3112, tid: 3112 >>> com.google.android.browser <<<", + "04-25 18:33:27.273 115 115 I DEBUG : signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 00000000", + "04-25 18:33:27.273 117 117 I DEBUG : *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***", + "04-25 18:33:27.273 117 117 I DEBUG : Build fingerprint: 'product:build:target'", + "04-25 18:33:27.273 117 117 I DEBUG : pid: 3113, tid: 3113 >>> com.google.android.browser <<<", + "04-25 18:33:27.273 117 117 I DEBUG : signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 00000000"); + + + LogcatItem logcat = new LogcatParser("2012").parse(lines); + assertNotNull(logcat); + assertEquals(parseTime("2012-04-25 09:55:47.799"), logcat.getStartTime()); + assertEquals(parseTime("2012-04-25 18:33:27.273"), logcat.getStopTime()); + assertEquals(6, logcat.getEvents().size()); + assertEquals(2, logcat.getAnrs().size()); + assertEquals(2, logcat.getJavaCrashes().size()); + assertEquals(2, logcat.getNativeCrashes().size()); + + assertEquals(312, logcat.getAnrs().get(0).getPid().intValue()); + assertEquals(366, logcat.getAnrs().get(0).getTid().intValue()); + assertEquals(parseTime("2012-04-25 17:17:08.445"), logcat.getAnrs().get(0).getEventTime()); + + assertEquals(312, logcat.getAnrs().get(1).getPid().intValue()); + assertEquals(366, logcat.getAnrs().get(1).getTid().intValue()); + assertEquals(parseTime("2012-04-25 17:17:08.445"), logcat.getAnrs().get(1).getEventTime()); + + assertEquals(3064, logcat.getJavaCrashes().get(0).getPid().intValue()); + assertEquals(3082, logcat.getJavaCrashes().get(0).getTid().intValue()); + assertEquals( + parseTime("2012-04-25 09:55:47.799"), + logcat.getJavaCrashes().get(0).getEventTime()); + + assertEquals(3065, logcat.getJavaCrashes().get(1).getPid().intValue()); + assertEquals(3090, logcat.getJavaCrashes().get(1).getTid().intValue()); + assertEquals( + parseTime("2012-04-25 09:55:47.799"), + logcat.getJavaCrashes().get(1).getEventTime()); + + assertEquals(3112, logcat.getNativeCrashes().get(0).getPid().intValue()); + assertEquals(3112, logcat.getNativeCrashes().get(0).getTid().intValue()); + assertEquals( + parseTime("2012-04-25 18:33:27.273"), + logcat.getNativeCrashes().get(0).getEventTime()); + + assertEquals(3113, logcat.getNativeCrashes().get(1).getPid().intValue()); + assertEquals(3113, logcat.getNativeCrashes().get(1).getTid().intValue()); + assertEquals( + parseTime("2012-04-25 18:33:27.273"), + logcat.getNativeCrashes().get(1).getEventTime()); + } + + /** Test that including extra uid column still parses the logs. */ + public void testParse_uid() throws ParseException { + List lines = + Arrays.asList( + "04-25 09:55:47.799 wifi 3064 3082 E AndroidRuntime: java.lang.Exception", + "04-25 09:55:47.799 wifi 3064 3082 E AndroidRuntime: \tat class.method1(Class.java:1)", + "04-25 09:55:47.799 wifi 3064 3082 E AndroidRuntime: \tat class.method2(Class.java:2)", + "04-25 09:55:47.799 wifi 3064 3082 E AndroidRuntime: \tat class.method3(Class.java:3)", + "04-25 09:55:47.799 wifi 3065 3090 E AndroidRuntime: java.lang.Exception", + "04-25 09:55:47.799 wifi 3065 3090 E AndroidRuntime: \tat class.method1(Class.java:1)", + "04-25 09:55:47.799 wifi 3065 3090 E AndroidRuntime: \tat class.method2(Class.java:2)", + "04-25 09:55:47.799 wifi 3065 3090 E AndroidRuntime: \tat class.method3(Class.java:3)", + "04-25 17:17:08.445 1337 312 366 E ActivityManager: ANR (application not responding) in process: com.android.package", + "04-25 17:17:08.445 1337 312 366 E ActivityManager: Reason: keyDispatchingTimedOut", + "04-25 17:17:08.445 1337 312 366 E ActivityManager: Load: 0.71 / 0.83 / 0.51", + "04-25 17:17:08.445 1337 312 366 E ActivityManager: 33% TOTAL: 21% user + 11% kernel + 0.3% iowait", + "04-25 17:17:08.445 1337 312 366 E ActivityManager: ANR (application not responding) in process: com.android.package", + "04-25 17:17:08.445 1337 312 366 E ActivityManager: Reason: keyDispatchingTimedOut", + "04-25 17:17:08.445 1337 312 366 E ActivityManager: Load: 0.71 / 0.83 / 0.51", + "04-25 17:17:08.445 1337 312 366 E ActivityManager: 33% TOTAL: 21% user + 11% kernel + 0.3% iowait", + "04-25 18:33:27.273 wifi123 115 115 I DEBUG : *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***", + "04-25 18:33:27.273 wifi123 115 115 I DEBUG : Build fingerprint: 'product:build:target'", + "04-25 18:33:27.273 wifi123 115 115 I DEBUG : pid: 3112, tid: 3112 >>> com.google.android.browser <<<", + "04-25 18:33:27.273 wifi123 115 115 I DEBUG : signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 00000000", + "04-25 18:33:27.273 wifi123 117 117 I DEBUG : *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***", + "04-25 18:33:27.273 wifi123 117 117 I DEBUG : Build fingerprint: 'product:build:target'", + "04-25 18:33:27.273 wifi123 117 117 I DEBUG : pid: 3113, tid: 3113 >>> com.google.android.browser <<<", + "04-25 18:33:27.273 wifi123 117 117 I DEBUG : signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 00000000"); + + + LogcatItem logcat = new LogcatParser("2012").parse(lines); + assertNotNull(logcat); + assertEquals(parseTime("2012-04-25 09:55:47.799"), logcat.getStartTime()); + assertEquals(parseTime("2012-04-25 18:33:27.273"), logcat.getStopTime()); + assertEquals(6, logcat.getEvents().size()); + assertEquals(2, logcat.getAnrs().size()); + assertEquals(2, logcat.getJavaCrashes().size()); + assertEquals(2, logcat.getNativeCrashes().size()); + + assertEquals(312, logcat.getAnrs().get(0).getPid().intValue()); + assertEquals(366, logcat.getAnrs().get(0).getTid().intValue()); + assertEquals(parseTime("2012-04-25 17:17:08.445"), logcat.getAnrs().get(0).getEventTime()); + + assertEquals(312, logcat.getAnrs().get(1).getPid().intValue()); + assertEquals(366, logcat.getAnrs().get(1).getTid().intValue()); + assertEquals(parseTime("2012-04-25 17:17:08.445"), logcat.getAnrs().get(1).getEventTime()); + + assertEquals(3064, logcat.getJavaCrashes().get(0).getPid().intValue()); + assertEquals(3082, logcat.getJavaCrashes().get(0).getTid().intValue()); + assertEquals(parseTime("2012-04-25 09:55:47.799"), + logcat.getJavaCrashes().get(0).getEventTime()); + + assertEquals(3065, logcat.getJavaCrashes().get(1).getPid().intValue()); + assertEquals(3090, logcat.getJavaCrashes().get(1).getTid().intValue()); + assertEquals(parseTime("2012-04-25 09:55:47.799"), + logcat.getJavaCrashes().get(1).getEventTime()); + + assertEquals(3112, logcat.getNativeCrashes().get(0).getPid().intValue()); + assertEquals(3112, logcat.getNativeCrashes().get(0).getTid().intValue()); + assertEquals(parseTime("2012-04-25 18:33:27.273"), + logcat.getNativeCrashes().get(0).getEventTime()); + + assertEquals(3113, logcat.getNativeCrashes().get(1).getPid().intValue()); + assertEquals(3113, logcat.getNativeCrashes().get(1).getTid().intValue()); + assertEquals(parseTime("2012-04-25 18:33:27.273"), + logcat.getNativeCrashes().get(1).getEventTime()); + } + + /** + * Test that multiple java crashes and native crashes can be parsed even when interleaved. + */ + public void testParse_multiple_events_interleaved() throws ParseException { + List lines = Arrays.asList( + "04-25 09:55:47.799 3064 3082 E AndroidRuntime: java.lang.Exception", + "04-25 09:55:47.799 3065 3090 E AndroidRuntime: java.lang.Exception", + "04-25 09:55:47.799 115 115 I DEBUG : *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***", + "04-25 09:55:47.799 117 117 I DEBUG : *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***", + "04-25 09:55:47.799 3064 3082 E AndroidRuntime: \tat class.method1(Class.java:1)", + "04-25 09:55:47.799 3065 3090 E AndroidRuntime: \tat class.method1(Class.java:1)", + "04-25 09:55:47.799 115 115 I DEBUG : Build fingerprint: 'product:build:target'", + "04-25 09:55:47.799 117 117 I DEBUG : Build fingerprint: 'product:build:target'", + "04-25 09:55:47.799 3064 3082 E AndroidRuntime: \tat class.method2(Class.java:2)", + "04-25 09:55:47.799 3065 3090 E AndroidRuntime: \tat class.method2(Class.java:2)", + "04-25 09:55:47.799 115 115 I DEBUG : pid: 3112, tid: 3112 >>> com.google.android.browser <<<", + "04-25 09:55:47.799 117 117 I DEBUG : pid: 3113, tid: 3113 >>> com.google.android.browser <<<", + "04-25 09:55:47.799 3064 3082 E AndroidRuntime: \tat class.method3(Class.java:3)", + "04-25 09:55:47.799 3065 3090 E AndroidRuntime: \tat class.method3(Class.java:3)", + "04-25 09:55:47.799 115 115 I DEBUG : signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 00000000", + "04-25 09:55:47.799 117 117 I DEBUG : signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 00000000"); + + LogcatItem logcat = new LogcatParser("2012").parse(lines); + assertNotNull(logcat); + assertEquals(parseTime("2012-04-25 09:55:47.799"), logcat.getStartTime()); + assertEquals(parseTime("2012-04-25 09:55:47.799"), logcat.getStopTime()); + assertEquals(4, logcat.getEvents().size()); + assertEquals(0, logcat.getAnrs().size()); + assertEquals(2, logcat.getJavaCrashes().size()); + assertEquals(2, logcat.getNativeCrashes().size()); + + assertEquals(3064, logcat.getJavaCrashes().get(0).getPid().intValue()); + assertEquals(3082, logcat.getJavaCrashes().get(0).getTid().intValue()); + assertEquals(parseTime("2012-04-25 09:55:47.799"), + logcat.getJavaCrashes().get(0).getEventTime()); + + assertEquals(3065, logcat.getJavaCrashes().get(1).getPid().intValue()); + assertEquals(3090, logcat.getJavaCrashes().get(1).getTid().intValue()); + assertEquals(parseTime("2012-04-25 09:55:47.799"), + logcat.getJavaCrashes().get(1).getEventTime()); + + assertEquals(3112, logcat.getNativeCrashes().get(0).getPid().intValue()); + assertEquals(3112, logcat.getNativeCrashes().get(0).getTid().intValue()); + assertEquals(parseTime("2012-04-25 09:55:47.799"), + logcat.getNativeCrashes().get(0).getEventTime()); + + assertEquals(3113, logcat.getNativeCrashes().get(1).getPid().intValue()); + assertEquals(3113, logcat.getNativeCrashes().get(1).getTid().intValue()); + assertEquals(parseTime("2012-04-25 09:55:47.799"), + logcat.getNativeCrashes().get(1).getEventTime()); + } + + /** + * Test that the preambles are set correctly. + */ + public void testParse_preambles() throws ParseException { + List lines = Arrays.asList( + "04-25 09:15:47.799 123 3082 I tag: message 1", + "04-25 09:20:47.799 3064 3082 I tag: message 2", + "04-25 09:25:47.799 345 3082 I tag: message 3", + "04-25 09:30:47.799 3064 3082 I tag: message 4", + "04-25 09:35:47.799 456 3082 I tag: message 5", + "04-25 09:40:47.799 3064 3082 I tag: message 6", + "04-25 09:45:47.799 567 3082 I tag: message 7", + "04-25 09:50:47.799 3064 3082 I tag: message 8", + "04-25 09:55:47.799 3064 3082 E AndroidRuntime: java.lang.Exception", + "04-25 09:55:47.799 3064 3082 E AndroidRuntime: \tat class.method1(Class.java:1)", + "04-25 09:55:47.799 3064 3082 E AndroidRuntime: \tat class.method2(Class.java:2)", + "04-25 09:55:47.799 3064 3082 E AndroidRuntime: \tat class.method3(Class.java:3)"); + + List expectedLastPreamble = Arrays.asList( + "04-25 09:15:47.799 123 3082 I tag: message 1", + "04-25 09:20:47.799 3064 3082 I tag: message 2", + "04-25 09:25:47.799 345 3082 I tag: message 3", + "04-25 09:30:47.799 3064 3082 I tag: message 4", + "04-25 09:35:47.799 456 3082 I tag: message 5", + "04-25 09:40:47.799 3064 3082 I tag: message 6", + "04-25 09:45:47.799 567 3082 I tag: message 7", + "04-25 09:50:47.799 3064 3082 I tag: message 8"); + + List expectedProcPreamble = Arrays.asList( + "04-25 09:20:47.799 3064 3082 I tag: message 2", + "04-25 09:30:47.799 3064 3082 I tag: message 4", + "04-25 09:40:47.799 3064 3082 I tag: message 6", + "04-25 09:50:47.799 3064 3082 I tag: message 8"); + + LogcatItem logcat = new LogcatParser("2012").parse(lines); + assertNotNull(logcat); + assertEquals(parseTime("2012-04-25 09:15:47.799"), logcat.getStartTime()); + assertEquals(parseTime("2012-04-25 09:55:47.799"), logcat.getStopTime()); + assertEquals(1, logcat.getEvents().size()); + assertEquals(1, logcat.getJavaCrashes().size()); + assertEquals(3064, logcat.getJavaCrashes().get(0).getPid().intValue()); + assertEquals(3082, logcat.getJavaCrashes().get(0).getTid().intValue()); + assertEquals(ArrayUtil.join("\n", expectedLastPreamble), + logcat.getJavaCrashes().get(0).getLastPreamble()); + assertEquals(ArrayUtil.join("\n", expectedProcPreamble), + logcat.getJavaCrashes().get(0).getProcessPreamble()); + assertEquals(parseTime("2012-04-25 09:55:47.799"), + logcat.getJavaCrashes().get(0).getEventTime()); + } + + /** + * Test that events while the device is rebooting are ignored. + */ + public void testParse_reboot() throws ParseException { + List lines = Arrays.asList( + "04-25 09:15:47.799 123 3082 I ShutdownThread: Rebooting, reason: null", + "04-25 09:55:47.799 3064 3082 E AndroidRuntime: java.lang.Exception", + "04-25 09:55:47.799 3064 3082 E AndroidRuntime: \tat class.method1(Class.java:1)", + "04-25 09:55:47.799 3064 3082 E AndroidRuntime: \tat class.method2(Class.java:2)", + "04-25 09:55:47.799 3064 3082 E AndroidRuntime: \tat class.method3(Class.java:3)"); + + LogcatItem logcat = new LogcatParser("2012").parse(lines); + assertNotNull(logcat); + assertEquals(parseTime("2012-04-25 09:15:47.799"), logcat.getStartTime()); + assertEquals(parseTime("2012-04-25 09:55:47.799"), logcat.getStopTime()); + assertEquals(0, logcat.getEvents().size()); + } + + /** + * Test that events while the device is rebooting are ignored, but devices after the reboot are + * captured. + */ + public void testParse_reboot_resume() throws ParseException { + List lines = Arrays.asList( + "04-25 09:15:47.799 123 3082 I ShutdownThread: Rebooting, reason: null", + "04-25 09:55:47.799 3064 3082 E AndroidRuntime: java.lang.Exception", + "04-25 09:55:47.799 3064 3082 E AndroidRuntime: \tat class.method1(Class.java:1)", + "04-25 09:55:47.799 3064 3082 E AndroidRuntime: \tat class.method2(Class.java:2)", + "04-25 09:55:47.799 3064 3082 E AndroidRuntime: \tat class.method3(Class.java:3)", + "logcat interrupted. May see duplicated content in log.--------- beginning of /dev/log/main", + "04-25 09:59:47.799 3064 3082 E AndroidRuntime: java.lang.Exception2", + "04-25 09:59:47.799 3064 3082 E AndroidRuntime: \tat class.method1(Class.java:1)", + "04-25 09:59:47.799 3064 3082 E AndroidRuntime: \tat class.method2(Class.java:2)", + "04-25 09:59:47.799 3064 3082 E AndroidRuntime: \tat class.method3(Class.java:3)"); + + + LogcatItem logcat = new LogcatParser("2012").parse(lines); + assertNotNull(logcat); + assertEquals(parseTime("2012-04-25 09:15:47.799"), logcat.getStartTime()); + assertEquals(parseTime("2012-04-25 09:59:47.799"), logcat.getStopTime()); + assertEquals(1, logcat.getEvents().size()); + assertEquals("java.lang.Exception2", logcat.getJavaCrashes().get(0).getException()); + + lines = Arrays.asList( + "04-25 09:15:47.799 123 3082 I ShutdownThread: Rebooting, reason: null", + "04-25 09:55:47.799 3064 3082 E AndroidRuntime: java.lang.Exception", + "04-25 09:55:47.799 3064 3082 E AndroidRuntime: \tat class.method1(Class.java:1)", + "04-25 09:55:47.799 3064 3082 E AndroidRuntime: \tat class.method2(Class.java:2)", + "04-25 09:55:47.799 3064 3082 E AndroidRuntime: \tat class.method3(Class.java:3)", + "logcat interrupted. May see duplicated content in log.--------- beginning of main", + "04-25 09:59:47.799 3064 3082 E AndroidRuntime: java.lang.Exception2", + "04-25 09:59:47.799 3064 3082 E AndroidRuntime: \tat class.method1(Class.java:1)", + "04-25 09:59:47.799 3064 3082 E AndroidRuntime: \tat class.method2(Class.java:2)", + "04-25 09:59:47.799 3064 3082 E AndroidRuntime: \tat class.method3(Class.java:3)"); + + + logcat = new LogcatParser("2012").parse(lines); + assertNotNull(logcat); + assertEquals(parseTime("2012-04-25 09:15:47.799"), logcat.getStartTime()); + assertEquals(parseTime("2012-04-25 09:59:47.799"), logcat.getStopTime()); + assertEquals(1, logcat.getEvents().size()); + assertEquals("java.lang.Exception2", logcat.getJavaCrashes().get(0).getException()); + } + + /** + * Test that the time logcat format can be parsed. + */ + public void testParse_time() throws ParseException { + List lines = Arrays.asList( + "04-25 09:55:47.799 E/AndroidRuntime(3064): java.lang.Exception", + "04-25 09:55:47.799 E/AndroidRuntime(3064): \tat class.method1(Class.java:1)", + "04-25 09:55:47.799 E/AndroidRuntime(3064): \tat class.method2(Class.java:2)", + "04-25 09:55:47.799 E/AndroidRuntime(3064): \tat class.method3(Class.java:3)"); + + LogcatItem logcat = new LogcatParser("2012").parse(lines); + assertNotNull(logcat); + assertEquals(parseTime("2012-04-25 09:55:47.799"), logcat.getStartTime()); + assertEquals(parseTime("2012-04-25 09:55:47.799"), logcat.getStopTime()); + assertEquals(1, logcat.getEvents().size()); + assertEquals(1, logcat.getJavaCrashes().size()); + assertEquals(3064, logcat.getJavaCrashes().get(0).getPid().intValue()); + assertNull(logcat.getJavaCrashes().get(0).getTid()); + assertEquals(parseTime("2012-04-25 09:55:47.799"), + logcat.getJavaCrashes().get(0).getEventTime()); + } + + /** + * Test that we can add and find custom patterns that match based on logcat Tags only. + */ + public void testAddPattern_byTagOnly() { + List lines = Arrays.asList( + "04-25 18:33:28.273 7813 7813 E HelloTag: Hello everyone!!!1", + "04-25 18:33:29.273 395 637 I Watchdog: find me!", + "04-25 18:33:39.273 395 637 W Watchdog: find me!"); + + LogcatParser parser = new LogcatParser("2012"); + assertNotNull(parser); + parser.addPattern(null, null, "HelloTag", "HelloCategory"); + parser.addPattern(null, null, "Watchdog", "WatchdogCategory"); + LogcatItem logcat = parser.parse(lines); + assertNotNull(logcat); + + /* verify that we find the HelloTag entry */ + List matchedEvents = logcat.getMiscEvents("HelloCategory"); + assertEquals(1, matchedEvents.size()); + assertEquals("HelloTag", matchedEvents.get(0).getTag()); + + /* verify that we find both Watchdog entries */ + matchedEvents = logcat.getMiscEvents("WatchdogCategory"); + assertEquals(2, matchedEvents.size()); + assertEquals("Watchdog", matchedEvents.get(0).getTag()); + } + + /** + * Test that we can add and find custom patterns that match based on Level AND Tag. + */ + public void testAddPattern_byLevelAndTagOnly() { + List lines = Arrays.asList( + "04-25 18:33:28.273 7813 7813 E HelloTag: GetBufferLock timed out for thread 7813 buffer 0x61 usage 0x200 LockState 1", + "04-25 18:33:29.273 395 637 I Watchdog: Info", + "04-25 18:33:29.273 395 637 W Watchdog: Warning"); + + LogcatParser parser = new LogcatParser("2012"); + assertNotNull(parser); + parser.addPattern(null, "I", "Watchdog", "WatchdogCategory"); + LogcatItem logcat = parser.parse(lines); + assertNotNull(logcat); + + List matchedEvents = logcat.getMiscEvents("WatchdogCategory"); + assertEquals(1, matchedEvents.size()); + assertEquals("Watchdog", matchedEvents.get(0).getTag()); + assertEquals("Info", matchedEvents.get(0).getStack()); + } + + /** + * Test that we can add and find custom patterns that match based on Level, Tag, AND Message. + */ + public void testAddPattern_byLevelTagAndMessageOnly() { + List lines = Arrays.asList( + "04-25 18:33:29.273 395 637 W Watchdog: I'm the one you need to find!", + "04-25 18:33:29.273 395 637 W Watchdog: my message doesn't match.", + "04-25 18:33:29.273 395 637 I Watchdog: my Level doesn't match, try and find me!", + "04-25 18:33:29.273 395 637 W NotMe: my Tag doesn't match, try and find me!"); + + LogcatParser parser = new LogcatParser("2012"); + assertNotNull(parser); + parser.addPattern(Pattern.compile(".*find*."), "W", "Watchdog", "WatchdogCategory"); + LogcatItem logcat = parser.parse(lines); + assertNotNull(logcat); + + /* verify that we find the only entry that matches based on Level, Tag, AND Message */ + List matchedEvents = logcat.getMiscEvents("WatchdogCategory"); + assertEquals(1, matchedEvents.size()); + assertEquals("Watchdog", matchedEvents.get(0).getTag()); + assertEquals("I'm the one you need to find!", matchedEvents.get(0).getStack()); + } + + public void testFatalException() { + List lines = Arrays.asList( + "06-05 06:14:51.529 1712 1712 D AndroidRuntime: Calling main entry com.android.commands.input.Input", + "06-05 06:14:51.709 1712 1712 E AndroidRuntime: *** FATAL EXCEPTION IN SYSTEM PROCESS: main", + "06-05 06:14:51.709 1712 1712 E AndroidRuntime: java.lang.NullPointerException", + "06-05 06:14:51.709 1712 1712 E AndroidRuntime: \tat android.hardware.input.InputManager.injectInputEvent(InputManager.java:641)", + "06-05 06:14:51.709 1712 1712 E AndroidRuntime: \tat com.android.commands.input.Input.injectKeyEvent(Input.java:233)", + "06-05 06:14:51.709 1712 1712 E AndroidRuntime: \tat com.android.commands.input.Input.sendKeyEvent(Input.java:184)", + "06-05 06:14:51.709 1712 1712 E AndroidRuntime: \tat com.android.commands.input.Input.run(Input.java:96)", + "06-05 06:14:51.709 1712 1712 E AndroidRuntime: \tat com.android.commands.input.Input.main(Input.java:59)", + "06-05 06:14:51.709 1712 1712 E AndroidRuntime: \tat com.android.internal.os.RuntimeInit.nativeFinishInit(Native Method)", + "06-05 06:14:51.709 1712 1712 E AndroidRuntime: \tat com.android.internal.os.RuntimeInit.main(RuntimeInit.java:243)", + "06-05 06:14:51.709 1712 1712 E AndroidRuntime: \tat dalvik.system.NativeStart.main(Native Method)"); + LogcatParser parser = new LogcatParser("2014"); + LogcatItem logcat = parser.parse(lines); + assertEquals(1, logcat.getJavaCrashes().size()); + JavaCrashItem crash = logcat.getJavaCrashes().get(0); + assertEquals("com.android.commands.input.Input", crash.getApp()); + } + + /** + * Test that an empty input returns {@code null}. + */ + public void testEmptyInput() { + LogcatItem item = new LogcatParser().parse(Arrays.asList("")); + assertNull(item); + } + + /** + * Test that after clearing a parser, reusing it produces a new LogcatItem instead of + * appending to the previous one. + */ + public void testClear() { + List lines = Arrays.asList( + "04-25 18:33:28.273 7813 7813 E HelloTag: GetBufferLock timed out for thread 7813 buffer 0x61 usage 0x200 LockState 1", + "04-25 18:33:28.273 7813 7813 E GoodbyeTag: GetBufferLock timed out for thread 7813 buffer 0x61 usage 0x200 LockState 1" + ); + LogcatParser parser = new LogcatParser(); + LogcatItem l1 = parser.parse(lines.subList(0, 1)); + parser.clear(); + LogcatItem l2 = parser.parse(lines.subList(1, 2)); + assertEquals(l1.getEvents().size(), 1); + assertEquals(l2.getEvents().size(), 1); + assertFalse(l1.getEvents().get(0).getTag().equals(l2.getEvents().get(0).getTag())); + } + + private Date parseTime(String timeStr) throws ParseException { + DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS"); + return formatter.parse(timeStr); + } +} diff --git a/javatests/src/com/android/loganalysis/parser/MemHealthParserTest.java b/javatests/src/com/android/loganalysis/parser/MemHealthParserTest.java new file mode 100644 index 0000000..4659b76 --- /dev/null +++ b/javatests/src/com/android/loganalysis/parser/MemHealthParserTest.java @@ -0,0 +1,184 @@ +/* + * Copyright (C) 2015 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.MemoryHealthItem; + +import junit.framework.TestCase; + +import java.util.Arrays; +import java.util.List; +import java.util.Map; + +/** + * Tests for memory health parser. + */ +public class MemHealthParserTest extends TestCase { + public void testOneForegroundProc() { + List lines = Arrays.asList("Foreground", + "com.google.android.gm", + "Average Native Heap: 10910", + "Average Dalvik Heap: 8011", + "Average PSS: 90454", + "Peak Native Heap: 11136", + "Peak Dalvik Heap: 9812", + "Peak PSS: 95161", + "Average Summary Java Heap: 8223", + "Average Summary Native Heap: 3852", + "Average Summary Code: 1804", + "Average Summary Stack: 246", + "Average Summary Graphics: 0", + "Average Summary Other: 855", + "Average Summary System: 9151", + "Average Summary Overall Pss: 24135", + "Count 528" + ); + + MemoryHealthItem item = new MemoryHealthParser().parse(lines); + Map> processes = item.getForeground(); + assertNotNull(processes); + assertNotNull(processes.get("com.google.android.gm")); + Map process = processes.get("com.google.android.gm"); + assertEquals(10910, process.get("native_avg").longValue()); + assertEquals(8011, process.get("dalvik_avg").longValue()); + assertEquals(90454, process.get("pss_avg").longValue()); + assertEquals(11136, process.get("native_peak").longValue()); + assertEquals(9812, process.get("dalvik_peak").longValue()); + assertEquals(95161, process.get("pss_peak").longValue()); + assertEquals(8223, process.get("summary_java_heap_avg").longValue()); + assertEquals(3852, process.get("summary_native_heap_avg").longValue()); + assertEquals(1804, process.get("summary_code_avg").longValue()); + assertEquals(246, process.get("summary_stack_avg").longValue()); + assertEquals(0, process.get("summary_graphics_avg").longValue()); + assertEquals(855, process.get("summary_other_avg").longValue()); + assertEquals(9151, process.get("summary_system_avg").longValue()); + assertEquals(24135, process.get("summary_overall_pss_avg").longValue()); + } + + public void testTwoForegroundProc() { + List lines = Arrays.asList("Foreground", + "com.google.android.gm", + "Average Native Heap: 10910", + "Average Dalvik Heap: 8011", + "Average PSS: 90454", + "Peak Native Heap: 11136", + "Peak Dalvik Heap: 9812", + "Peak PSS: 95161", + "Average Summary Java Heap: 8223", + "Average Summary Native Heap: 3852", + "Average Summary Code: 1804", + "Average Summary Stack: 246", + "Average Summary Graphics: 0", + "Average Summary Other: 855", + "Average Summary System: 9151", + "Average Summary Overall Pss: 24135", + "Count 528", + "com.google.android.music", + "Average Native Heap: 1", + "Average Dalvik Heap: 2", + "Average PSS: 3", + "Peak Native Heap: 4", + "Peak Dalvik Heap: 5", + "Peak PSS: 6", + "Average Summary Java Heap: 7", + "Average Summary Native Heap: 8", + "Average Summary Code: 9", + "Average Summary Stack: 10", + "Average Summary Graphics: 11", + "Average Summary Other: 12", + "Average Summary System: 13", + "Average Summary Overall Pss: 14", + "Count 7" + ); + + MemoryHealthItem item = new MemoryHealthParser().parse(lines); + Map> processes = item.getForeground(); + assertEquals(2, processes.size()); + Map process = processes.get("com.google.android.music"); + assertEquals(1, process.get("native_avg").longValue()); + assertEquals(2, process.get("dalvik_avg").longValue()); + assertEquals(3, process.get("pss_avg").longValue()); + assertEquals(4, process.get("native_peak").longValue()); + assertEquals(5, process.get("dalvik_peak").longValue()); + assertEquals(6, process.get("pss_peak").longValue()); + assertEquals(7, process.get("summary_java_heap_avg").longValue()); + assertEquals(8, process.get("summary_native_heap_avg").longValue()); + assertEquals(9, process.get("summary_code_avg").longValue()); + assertEquals(10, process.get("summary_stack_avg").longValue()); + assertEquals(11, process.get("summary_graphics_avg").longValue()); + assertEquals(12, process.get("summary_other_avg").longValue()); + assertEquals(13, process.get("summary_system_avg").longValue()); + assertEquals(14, process.get("summary_overall_pss_avg").longValue()); + } + + public void testForegroundBackgroundProc() { + List lines = Arrays.asList("Foreground", + "com.google.android.gm", + "Average Native Heap: 10910", + "Average Dalvik Heap: 8011", + "Average PSS: 90454", + "Peak Native Heap: 11136", + "Peak Dalvik Heap: 9812", + "Peak PSS: 95161", + "Average Summary Java Heap: 8223", + "Average Summary Native Heap: 3852", + "Average Summary Code: 1804", + "Average Summary Stack: 246", + "Average Summary Graphics: 0", + "Average Summary Other: 855", + "Average Summary System: 9151", + "Average Summary Overall Pss: 24135", + "Count 528", + "Background", + "com.google.android.music", + "Average Native Heap: 1", + "Average Dalvik Heap: 2", + "Average PSS: 3", + "Peak Native Heap: 4", + "Peak Dalvik Heap: 5", + "Peak PSS: 6", + "Average Summary Java Heap: 7", + "Average Summary Native Heap: 8", + "Average Summary Code: 9", + "Average Summary Stack: 10", + "Average Summary Graphics: 11", + "Average Summary Other: 12", + "Average Summary System: 13", + "Average Summary Overall Pss: 14", + "Count 7" + ); + + MemoryHealthItem item = new MemoryHealthParser().parse(lines); + Map> processes = item.getForeground(); + assertEquals(1, processes.size()); + assertEquals(1, item.getBackground().size()); + Map process = item.getBackground().get("com.google.android.music"); + assertEquals(1, process.get("native_avg").longValue()); + assertEquals(2, process.get("dalvik_avg").longValue()); + assertEquals(3, process.get("pss_avg").longValue()); + assertEquals(4, process.get("native_peak").longValue()); + assertEquals(5, process.get("dalvik_peak").longValue()); + assertEquals(6, process.get("pss_peak").longValue()); + assertEquals(7, process.get("summary_java_heap_avg").longValue()); + assertEquals(8, process.get("summary_native_heap_avg").longValue()); + assertEquals(9, process.get("summary_code_avg").longValue()); + assertEquals(10, process.get("summary_stack_avg").longValue()); + assertEquals(11, process.get("summary_graphics_avg").longValue()); + assertEquals(12, process.get("summary_other_avg").longValue()); + assertEquals(13, process.get("summary_system_avg").longValue()); + assertEquals(14, process.get("summary_overall_pss_avg").longValue()); + } +} diff --git a/javatests/src/com/android/loganalysis/parser/MemInfoParserTest.java b/javatests/src/com/android/loganalysis/parser/MemInfoParserTest.java new file mode 100644 index 0000000..ab41b33 --- /dev/null +++ b/javatests/src/com/android/loganalysis/parser/MemInfoParserTest.java @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2011 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.MemInfoItem; +import com.android.loganalysis.util.ArrayUtil; + +import junit.framework.TestCase; + +import java.util.Arrays; +import java.util.List; + +/** + * Unit tests for {@link MemInfoParser} + */ +public class MemInfoParserTest extends TestCase { + + /** + * Test that normal input is parsed. + */ + public void testMemInfoParser() { + List inputBlock = Arrays.asList( + "MemTotal: 353332 kB", + "MemFree: 65420 kB", + "Buffers: 20800 kB", + "Cached: 86204 kB", + "SwapCached: 0 kB", + "Long: 34359640152 kB", + "ExtraLongIgnore: 12345678901234567890 kB"); + + MemInfoItem item = new MemInfoParser().parse(inputBlock); + + assertEquals(6, item.size()); + assertEquals((Long)353332l, item.get("MemTotal")); + assertEquals((Long)65420l, item.get("MemFree")); + assertEquals((Long)20800l, item.get("Buffers")); + assertEquals((Long)86204l, item.get("Cached")); + assertEquals((Long)0l, item.get("SwapCached")); + assertEquals((Long)34359640152l, item.get("Long")); + assertNull(item.get("ExtraLongIgnore")); + assertEquals(ArrayUtil.join("\n", inputBlock), item.getText()); + } + + /** + * Test that an empty input returns {@code null}. + */ + public void testEmptyInput() { + MemInfoItem item = new MemInfoParser().parse(Arrays.asList("")); + assertNull(item); + } +} diff --git a/javatests/src/com/android/loganalysis/parser/MonkeyLogParserTest.java b/javatests/src/com/android/loganalysis/parser/MonkeyLogParserTest.java new file mode 100644 index 0000000..b7e867d --- /dev/null +++ b/javatests/src/com/android/loganalysis/parser/MonkeyLogParserTest.java @@ -0,0 +1,786 @@ +/* + * Copyright (C) 2012 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.AnrItem; +import com.android.loganalysis.item.JavaCrashItem; +import com.android.loganalysis.item.MonkeyLogItem; +import com.android.loganalysis.item.MonkeyLogItem.DroppedCategory; +import com.android.loganalysis.item.NativeCrashItem; +import com.android.loganalysis.util.ArrayUtil; + +import junit.framework.TestCase; + +import java.text.DateFormat; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Arrays; +import java.util.Date; +import java.util.List; + +/** + * Unit tests for {@link MonkeyLogParser} + */ +public class MonkeyLogParserTest extends TestCase { + + /** + * Test that a monkey can be parsed if there are no crashes. + */ + public void testParse_success() { + List lines = Arrays.asList( + "# Wednesday, 04/25/2012 01:37:12 AM - device uptime = 242.13: Monkey command used for this test:", + "adb shell monkey -p com.google.android.browser -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 528 -v -v -v 10000 ", + "", + ":Monkey: seed=528 count=10000", + ":AllowPackage: com.google.android.browser", + ":IncludeCategory: android.intent.category.LAUNCHER", + ":Switch: #Intent;action=android.intent.action.MAIN;category=android.intent.category.LAUNCHER;launchFlags=0x10200000;component=com.google.android.browser/com.android.browser.BrowserActivity;end", + " // Allowing start of Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] cmp=com.google.android.browser/com.android.browser.BrowserActivity } in package com.google.android.browser", + "Sleeping for 100 milliseconds", + ":Sending Key (ACTION_DOWN): 23 // KEYCODE_DPAD_CENTER", + ":Sending Key (ACTION_UP): 23 // KEYCODE_DPAD_CENTER", + "Sleeping for 100 milliseconds", + ":Sending Trackball (ACTION_MOVE): 0:(-5.0,3.0)", + ":Sending Trackball (ACTION_MOVE): 0:(3.0,3.0)", + ":Sending Trackball (ACTION_MOVE): 0:(-1.0,3.0)", + ":Sending Trackball (ACTION_MOVE): 0:(4.0,-2.0)", + ":Sending Trackball (ACTION_MOVE): 0:(1.0,4.0)", + ":Sending Trackball (ACTION_MOVE): 0:(-4.0,2.0)", + " //[calendar_time:2012-04-25 01:42:20.140 system_uptime:535179]", + " // Sending event #9900", + ":Sending Trackball (ACTION_MOVE): 0:(2.0,-4.0)", + ":Sending Trackball (ACTION_MOVE): 0:(-2.0,0.0)", + ":Sending Trackball (ACTION_MOVE): 0:(2.0,2.0)", + ":Sending Trackball (ACTION_MOVE): 0:(-5.0,4.0)", + "Events injected: 10000", + ":Dropped: keys=5 pointers=6 trackballs=7 flips=8 rotations=9", + "// Monkey finished", + "", + "# Wednesday, 04/25/2012 01:42:09 AM - device uptime = 539.21: Monkey command ran for: 04:57 (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-25 01:37:12"), monkeyLog.getStartTime()); + // assertEquals(parseTime("2012-04-25 01:42:09"), monkeyLog.getStopTime()); + assertEquals(1, monkeyLog.getPackages().size()); + assertTrue(monkeyLog.getPackages().contains("com.google.android.browser")); + assertEquals(1, monkeyLog.getCategories().size()); + assertTrue(monkeyLog.getCategories().contains("android.intent.category.LAUNCHER")); + assertEquals(100, monkeyLog.getThrottle()); + assertEquals(528, monkeyLog.getSeed().intValue()); + assertEquals(10000, monkeyLog.getTargetCount().intValue()); + assertTrue(monkeyLog.getIgnoreSecurityExceptions()); + assertEquals(4 * 60 * 1000 + 57 * 1000, monkeyLog.getTotalDuration().longValue()); + assertEquals(242130, monkeyLog.getStartUptimeDuration().longValue()); + assertEquals(539210, monkeyLog.getStopUptimeDuration().longValue()); + assertTrue(monkeyLog.getIsFinished()); + assertFalse(monkeyLog.getNoActivities()); + assertEquals(9900, monkeyLog.getIntermediateCount()); + assertEquals(10000, monkeyLog.getFinalCount().intValue()); + assertEquals(5, monkeyLog.getDroppedCount(DroppedCategory.KEYS).intValue()); + assertEquals(6, monkeyLog.getDroppedCount(DroppedCategory.POINTERS).intValue()); + assertEquals(7, monkeyLog.getDroppedCount(DroppedCategory.TRACKBALLS).intValue()); + assertEquals(8, monkeyLog.getDroppedCount(DroppedCategory.FLIPS).intValue()); + assertEquals(9, monkeyLog.getDroppedCount(DroppedCategory.ROTATIONS).intValue()); + assertNull(monkeyLog.getCrash()); + } + + /** + * Test that a monkey can be parsed if there is an ANR. + */ + public void testParse_anr() { + List 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 3301)", + "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", + "", + "procrank:", + "// procrank status was 0", + "anr traces:", + "", + "", + "----- pid 2887 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)", + " at class.method2(Class.java:2)", + " at class.method2(Class.java:2)", + "", + "----- end 2887 -----", + "// 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)", + "", + "----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------", + ""); + + List expectedStack = Arrays.asList( + "\"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)", + " at class.method2(Class.java:2)", + " at class.method2(Class.java:2)"); + + 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()); + assertEquals(ArrayUtil.join("\n", expectedStack), + ((AnrItem) monkeyLog.getCrash()).getTrace()); + } + + /** + * Test that a monkey can be parsed if there is a Java crash. + */ + public void testParse_java_crash() { + List lines = Arrays.asList( + "# Tuesday, 04/24/2012 05:05:50 PM - device uptime = 232.65: Monkey command used for this test:", + "adb shell monkey -p com.google.android.apps.maps -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 501 -v -v -v 10000 ", + "", + ":Monkey: seed=501 count=10000", + ":AllowPackage: com.google.android.apps.maps", + ":IncludeCategory: android.intent.category.LAUNCHER", + ":Switch: #Intent;action=android.intent.action.MAIN;category=android.intent.category.LAUNCHER;launchFlags=0x10200000;component=com.google.android.apps.maps/com.google.android.maps.LatitudeActivity;end", + " // Allowing start of Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] cmp=com.google.android.apps.maps/com.google.android.maps.LatitudeActivity } in package com.google.android.apps.maps", + "Sleeping for 100 milliseconds", + ":Sending Touch (ACTION_DOWN): 0:(332.0,70.0)", + ":Sending Touch (ACTION_UP): 0:(332.55292,76.54678)", + " //[calendar_time:2012-04-25 00:06:38.419 system_uptime:280799]", + " // Sending event #1600", + ":Sending Touch (ACTION_MOVE): 0:(1052.2666,677.64594)", + ":Sending Touch (ACTION_UP): 0:(1054.7593,687.3757)", + "Sleeping for 100 milliseconds", + "// CRASH: com.google.android.apps.maps (pid 3161)", + "// Short Msg: java.lang.Exception", + "// Long Msg: java.lang.Exception: This is the message", + "// Build Label: google/yakju/maguro:JellyBean/JRN24B/338896:userdebug/dev-keys", + "// Build Changelist: 338896", + "// Build Time: 1335309051000", + "// java.lang.Exception: This is the message", + "// \tat class.method1(Class.java:1)", + "// \tat class.method2(Class.java:2)", + "// \tat class.method3(Class.java:3)", + "// ", + "** Monkey aborted due to error.", + "Events injected: 1649", + ":Sending rotation degree=0, persist=false", + ":Dropped: keys=0 pointers=0 trackballs=0 flips=0 rotations=0", + "## Network stats: elapsed time=48897ms (0ms mobile, 48897ms wifi, 0ms not connected)", + "** System appears to have crashed at event 1649 of 10000 using seed 501", + "", + "# Tuesday, 04/24/2012 05:06:40 PM - device uptime = 282.53: Monkey command ran for: 00:49 (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:05:50"), monkeyLog.getStartTime()); + // assertEquals(parseTime("2012-04-24 17:06:40"), monkeyLog.getStopTime()); + assertEquals(1, monkeyLog.getPackages().size()); + assertTrue(monkeyLog.getPackages().contains("com.google.android.apps.maps")); + assertEquals(1, monkeyLog.getCategories().size()); + assertTrue(monkeyLog.getCategories().contains("android.intent.category.LAUNCHER")); + assertEquals(100, monkeyLog.getThrottle()); + assertEquals(501, monkeyLog.getSeed().intValue()); + assertEquals(10000, monkeyLog.getTargetCount().intValue()); + assertTrue(monkeyLog.getIgnoreSecurityExceptions()); + assertEquals(49 * 1000, monkeyLog.getTotalDuration().longValue()); + assertEquals(232650, monkeyLog.getStartUptimeDuration().longValue()); + assertEquals(282530, monkeyLog.getStopUptimeDuration().longValue()); + assertFalse(monkeyLog.getIsFinished()); + assertFalse(monkeyLog.getNoActivities()); + assertEquals(1600, monkeyLog.getIntermediateCount()); + assertEquals(1649, monkeyLog.getFinalCount().intValue()); + assertNotNull(monkeyLog.getCrash()); + assertTrue(monkeyLog.getCrash() instanceof JavaCrashItem); + assertEquals("com.google.android.apps.maps", monkeyLog.getCrash().getApp()); + assertEquals(3161, monkeyLog.getCrash().getPid().intValue()); + assertEquals("java.lang.Exception", ((JavaCrashItem) monkeyLog.getCrash()).getException()); + } + + /** + * Test that a monkey can be parsed if there is a Java crash even if monkey lines are mixed in + * the crash. + */ + public void testParse_java_crash_mixed() { + List lines = Arrays.asList( + "# Tuesday, 04/24/2012 05:05:50 PM - device uptime = 232.65: Monkey command used for this test:", + "adb shell monkey -p com.google.android.apps.maps -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 501 -v -v -v 10000 ", + "", + ":Monkey: seed=501 count=10000", + ":AllowPackage: com.google.android.apps.maps", + ":IncludeCategory: android.intent.category.LAUNCHER", + ":Switch: #Intent;action=android.intent.action.MAIN;category=android.intent.category.LAUNCHER;launchFlags=0x10200000;component=com.google.android.apps.maps/com.google.android.maps.LatitudeActivity;end", + " // Allowing start of Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] cmp=com.google.android.apps.maps/com.google.android.maps.LatitudeActivity } in package com.google.android.apps.maps", + "Sleeping for 100 milliseconds", + ":Sending Touch (ACTION_DOWN): 0:(332.0,70.0)", + ":Sending Touch (ACTION_UP): 0:(332.55292,76.54678)", + " //[calendar_time:2012-04-25 00:06:38.419 system_uptime:280799]", + " // Sending event #1600", + ":Sending Touch (ACTION_MOVE): 0:(1052.2666,677.64594)", + "// CRASH: com.google.android.apps.maps (pid 3161)", + "// Short Msg: java.lang.Exception", + ":Sending Touch (ACTION_UP): 0:(1054.7593,687.3757)", + "// Long Msg: java.lang.Exception: This is the message", + "// Build Label: google/yakju/maguro:JellyBean/JRN24B/338896:userdebug/dev-keys", + "// Build Changelist: 338896", + "Sleeping for 100 milliseconds", + "// Build Time: 1335309051000", + "// java.lang.Exception: This is the message", + "// \tat class.method1(Class.java:1)", + "// \tat class.method2(Class.java:2)", + "// \tat class.method3(Class.java:3)", + "// ", + "** Monkey aborted due to error.", + "Events injected: 1649", + ":Sending rotation degree=0, persist=false", + ":Dropped: keys=0 pointers=0 trackballs=0 flips=0 rotations=0", + "## Network stats: elapsed time=48897ms (0ms mobile, 48897ms wifi, 0ms not connected)", + "** System appears to have crashed at event 1649 of 10000 using seed 501", + "", + "# Tuesday, 04/24/2012 05:06:40 PM - device uptime = 282.53: Monkey command ran for: 00:49 (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:05:50"), monkeyLog.getStartTime()); + // assertEquals(parseTime("2012-04-24 17:06:40"), monkeyLog.getStopTime()); + assertEquals(1, monkeyLog.getPackages().size()); + assertTrue(monkeyLog.getPackages().contains("com.google.android.apps.maps")); + assertEquals(1, monkeyLog.getCategories().size()); + assertTrue(monkeyLog.getCategories().contains("android.intent.category.LAUNCHER")); + assertEquals(100, monkeyLog.getThrottle()); + assertEquals(501, monkeyLog.getSeed().intValue()); + assertEquals(10000, monkeyLog.getTargetCount().intValue()); + assertTrue(monkeyLog.getIgnoreSecurityExceptions()); + assertEquals(49 * 1000, monkeyLog.getTotalDuration().longValue()); + assertEquals(232650, monkeyLog.getStartUptimeDuration().longValue()); + assertEquals(282530, monkeyLog.getStopUptimeDuration().longValue()); + assertFalse(monkeyLog.getIsFinished()); + assertFalse(monkeyLog.getNoActivities()); + assertEquals(1600, monkeyLog.getIntermediateCount()); + assertEquals(1649, monkeyLog.getFinalCount().intValue()); + assertNotNull(monkeyLog.getCrash()); + assertTrue(monkeyLog.getCrash() instanceof JavaCrashItem); + assertEquals("com.google.android.apps.maps", monkeyLog.getCrash().getApp()); + assertEquals(3161, monkeyLog.getCrash().getPid().intValue()); + assertEquals("java.lang.Exception", ((JavaCrashItem) monkeyLog.getCrash()).getException()); + } + + + /** + * Test that a monkey can be parsed if there is a native crash. + */ + public void testParse_native_crash() { + List lines = Arrays.asList( + "# Tuesday, 04/24/2012 05:05:50 PM - device uptime = 232.65: Monkey command used for this test:", + "adb shell monkey -p com.google.android.apps.maps -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 501 -v -v -v 10000 ", + "", + ":Monkey: seed=501 count=10000", + ":AllowPackage: com.google.android.apps.maps", + ":IncludeCategory: android.intent.category.LAUNCHER", + ":Switch: #Intent;action=android.intent.action.MAIN;category=android.intent.category.LAUNCHER;launchFlags=0x10200000;component=com.google.android.apps.maps/com.google.android.maps.LatitudeActivity;end", + " // Allowing start of Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] cmp=com.google.android.apps.maps/com.google.android.maps.LatitudeActivity } in package com.google.android.apps.maps", + "Sleeping for 100 milliseconds", + ":Sending Touch (ACTION_DOWN): 0:(332.0,70.0)", + ":Sending Touch (ACTION_UP): 0:(332.55292,76.54678)", + " //[calendar_time:2012-04-25 00:06:38.419 system_uptime:280799]", + " // Sending event #1600", + ":Sending Touch (ACTION_MOVE): 0:(1052.2666,677.64594)", + ":Sending Touch (ACTION_UP): 0:(1054.7593,687.3757)", + "Sleeping for 100 milliseconds", + "// CRASH: com.android.chrome (pid 2162)", + "// Short Msg: Native crash", + "// Long Msg: Native crash: Segmentation fault", + "// Build Label: google/mantaray/manta:JellyBeanMR2/JWR02/624470:userdebug/dev-keys", + "// Build Changelist: 624470", + "// Build Time: 1364920502000", + "// *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***", + "// Build fingerprint: 'google/mantaray/manta:4.1/JRO01/12345:userdebug/dev-keys'", + "// Revision: '7'", + "// pid: 2162, tid: 2216, name: .android.chrome >>> com.android.chrome <<<", + "// signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr deadbaad", + "// r0 00000027 r1 00001000 r2 00000008 r3 deadbaad", + "// r4 00000000 r5 7af65e64 r6 00000000 r7 7af65ea4", + "// r8 401291f4 r9 00200000 sl 7784badc fp 00001401", + "// ip 7af65ea4 sp 7af65e60 lr 400fed6b pc 400fc2d4 cpsr 600f0030", + "// d0 3332303033312034 d1 6361707320737332", + "// d2 632e6c6f6f705f34 d3 205d29383231280a", + "// scr 60000010", + "// ", + "// backtrace:", + "// #00 pc 0001e2d4 /system/lib/libc.so", + "// #01 pc 0001c4bc /system/lib/libc.so (abort+4)", + "// #02 pc 0023a515 /system/lib/libchromeview.so", + "// #03 pc 006f8a27 /system/lib/libchromeview.so", + "// ", + "// stack:", + "// 7af65e20 77856cf8 ", + "// 7af65e24 7af65e64 [stack:2216]", + "// 7af65e28 00000014 ", + "// 7af65e2c 76a88e6c /system/lib/libchromeview.so", + "** Monkey aborted due to error.", + "Events injected: 1649", + ":Sending rotation degree=0, persist=false", + ":Dropped: keys=0 pointers=0 trackballs=0 flips=0 rotations=0", + "## Network stats: elapsed time=48897ms (0ms mobile, 48897ms wifi, 0ms not connected)", + "** System appears to have crashed at event 1649 of 10000 using seed 501", + "", + "# Tuesday, 04/24/2012 05:06:40 PM - device uptime = 282.53: Monkey command ran for: 00:49 (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:05:50"), monkeyLog.getStartTime()); + // assertEquals(parseTime("2012-04-24 17:06:40"), monkeyLog.getStopTime()); + assertEquals(1, monkeyLog.getPackages().size()); + assertTrue(monkeyLog.getPackages().contains("com.google.android.apps.maps")); + assertEquals(1, monkeyLog.getCategories().size()); + assertTrue(monkeyLog.getCategories().contains("android.intent.category.LAUNCHER")); + assertEquals(100, monkeyLog.getThrottle()); + assertEquals(501, monkeyLog.getSeed().intValue()); + assertEquals(10000, monkeyLog.getTargetCount().intValue()); + assertTrue(monkeyLog.getIgnoreSecurityExceptions()); + assertEquals(49 * 1000, monkeyLog.getTotalDuration().longValue()); + assertEquals(232650, monkeyLog.getStartUptimeDuration().longValue()); + assertEquals(282530, monkeyLog.getStopUptimeDuration().longValue()); + assertFalse(monkeyLog.getIsFinished()); + assertFalse(monkeyLog.getNoActivities()); + assertEquals(1600, monkeyLog.getIntermediateCount()); + assertEquals(1649, monkeyLog.getFinalCount().intValue()); + assertNotNull(monkeyLog.getCrash()); + assertTrue(monkeyLog.getCrash() instanceof NativeCrashItem); + assertEquals("com.android.chrome", monkeyLog.getCrash().getApp()); + assertEquals(2162, monkeyLog.getCrash().getPid().intValue()); + assertEquals("google/mantaray/manta:4.1/JRO01/12345:userdebug/dev-keys", + ((NativeCrashItem) monkeyLog.getCrash()).getFingerprint()); + // Make sure that the entire stack is included. + assertEquals(23, ((NativeCrashItem) monkeyLog.getCrash()).getStack().split("\n").length); + } + + /** + * Test that a monkey can be parsed if there is a native crash with extra info at the end. + */ + public void testParse_native_crash_strip_extra() { + List lines = Arrays.asList( + "# Tuesday, 04/24/2012 05:05:50 PM - device uptime = 232.65: Monkey command used for this test:", + "adb shell monkey -p com.google.android.apps.maps -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 501 -v -v -v 10000 ", + "", + ":Monkey: seed=501 count=10000", + ":AllowPackage: com.google.android.apps.maps", + ":IncludeCategory: android.intent.category.LAUNCHER", + ":Switch: #Intent;action=android.intent.action.MAIN;category=android.intent.category.LAUNCHER;launchFlags=0x10200000;component=com.google.android.apps.maps/com.google.android.maps.LatitudeActivity;end", + " // Allowing start of Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] cmp=com.google.android.apps.maps/com.google.android.maps.LatitudeActivity } in package com.google.android.apps.maps", + "Sleeping for 100 milliseconds", + ":Sending Touch (ACTION_DOWN): 0:(332.0,70.0)", + ":Sending Touch (ACTION_UP): 0:(332.55292,76.54678)", + " //[calendar_time:2012-04-25 00:06:38.419 system_uptime:280799]", + " // Sending event #1600", + ":Sending Touch (ACTION_MOVE): 0:(1052.2666,677.64594)", + ":Sending Touch (ACTION_UP): 0:(1054.7593,687.3757)", + "Sleeping for 100 milliseconds", + "// CRASH: com.android.chrome (pid 2162)", + "// Short Msg: Native crash", + "// Long Msg: Native crash: Segmentation fault", + "// Build Label: google/mantaray/manta:JellyBeanMR2/JWR02/624470:userdebug/dev-keys", + "// Build Changelist: 624470", + "// Build Time: 1364920502000", + "// *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***", + "// Build fingerprint: 'google/mantaray/manta:4.1/JRO01/12345:userdebug/dev-keys'", + "// Revision: '7'", + "// pid: 2162, tid: 2216, name: .android.chrome >>> com.android.chrome <<<", + "// signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr deadbaad", + "// r0 00000027 r1 00001000 r2 00000008 r3 deadbaad", + "// r4 00000000 r5 7af65e64 r6 00000000 r7 7af65ea4", + "// r8 401291f4 r9 00200000 sl 7784badc fp 00001401", + "// ip 7af65ea4 sp 7af65e60 lr 400fed6b pc 400fc2d4 cpsr 600f0030", + "// d0 3332303033312034 d1 6361707320737332", + "// d2 632e6c6f6f705f34 d3 205d29383231280a", + "// scr 60000010", + "// ", + "// backtrace:", + "// #00 pc 0001e2d4 /system/lib/libc.so", + "// #01 pc 0001c4bc /system/lib/libc.so (abort+4)", + "// #02 pc 0023a515 /system/lib/libchromeview.so", + "// #03 pc 006f8a27 /system/lib/libchromeview.so", + "// ", + "// stack:", + "// 7af65e20 77856cf8 ", + "// 7af65e24 7af65e64 [stack:2216]", + "// 7af65e28 00000014 ", + "// 7af65e2c 76a88e6c /system/lib/libchromeview.so", + "// ** New native crash detected.", + "** Monkey aborted due to error.", + "Events injected: 1649", + ":Sending rotation degree=0, persist=false", + ":Dropped: keys=0 pointers=0 trackballs=0 flips=0 rotations=0", + "## Network stats: elapsed time=48897ms (0ms mobile, 48897ms wifi, 0ms not connected)", + "** System appears to have crashed at event 1649 of 10000 using seed 501", + "", + "# Tuesday, 04/24/2012 05:06:40 PM - device uptime = 282.53: Monkey command ran for: 00:49 (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:05:50"), monkeyLog.getStartTime()); + // assertEquals(parseTime("2012-04-24 17:06:40"), monkeyLog.getStopTime()); + assertEquals(1, monkeyLog.getPackages().size()); + assertTrue(monkeyLog.getPackages().contains("com.google.android.apps.maps")); + assertEquals(1, monkeyLog.getCategories().size()); + assertTrue(monkeyLog.getCategories().contains("android.intent.category.LAUNCHER")); + assertEquals(100, monkeyLog.getThrottle()); + assertEquals(501, monkeyLog.getSeed().intValue()); + assertEquals(10000, monkeyLog.getTargetCount().intValue()); + assertTrue(monkeyLog.getIgnoreSecurityExceptions()); + assertEquals(49 * 1000, monkeyLog.getTotalDuration().longValue()); + assertEquals(232650, monkeyLog.getStartUptimeDuration().longValue()); + assertEquals(282530, monkeyLog.getStopUptimeDuration().longValue()); + assertFalse(monkeyLog.getIsFinished()); + assertFalse(monkeyLog.getNoActivities()); + assertEquals(1600, monkeyLog.getIntermediateCount()); + assertEquals(1649, monkeyLog.getFinalCount().intValue()); + assertNotNull(monkeyLog.getCrash()); + assertTrue(monkeyLog.getCrash() instanceof NativeCrashItem); + assertEquals("com.android.chrome", monkeyLog.getCrash().getApp()); + assertEquals(2162, monkeyLog.getCrash().getPid().intValue()); + NativeCrashItem nc = (NativeCrashItem) monkeyLog.getCrash(); + assertEquals("google/mantaray/manta:4.1/JRO01/12345:userdebug/dev-keys", + nc.getFingerprint()); + // Make sure that the stack with the last line stripped is included. + assertEquals(23, nc.getStack().split("\n").length); + assertFalse(nc.getStack().contains("New native crash detected")); + } + + /** + * Test that a monkey can be parsed if there is an empty native crash. + */ + public void testParse_native_crash_empty() { + List lines = Arrays.asList( + "# Tuesday, 04/24/2012 05:05:50 PM - device uptime = 232.65: Monkey command used for this test:", + "adb shell monkey -p com.google.android.apps.maps -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 501 -v -v -v 10000 ", + "", + ":Monkey: seed=501 count=10000", + ":AllowPackage: com.google.android.apps.maps", + ":IncludeCategory: android.intent.category.LAUNCHER", + ":Switch: #Intent;action=android.intent.action.MAIN;category=android.intent.category.LAUNCHER;launchFlags=0x10200000;component=com.google.android.apps.maps/com.google.android.maps.LatitudeActivity;end", + " // Allowing start of Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] cmp=com.google.android.apps.maps/com.google.android.maps.LatitudeActivity } in package com.google.android.apps.maps", + "Sleeping for 100 milliseconds", + ":Sending Touch (ACTION_DOWN): 0:(332.0,70.0)", + ":Sending Touch (ACTION_UP): 0:(332.55292,76.54678)", + " //[calendar_time:2012-04-25 00:06:38.419 system_uptime:280799]", + " // Sending event #1600", + ":Sending Touch (ACTION_MOVE): 0:(1052.2666,677.64594)", + ":Sending Touch (ACTION_UP): 0:(1054.7593,687.3757)", + "Sleeping for 100 milliseconds", + "** New native crash detected.", + "** Monkey aborted due to error.", + "Events injected: 1649", + ":Sending rotation degree=0, persist=false", + ":Dropped: keys=0 pointers=0 trackballs=0 flips=0 rotations=0", + "## Network stats: elapsed time=48897ms (0ms mobile, 48897ms wifi, 0ms not connected)", + "** System appears to have crashed at event 1649 of 10000 using seed 501", + "", + "# Tuesday, 04/24/2012 05:06:40 PM - device uptime = 282.53: Monkey command ran for: 00:49 (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:05:50"), monkeyLog.getStartTime()); + // assertEquals(parseTime("2012-04-24 17:06:40"), monkeyLog.getStopTime()); + assertEquals(1, monkeyLog.getPackages().size()); + assertTrue(monkeyLog.getPackages().contains("com.google.android.apps.maps")); + assertEquals(1, monkeyLog.getCategories().size()); + assertTrue(monkeyLog.getCategories().contains("android.intent.category.LAUNCHER")); + assertEquals(100, monkeyLog.getThrottle()); + assertEquals(501, monkeyLog.getSeed().intValue()); + assertEquals(10000, monkeyLog.getTargetCount().intValue()); + assertTrue(monkeyLog.getIgnoreSecurityExceptions()); + assertEquals(49 * 1000, monkeyLog.getTotalDuration().longValue()); + assertEquals(232650, monkeyLog.getStartUptimeDuration().longValue()); + assertEquals(282530, monkeyLog.getStopUptimeDuration().longValue()); + assertFalse(monkeyLog.getIsFinished()); + assertFalse(monkeyLog.getNoActivities()); + assertEquals(1600, monkeyLog.getIntermediateCount()); + assertEquals(1649, monkeyLog.getFinalCount().intValue()); + assertNotNull(monkeyLog.getCrash()); + assertTrue(monkeyLog.getCrash() instanceof NativeCrashItem); + assertNull(monkeyLog.getCrash().getApp()); + assertNull(monkeyLog.getCrash().getPid()); + NativeCrashItem nc = (NativeCrashItem) monkeyLog.getCrash(); + assertNull(nc.getFingerprint()); + assertEquals("", nc.getStack()); + } + + /** + * Test that a monkey can be parsed if there are no activities to run. + */ + public void testParse_no_activities() { + List lines = Arrays.asList( + "# Wednesday, 04/25/2012 01:37:12 AM - device uptime = 242.13: Monkey command used for this test:", + "adb shell monkey -p com.google.android.browser -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 528 -v -v -v 10000 ", + "", + ":Monkey: seed=528 count=10000", + ":AllowPackage: com.google.android.browser", + ":IncludeCategory: android.intent.category.LAUNCHER", + "** No activities found to run, monkey aborted.", + "", + "# Wednesday, 04/25/2012 01:42:09 AM - device uptime = 539.21: Monkey command ran for: 04:57 (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-25 01:37:12"), monkeyLog.getStartTime()); + // assertEquals(parseTime("2012-04-25 01:42:09"), monkeyLog.getStopTime()); + assertEquals(1, monkeyLog.getPackages().size()); + assertTrue(monkeyLog.getPackages().contains("com.google.android.browser")); + assertEquals(1, monkeyLog.getCategories().size()); + assertTrue(monkeyLog.getCategories().contains("android.intent.category.LAUNCHER")); + assertEquals(100, monkeyLog.getThrottle()); + assertEquals(528, monkeyLog.getSeed().intValue()); + assertEquals(10000, monkeyLog.getTargetCount().intValue()); + assertTrue(monkeyLog.getIgnoreSecurityExceptions()); + assertEquals(4 * 60 * 1000 + 57 * 1000, monkeyLog.getTotalDuration().longValue()); + assertEquals(242130, monkeyLog.getStartUptimeDuration().longValue()); + assertEquals(539210, monkeyLog.getStopUptimeDuration().longValue()); + assertFalse(monkeyLog.getIsFinished()); + assertTrue(monkeyLog.getNoActivities()); + assertEquals(0, monkeyLog.getIntermediateCount()); + assertNull(monkeyLog.getFinalCount()); + assertNull(monkeyLog.getDroppedCount(DroppedCategory.KEYS)); + assertNull(monkeyLog.getDroppedCount(DroppedCategory.POINTERS)); + assertNull(monkeyLog.getDroppedCount(DroppedCategory.TRACKBALLS)); + assertNull(monkeyLog.getDroppedCount(DroppedCategory.FLIPS)); + assertNull(monkeyLog.getDroppedCount(DroppedCategory.ROTATIONS)); + assertNull(monkeyLog.getCrash()); + } + + /** + * Test that a monkey can be parsed if there is an ANR in the middle of the traces. + */ + public void testParse_malformed_anr() { + List 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() { + List lines = Arrays.asList( + "# Tue Apr 24 17:05:50 PST 2012 - device uptime = 232.65: Monkey command used for this test:", + "adb shell monkey -p com.google.android.apps.maps -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 501 -v -v -v 10000 ", + "", + "# Tue Apr 24 17:06:40 PST 2012 - device uptime = 282.53: Monkey command ran for: 00:49 (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:05:50"), monkeyLog.getStartTime()); + // assertEquals(parseTime("2012-04-24 17:06:40"), monkeyLog.getStopTime()); + } + + @SuppressWarnings("unused") + private Date parseTime(String timeStr) throws ParseException { + DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + return formatter.parse(timeStr); + } +} + diff --git a/javatests/src/com/android/loganalysis/parser/NativeCrashParserTest.java b/javatests/src/com/android/loganalysis/parser/NativeCrashParserTest.java new file mode 100644 index 0000000..6c5cf98 --- /dev/null +++ b/javatests/src/com/android/loganalysis/parser/NativeCrashParserTest.java @@ -0,0 +1,192 @@ +/* + * Copyright (C) 2012 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.NativeCrashItem; +import com.android.loganalysis.util.ArrayUtil; + +import junit.framework.TestCase; + +import java.util.Arrays; +import java.util.List; + +/** + * Unit tests for {@link NativeCrashParser}. + */ +public class NativeCrashParserTest extends TestCase { + + /** + * Test that native crashes are parsed. + */ + public void testParseage() { + List lines = Arrays.asList( + "Build fingerprint: 'google/soju/crespo:4.0.4/IMM76D/299849:userdebug/test-keys'", + "pid: 2058, tid: 2523 >>> com.google.android.browser <<<", + "signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 00000000", + " r0 00000000 r1 007d9064 r2 007d9063 r3 00000004", + " r4 006bf518 r5 0091e3b0 r6 00000000 r7 9e3779b9", + " r8 000006c1 r9 000006c3 10 00000000 fp 67d246c1", + " ip d2363b58 sp 50ed71d8 lr 4edfc89b pc 4edfc6a0 cpsr 20000030", + " d0 00640065005f0065 d1 0072006f00740069", + " d2 00730075006e006b d3 0066006900670000", + " d4 00e6d48800e6d3b8 d5 02d517a000e6d518", + " d6 0000270f02d51860 d7 0000000002d51a80", + " d8 41d3dc5261e7893b d9 3fa999999999999a", + " d10 0000000000000000 d11 0000000000000000", + " d12 0000000000000000 d13 0000000000000000", + " d14 0000000000000000 d15 0000000000000000", + " d16 4070000000000000 d17 40c3878000000000", + " d18 412310f000000000 d19 3f91800dedacf040", + " d20 0000000000000000 d21 0000000000000000", + " d22 4010000000000000 d23 0000000000000000", + " d24 3ff0000000000000 d25 0000000000000000", + " d26 0000000000000000 d27 8000000000000000", + " d28 0000000000000000 d29 3ff0000000000000", + " d30 0000000000000000 d31 3ff0000000000000", + " scr 20000013", + "", + " #00 pc 001236a0 /system/lib/libwebcore.so", + " #01 pc 00123896 /system/lib/libwebcore.so", + " #02 pc 00123932 /system/lib/libwebcore.so", + " #03 pc 00123e3a /system/lib/libwebcore.so", + " #04 pc 00123e84 /system/lib/libwebcore.so", + " #05 pc 003db92a /system/lib/libwebcore.so", + " #06 pc 003dd01c /system/lib/libwebcore.so", + " #07 pc 002ffb92 /system/lib/libwebcore.so", + " #08 pc 0031c120 /system/lib/libwebcore.so", + " #09 pc 0031c134 /system/lib/libwebcore.so", + " #10 pc 0013fb98 /system/lib/libwebcore.so", + " #11 pc 0015b026 /system/lib/libwebcore.so", + " #12 pc 0015b164 /system/lib/libwebcore.so", + " #13 pc 0015f4cc /system/lib/libwebcore.so", + " #14 pc 00170472 /system/lib/libwebcore.so", + " #15 pc 0016ecb6 /system/lib/libwebcore.so", + " #16 pc 0027120e /system/lib/libwebcore.so", + " #17 pc 0026efec /system/lib/libwebcore.so", + " #18 pc 0026fcd8 /system/lib/libwebcore.so", + " #19 pc 00122efa /system/lib/libwebcore.so", + "", + "code around pc:", + "4edfc680 4a14b5f7 0601f001 23000849 3004f88d ...J....I..#...0", + "4edfc690 460a9200 3006f8ad e00e4603 3a019f00 ...F...0.F.....:", + "4edfc6a0 5c04f833 f83319ed 042c7c02 2cc7ea84 3..\\..3..|,....,", + "4edfc6b0 0405ea8c 24d4eb04 33049400 d1ed2a00 .......$...3.*..", + "4edfc6c0 f830b126 46681021 ff72f7ff f7ff4668 &.0.!.hF..r.hF..", + "", + "code around lr:", + "4edfc878 f9caf7ff 60209e03 9605e037 5b04f856 ...... `7...V..[", + "4edfc888 d0302d00 d13b1c6b 68a8e02d f7ff6869 .-0.k.;.-..hih..", + "4edfc898 6128fef3 b010f8d5 99022500 ea0146aa ..(a.....%...F..", + "4edfc8a8 9b01080b 0788eb03 3028f853 b9bdb90b ........S.(0....", + "4edfc8b8 3301e015 4638d005 f7ff9905 b970ff15 ...3..8F......p.", + "", + "stack:", + " 50ed7198 01d02c08 [heap]", + " 50ed719c 40045881 /system/lib/libc.so", + " 50ed71a0 400784c8", + " 50ed71a4 400784c8", + " 50ed71a8 02b40c68 [heap]", + " 50ed71ac 02b40c90 [heap]", + " 50ed71b0 50ed7290", + " 50ed71b4 006bf518 [heap]", + " 50ed71b8 00010000", + " 50ed71bc 50ed72a4", + " 50ed71c0 7da5a695", + " 50ed71c4 50ed7290", + " 50ed71c8 00000000", + " 50ed71cc 00000008", + " 50ed71d0 df0027ad", + " 50ed71d4 00000000", + "#00 50ed71d8 9e3779b9", + " 50ed71dc 00002000", + " 50ed71e0 00004000", + " 50ed71e4 006bf518 [heap]", + " 50ed71e8 0091e3b0 [heap]", + " 50ed71ec 01d72588 [heap]", + " 50ed71f0 00000000", + " 50ed71f4 4edfc89b /system/lib/libwebcore.so", + "#01 50ed71f8 01d70a78 [heap]", + " 50ed71fc 02b6afa8 [heap]", + " 50ed7200 00003fff", + " 50ed7204 01d70a78 [heap]", + " 50ed7208 00004000", + " 50ed720c 01d72584 [heap]", + " 50ed7210 00000000", + " 50ed7214 00000006", + " 50ed7218 006bf518 [heap]", + " 50ed721c 50ed72a4", + " 50ed7220 7da5a695", + " 50ed7224 50ed7290", + " 50ed7228 000016b8", + " 50ed722c 00000008", + " 50ed7230 01d70a78 [heap]", + " 50ed7234 4edfc937 /system/lib/libwebcore.so", + "debuggerd committing suicide to free the zombie!", + "debuggerd"); + + NativeCrashItem nc = new NativeCrashParser().parse(lines); + assertNotNull(nc); + assertEquals(2058, nc.getPid().intValue()); + assertEquals(2523, nc.getTid().intValue()); + assertEquals("com.google.android.browser", nc.getApp()); + assertEquals("google/soju/crespo:4.0.4/IMM76D/299849:userdebug/test-keys", + nc.getFingerprint()); + assertEquals(ArrayUtil.join("\n", lines), nc.getStack()); + } + + /** + * Test that both types of native crash app lines are parsed. + */ + public void testParseApp() { + List lines = Arrays.asList( + "*** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***", + "Build fingerprint: 'google/soju/crespo:4.0.4/IMM76D/299849:userdebug/test-keys'", + "pid: 2058, tid: 2523 >>> com.google.android.browser <<<", + "signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 00000000"); + + NativeCrashItem nc = new NativeCrashParser().parse(lines); + assertNotNull(nc); + assertEquals(2058, nc.getPid().intValue()); + assertEquals(2523, nc.getTid().intValue()); + assertEquals("com.google.android.browser", nc.getApp()); + + lines = Arrays.asList( + "*** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***", + "Build fingerprint: 'google/soju/crespo:4.0.4/IMM76D/299849:userdebug/test-keys'", + "pid: 2058, tid: 2523, name: com.google.android.browser >>> com.google.android.browser <<<", + "signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 00000000"); + + nc = new NativeCrashParser().parse(lines); + assertNotNull(nc); + + assertEquals(2058, nc.getPid().intValue()); + assertEquals(2523, nc.getTid().intValue()); + assertEquals("com.google.android.browser", nc.getApp()); + + lines = Arrays.asList( + "*** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***", + "Build fingerprint: 'google/soju/crespo:4.0.4/IMM76D/299849:userdebug/test-keys'", + "pid: 2058, tid: 2523, name: Atlas Worker #1 >>> com.google.android.browser <<<", + "signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 00000000"); + + nc = new NativeCrashParser().parse(lines); + assertNotNull(nc); + + assertEquals(2058, nc.getPid().intValue()); + assertEquals(2523, nc.getTid().intValue()); + assertEquals("com.google.android.browser", nc.getApp()); + } +} diff --git a/javatests/src/com/android/loganalysis/parser/ProcessUsageParserTest.java b/javatests/src/com/android/loganalysis/parser/ProcessUsageParserTest.java new file mode 100644 index 0000000..bfba620 --- /dev/null +++ b/javatests/src/com/android/loganalysis/parser/ProcessUsageParserTest.java @@ -0,0 +1,78 @@ +/* + * Copyright (C) 2015 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.ProcessUsageItem; +import com.android.loganalysis.item.ProcessUsageItem.ProcessUsageInfoItem; +import com.android.loganalysis.item.ProcessUsageItem.SensorInfoItem; + +import junit.framework.TestCase; + +import java.util.Arrays; +import java.util.LinkedList; +import java.util.List; + +/** + * Unit tests for {@link ProcessUsageParser} + */ +public class ProcessUsageParserTest extends TestCase { + + /** + * Test that normal input is parsed. + */ + public void testProcessUsageParser() { + List inputBlock = Arrays.asList( + " 0:", + " Mobile network: 173.70KB received, 102.55KB sent (packets 129)", + " Mobile radio active: 6m 5s 80ms (14.9%) 80x @ 139 mspp", + " 1000:", + " Mobile network: 16.43KB received, 26.26KB sent", + " Mobile radio active: 1m 17s 489ms (3.2%) 61x @ 179 mspp", + " Sensor 44: 27m 18s 207ms realtime (22 times)", + " Sensor 36: 6s 483ms realtime (3 times)", + " Proc servicemanager:", + " CPU: 2s 20ms usr + 4s 60ms krn ; 0ms fg", + " Apk android:", + " 266 wakeup alarms", + " u0a2:", + " Mobile network: 16.43KB received, 26.26KB sent", + " Mobile radio active: 1m 17s 489ms (3.2%) 61x @ 179 mspp", + " Sensor 0: 5s 207ms realtime (2 times)", + " Proc servicemanager:", + " CPU: 2s 20ms usr + 4s 60ms krn ; 0ms fg", + " Apk android:", + " 2 wakeup alarms", + " "); + + ProcessUsageItem processUsage = new ProcessUsageParser().parse(inputBlock); + + assertEquals(3, processUsage.getProcessUsage().size()); + + LinkedList processUsageInfo = + (LinkedList)processUsage.getProcessUsage(); + + assertEquals("1000", processUsageInfo.get(1).getProcessUID()); + assertEquals(266, processUsageInfo.get(1).getAlarmWakeups()); + + LinkedList sensor = processUsageInfo.get(1).getSensorUsage(); + assertEquals("44", sensor.get(0).getSensorName()); + assertEquals("36", sensor.get(1).getSensorName()); + + sensor = processUsageInfo.get(2).getSensorUsage(); + assertEquals("0", sensor.get(0).getSensorName()); + } +} + diff --git a/javatests/src/com/android/loganalysis/parser/ProcrankParserTest.java b/javatests/src/com/android/loganalysis/parser/ProcrankParserTest.java new file mode 100644 index 0000000..c47b750 --- /dev/null +++ b/javatests/src/com/android/loganalysis/parser/ProcrankParserTest.java @@ -0,0 +1,105 @@ +/* + * Copyright (C) 2011 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.ProcrankItem; +import com.android.loganalysis.util.ArrayUtil; + +import junit.framework.TestCase; + +import java.util.Arrays; +import java.util.List; + +/** + * Unit tests for {@link ProcrankParser} + */ +public class ProcrankParserTest extends TestCase { + + /** + * Test that normal input is parsed. + */ + public void testProcRankParserShortLine() { + List inputBlock = Arrays.asList( + " PID Vss Rss Pss Uss cmdline", + " 178 87136K 81684K 52829K 50012K system_server", + " 1313 78128K 77996K 48603K 45812K com.google.android.apps.maps", + " 3247 61652K 61492K 33122K 30972K com.android.browser", + " 334 55740K 55572K 29629K 28360K com.android.launcher", + " 2072 51348K 51172K 24263K 22812K android.process.acore", + " 1236 51440K 51312K 22911K 20608K com.android.settings", + " 51312K 22911K 20608K invalid.format", + " ------ ------ ------", + " 203624K 163604K TOTAL", + "RAM: 731448K total, 415804K free, 9016K buffers, 108548K cached", + "[procrank: 1.6s elapsed]"); + + ProcrankItem procrank = new ProcrankParser().parse(inputBlock); + + // Ensures that only valid lines are parsed. Only 6 of the 11 lines under the header are + // valid. + assertEquals(6, procrank.getPids().size()); + + // Make sure all expected rows are present, and do a diagonal check of values + assertEquals((Integer) 87136, procrank.getVss(178)); + assertEquals((Integer) 77996, procrank.getRss(1313)); + assertEquals((Integer) 33122, procrank.getPss(3247)); + assertEquals((Integer) 28360, procrank.getUss(334)); + assertEquals("android.process.acore", procrank.getProcessName(2072)); + assertEquals(ArrayUtil.join("\n", inputBlock), procrank.getText()); + } + + /** + * Test that normal input is parsed. + */ + public void testProcRankParserLongLine() { + List inputBlock = Arrays.asList( + " PID Vss Rss Pss Uss Swap PSwap USwap ZSwap cmdline", + " 6711 3454396K 146300K 108431K 105524K 31540K 20522K 20188K 4546K com.google.android.GoogleCamera", + " 1515 2535920K 131984K 93750K 89440K 42676K 31792K 31460K 7043K system_server", + "19906 2439540K 130228K 85418K 69296K 11680K 353K 0K 78K com.android.chrome:sandboxed_process10", + "13790 2596308K 124424K 75673K 69680K 11336K 334K 0K 74K com.google.android.youtube", + " 9288 2437704K 119496K 74288K 69532K 11344K 334K 0K 74K com.google.android.videos", + " 51312K 22911K 20608K 0K 0K 0K invalid.format", + " ------ ------ ------ ------ ------ ------ ------", + " 1061237K 940460K 619796K 225468K 201688K 49950K TOTAL", + "ZRAM: 52892K physical used for 238748K in swap (520908K total swap)", + "RAM: 1857348K total, 51980K free, 3780K buffers, 456272K cached, 29220K shmem, 97560K slab", + "[/system/xbin/su: 3.260s elapsed]"); + + ProcrankItem procrank = new ProcrankParser().parse(inputBlock); + + // Ensures that only valid lines are parsed. Only 6 of the 11 lines under the header are + // valid. + assertEquals(5, procrank.getPids().size()); + + // Make sure all expected rows are present, and do a diagonal check of values + assertEquals((Integer) 3454396, procrank.getVss(6711)); + assertEquals((Integer) 146300, procrank.getRss(6711)); + assertEquals((Integer) 108431, procrank.getPss(6711)); + assertEquals((Integer) 105524, procrank.getUss(6711)); + assertEquals("com.google.android.GoogleCamera", procrank.getProcessName(6711)); + assertEquals(ArrayUtil.join("\n", inputBlock), procrank.getText()); + } + + /** + * Test that an empty input returns {@code null}. + */ + public void testEmptyInput() { + ProcrankItem item = new ProcrankParser().parse(Arrays.asList("")); + assertNull(item); + } +} + diff --git a/javatests/src/com/android/loganalysis/parser/QtaguidParserTest.java b/javatests/src/com/android/loganalysis/parser/QtaguidParserTest.java new file mode 100644 index 0000000..f9442a6 --- /dev/null +++ b/javatests/src/com/android/loganalysis/parser/QtaguidParserTest.java @@ -0,0 +1,73 @@ +/* + * Copyright (C) 2015 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.QtaguidItem; + +import junit.framework.TestCase; + +import java.util.Arrays; +import java.util.List; + +public class QtaguidParserTest extends TestCase { + + public void testSingleLine() { + List input = Arrays.asList("12 wlan0 0x0 10009 0 111661 353 258252 484 111661 353 0 0 0 0 258252 484 0 0 0 0"); + + QtaguidItem item = new QtaguidParser().parse(input); + + assertEquals(1, item.getUids().size()); + assertEquals(111661, item.getRxBytes(10009)); + assertEquals(258252, item.getTxBytes(10009)); + } + + public void testMalformedLine() { + List input = Arrays.asList("a b c d", "a b c d e f g h i j k l"); + + QtaguidItem item = new QtaguidParser().parse(input); + + assertEquals(0, item.getUids().size()); + } + + public void testMultipleLines() { + List input = Arrays.asList( + "IDX IFACE ACCT_TAG_HEX UID_TAG_INT CNT_SET RX_BYTES RX_PACKETS TX_BYTES TX_PACKETS " + + "rx_tcp_bytes rx_tcp_packets rx_udp_bytes rx_udp_packets rx_other_bytes rx_other_packets " + + "tx_tcp_bytes tx_tcp_packets tx_udp_bytes tx_udp_packets tx_other_bytes tx_other_packets", + "2 wlan0 0x0 0 0 669013 7534 272120 2851 161253 1606 203916 1228 303844 4700 123336 998 108412 1268 40372 585", + "3 wlan0 0x0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0", + "4 wlan0 0x0 1000 0 104010 860 135166 2090 2304 23 101706 837 0 0 3774 36 85344 843 46048 1211", + "5 wlan0 0x0 1000 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0", + "6 wlan0 0x0 1020 0 68666 162 110566 260 0 0 68666 162 0 0 0 0 110566 260 0 0", + "7 wlan0 0x0 1020 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0", + "8 wlan0 0x0 10000 0 826063 2441 486365 2402 725175 2202 100888 239 0 0 427377 2261 58988 141 0 0", + "9 wlan0 0x0 10000 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0", + "10 wlan0 0x0 10007 0 0 0 640 10 0 0 0 0 0 0 640 10 0 0 0 0", + "11 wlan0 0x0 10007 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0", + "12 wlan0 0x0 10009 0 17773800 18040 6588861 16079 17773800 18040 0 0 0 0 6588861 16079 0 0 0 0", + "13 wlan0 0x0 10009 1 6392090 5092 109907 1235 6392090 5092 0 0 0 0 109907 1235 0 0 0 0", + "14 wlan0 0x0 10010 0 33397 41 5902 59 33397 41 0 0 0 0 5902 59 0 0 0 0", + "15 wlan0 0x0 10010 1 14949782 13336 1099914 12201 14949782 13336 0 0 0 0 1099914 12201 0 0 0 0", + "16 wlan0 0x0 10014 0 54459314 43660 1000730 9780 54459314 43660 0 0 0 0 1000730 9780 0 0 0 0", + "17 wlan0 0x0 10014 1 5411545 4459 416719 4154 5411545 4459 0 0 0 0 416719 4154 0 0 0 0", + "18 wlan0 0x0 10024 0 98775055 80471 3929490 45504 98775055 80471 0 0 0 0 3929490 45504 0 0 0 0", + "19 wlan0 0x0 10024 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0"); + QtaguidItem item = new QtaguidParser().parse(input); + assertEquals(9, item.getUids().size()); + assertEquals(24165890, item.getRxBytes(10009)); + assertEquals(6698768, item.getTxBytes(10009)); + } +} diff --git a/javatests/src/com/android/loganalysis/parser/SmartMonkeyLogParserTest.java b/javatests/src/com/android/loganalysis/parser/SmartMonkeyLogParserTest.java new file mode 100644 index 0000000..1249f7c --- /dev/null +++ b/javatests/src/com/android/loganalysis/parser/SmartMonkeyLogParserTest.java @@ -0,0 +1,147 @@ +/* + * 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.SmartMonkeyLogItem; +import com.android.loganalysis.parser.SmartMonkeyLogParser; + +import java.text.ParseException; +import java.util.Arrays; +import java.util.List; +import junit.framework.TestCase; + +/** + * Unit tests for {@link SmartMonkeyLogParser} and {@link SmartMonkeyLogItem} + */ +public class SmartMonkeyLogParserTest extends TestCase { + + /** + * Test for detecting UI exceptions + * @throws ParseException + */ + public void testExceptions() throws ParseException { + List lines = Arrays.asList( + "2013-03-04 12:33:18.789: Starting [UiAutomator Tests][com.android.cts.uiautomator]", + "2013-03-04 12:33:18.792: Target invocation count: 1000", + "2013-03-04 12:33:18.793: Throttle: 0 ms", + "2013-03-04 12:33:19.795: [ 0](Seq: -1)-Launching UiAutomator Tests", + "2013-03-04 12:33:37.211: [ 0](Seq: 0)-Found 6 candidates. Using index: 1", + "2013-03-04 12:33:37.336: [ 0](Seq: 0)-Clicking: CheckBox (760,194)", + "2013-03-04 12:33:38.443: [ 1](Seq: 0)-Found 6 candidates. Using index: 5", + "2013-03-04 12:33:38.533: [ 1](Seq: 0)-Clicking: Button~Description for Button (723,874)", + "2013-03-04 12:33:39.510: [ 2](Seq: 0)-UI Exception: CRASH: Unfortunately, UiAutomator Test App has stopped.", + "2013-03-04 12:43:39.510: [ 2](Seq: 0)-UI Exception: ANR: UiAutomator is not responding.", + "2013-03-04 12:53:39.513: Invocations requested: 1000", + "2013-03-04 12:53:39.518: Invocations completed: 2", + "2013-03-04 12:53:39.520: Device uptime: 608193 sec, Monkey run duration: 20 sec"); + + SmartMonkeyLogItem monkeyLog = new SmartMonkeyLogParser().parse(lines); + assertNotNull(monkeyLog); + assertEquals(1, monkeyLog.getCrashTimes().size()); + assertEquals(1, monkeyLog.getAnrTimes().size()); + assertEquals(SmartMonkeyLogParser.parseTime("2013-03-04 12:33:39.510"), + monkeyLog.getCrashTimes().toArray()[0]); + assertEquals(SmartMonkeyLogParser.parseTime("2013-03-04 12:43:39.510"), + monkeyLog.getAnrTimes().toArray()[0]); + } + + /** + * Tests for parsing smart monkey log header + * @throws ParseException + */ + public void testHeader() throws ParseException { + List lines = Arrays.asList( + "2013-03-04 12:33:18.789: Starting [UiAutomator Tests|YouTube][com.android.cts.uiautomator|com.google.android.youtube]", + "2013-03-04 12:33:18.792: Target invocation count: 1000", + "2013-03-04 12:33:18.793: Throttle: 1500 ms", + "2013-03-04 12:33:18.793: Device uptime: 608173 sec", + "2013-03-04 12:33:19.795: [ 0](Seq: -1)-Launching UiAutomator Tests", + "2013-03-04 12:33:37.211: [ 0](Seq: 0)-Found 6 candidates. Using index: 1", + "2013-03-04 12:33:37.336: [ 0](Seq: 0)-Clicking: CheckBox (760,194)", + "2013-03-04 12:33:38.443: [ 1](Seq: 0)-Found 6 candidates. Using index: 5", + "2013-03-04 12:33:38.533: [ 1](Seq: 0)-Clicking: Button~Description for Button (723,874)", + "2013-03-04 12:33:39.510: [ 2](Seq: 0)-UI Exception: CRASH: Unfortunately, UiAutomator Test App has stopped.", + "2013-03-04 12:43:39.510: [ 2](Seq: 0)-UI Exception: ANR: UiAutomator is not responding.", + "2013-03-04 12:53:39.513: Invocations requested: 1000", + "2013-03-04 12:53:39.518: Invocations completed: 2", + "2013-03-04 12:53:39.520: Device uptime: 608193 sec, Monkey run duration: 20 sec"); + SmartMonkeyLogItem monkeyLog = new SmartMonkeyLogParser().parse(lines); + assertNotNull(monkeyLog); + assertEquals(2, monkeyLog.getApplications().size()); + assertEquals("UiAutomator Tests", monkeyLog.getApplications().get(0)); + assertEquals("YouTube", monkeyLog.getApplications().get(1)); + assertEquals(2, monkeyLog.getPackages().size()); + assertEquals("com.android.cts.uiautomator", monkeyLog.getPackages().get(0)); + assertEquals("com.google.android.youtube", monkeyLog.getPackages().get(1)); + assertEquals(SmartMonkeyLogParser.parseTime("2013-03-04 12:33:18.789"), + monkeyLog.getStartTime()); + assertEquals(608173, monkeyLog.getStartUptimeDuration()); + assertEquals(1000, monkeyLog.getTargetInvocations()); + assertEquals(1500, monkeyLog.getThrottle()); + } + + /** + * Test for parsing log in flight + * @throws ParseException + */ + public void testIntermidiateStop() throws ParseException { + List lines = Arrays.asList( + "2013-03-04 12:33:18.789: Starting [UiAutomator Tests|YouTube][com.android.cts.uiautomator|com.google.android.youtube]", + "2013-03-04 12:33:18.792: Target invocation count: 1000", + "2013-03-04 12:33:18.793: Throttle: 1500 ms", + "2013-03-04 12:33:19.795: [ 0](Seq: -1)-Launching UiAutomator Tests", + "2013-03-04 12:33:37.211: [ 0](Seq: 0)-Found 6 candidates. Using index: 1", + "2013-03-04 12:33:37.336: [ 0](Seq: 0)-Clicking: CheckBox (760,194)", + "2013-03-04 12:33:38.443: [ 1](Seq: 0)-Found 6 candidates. Using index: 5", + "2013-03-04 12:33:38.533: [ 12](Seq: 3)-Clicking: Button~Description for Button (723,874)", + "2013-03-04 12:33:39.510: [ 12](Seq: 3)-UI Exception: CRASH: Unfortunately, UiAutomator Test App has stopped."); + + SmartMonkeyLogItem monkeyLog = new SmartMonkeyLogParser().parse(lines); + assertNotNull(monkeyLog); + assertEquals(12, monkeyLog.getIntermediateCount()); + assertEquals(SmartMonkeyLogParser.parseTime("2013-03-04 12:33:39.510"), + monkeyLog.getIntermediateTime()); + } + + /** + * Tests for parsing smart monkey log footer + * @throws ParseException + */ + public void testFooter() throws ParseException { + List lines = Arrays.asList( + "2013-03-04 12:33:18.789: Starting [UiAutomator Tests|YouTube][com.android.cts.uiautomator|com.google.android.youtube]", + "2013-03-04 12:33:18.792: Target invocation count: 1000", + "2013-03-04 12:33:18.793: Throttle: 1500 ms", + "2013-03-04 12:33:19.795: [ 0](Seq: -1)-Launching UiAutomator Tests", + "2013-03-04 12:33:37.211: [ 0](Seq: 0)-Found 6 candidates. Using index: 1", + "2013-03-04 12:33:37.336: [ 0](Seq: 0)-Clicking: CheckBox (760,194)", + "2013-03-04 12:33:38.443: [ 1](Seq: 0)-Found 6 candidates. Using index: 5", + "2013-03-04 12:33:38.533: [ 1](Seq: 0)-Clicking: Button~Description for Button (723,874)", + "2013-03-04 12:33:38.443: [ 2](Seq: 0)-Found 6 candidates. Using index: 5", + "2013-03-04 12:33:38.533: [ 2](Seq: 0)-Clicking: Button~Description for Button (723,874)", + "2013-03-04 12:53:39.513: Monkey aborted.", + "2013-03-04 12:53:39.513: Invocations requested: 1000", + "2013-03-04 12:53:39.518: Invocations completed: 999", + "2013-03-04 12:53:39.520: Device uptime: 608193 sec, Monkey run duration: 20 sec"); + + SmartMonkeyLogItem monkeyLog = new SmartMonkeyLogParser().parse(lines); + assertNotNull(monkeyLog); + assertEquals(999, monkeyLog.getFinalCount()); + assertEquals(20, monkeyLog.getTotalDuration()); + assertEquals(608193, monkeyLog.getStopUptimeDuration()); + assertEquals(true, monkeyLog.getIsAborted()); + } +} diff --git a/javatests/src/com/android/loganalysis/parser/SystemPropsParserTest.java b/javatests/src/com/android/loganalysis/parser/SystemPropsParserTest.java new file mode 100644 index 0000000..f6dc8a1 --- /dev/null +++ b/javatests/src/com/android/loganalysis/parser/SystemPropsParserTest.java @@ -0,0 +1,75 @@ +/* + * Copyright (C) 2011 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.SystemPropsItem; + +import junit.framework.TestCase; + +import java.util.Arrays; +import java.util.List; + +/** + * Unit tests for {@link SystemPropsParser} + */ +public class SystemPropsParserTest extends TestCase { + + /** + * Test that normal input is parsed. + */ + public void testSimpleParse() { + List inputBlock = Arrays.asList( + "[dalvik.vm.dexopt-flags]: [m=y]", + "[dalvik.vm.heapgrowthlimit]: [48m]", + "[dalvik.vm.heapsize]: [256m]", + "[gsm.version.ril-impl]: [android moto-ril-multimode 1.0]"); + + SystemPropsItem map = new SystemPropsParser().parse(inputBlock); + + assertEquals(4, map.size()); + assertEquals("m=y", map.get("dalvik.vm.dexopt-flags")); + assertEquals("48m", map.get("dalvik.vm.heapgrowthlimit")); + assertEquals("256m", map.get("dalvik.vm.heapsize")); + assertEquals("android moto-ril-multimode 1.0", map.get("gsm.version.ril-impl")); + } + + /** + * Make sure that a parse error on one line doesn't prevent the rest of the lines from being + * parsed + */ + public void testParseError() { + List inputBlock = Arrays.asList( + "[dalvik.vm.dexopt-flags]: [m=y]", + "[ends with newline]: [yup", + "]", + "[dalvik.vm.heapsize]: [256m]"); + + SystemPropsItem map = new SystemPropsParser().parse(inputBlock); + + assertEquals(2, map.size()); + assertEquals("m=y", map.get("dalvik.vm.dexopt-flags")); + assertEquals("256m", map.get("dalvik.vm.heapsize")); + } + + /** + * Test that an empty input returns {@code null}. + */ + public void testEmptyInput() { + SystemPropsItem item = new SystemPropsParser().parse(Arrays.asList("")); + assertNull(item); + } +} + diff --git a/javatests/src/com/android/loganalysis/parser/TimingsLogParserTest.java b/javatests/src/com/android/loganalysis/parser/TimingsLogParserTest.java new file mode 100644 index 0000000..48881ea --- /dev/null +++ b/javatests/src/com/android/loganalysis/parser/TimingsLogParserTest.java @@ -0,0 +1,354 @@ +/* + * Copyright (C) 2019 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.GenericTimingItem; +import com.android.loganalysis.item.SystemServicesTimingItem; + +import junit.framework.TestCase; + +import java.io.BufferedReader; +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.util.List; +import java.util.regex.Pattern; + +/** Unit Test for {@link TimingsLogParser} */ +public class TimingsLogParserTest extends TestCase { + + private TimingsLogParser mParser; + + public TimingsLogParserTest() { + mParser = new TimingsLogParser(); + } + + public void testParseGenericTiming_noPattern() throws IOException { + // Test when input is empty + String log = ""; + List items = mParser.parseGenericTimingItems(createBufferedReader(log)); + assertNotNull(items); + assertEquals(0, items.size()); + // Test when input is not empty + log = + String.join( + "\n", + "01-17 01:22:39.513 0 0 I CPU features: detected feature: GIC system register CPU interface", + "01-17 01:22:39.513 0 0 I CPU features: kernel page table isolation forced ON by command line option", + "01-17 01:22:39.513 0 0 I CPU features: detected feature: 32-bit EL0 Support", + "01-17 01:22:59.823 0 0 I init : Service 'bootanim' (pid 1030) exited with status 0", + "01-17 01:22:59.966 0 0 I init : processing action (sys.boot_completed=1) from (/init.rc:796)"); + items = mParser.parseGenericTimingItems(createBufferedReader(log)); + assertNotNull(items); + assertEquals(0, items.size()); + } + + public void testParseGenericTiming_multiplePattern_oneOccurrenceEach() throws IOException { + String log = + String.join( + "\n", + "01-17 01:22:39.503 0 0 I : Linux version 4.4.177 (Kernel Boot Started)", + "01-17 01:22:39.513 0 0 I CPU features: detected feature: GIC system register CPU interface", + "01-17 01:22:39.513 0 0 I CPU features: kernel page table isolation forced ON by command line option", + "01-17 01:22:39.513 0 0 I CPU features: detected feature: 32-bit EL0 Support", + "01-17 01:22:43.634 0 0 I init : starting service 'zygote'...", + "01-17 01:22:48.634 0 0 I init : 'zygote' started", + "01-17 01:22:53.392 0 0 I init : starting service 'fake service'", + "01-17 01:22:59.823 0 0 I init : Service 'bootanim' (pid 1030) exited with status 0", + "01-17 01:22:60.334 0 0 I init : 'fake service' started", + "01-17 01:22:61.362 938 1111 I ActivityManager: my app started", + "01-17 01:22:61.977 938 1111 I ActivityManager: my app displayed"); + + mParser.addDurationPatternPair( + "BootToAnimEnd", + Pattern.compile("Linux version"), + Pattern.compile("Service 'bootanim'")); + mParser.addDurationPatternPair( + "ZygoteStartTime", + Pattern.compile("starting service 'zygote'"), + Pattern.compile("'zygote' started")); + mParser.addDurationPatternPair( + "FakeServiceStartTime", + Pattern.compile("starting service 'fake service'"), + Pattern.compile("'fake service' started")); + mParser.addDurationPatternPair( + "BootToAppStart", + Pattern.compile("Linux version"), + Pattern.compile("my app displayed")); + mParser.addDurationPatternPair( + "AppStartTime", + Pattern.compile("my app started"), + Pattern.compile("my app displayed")); + mParser.addDurationPatternPair( + "ZygoteToApp", + Pattern.compile("'zygote' started"), + Pattern.compile("my app started")); + List items = mParser.parseGenericTimingItems(createBufferedReader(log)); + assertNotNull(items); + assertEquals(6, items.size()); + // 1st item + assertEquals("ZygoteStartTime", items.get(0).getName()); + assertEquals(5000.0, items.get(0).getDuration()); + // 2nd item + assertEquals("BootToAnimEnd", items.get(1).getName()); + assertEquals(20320.0, items.get(1).getDuration()); + // 3rd item + assertEquals("FakeServiceStartTime", items.get(2).getName()); + assertEquals(6942.0, items.get(2).getDuration()); + // 4th item + assertEquals("ZygoteToApp", items.get(3).getName()); + assertEquals(12728.0, items.get(3).getDuration()); + // 5th item + assertEquals("BootToAppStart", items.get(4).getName()); + assertEquals(22474.0, items.get(4).getDuration()); + // 6th item + assertEquals("AppStartTime", items.get(5).getName()); + assertEquals(615.0, items.get(5).getDuration()); + } + + public void testParseGenericTiming_multiplePattern_someNotMatched() throws IOException { + String log = + String.join( + "\n", + "01-17 01:22:39.503 0 0 I : Linux version 4.4.177 (Kernel Boot Started)", + "01-17 01:22:39.513 0 0 I CPU features: detected feature: GIC system register CPU interface", + "01-17 01:22:39.513 0 0 I CPU features: kernel page table isolation forced ON by command line option", + "01-17 01:22:39.513 0 0 I CPU features: detected feature: 32-bit EL0 Support", + "01-17 01:22:43.634 0 0 I init : starting service 'zygote'...", + "01-17 01:22:48.634 0 0 I init : 'zygote' started", + "01-17 01:22:53.392 0 0 I init : starting service 'fake service'", + "01-17 01:22:59.823 0 0 I init : Service 'bootanim' (pid 1030) exited with status 0", + "01-17 01:22:60.334 0 0 I init : 'fake service' started", + "01-17 01:22:61.362 938 1111 I ActivityManager: my app started", + "01-17 01:22:61.977 938 1111 I ActivityManager: my app displayed"); + + mParser.addDurationPatternPair( + "BootToAnimEnd", + Pattern.compile("Linux version"), + Pattern.compile("Service 'bootanim'")); + mParser.addDurationPatternPair( + "ZygoteStartTime", + Pattern.compile("starting service 'zygote'"), + Pattern.compile("End line no there")); + mParser.addDurationPatternPair( + "FakeServiceStartTime", + Pattern.compile("Start line not there"), + Pattern.compile("'fake service' started")); + mParser.addDurationPatternPair( + "AppStartTime", + Pattern.compile("Start line not there"), + Pattern.compile("End line not there")); + + List items = mParser.parseGenericTimingItems(createBufferedReader(log)); + assertNotNull(items); + assertEquals(1, items.size()); + assertEquals("BootToAnimEnd", items.get(0).getName()); + } + + public void testParseGenericTiming_clearExistingPatterns() throws IOException { + String log = + String.join( + "\n", + "01-17 01:22:39.503 0 0 I : Linux version 4.4.177 (Kernel Boot Started)", + "01-17 01:22:53.392 0 0 I init : starting service 'fake service'", + "01-17 01:22:59.823 0 0 I init : Service 'bootanim' (pid 1030) exited with status 0", + "01-17 01:22:60.334 0 0 I init : 'fake service' started", + "01-17 01:22:61.362 938 1111 I ActivityManager: my app started", + "01-17 01:22:61.977 938 1111 I ActivityManager: my app displayed"); + mParser.addDurationPatternPair( + "BootToAnimEnd", + Pattern.compile("Linux version"), + Pattern.compile("Service 'bootanim'")); + List items = mParser.parseGenericTimingItems(createBufferedReader(log)); + assertNotNull(items); + assertEquals(1, items.size()); + + mParser.clearDurationPatterns(); + items = mParser.parseGenericTimingItems(createBufferedReader(log)); + assertNotNull(items); + assertEquals(0, items.size()); + } + + public void testParseGenericTiming_multiplePattern_multipleOccurrence() throws IOException { + String log = + String.join( + "\n", + "01-17 01:22:39.503 0 0 I : Linux version 4.4.177 (Kernel Boot Started)", + "01-17 01:22:39.513 0 0 I CPU features: detected feature: GIC system register CPU interface", + "01-17 01:22:39.513 0 0 I CPU features: kernel page table isolation forced ON by command line option", + "01-17 01:22:39.513 0 0 I CPU features: detected feature: 32-bit EL0 Support", + "01-17 01:22:43.634 0 0 I init : starting service 'zygote'...", + "01-17 01:22:48.634 0 0 I init : 'zygote' started", + "01-17 01:22:53.392 0 0 I init : starting service 'fake service'", + "01-17 01:22:59.823 0 0 I init : 'bootanim' not reported", + "01-17 01:22:60.334 0 0 I init : 'fake service' started", + "01-17 01:32:39.503 0 0 I : Linux version 4.4.177 (Kernel Boot Started)", + "01-17 01:32:39.513 0 0 I CPU features: detected feature: GIC system register CPU interface", + "01-17 01:32:39.513 0 0 I CPU features: kernel page table isolation forced ON by command line option", + "01-17 01:32:39.513 0 0 I CPU features: detected feature: 32-bit EL0 Support", + "01-17 01:32:43.634 0 0 I init : starting service 'zygote'...", + "01-17 01:32:48.634 0 0 I init : 'zygote' started", + "01-17 01:32:53.392 0 0 I init : starting service 'a different service'", + "01-17 01:32:59.823 0 0 I init : Service 'bootanim' (pid 1030) exited with status 0", + "01-17 01:32:60.334 0 0 I init : 'fake service' started", + "01-17 01:32:61.362 938 1111 I ActivityManager: my app started", + "01-17 01:32:61.977 938 1111 I ActivityManager: my app displayed"); + + mParser.addDurationPatternPair( + "BootToAnimEnd", + Pattern.compile("Linux version"), + Pattern.compile("Service 'bootanim'")); + mParser.addDurationPatternPair( + "ZygoteStartTime", + Pattern.compile("starting service 'zygote'"), + Pattern.compile("'zygote' started")); + mParser.addDurationPatternPair( + "FakeServiceStartTime", + Pattern.compile("starting service 'fake service'"), + Pattern.compile("'fake service' started")); + mParser.addDurationPatternPair( + "AppStartTime", + Pattern.compile("my app started"), + Pattern.compile("my app displayed")); + List items = mParser.parseGenericTimingItems(createBufferedReader(log)); + assertNotNull(items); + assertEquals(5, items.size()); + // 1st item + assertEquals("ZygoteStartTime", items.get(0).getName()); + assertEquals(5000.0, items.get(0).getDuration()); + // 2nd item + assertEquals("FakeServiceStartTime", items.get(1).getName()); + assertEquals(6942.0, items.get(1).getDuration()); + // 3rd item + assertEquals("ZygoteStartTime", items.get(2).getName()); + assertEquals(5000.0, items.get(2).getDuration()); + // 4th item + assertEquals("BootToAnimEnd", items.get(3).getName()); + assertEquals(20320.0, items.get(3).getDuration()); + // 5th item + assertEquals("AppStartTime", items.get(4).getName()); + assertEquals(615.0, items.get(4).getDuration()); + } + + public void testParseGenericTiming_wrongTimeFormat() throws IOException { + String log = + String.join( + "\n", + "1234252.234 0 0 I : Linux version 4.4.177 (Kernel Boot Started)", + "1234259.342 0 0 I CPU features: detected feature: GIC system register CPU interface"); + mParser.addDurationPatternPair( + "BootToAnimEnd", + Pattern.compile("Linux version"), + Pattern.compile("Service 'bootanim'")); + try { + List items = + mParser.parseGenericTimingItems(createBufferedReader(log)); + } catch (RuntimeException e) { + assertTrue( + "Test should report ParseException", + e.getCause().toString().startsWith("java.text.ParseException")); + return; + } + fail("Test should throw ParseException"); + } + + /** Test that system services duration can be parsed as expected */ + public void testParseSystemServicesTiming_system_services_duration() throws IOException { + String log = + String.join( + "\n", + "01-10 01:25:57.675 981 981 D SystemServerTiming: StartWatchdog took to complete: 38ms", + "01-10 01:25:57.675 981 981 I SystemServer: Reading configuration...", + "01-10 01:25:57.675 981 981 I SystemServer: ReadingSystemConfig", + "01-10 01:25:57.676 981 981 D SystemServerTiming: ReadingSystemConfig took to complete: 0.53ms", + "01-10 01:25:57.676 981 981 D SystemServerTiming: ReadingSystemConfig took to complete: 0.53ms", // Parser should skip duplicated log line + "01-10 01:25:57.677 465 465 I snet_event_log: [121035042,-1,]", + "01-10 01:25:57.678 900 900 I FakeComponent: FakeSubcomponent wrong format took to complete: 10ms", + "01-10 01:25:57.678 900 900 I FakeComponent: FakeSubcomponent took to complete: 20s", + "01-10 01:25:57.680 981 981 D SystemServerTiming: StartInstaller took to complete: 5ms wrong format", + "01-10 01:25:57.682 981 981 D SystemServerTiming: DeviceIdentifiersPolicyService took to complete: 2ms", + "01-10 01:25:57.682 981 981 D SystemServerTiming: DeviceIdentifiersPolicyService took to complete: 2ms", + "06-06 19:23:54.410 1295 1295 D OtherService : StartTestStack took to complete: 7ms", + "06-06 19:23:55.410 129 129 D FakeService : Validtook to complete: 8ms", + "06-06 19:23:56.410 981 981 D SystemServerTiming: StartWatchdog took to complete: 38ms"); //Parser should parse the same metric at a different time + + List items = + mParser.parseSystemServicesTimingItems(createBufferedReader(log)); + assertNotNull(items); + assertEquals(6, items.size()); + assertEquals("SystemServerTiming", items.get(0).getComponent()); + assertEquals(38.0, items.get(0).getDuration()); + assertNull(items.get(0).getStartTime()); + assertEquals("ReadingSystemConfig", items.get(1).getSubcomponent()); + assertEquals(0.53, items.get(1).getDuration()); + assertNull(items.get(1).getStartTime()); + assertEquals("DeviceIdentifiersPolicyService", items.get(2).getSubcomponent()); + assertEquals("OtherService", items.get(3).getComponent()); + assertEquals("StartTestStack", items.get(3).getSubcomponent()); + assertEquals(7.0, items.get(3).getDuration()); + assertEquals("FakeService", items.get(4).getComponent()); + assertEquals("Valid", items.get(4).getSubcomponent()); + assertEquals(8.0, items.get(4).getDuration()); + assertNull(items.get(4).getStartTime()); + assertEquals("SystemServerTiming", items.get(5).getComponent()); + assertEquals("StartWatchdog", items.get(5).getSubcomponent()); + assertEquals(38.0, items.get(5).getDuration()); + } + + /** Test that system services start time can be parsed as expected */ + public void testParseSystemServicesTiming_system_services_start_time() throws IOException { + String log = + String.join( + "\n", + "01-10 01:24:45.536 1079 1079 D BootAnimation: BootAnimationStartTiming start time: 8611ms", + "01-10 01:24:45.537 1079 1079 D BootAnimation: BootAnimationPreloadTiming start time: 8611ms", + "01-10 01:24:45.556 874 1021 I ServiceManager: Waiting for service 'package_native' on '/dev/binder'...", + "01-10 01:24:45.561 466 466 I snet_event_log: [121035042,-1,]", + "01-10 01:24:45.583 1080 1080 I SystemServer: InitBeforeStartServices start time: 2345ms wrong format", + "01-10 01:25:24.095 1014 1111 D BootAnimation: BootAnimationShownTiming start time: 9191s", + "06-06 19:23:49.299 603 603 E qdmetadata: Unknown paramType 2", + "06-06 19:23:49.299 603 603 I FakeComponent : wrong subcomponent start time: 234ms", + "06-06 19:23:49.299 603 603 D FakeComponent: Subcomponent start time 234ms", + "06-06 19:23:49.299 1079 1079 D BootAnimation: BootAnimationStopTiming start time: 24839ms", + "06-06 19:23:59.299 179 179 D FakeService : Validstart time: 34839ms"); + + List items = + mParser.parseSystemServicesTimingItems(createBufferedReader(log)); + assertNotNull(items); + assertEquals(4, items.size()); + assertEquals("BootAnimation", items.get(0).getComponent()); + assertEquals("BootAnimationStartTiming", items.get(0).getSubcomponent()); + assertEquals(8611.0, items.get(0).getStartTime()); + assertNull(items.get(0).getDuration()); + assertEquals("BootAnimationPreloadTiming", items.get(1).getSubcomponent()); + assertEquals("BootAnimation", items.get(2).getComponent()); + assertEquals("BootAnimationStopTiming", items.get(2).getSubcomponent()); + assertEquals(24839.0, items.get(2).getStartTime()); + assertNull(items.get(2).getDuration()); + assertEquals("FakeService", items.get(3).getComponent()); + assertEquals("Valid", items.get(3).getSubcomponent()); + assertEquals(34839.0, items.get(3).getStartTime()); + assertNull(items.get(3).getDuration()); + } + + private BufferedReader createBufferedReader(String input) { + InputStream inputStream = new ByteArrayInputStream(input.getBytes()); + InputStreamReader reader = new InputStreamReader(inputStream); + return new BufferedReader(reader); + } +} diff --git a/javatests/src/com/android/loganalysis/parser/TopParserTest.java b/javatests/src/com/android/loganalysis/parser/TopParserTest.java new file mode 100644 index 0000000..9b2253b --- /dev/null +++ b/javatests/src/com/android/loganalysis/parser/TopParserTest.java @@ -0,0 +1,83 @@ +/* + * 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.TopItem; +import com.android.loganalysis.util.ArrayUtil; + +import junit.framework.TestCase; + +import java.util.Arrays; +import java.util.List; + +/** + * Unit tests for {@link ProcrankParser} + */ +public class TopParserTest extends TestCase { + + /** + * Test that the output of the top command is parsed. + */ + public void testTopParser() { + List inputBlock = Arrays.asList( + "User 20%, System 20%, IOW 5%, IRQ 3%", + "User 150 + Nice 50 + Sys 200 + Idle 510 + IOW 60 + IRQ 5 + SIRQ 25 = 1000", + "", + " PID TID PR CPU% S VSS RSS PCY UID Thread Proc", + " 4474 4474 0 2% R 1420K 768K shell top top"); + + TopItem item = new TopParser().parse(inputBlock); + + assertEquals(150, item.getUser()); + assertEquals(50, item.getNice()); + assertEquals(200, item.getSystem()); + assertEquals(510, item.getIdle()); + assertEquals(60, item.getIow()); + assertEquals(5, item.getIrq()); + assertEquals(25, item.getSirq()); + assertEquals(1000, item.getTotal()); + assertEquals(ArrayUtil.join("\n", inputBlock), item.getText()); + } + + /** + * Test that the last output is stored. + */ + public void testLastTop() { + List inputBlock = Arrays.asList( + "User 0 + Nice 0 + Sys 0 + Idle 1000 + IOW 0 + IRQ 0 + SIRQ 0 = 1000", + "User 0 + Nice 0 + Sys 0 + Idle 1000 + IOW 0 + IRQ 0 + SIRQ 0 = 1000", + "User 150 + Nice 50 + Sys 200 + Idle 510 + IOW 60 + IRQ 5 + SIRQ 25 = 1000"); + + TopItem item = new TopParser().parse(inputBlock); + + assertEquals(150, item.getUser()); + assertEquals(50, item.getNice()); + assertEquals(200, item.getSystem()); + assertEquals(510, item.getIdle()); + assertEquals(60, item.getIow()); + assertEquals(5, item.getIrq()); + assertEquals(25, item.getSirq()); + assertEquals(1000, item.getTotal()); + } + + /** + * Test that an empty input returns {@code null}. + */ + public void testEmptyInput() { + TopItem item = new TopParser().parse(Arrays.asList("")); + assertNull(item); + } +} diff --git a/javatests/src/com/android/loganalysis/parser/TraceFormatParserTest.java b/javatests/src/com/android/loganalysis/parser/TraceFormatParserTest.java new file mode 100644 index 0000000..06ce9ec --- /dev/null +++ b/javatests/src/com/android/loganalysis/parser/TraceFormatParserTest.java @@ -0,0 +1,227 @@ +/* + * Copyright (C) 2017 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 static org.junit.Assert.fail; + +import com.android.loganalysis.item.TraceFormatItem; + +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +import java.util.Arrays; +import java.util.List; +import java.util.regex.Matcher; + +/** Test for {@link TraceFormatParser}. */ +@RunWith(JUnit4.class) +public class TraceFormatParserTest { + private TraceFormatParser mParser; + + // "unwrap" the regex strings so that we can compare with the generated regex + private static final String MATCH_NUM_UNESCAPED = + TraceFormatParser.MATCH_NUM.replaceAll("\\\\\\\\", "\\\\"); + private static final String MATCH_HEX_UNESCAPED = + TraceFormatParser.MATCH_HEX.replaceAll("\\\\\\\\", "\\\\"); + private static final String MATCH_STR_UNESCAPED = + TraceFormatParser.MATCH_STR.replaceAll("\\\\\\\\", "\\\\"); + + @Before + public void setUp() { + mParser = new TraceFormatParser(); + } + + @Test + public void testParseFormatLine() { + List formatLine = + Arrays.asList("print fmt: \"foo=%llu, bar=%s\", REC->foo, REC->bar"); + String expectedRegex = + String.format( + "foo=(?%s), bar=(?%s)", MATCH_NUM_UNESCAPED, MATCH_STR_UNESCAPED); + List expectedParameters = Arrays.asList("foo", "bar"); + List expectedNumericParameters = Arrays.asList("foo"); + List expectedHexParameters = Arrays.asList(); + List expectedStringParameters = Arrays.asList("bar"); + String shouldMatch = "foo=123, bar=enabled"; + + TraceFormatItem parsedItem = mParser.parse(formatLine); + Assert.assertEquals(expectedParameters, parsedItem.getParameters()); + Assert.assertEquals(expectedNumericParameters, parsedItem.getNumericParameters()); + Assert.assertEquals(expectedHexParameters, parsedItem.getHexParameters()); + Assert.assertEquals(expectedStringParameters, parsedItem.getStringParameters()); + Assert.assertEquals(expectedRegex, parsedItem.getRegex().toString()); + Matcher m = parsedItem.getRegex().matcher(shouldMatch); + Assert.assertTrue(m.matches()); + Assert.assertEquals(m.group("foo"), "123"); + Assert.assertEquals(m.group("bar"), "enabled"); + } + + @Test + public void testNoParameters() { + List formatLine = Arrays.asList("print fmt: \"foo\""); + String expectedRegex = "foo"; + List expectedParameters = Arrays.asList(); + String shouldMatch = "foo"; + + TraceFormatItem parsedItem = mParser.parse(formatLine); + Assert.assertEquals(expectedParameters, parsedItem.getParameters()); + Assert.assertEquals(expectedRegex, parsedItem.getRegex().toString()); + Matcher m = parsedItem.getRegex().matcher(shouldMatch); + Assert.assertTrue(m.matches()); + } + + @Test + public void testNullInput() { + try { + mParser.parse(null); + fail("Expected an exception thrown by TraceFormatParser"); + } catch (RuntimeException e) { + // expected + } + } + + @Test + public void testEmptyInput() { + List formatLine = Arrays.asList(""); + try { + mParser.parse(formatLine); + fail("Expected an exception thrown by TraceFormatParser"); + } catch (RuntimeException e) { + // expected + } + } + + @Test + public void testMultiLineInput() { + List formatLine = Arrays.asList("foo", "bar"); + try { + mParser.parse(formatLine); + fail("Expected an exception thrown by TraceFormatParser"); + } catch (RuntimeException e) { + // expected + } + } + + @Test + public void testOneLineInvalidInput() { + List formatLine = Arrays.asList("foo bar"); + try { + mParser.parse(formatLine); + fail("Expected an exception thrown by TraceFormatParser"); + } catch (RuntimeException e) { + // expected + } + } + + @Test + public void testQuoteInParams() { + List formatLine = + Arrays.asList("print fmt: \"foo %s\", REC->foo ? \"online\" : \"offline\""); + String expectedRegex = String.format("foo (?%s)", MATCH_STR_UNESCAPED); + String shouldMatch = "foo online"; + + TraceFormatItem parsedItem = mParser.parse(formatLine); + Assert.assertEquals(expectedRegex, parsedItem.getRegex().toString()); + Matcher m = parsedItem.getRegex().matcher(shouldMatch); + Assert.assertTrue(m.matches()); + Assert.assertEquals(m.group("foo"), "online"); + } + + @Test + public void testCategorizeParameters() { + List formatLine = + Arrays.asList( + "print fmt: \"num1=%lu, num2=%f, hex=%08x, str=%s\", REC->num1, REC->num2, REC->hex, REC->str"); + List expectedNumericParameters = Arrays.asList("num1", "num2"); + List expectedHexParameters = Arrays.asList("hex"); + List expectedStringParameters = Arrays.asList("str"); + + TraceFormatItem parsedItem = mParser.parse(formatLine); + Assert.assertEquals(expectedNumericParameters, parsedItem.getNumericParameters()); + Assert.assertEquals(expectedHexParameters, parsedItem.getHexParameters()); + Assert.assertEquals(expectedStringParameters, parsedItem.getStringParameters()); + } + + @Test + public void testCaseConvertParameterName() { + List formatLine = Arrays.asList("print fmt: \"foo_bar=%llu\", REC->foo_bar"); + List expectedParameters = Arrays.asList("fooBar"); + String shouldMatch = "foo_bar=123"; + + TraceFormatItem parsedItem = mParser.parse(formatLine); + Assert.assertEquals(expectedParameters, parsedItem.getParameters()); + Matcher m = parsedItem.getRegex().matcher(shouldMatch); + Assert.assertTrue(m.matches()); + Assert.assertEquals(m.group("fooBar"), "123"); + } + + @Test + public void testMatchInt() { + List formatLine = + Arrays.asList("print fmt: \"foo=%d, bar=%lu\", REC->foo, REC->bar"); + String shouldMatch = "foo=-123, bar=456"; + + TraceFormatItem parsedItem = mParser.parse(formatLine); + Matcher m = parsedItem.getRegex().matcher(shouldMatch); + Assert.assertTrue(m.matches()); + Assert.assertEquals(m.group("foo"), "-123"); + Assert.assertEquals(m.group("bar"), "456"); + } + + @Test + public void testMatchFloat() { + List formatLine = + Arrays.asList("print fmt: \"foo=%f, bar=%.2f\", REC->foo, REC->bar"); + String shouldMatch = "foo=123.4567, bar=456.78"; + + TraceFormatItem parsedItem = mParser.parse(formatLine); + Matcher m = parsedItem.getRegex().matcher(shouldMatch); + Assert.assertTrue(m.matches()); + Assert.assertEquals(m.group("foo"), "123.4567"); + Assert.assertEquals(m.group("bar"), "456.78"); + } + + @Test + public void testMatchHex() { + List formatLine = + Arrays.asList( + "print fmt: \"foo=0x%04x, bar=0x%08X, baz=%x\", REC->foo, REC->bar, REC->baz"); + String shouldMatch = "foo=0x007b, bar=0x000001C8, baz=7b"; + + TraceFormatItem parsedItem = mParser.parse(formatLine); + Matcher m = parsedItem.getRegex().matcher(shouldMatch); + Assert.assertTrue(m.matches()); + Assert.assertEquals(m.group("foo"), "007b"); + Assert.assertEquals(m.group("bar"), "000001C8"); + Assert.assertEquals(m.group("baz"), "7b"); + } + + @Test + public void testMatchString() { + List formatLine = + Arrays.asList("print fmt: \"foo=%s, bar=%s\", REC->foo, REC->bar"); + String shouldMatch = "foo=oof, bar=123"; + + TraceFormatItem parsedItem = mParser.parse(formatLine); + Matcher m = parsedItem.getRegex().matcher(shouldMatch); + Assert.assertTrue(m.matches()); + Assert.assertEquals(m.group("foo"), "oof"); + Assert.assertEquals(m.group("bar"), "123"); + } +} diff --git a/javatests/src/com/android/loganalysis/parser/TracesParserTest.java b/javatests/src/com/android/loganalysis/parser/TracesParserTest.java new file mode 100644 index 0000000..c5046e3 --- /dev/null +++ b/javatests/src/com/android/loganalysis/parser/TracesParserTest.java @@ -0,0 +1,167 @@ +/* + * Copyright (C) 2011 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.TracesItem; +import com.android.loganalysis.util.ArrayUtil; + +import junit.framework.TestCase; + +import java.util.Arrays; +import java.util.List; + +/** + * Unit tests for {@link TracesParser} + */ +public class TracesParserTest extends TestCase { + + /** + * Test that the parser parses the correct stack. + */ + public void testTracesParser() { + List lines = Arrays.asList( + "", + "", + "----- pid 2887 at 2012-05-02 16:43:41 -----", + "Cmd line: com.android.package", + "", + "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)", + " at class.method2(Class.java:2)", + " at class.method2(Class.java:2)", + "", + "\"Task_1\" prio=5 tid=27 WAIT", + " | group=\"main\" sCount=1 dsCount=0 obj=0x00000001 self=0x00000001", + " | sysTid=4789 nice=10 sched=0/0 cgrp=bg_non_interactive handle=0000000001", + " | schedstat=( 0 0 0 ) utm=0 stm=0 core=0", + " at class.method1(Class.java:1)", + " - waiting on <0x00000001> (a java.lang.Thread) held by tid=27 (Task_1)", + " at class.method2(Class.java:2)", + " at class.method2(Class.java:2)", + "", + "\"Task_2\" prio=5 tid=26 NATIVE", + " | group=\"main\" sCount=1 dsCount=0 obj=0x00000001 self=0x00000001", + " | sysTid=4343 nice=0 sched=0/0 cgrp=foreground handle=0000000001", + " | schedstat=( 0 0 0 ) utm=6 stm=3 core=0", + " #00 pc 00001234 /system/lib/lib.so (addr+8)", + " #01 pc 00001235 /system/lib/lib.so (addr+16)", + " #02 pc 00001236 /system/lib/lib.so (addr+24)", + " at class.method1(Class.java:1)", + "", + "----- end 2887 -----", + "", + "", + "----- pid 256 at 2012-05-02 16:43:41 -----", + "Cmd line: system", + "", + "DALVIK THREADS:", + "(mutexes: tll=0 tsl=0 tscl=0 ghl=0)", + "", + "\"main\" prio=5 tid=1 NATIVE", + " | group=\"main\" sCount=1 dsCount=0 obj=0x00000001 self=0x00000001", + " | sysTid=256 nice=0 sched=0/0 cgrp=foreground handle=0000000001", + " | schedstat=( 0 0 0 ) utm=175 stm=41 core=0", + " #00 pc 00001234 /system/lib/lib.so (addr+8)", + " #01 pc 00001235 /system/lib/lib.so (addr+16)", + " #02 pc 00001236 /system/lib/lib.so (addr+24)", + " at class.method1(Class.java:1)", + " at class.method2(Class.java:2)", + " at class.method2(Class.java:2)", + "", + "----- end 256 -----", + ""); + + List expectedStack = Arrays.asList( + "\"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)", + " at class.method2(Class.java:2)", + " at class.method2(Class.java:2)"); + + TracesItem traces = new TracesParser().parse(lines); + assertEquals(2887, traces.getPid().intValue()); + assertEquals("com.android.package", traces.getApp()); + assertEquals(ArrayUtil.join("\n", expectedStack), traces.getStack()); + } + + /** + * Test that both forms of cmd line match for the trace. + */ + public void testTracesParser_cmdline() { + List expectedStack = Arrays.asList( + "\"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)", + " at class.method2(Class.java:2)", + " at class.method2(Class.java:2)"); + + List lines = Arrays.asList( + "", + "", + "----- pid 2887 at 2012-05-02 16:43:41 -----", + "Cmd line: com.android.package", + "", + "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)", + " at class.method2(Class.java:2)", + " at class.method2(Class.java:2)", + ""); + + TracesItem traces = new TracesParser().parse(lines); + assertEquals(2887, traces.getPid().intValue()); + assertEquals("com.android.package", traces.getApp()); + assertEquals(ArrayUtil.join("\n", expectedStack), traces.getStack()); + + lines = Arrays.asList( + "", + "", + "----- pid 2887 at 2012-05-02 16:43:41 -----", + "Cmdline: com.android.package Original command line: ", + "", + "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)", + " at class.method2(Class.java:2)", + " at class.method2(Class.java:2)", + ""); + + traces = new TracesParser().parse(lines); + assertEquals(2887, traces.getPid().intValue()); + assertEquals("com.android.package", traces.getApp()); + assertEquals(ArrayUtil.join("\n", expectedStack), traces.getStack()); + } +} diff --git a/javatests/src/com/android/loganalysis/parser/WakelockParserTest.java b/javatests/src/com/android/loganalysis/parser/WakelockParserTest.java new file mode 100644 index 0000000..eff4ec8 --- /dev/null +++ b/javatests/src/com/android/loganalysis/parser/WakelockParserTest.java @@ -0,0 +1,127 @@ +/* + * Copyright (C) 2015 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.WakelockItem; +import com.android.loganalysis.item.WakelockItem.WakeLockCategory; + +import junit.framework.TestCase; + +import java.util.Arrays; +import java.util.List; + +/** + * Unit tests for {@link WakelockParser} + */ +public class WakelockParserTest extends TestCase { + + /** + * Test that normal input is parsed. + */ + public void testKernelWakelockParser() { + List inputBlock = Arrays.asList( + " All kernel wake locks:", + " Kernel Wake lock PowerManagerService.WakeLocks: 1h 3m 50s 5ms (8 times) realtime", + " Kernel Wake lock event0-2656 : 3m 49s 268ms (2399 times) realtime", + " Kernel Wake lock wlan_wd_wake: 3m 34s 639ms (1751 times) realtime", + " Kernel Wake lock wlan_rx_wake: 3m 19s 887ms (225 times) realtime", + " Kernel Wake lock wlan_tx_wake: 2m 19s 887ms (225 times) realtime", + " Kernel Wake lock tx_wake: 1m 19s 887ms (225 times) realtime", + " " + ); + + WakelockItem wakelock = new WakelockParser().parse(inputBlock); + + assertEquals(WakelockParser.TOP_WAKELOCK_COUNT, + wakelock.getWakeLocks(WakeLockCategory.KERNEL_WAKELOCK).size()); + assertEquals("event0-2656 ", + wakelock.getWakeLocks(WakeLockCategory.KERNEL_WAKELOCK).get(0).getName()); + assertEquals(229268, wakelock.getWakeLocks(WakeLockCategory.KERNEL_WAKELOCK). + get(0).getHeldTime()); + assertEquals(2399, wakelock.getWakeLocks(WakeLockCategory.KERNEL_WAKELOCK). + get(0).getLockedCount()); + } + + public void testPartialWakelockParser() { + List inputBlock = Arrays.asList( + " All partial wake locks:", + " Wake lock u0a7 NlpWakeLock: 8m 13s 203ms (1479 times) max=0 realtime", + " Wake lock u0a7 NlpCollectorWakeLock: 6m 29s 18ms (238 times) max=0 realtime", + " Wake lock u0a7 GCM_CONN_ALARM: 6m 8s 587ms (239 times) max=0 realtime", + " Wake lock 1000 *alarm*: 5m 11s 316ms (1469 times) max=0 realtime", + " Wake lock u10 xxx: 4m 11s 316ms (1469 times) max=0 realtime", + " Wake lock u30 cst: 2m 11s 316ms (1469 times) max=0 realtime", + ""); + + WakelockItem wakelock = new WakelockParser().parse(inputBlock); + + assertEquals(WakelockParser.TOP_WAKELOCK_COUNT, + wakelock.getWakeLocks(WakeLockCategory.PARTIAL_WAKELOCK).size()); + assertEquals("NlpWakeLock", wakelock.getWakeLocks(WakeLockCategory.PARTIAL_WAKELOCK). + get(0).getName()); + assertEquals("u0a7", wakelock.getWakeLocks(WakeLockCategory.PARTIAL_WAKELOCK). + get(0).getProcessUID()); + assertEquals(493203, wakelock.getWakeLocks(WakeLockCategory.PARTIAL_WAKELOCK). + get(0).getHeldTime()); + assertEquals(1479, wakelock.getWakeLocks(WakeLockCategory.PARTIAL_WAKELOCK). + get(0).getLockedCount()); + } + + public void testPartialWakelockParserOnOldFormat() { + List inputBlock = Arrays.asList( + " All partial wake locks:", + " Wake lock u0a7 NlpWakeLock: 8m 13s 203ms (1479 times) realtime", + " Wake lock u0a7 NlpCollectorWakeLock: 6m 29s 18ms (238 times) realtime", + " Wake lock u0a7 GCM_CONN_ALARM: 6m 8s 587ms (239 times) realtime", + " Wake lock 1000 *alarm*: 5m 11s 316ms (1469 times) realtime", + " Wake lock u10 xxx: 4m 11s 316ms (1469 times) realtime", + " Wake lock u30 cst: 2m 11s 316ms (1469 times) realtime", + ""); + + WakelockItem wakelock = new WakelockParser().parse(inputBlock); + + assertEquals(WakelockParser.TOP_WAKELOCK_COUNT, + wakelock.getWakeLocks(WakeLockCategory.PARTIAL_WAKELOCK).size()); + assertEquals("NlpWakeLock", wakelock.getWakeLocks(WakeLockCategory.PARTIAL_WAKELOCK). + get(0).getName()); + assertEquals("u0a7", wakelock.getWakeLocks(WakeLockCategory.PARTIAL_WAKELOCK). + get(0).getProcessUID()); + assertEquals(493203, wakelock.getWakeLocks(WakeLockCategory.PARTIAL_WAKELOCK). + get(0).getHeldTime()); + assertEquals(1479, wakelock.getWakeLocks(WakeLockCategory.PARTIAL_WAKELOCK). + get(0).getLockedCount()); + } + + public void testInvalidInputWakelockParser() { + List inputBlock = Arrays.asList( + " lock PowerManagerService.WakeLocks: 1h 3m 50s 5ms (8 times) realtime", + " lock event0-2656 : 3m 49s 268ms (2399 times) realtime", + " lock wlan_wd_wake: 3m 34s 639ms (1751 times) realtime", + " lock wlan_rx_wake: 3m 19s 887ms (225 times) realtime", + " wlan_tx_wake: 2m 19s 887ms (225 times) realtime", + " tx_wake: 1m 19s 887ms (225 times) realtime", + " " + ); + + WakelockItem wakelock = new WakelockParser().parse(inputBlock); + + assertEquals(0, + wakelock.getWakeLocks(WakeLockCategory.KERNEL_WAKELOCK).size()); + assertEquals(0, + wakelock.getWakeLocks(WakeLockCategory.PARTIAL_WAKELOCK).size()); + } +} + diff --git a/javatests/src/com/android/loganalysis/rule/InterruptRuleTest.java b/javatests/src/com/android/loganalysis/rule/InterruptRuleTest.java new file mode 100644 index 0000000..7a08db0 --- /dev/null +++ b/javatests/src/com/android/loganalysis/rule/InterruptRuleTest.java @@ -0,0 +1,101 @@ +/* + * Copyright (C) 2016 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.rule; + +import com.android.loganalysis.item.BatteryStatsDetailedInfoItem; +import com.android.loganalysis.item.BugreportItem; +import com.android.loganalysis.item.DumpsysBatteryStatsItem; +import com.android.loganalysis.item.DumpsysItem; +import com.android.loganalysis.item.InterruptItem; +import com.android.loganalysis.item.InterruptItem.InterruptCategory; + +import junit.framework.TestCase; + +import org.json.JSONObject; + +/** + * Unit tests for {@link InterruptRule} + */ +public class InterruptRuleTest extends TestCase { + + BugreportItem mBugreport; + DumpsysItem mDumpsys; + DumpsysBatteryStatsItem mDumpsysBatteryStats; + BatteryStatsDetailedInfoItem mBatteryStatsDetailedInfo; + + @Override + public void setUp() { + mBugreport = new BugreportItem(); + mDumpsys = new DumpsysItem(); + mDumpsysBatteryStats = new DumpsysBatteryStatsItem(); + mBatteryStatsDetailedInfo = new BatteryStatsDetailedInfoItem(); + + mBatteryStatsDetailedInfo.setTimeOnBattery(3902004); + mDumpsysBatteryStats.setDetailedBatteryStatsItem(mBatteryStatsDetailedInfo); + mDumpsys.setBatteryInfo(mDumpsysBatteryStats); + mBugreport.setDumpsys(mDumpsys); + } + + /** + * Test interrupt analysis + */ + public void testInterruptAnalysis() throws Exception { + InterruptItem interrupt = new InterruptItem(); + interrupt.addInterrupt("2:bcmsdh_sdmmc:2:qcom,smd:2:msmgio", 40, + InterruptCategory.WIFI_INTERRUPT); + interrupt.addInterrupt("2:qcom,smd-rpm:2:fc4c.qcom,spmi", 7, + InterruptCategory.UNKNOWN_INTERRUPT); + + mBatteryStatsDetailedInfo.setInterruptItem(interrupt); + + InterruptRule interruptRule = new InterruptRule(mBugreport); + interruptRule.applyRule(); + JSONObject analysis = interruptRule.getAnalysis(); + assertNotNull(analysis); + assertTrue(analysis.has("INTERRUPT_ANALYSIS")); + assertEquals(analysis.getString("INTERRUPT_ANALYSIS"), + "Frequent interrupts from WIFI_INTERRUPT (2:bcmsdh_sdmmc:2:qcom,smd:2:msmgio)."); + } + + + public void testNoSignificantInterruptAnalysis() throws Exception { + InterruptItem interrupt = new InterruptItem(); + interrupt.addInterrupt("2:bcmsdh_sdmmc:2:qcom,smd:2:msmgio", 5, + InterruptCategory.WIFI_INTERRUPT); + interrupt.addInterrupt("2:qcom,smd-rpm:2:fc4c.qcom,spmi", 7, + InterruptCategory.UNKNOWN_INTERRUPT); + + mBatteryStatsDetailedInfo.setInterruptItem(interrupt); + + InterruptRule interruptRule = new InterruptRule(mBugreport); + interruptRule.applyRule(); + JSONObject analysis = interruptRule.getAnalysis(); + assertNotNull(analysis); + assertTrue(analysis.has("INTERRUPT_ANALYSIS")); + assertEquals(analysis.getString("INTERRUPT_ANALYSIS"), + "No interrupts woke up device more frequent than 120 secs."); + } + + public void testMissingInterruptAnalysis() throws Exception { + InterruptRule interruptRule = new InterruptRule(mBugreport); + interruptRule.applyRule(); + JSONObject analysis = interruptRule.getAnalysis(); + assertNotNull(analysis); + assertTrue(analysis.has("INTERRUPT_ANALYSIS")); + assertEquals(analysis.getString("INTERRUPT_ANALYSIS"), + "No interrupts woke up device more frequent than 120 secs."); + } +} diff --git a/javatests/src/com/android/loganalysis/rule/LocationUsageRuleTest.java b/javatests/src/com/android/loganalysis/rule/LocationUsageRuleTest.java new file mode 100644 index 0000000..5dd7e9e --- /dev/null +++ b/javatests/src/com/android/loganalysis/rule/LocationUsageRuleTest.java @@ -0,0 +1,100 @@ +/* + * Copyright (C) 2016 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.rule; + +import com.android.loganalysis.item.ActivityServiceItem; +import com.android.loganalysis.item.BatteryStatsDetailedInfoItem; +import com.android.loganalysis.item.BugreportItem; +import com.android.loganalysis.item.DumpsysBatteryStatsItem; +import com.android.loganalysis.item.DumpsysItem; +import com.android.loganalysis.item.LocationDumpsItem; + +import junit.framework.TestCase; + +import org.json.JSONObject; + +/** + * Unit tests for {@link LocationUsageRule} + */ +public class LocationUsageRuleTest extends TestCase { + + BugreportItem mBugreport; + DumpsysItem mDumpsys; + DumpsysBatteryStatsItem mDumpsysBatteryStats; + BatteryStatsDetailedInfoItem mBatteryStatsDetailedInfo; + ActivityServiceItem mActivityService; + + @Override + public void setUp() { + mBugreport = new BugreportItem(); + mDumpsys = new DumpsysItem(); + mDumpsysBatteryStats = new DumpsysBatteryStatsItem(); + mBatteryStatsDetailedInfo = new BatteryStatsDetailedInfoItem(); + mActivityService = new ActivityServiceItem(); + + mBatteryStatsDetailedInfo.setTimeOnBattery(3902004); + mDumpsysBatteryStats.setDetailedBatteryStatsItem(mBatteryStatsDetailedInfo); + mDumpsys.setBatteryInfo(mDumpsysBatteryStats); + mBugreport.setDumpsys(mDumpsys); + mBugreport.setActivityService(mActivityService); + } + + /** + * Test location usage analysis + */ + public void testLocationUsageAnalysis() throws Exception { + LocationDumpsItem location = new LocationDumpsItem(); + location.addLocationClient("com.google.android.gms", 1, 0, 0, "PRIORITY_NO_POWER", 140); + location.addLocationClient("com.google.android.gms", 5, 5, 5, + "PRIORITY_BALANCED_POWER_ACCURACY", 140); + mActivityService.setLocationDumps(location); + + LocationUsageRule locationUsageRule = new LocationUsageRule(mBugreport); + locationUsageRule.applyRule(); + JSONObject analysis = locationUsageRule.getAnalysis(); + assertNotNull(analysis); + assertTrue(analysis.has("LOCATION_USAGE_ANALYSIS")); + assertEquals(analysis.getString("LOCATION_USAGE_ANALYSIS"), + "Package com.google.android.gms is requesting for location updates every 5 secs " + + "with priority PRIORITY_BALANCED_POWER_ACCURACY."); + } + + public void testNoSignificantLocationUsageAnalysis() throws Exception { + LocationDumpsItem location = new LocationDumpsItem(); + location.addLocationClient("com.google.android.gms", 1, 0, 0, "PRIORITY_NO_POWER", 140); + location.addLocationClient("com.google.android.gms", 285, 285, 285, + "PRIORITY_BALANCED_POWER_ACCURACY", 140); + mActivityService.setLocationDumps(location); + + LocationUsageRule locationUsageRule = new LocationUsageRule(mBugreport); + locationUsageRule.applyRule(); + JSONObject analysis = locationUsageRule.getAnalysis(); + assertNotNull(analysis); + assertTrue(analysis.has("LOCATION_USAGE_ANALYSIS")); + assertEquals(analysis.getString("LOCATION_USAGE_ANALYSIS"), + "No apps requested for frequent location updates."); + } + + public void testNoLocationUsageAnalysis() throws Exception { + LocationUsageRule locationUsageRule = new LocationUsageRule(mBugreport); + locationUsageRule.applyRule(); + JSONObject analysis = locationUsageRule.getAnalysis(); + assertNotNull(analysis); + assertTrue(analysis.has("LOCATION_USAGE_ANALYSIS")); + assertEquals(analysis.getString("LOCATION_USAGE_ANALYSIS"), + "No apps requested for frequent location updates."); + } +} diff --git a/javatests/src/com/android/loganalysis/rule/ProcessUsageRuleTest.java b/javatests/src/com/android/loganalysis/rule/ProcessUsageRuleTest.java new file mode 100644 index 0000000..cc322dc --- /dev/null +++ b/javatests/src/com/android/loganalysis/rule/ProcessUsageRuleTest.java @@ -0,0 +1,111 @@ +/* + * Copyright (C) 2016 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.rule; + +import com.android.loganalysis.item.BatteryStatsDetailedInfoItem; +import com.android.loganalysis.item.BugreportItem; +import com.android.loganalysis.item.DumpsysBatteryStatsItem; +import com.android.loganalysis.item.DumpsysItem; +import com.android.loganalysis.item.ProcessUsageItem; +import com.android.loganalysis.item.ProcessUsageItem.SensorInfoItem; + +import java.util.LinkedList; +import junit.framework.TestCase; + +import org.json.JSONObject; + +/** + * Unit tests for {@link ProcessUsageRule} + */ +public class ProcessUsageRuleTest extends TestCase { + + BugreportItem mBugreport; + DumpsysItem mDumpsys; + DumpsysBatteryStatsItem mDumpsysBatteryStats; + BatteryStatsDetailedInfoItem mBatteryStatsDetailedInfo; + + @Override + public void setUp() { + mBugreport = new BugreportItem(); + mDumpsys = new DumpsysItem(); + mDumpsysBatteryStats = new DumpsysBatteryStatsItem(); + mBatteryStatsDetailedInfo = new BatteryStatsDetailedInfoItem(); + + mBatteryStatsDetailedInfo.setTimeOnBattery(3902004); + mDumpsysBatteryStats.setDetailedBatteryStatsItem(mBatteryStatsDetailedInfo); + mDumpsys.setBatteryInfo(mDumpsysBatteryStats); + mBugreport.setDumpsys(mDumpsys); + } + + /** + * Test alarm usage analysis + */ + public void testAlarmAnalysis() throws Exception { + ProcessUsageItem processUsage = new ProcessUsageItem(); + LinkedList uid0Sensor = new LinkedList(); + uid0Sensor.add(new SensorInfoItem("0", 9908)); + uid0Sensor.add(new SensorInfoItem("1", 9997)); + + LinkedList uidU0a9Sensor = new LinkedList(); + uidU0a9Sensor.add(new SensorInfoItem("2", 1315)); + + processUsage.addProcessUsage("0", 0, uid0Sensor); + processUsage.addProcessUsage("u0a9", 180, uidU0a9Sensor); + processUsage.addProcessUsage("u0a8", 0, null); + + mBatteryStatsDetailedInfo.setProcessUsageItem(processUsage); + ProcessUsageRule usage = new ProcessUsageRule(mBugreport); + usage.applyRule(); + JSONObject analysis = usage.getAnalysis(); + assertNotNull(analysis); + assertTrue(analysis.has("ALARM_USAGE_ANALYSIS")); + assertEquals(analysis.getString("ALARM_USAGE_ANALYSIS"), + "UID u0a9 has requested frequent repeating alarms."); + assertTrue(analysis.has("SENSOR_USAGE_ANALYSIS")); + assertEquals(analysis.getString("SENSOR_USAGE_ANALYSIS"), + "No apps used sensors more than 10% time on battery."); + } + + /** + * Test sensor usage analysis + */ + public void testSensorAnalysis() throws Exception { + ProcessUsageItem processUsage = new ProcessUsageItem(); + LinkedList uid0Sensor = new LinkedList(); + uid0Sensor.add(new SensorInfoItem("0", 9908)); + uid0Sensor.add(new SensorInfoItem("1", 9997)); + + LinkedList uidU0a9Sensor = new LinkedList(); + uidU0a9Sensor.add(new SensorInfoItem("2", 913015)); + + processUsage.addProcessUsage("0", 0, uid0Sensor); + processUsage.addProcessUsage("u0a9", 15, uidU0a9Sensor); + processUsage.addProcessUsage("u0a8", 0, null); + + mBatteryStatsDetailedInfo.setProcessUsageItem(processUsage); + ProcessUsageRule usage = new ProcessUsageRule(mBugreport); + usage.applyRule(); + JSONObject analysis = usage.getAnalysis(); + assertNotNull(analysis); + assertTrue(analysis.has("SENSOR_USAGE_ANALYSIS")); + assertEquals(analysis.getString("SENSOR_USAGE_ANALYSIS"), + "sensor 2 was used for 0d 0h 15m 13s by UID u0a9."); + + assertTrue(analysis.has("ALARM_USAGE_ANALYSIS")); + assertEquals(analysis.getString("ALARM_USAGE_ANALYSIS"), + "No apps requested for alarms more frequent than 60 secs."); + } +} diff --git a/javatests/src/com/android/loganalysis/rule/WakelockRuleTest.java b/javatests/src/com/android/loganalysis/rule/WakelockRuleTest.java new file mode 100644 index 0000000..6900c07 --- /dev/null +++ b/javatests/src/com/android/loganalysis/rule/WakelockRuleTest.java @@ -0,0 +1,108 @@ +/* + * Copyright (C) 2016 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.rule; + +import com.android.loganalysis.item.BatteryStatsDetailedInfoItem; +import com.android.loganalysis.item.BugreportItem; +import com.android.loganalysis.item.DumpsysBatteryStatsItem; +import com.android.loganalysis.item.DumpsysItem; +import com.android.loganalysis.item.WakelockItem; +import com.android.loganalysis.item.WakelockItem.WakeLockCategory; + +import junit.framework.TestCase; + +import org.json.JSONObject; + +/** + * Unit tests for {@link WakelockRule} + */ +public class WakelockRuleTest extends TestCase { + + BugreportItem mBugreport; + DumpsysItem mDumpsys; + DumpsysBatteryStatsItem mDumpsysBatteryStats; + BatteryStatsDetailedInfoItem mBatteryStatsDetailedInfo; + + @Override + public void setUp() { + mBugreport = new BugreportItem(); + mDumpsys = new DumpsysItem(); + mDumpsysBatteryStats = new DumpsysBatteryStatsItem(); + mBatteryStatsDetailedInfo = new BatteryStatsDetailedInfoItem(); + + mBatteryStatsDetailedInfo.setTimeOnBattery(3902004); + mDumpsysBatteryStats.setDetailedBatteryStatsItem(mBatteryStatsDetailedInfo); + mDumpsys.setBatteryInfo(mDumpsysBatteryStats); + mBugreport.setDumpsys(mDumpsys); + } + + /** + * Test wakelock analysis + */ + public void testWakelockAnalysis() throws Exception { + WakelockItem wakelock = new WakelockItem(); + wakelock.addWakeLock("PowerManagerService.WakeLocks", 310006, 2, + WakeLockCategory.KERNEL_WAKELOCK); + wakelock.addWakeLock("msm_serial_hs_rx", 133612, 258, + WakeLockCategory.KERNEL_WAKELOCK); + + wakelock.addWakeLock("ProxyController", "1001", 3887565, 4, + WakeLockCategory.PARTIAL_WAKELOCK); + wakelock.addWakeLock("AudioMix", "1013", 1979, 3, + WakeLockCategory.PARTIAL_WAKELOCK); + + mBatteryStatsDetailedInfo.setWakelockItem(wakelock); + WakelockRule wakelockRule = new WakelockRule(mBugreport); + wakelockRule.applyRule(); + JSONObject analysis = wakelockRule.getAnalysis(); + assertNotNull(analysis); + assertTrue(analysis.has("WAKELOCK_ANALYSIS")); + assertEquals(analysis.getString("WAKELOCK_ANALYSIS"), + "ProxyController PARTIAL_WAKELOCK is held for 0d 1h 4m 47s."); + } + + public void testNoSignificantWakelockAnalysis() throws Exception { + WakelockItem wakelock = new WakelockItem(); + wakelock.addWakeLock("PowerManagerService.WakeLocks", 310006, 2, + WakeLockCategory.KERNEL_WAKELOCK); + wakelock.addWakeLock("msm_serial_hs_rx", 133612, 258, + WakeLockCategory.KERNEL_WAKELOCK); + + wakelock.addWakeLock("ProxyController", "1001", 287565, 4, + WakeLockCategory.PARTIAL_WAKELOCK); + wakelock.addWakeLock("AudioMix", "1013", 1979, 3, + WakeLockCategory.PARTIAL_WAKELOCK); + + mBatteryStatsDetailedInfo.setWakelockItem(wakelock); + WakelockRule wakelockRule = new WakelockRule(mBugreport); + wakelockRule.applyRule(); + JSONObject analysis = wakelockRule.getAnalysis(); + assertNotNull(analysis); + assertTrue(analysis.has("WAKELOCK_ANALYSIS")); + assertEquals(analysis.getString("WAKELOCK_ANALYSIS"), + "No wakelocks were held for more than 10% of time on battery."); + } + + public void testNoWakelockAnalysis() throws Exception { + WakelockRule wakelockRule = new WakelockRule(mBugreport); + wakelockRule.applyRule(); + JSONObject analysis = wakelockRule.getAnalysis(); + assertNotNull(analysis); + assertTrue(analysis.has("WAKELOCK_ANALYSIS")); + assertEquals(analysis.getString("WAKELOCK_ANALYSIS"), + "No wakelocks were held for more than 10% of time on battery."); + } +} diff --git a/javatests/src/com/android/loganalysis/rule/WifiStatsRuleTest.java b/javatests/src/com/android/loganalysis/rule/WifiStatsRuleTest.java new file mode 100644 index 0000000..984ed20 --- /dev/null +++ b/javatests/src/com/android/loganalysis/rule/WifiStatsRuleTest.java @@ -0,0 +1,103 @@ +/* + * Copyright (C) 2016 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.rule; + +import com.android.loganalysis.item.BatteryStatsDetailedInfoItem; +import com.android.loganalysis.item.BugreportItem; +import com.android.loganalysis.item.DumpsysBatteryStatsItem; +import com.android.loganalysis.item.DumpsysItem; +import com.android.loganalysis.item.DumpsysWifiStatsItem; + +import junit.framework.TestCase; + +import org.json.JSONObject; + +/** + */ +public class WifiStatsRuleTest extends TestCase { + + BugreportItem mBugreport; + DumpsysItem mDumpsys; + DumpsysBatteryStatsItem mDumpsysBatteryStats; + BatteryStatsDetailedInfoItem mBatteryStatsDetailedInfo; + + @Override + public void setUp() { + mBugreport = new BugreportItem(); + mDumpsys = new DumpsysItem(); + mDumpsysBatteryStats = new DumpsysBatteryStatsItem(); + mBatteryStatsDetailedInfo = new BatteryStatsDetailedInfoItem(); + + mBatteryStatsDetailedInfo.setTimeOnBattery(302004); + mDumpsysBatteryStats.setDetailedBatteryStatsItem(mBatteryStatsDetailedInfo); + mDumpsys.setBatteryInfo(mDumpsysBatteryStats); + mBugreport.setDumpsys(mDumpsys); + } + + /** + * Test wifistats analysis + */ + public void testWifiDisconnectAnalysis() throws Exception { + DumpsysWifiStatsItem wifiStats = new DumpsysWifiStatsItem(); + wifiStats.setNumWifiDisconnect(1); + wifiStats.setNumWifiScan(0); + wifiStats.setNumWifiAssociation(0); + + mDumpsys.setWifiStats(wifiStats); + WifiStatsRule wifiStatsRule = new WifiStatsRule(mBugreport); + wifiStatsRule.applyRule(); + JSONObject analysis = wifiStatsRule.getAnalysis(); + assertNotNull(analysis); + assertTrue(analysis.has("WIFI_STATS")); + assertEquals(analysis.getString("WIFI_STATS"), + "No apps requested for frequent wifi scans. Wifi got disconnected 1 times. " + + "No frequent wifi associations were observed."); + } + + public void testWifiScanAnalysis() throws Exception { + DumpsysWifiStatsItem wifiStats = new DumpsysWifiStatsItem(); + wifiStats.setNumWifiDisconnect(0); + wifiStats.setNumWifiScan(3); + wifiStats.setNumWifiAssociation(0); + + mDumpsys.setWifiStats(wifiStats); + WifiStatsRule wifiStatsRule = new WifiStatsRule(mBugreport); + wifiStatsRule.applyRule(); + JSONObject analysis = wifiStatsRule.getAnalysis(); + assertNotNull(analysis); + assertTrue(analysis.has("WIFI_STATS")); + assertEquals(analysis.getString("WIFI_STATS"), + "Wifi scans happened every 100 seconds. No frequent wifi disconnects were " + + "observed. No frequent wifi associations were observed."); + } + + public void testWifiAssociationAnalysis() throws Exception { + DumpsysWifiStatsItem wifiStats = new DumpsysWifiStatsItem(); + wifiStats.setNumWifiDisconnect(0); + wifiStats.setNumWifiScan(0); + wifiStats.setNumWifiAssociation(3); + + mDumpsys.setWifiStats(wifiStats); + WifiStatsRule wifiStatsRule = new WifiStatsRule(mBugreport); + wifiStatsRule.applyRule(); + JSONObject analysis = wifiStatsRule.getAnalysis(); + assertNotNull(analysis); + assertTrue(analysis.has("WIFI_STATS")); + assertEquals(analysis.getString("WIFI_STATS"), + "No apps requested for frequent wifi scans. No frequent wifi disconnects were " + + "observed. Wifi got associated with AP 3 times."); + } +} diff --git a/javatests/src/com/android/loganalysis/util/ArrayUtilTest.java b/javatests/src/com/android/loganalysis/util/ArrayUtilTest.java new file mode 100644 index 0000000..98d85e6 --- /dev/null +++ b/javatests/src/com/android/loganalysis/util/ArrayUtilTest.java @@ -0,0 +1,68 @@ +/* + * Copyright (C) 2011 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.util; + +import junit.framework.TestCase; + +import java.util.Arrays; +import java.util.List; + +/** + * Unit tests for {@link ArrayUtil} + */ +public class ArrayUtilTest extends TestCase { + + /** + * Simple test for {@link ArrayUtil#buildArray(String[][])} + */ + public void testBuildArray_arrays() { + String[] newArray = ArrayUtil.buildArray(new String[] {"1", "2"}, new String[] {"3"}, + new String[] {"4"}); + assertEquals(4, newArray.length); + for (int i = 0; i < 4; i++) { + assertEquals(Integer.toString(i+1), newArray[i]); + } + } + + /** + * Make sure that Collections aren't double-wrapped + */ + public void testJoinCollection() { + List list = Arrays.asList("alpha", "beta", "gamma"); + final String expected = "alpha, beta, gamma"; + String str = ArrayUtil.join(", ", list); + assertEquals(expected, str); + } + + /** + * Make sure that Arrays aren't double-wrapped + */ + public void testJoinArray() { + String[] ary = new String[] {"alpha", "beta", "gamma"}; + final String expected = "alpha, beta, gamma"; + String str = ArrayUtil.join(", ", (Object[]) ary); + assertEquals(expected, str); + } + + /** + * Make sure that join on varargs arrays work as expected + */ + public void testJoinNormal() { + final String expected = "alpha, beta, gamma"; + String str = ArrayUtil.join(", ", "alpha", "beta", "gamma"); + assertEquals(expected, str); + } +} diff --git a/javatests/src/com/android/loganalysis/util/LogPatternUtilTest.java b/javatests/src/com/android/loganalysis/util/LogPatternUtilTest.java new file mode 100644 index 0000000..98226d4 --- /dev/null +++ b/javatests/src/com/android/loganalysis/util/LogPatternUtilTest.java @@ -0,0 +1,57 @@ +/* + * 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.util; + +import junit.framework.TestCase; + +import java.util.regex.Pattern; + +/** + * Unit tests for {@link LogPatternUtil}. + */ +public class LogPatternUtilTest extends TestCase { + + /** + * Test basic pattern matching. + */ + public void testPatternMatching() { + LogPatternUtil patternUtil = new LogPatternUtil(); + patternUtil.addPattern(Pattern.compile("abc"), "cat1"); + patternUtil.addPattern(Pattern.compile("123"), "cat2"); + + assertNull(patternUtil.checkMessage("xyz")); + assertEquals("cat1", patternUtil.checkMessage("abc")); + assertEquals("cat2", patternUtil.checkMessage("123")); + } + + /** + * Test pattern matching with extras. + */ + public void testExtrasMatching() { + LogPatternUtil patternUtil = new LogPatternUtil(); + patternUtil.addPattern(Pattern.compile("abc"), null, "cat1"); + patternUtil.addPattern(Pattern.compile("123"), "E/tag1", "cat2"); + patternUtil.addPattern(Pattern.compile("123"), "E/tag2", "cat3"); + + assertNull(patternUtil.checkMessage("xyz")); + assertEquals("cat1", patternUtil.checkMessage("abc")); + assertEquals("cat1", patternUtil.checkMessage("abc", "E/tag1")); + assertEquals("cat1", patternUtil.checkMessage("abc", "E/tag2")); + assertNull(patternUtil.checkMessage("123")); + assertEquals("cat2", patternUtil.checkMessage("123", "E/tag1")); + assertEquals("cat3", patternUtil.checkMessage("123", "E/tag2")); + } +} diff --git a/javatests/src/com/android/loganalysis/util/LogTailUtilTest.java b/javatests/src/com/android/loganalysis/util/LogTailUtilTest.java new file mode 100644 index 0000000..d7316c6 --- /dev/null +++ b/javatests/src/com/android/loganalysis/util/LogTailUtilTest.java @@ -0,0 +1,66 @@ +/* + * 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.util; + +import junit.framework.TestCase; + +/** + * Unit tests for {@link LogTailUtil}. + */ +public class LogTailUtilTest extends TestCase { + + /** + * Test that last and id tails of the log are returned correctly. + */ + public void testGetPreambles() { + LogTailUtil preambleUtil = new LogTailUtil(500, 3, 3); + + assertEquals("", preambleUtil.getLastTail()); + assertEquals("", preambleUtil.getIdTail(1)); + + preambleUtil.addLine(1, "line 1"); + preambleUtil.addLine(2, "line 2"); + + assertEquals("line 1\nline 2", preambleUtil.getLastTail()); + assertEquals("line 1", preambleUtil.getIdTail(1)); + + preambleUtil.addLine(1, "line 3"); + preambleUtil.addLine(2, "line 4"); + preambleUtil.addLine(1, "line 5"); + preambleUtil.addLine(2, "line 6"); + preambleUtil.addLine(1, "line 7"); + preambleUtil.addLine(2, "line 8"); + + assertEquals("line 6\nline 7\nline 8", preambleUtil.getLastTail()); + assertEquals("line 3\nline 5\nline 7", preambleUtil.getIdTail(1)); + } + + /** + * Test that the ring buffer is limited to a certain size. + */ + public void testRingBufferSize() { + LogTailUtil preambleUtil = new LogTailUtil(5, 3, 3); + preambleUtil.addLine(1, "line 1"); + preambleUtil.addLine(2, "line 2"); + preambleUtil.addLine(2, "line 3"); + preambleUtil.addLine(2, "line 4"); + preambleUtil.addLine(2, "line 5"); + preambleUtil.addLine(2, "line 6"); + + // The first line should roll off the end of the buffer. + assertEquals("", preambleUtil.getIdTail(1)); + } +} diff --git a/javatests/src/com/android/loganalysis/util/RegexTrieTest.java b/javatests/src/com/android/loganalysis/util/RegexTrieTest.java new file mode 100644 index 0000000..4b689b6 --- /dev/null +++ b/javatests/src/com/android/loganalysis/util/RegexTrieTest.java @@ -0,0 +1,284 @@ +/* + * Copyright (C) 2010 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.util; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotEquals; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; + +import com.android.loganalysis.util.RegexTrie.CompPattern; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.regex.Pattern; + +/** Set of unit tests to verify the behavior of the RegexTrie */ +@RunWith(JUnit4.class) +public class RegexTrieTest { + private RegexTrie mTrie = null; + private static final Integer STORED_VAL = 42; + private static final List NULL_LIST = Arrays.asList((String)null); + + @Before + public void setUp() throws Exception { + mTrie = new RegexTrie(); + } + + @Test + public void testStringPattern() { + mTrie.put(STORED_VAL, "[p]art1", "[p]art2", "[p]art3"); + Integer retrieved = mTrie.retrieve("part1", "part2", "part3"); + assertEquals(STORED_VAL, retrieved); + } + + @Test + public void testAlternation_single() { + mTrie.put(STORED_VAL, "alpha|beta"); + Integer retrieved; + retrieved = mTrie.retrieve("alpha"); + assertEquals(STORED_VAL, retrieved); + retrieved = mTrie.retrieve("beta"); + assertEquals(STORED_VAL, retrieved); + retrieved = mTrie.retrieve("alpha|beta"); + assertNull(retrieved); + retrieved = mTrie.retrieve("gamma"); + assertNull(retrieved); + retrieved = mTrie.retrieve("alph"); + assertNull(retrieved); + } + + @Test + public void testAlternation_multiple() { + mTrie.put(STORED_VAL, "a|alpha", "b|beta"); + Integer retrieved; + retrieved = mTrie.retrieve("a", "b"); + assertEquals(STORED_VAL, retrieved); + retrieved = mTrie.retrieve("a", "beta"); + assertEquals(STORED_VAL, retrieved); + retrieved = mTrie.retrieve("alpha", "b"); + assertEquals(STORED_VAL, retrieved); + retrieved = mTrie.retrieve("alpha", "beta"); + assertEquals(STORED_VAL, retrieved); + + retrieved = mTrie.retrieve("alpha"); + assertNull(retrieved); + retrieved = mTrie.retrieve("beta"); + assertNull(retrieved); + retrieved = mTrie.retrieve("alpha", "bet"); + assertNull(retrieved); + } + + @Test + public void testGroups_fullMatch() { + mTrie.put(STORED_VAL, "a|(alpha)", "b|(beta)"); + Integer retrieved; + List> groups = new ArrayList>(); + + retrieved = mTrie.retrieve(groups, "a", "b"); + assertEquals(STORED_VAL, retrieved); + assertEquals(2, groups.size()); + assertEquals(NULL_LIST, groups.get(0)); + assertEquals(NULL_LIST, groups.get(1)); + + retrieved = mTrie.retrieve(groups, "a", "beta"); + assertEquals(STORED_VAL, retrieved); + assertEquals(2, groups.size()); + assertEquals(NULL_LIST, groups.get(0)); + assertEquals(Arrays.asList("beta"), groups.get(1)); + + retrieved = mTrie.retrieve(groups, "alpha", "b"); + assertEquals(STORED_VAL, retrieved); + assertEquals(2, groups.size()); + assertEquals(Arrays.asList("alpha"), groups.get(0)); + assertEquals(NULL_LIST, groups.get(1)); + + retrieved = mTrie.retrieve(groups, "alpha", "beta"); + assertEquals(STORED_VAL, retrieved); + assertEquals(2, groups.size()); + assertEquals(Arrays.asList("alpha"), groups.get(0)); + assertEquals(Arrays.asList("beta"), groups.get(1)); + } + + @Test + public void testGroups_partialMatch() { + mTrie.put(STORED_VAL, "a|(alpha)", "b|(beta)"); + Integer retrieved; + List> groups = new ArrayList>(); + + retrieved = mTrie.retrieve(groups, "alpha"); + assertNull(retrieved); + assertEquals(1, groups.size()); + assertEquals(Arrays.asList("alpha"), groups.get(0)); + + retrieved = mTrie.retrieve(groups, "beta"); + assertNull(retrieved); + assertEquals(0, groups.size()); + + retrieved = mTrie.retrieve(groups, "alpha", "bet"); + assertNull(retrieved); + assertEquals(1, groups.size()); + assertEquals(Arrays.asList("alpha"), groups.get(0)); + + retrieved = mTrie.retrieve(groups, "alpha", "betar"); + assertNull(retrieved); + assertEquals(1, groups.size()); + assertEquals(Arrays.asList("alpha"), groups.get(0)); + + retrieved = mTrie.retrieve(groups, "alpha", "beta", "gamma"); + assertNull(retrieved); + assertEquals(2, groups.size()); + assertEquals(Arrays.asList("alpha"), groups.get(0)); + assertEquals(Arrays.asList("beta"), groups.get(1)); + } + + /** Make sure that the wildcard functionality works */ + @Test + public void testWildcard() { + mTrie.put(STORED_VAL, "a", null); + Integer retrieved; + List> groups = new ArrayList>(); + + retrieved = mTrie.retrieve(groups, "a", "b", "c"); + assertEquals(STORED_VAL, retrieved); + assertEquals(3, groups.size()); + assertTrue(groups.get(0).isEmpty()); + assertEquals(Arrays.asList("b"), groups.get(1)); + assertEquals(Arrays.asList("c"), groups.get(2)); + + retrieved = mTrie.retrieve(groups, "a"); + assertNull(retrieved); + assertEquals(1, groups.size()); + assertTrue(groups.get(0).isEmpty()); + } + + /** + * Make sure that if a wildcard and a more specific match could both match, that the more + * specific match takes precedence + */ + @Test + public void testWildcard_precedence() { + // Do one before and one after the wildcard to check for ordering effects + mTrie.put(STORED_VAL + 1, "a", "(b)"); + mTrie.put(STORED_VAL, "a", null); + mTrie.put(STORED_VAL + 2, "a", "(c)"); + Integer retrieved; + List> groups = new ArrayList>(); + + retrieved = mTrie.retrieve(groups, "a", "d"); + assertEquals(STORED_VAL, retrieved); + assertEquals(2, groups.size()); + assertTrue(groups.get(0).isEmpty()); + assertEquals(Arrays.asList("d"), groups.get(1)); + + retrieved = mTrie.retrieve(groups, "a", "b"); + assertEquals((Integer)(STORED_VAL + 1), retrieved); + assertEquals(2, groups.size()); + assertTrue(groups.get(0).isEmpty()); + assertEquals(Arrays.asList("b"), groups.get(1)); + + retrieved = mTrie.retrieve(groups, "a", "c"); + assertEquals((Integer)(STORED_VAL + 2), retrieved); + assertEquals(2, groups.size()); + assertTrue(groups.get(0).isEmpty()); + assertEquals(Arrays.asList("c"), groups.get(1)); + } + + /** + * Verify a bugfix: make sure that no NPE results from calling #retrieve with a wildcard but + * without a place to retrieve captures. + */ + @Test + public void testWildcard_noCapture() throws NullPointerException { + mTrie.put(STORED_VAL, "a", null); + String[] key = new String[] {"a", "b", "c"}; + + mTrie.retrieve(key); + mTrie.retrieve(null, key); + // test passes if no exceptions were thrown + } + + @Test + public void testMultiChild() { + mTrie.put(STORED_VAL + 1, "a", "b"); + mTrie.put(STORED_VAL + 2, "a", "c"); + + Object retrieved; + retrieved = mTrie.retrieve("a", "b"); + assertEquals(STORED_VAL + 1, retrieved); + retrieved = mTrie.retrieve("a", "c"); + assertEquals(STORED_VAL + 2, retrieved); + } + + /** + * Make sure that {@link CompPattern#equals} works as expected. Shake a proverbial fist at Java + */ + @Test + public void testCompPattern_equality() { + String regex = "regex"; + Pattern p1 = Pattern.compile(regex); + Pattern p2 = Pattern.compile(regex); + Pattern pOther = Pattern.compile("other"); + CompPattern cp1 = new CompPattern(p1); + CompPattern cp2 = new CompPattern(p2); + CompPattern cpOther = new CompPattern(pOther); + + // This is the problem with Pattern as implemented + assertNotEquals(p1, p2); + assertNotEquals(p2, p1); + + // Make sure that wrapped patterns with the same regex are considered equivalent + assertEquals(cp2, p1); + assertEquals(cp2, p1); + assertEquals(cp2, cp1); + + // And make sure that wrapped patterns with different regexen are still considered different + assertNotEquals(cp2, pOther); + assertNotEquals(cp2, cpOther); + } + + @Test + public void testCompPattern_hashmap() { + HashMap map = new HashMap(); + String regex = "regex"; + Pattern p1 = Pattern.compile(regex); + Pattern p2 = Pattern.compile(regex); + Pattern pOther = Pattern.compile("other"); + CompPattern cp1 = new CompPattern(p1); + CompPattern cp2 = new CompPattern(p2); + CompPattern cpOther = new CompPattern(pOther); + + map.put(cp1, STORED_VAL); + assertTrue(map.containsKey(cp1)); + assertTrue(map.containsKey(cp2)); + assertFalse(map.containsKey(cpOther)); + + map.put(cpOther, STORED_VAL); + assertEquals(map.size(), 2); + assertTrue(map.containsKey(cp1)); + assertTrue(map.containsKey(cp2)); + assertTrue(map.containsKey(cpOther)); + } +} + diff --git a/javatests/src/com/android/loganalysis/util/config/ArgsOptionParserTest.java b/javatests/src/com/android/loganalysis/util/config/ArgsOptionParserTest.java new file mode 100644 index 0000000..524cfa0 --- /dev/null +++ b/javatests/src/com/android/loganalysis/util/config/ArgsOptionParserTest.java @@ -0,0 +1,629 @@ +/* + * Copyright (C) 2010 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.util.config; + +import com.android.loganalysis.util.config.Option.Importance; + +import junit.framework.TestCase; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * Unit tests for {@link ArgsOptionParser}. + */ +@SuppressWarnings("unused") +public class ArgsOptionParserTest extends TestCase { + + /** + * An option source with one {@link Option} specified. + */ + private static class OneOptionSource { + + private static final String DEFAULT_VALUE = "default"; + private static final String OPTION_NAME = "my_option"; + private static final String OPTION_DESC = "option description"; + + @Option(name=OPTION_NAME, shortName='o', description=OPTION_DESC) + private String mMyOption = DEFAULT_VALUE; + } + + /** + * An option source with one {@link Option} specified. + */ + private static class MapOptionSource { + + private static final String OPTION_NAME = "my_option"; + private static final String OPTION_DESC = "option description"; + + @Option(name=OPTION_NAME, shortName='o', description=OPTION_DESC) + private Map mMyOption = new HashMap(); + } + + /** + * An option source with boolean {@link Option} specified. + */ + private static class BooleanOptionSource { + + private static final boolean DEFAULT_BOOL = false; + private static final String DEFAULT_VALUE = "default"; + + @Option(name="my_boolean", shortName='b') + private boolean mMyBool = DEFAULT_BOOL; + + @Option(name="my_option", shortName='o') + protected String mMyOption = DEFAULT_VALUE; + } + + /** + * An option source with boolean {@link Option} specified with default = true. + */ + private static class BooleanTrueOptionSource { + + private static final boolean DEFAULT_BOOL = true; + + @Option(name="my_boolean", shortName='b') + private boolean mMyBool = DEFAULT_BOOL; + } + + /** + * An option source that has a superclass with options + */ + private static class InheritedOptionSource extends OneOptionSource { + + private static final String OPTION_NAME = "my_sub_option"; + private static final String OPTION_DESC = "sub description"; + + @Option(name=OPTION_NAME, description=OPTION_DESC) + private String mMySubOption = ""; + } + + /** + * An option source for testing the {@link Option#importance()} settings + */ + private static class ImportantOptionSource { + + private static final String IMPORTANT_OPTION_NAME = "important_option"; + private static final String IMPORTANT_UNSET_OPTION_NAME = "unset_important_option"; + private static final String UNIMPORTANT_OPTION_NAME = "unimportant_option"; + + @Option(name = IMPORTANT_OPTION_NAME, description = IMPORTANT_OPTION_NAME, + importance = Importance.ALWAYS) + private String mImportantOption = "foo"; + + @Option(name = IMPORTANT_UNSET_OPTION_NAME, description = IMPORTANT_UNSET_OPTION_NAME, + importance = Importance.IF_UNSET) + private String mImportantUnsetOption = null; + + @Option(name = UNIMPORTANT_OPTION_NAME, description = UNIMPORTANT_OPTION_NAME, + importance = Importance.NEVER) + private String mUnimportantOption = null; + + ImportantOptionSource(String setOption) { + mImportantUnsetOption = setOption; + } + + ImportantOptionSource() { + } + } + + /** + * Option source whose options shouldn't end up in the global namespace + */ + @OptionClass(alias = "ngos", global_namespace = false) + private static class NonGlobalOptionSource { + @Option(name = "option") + Boolean mOption = null; + } + + /** + * Option source with mandatory options + */ + private static class MandatoryOptionSourceNoDefault { + @Option(name = "no-default", mandatory = true) + private String mNoDefaultOption; + } + + /** + * Option source with mandatory options + */ + private static class MandatoryOptionSourceNull { + @Option(name = "null", mandatory = true) + private String mNullOption = null; + } + + /** + * Option source with mandatory options + */ + private static class MandatoryOptionSourceEmptyCollection { + @Option(name = "empty-collection", mandatory = true) + private Collection mEmptyCollection = new ArrayList(0); + } + + /** + * Option source with mandatory options + */ + private static class MandatoryOptionSourceEmptyMap { + @Option(name = "empty-map", mandatory = true) + private Map mEmptyMap = new HashMap(); + } + + /** + * An option source that exercises the {@link OptionUpdateRule}s. + */ + private static class OptionUpdateRuleSource { + + public static final String DEFAULT_VALUE = "5 default"; + public static final String BIGGER_VALUE = "9 bigger"; + public static final String SMALLER_VALUE = "0 smaller"; + + @Option(name = "default") + private String mDefaultOption = DEFAULT_VALUE; + + @Option(name = "first", updateRule = OptionUpdateRule.FIRST) + private String mFirstOption = DEFAULT_VALUE; + + @Option(name = "last", updateRule = OptionUpdateRule.LAST) + private String mLastOption = DEFAULT_VALUE; + + @Option(name = "greatest", updateRule = OptionUpdateRule.GREATEST) + private String mGreatestOption = DEFAULT_VALUE; + + @Option(name = "least", updateRule = OptionUpdateRule.LEAST) + private String mLeastOption = DEFAULT_VALUE; + + @Option(name = "immutable", updateRule = OptionUpdateRule.IMMUTABLE) + private String mImmutableOption = DEFAULT_VALUE; + + @Option(name = "null-immutable", updateRule = OptionUpdateRule.IMMUTABLE) + private String mNullImmutableOption = null; + } + + /** + * Verify that {@link OptionUpdateRule}s work properly when the update compares to greater-than + * the default value. + */ + public void testOptionUpdateRule_greater() throws Exception { + OptionUpdateRuleSource object = new OptionUpdateRuleSource(); + ArgsOptionParser parser = new ArgsOptionParser(object); + final String current = OptionUpdateRuleSource.DEFAULT_VALUE; + final String big = OptionUpdateRuleSource.BIGGER_VALUE; + + parser.parse(new String[] {"--default", big, "--first", big, "--last", big, + "--greatest", big, "--least", big}); + assertEquals(current, object.mFirstOption); + assertEquals(big, object.mLastOption); + assertEquals(big, object.mDefaultOption); // default should be LAST + assertEquals(big, object.mGreatestOption); + assertEquals(current, object.mLeastOption); + } + + /** + * Verify that {@link OptionUpdateRule}s work properly when the update compares to greater-than + * the default value. + */ + public void testOptionUpdateRule_lesser() throws Exception { + OptionUpdateRuleSource object = new OptionUpdateRuleSource(); + ArgsOptionParser parser = new ArgsOptionParser(object); + final String current = OptionUpdateRuleSource.DEFAULT_VALUE; + final String small = OptionUpdateRuleSource.SMALLER_VALUE; + + parser.parse(new String[] {"--default", small, "--first", small, "--last", small, + "--greatest", small, "--least", small}); + assertEquals(current, object.mFirstOption); + assertEquals(small, object.mLastOption); + assertEquals(small, object.mDefaultOption); // default should be LAST + assertEquals(current, object.mGreatestOption); + assertEquals(small, object.mLeastOption); + } + + /** + * Verify that {@link OptionUpdateRule}s work properly when the update compares to greater-than + * the default value. + */ + public void testOptionUpdateRule_immutable() throws Exception { + OptionUpdateRuleSource object = new OptionUpdateRuleSource(); + ArgsOptionParser parser = new ArgsOptionParser(object); + final String update = OptionUpdateRuleSource.BIGGER_VALUE; + + try { + parser.parse(new String[] {"--immutable", update}); + fail("ConfigurationException not thrown when updating an IMMUTABLE option"); + } catch (ConfigurationException e) { + // expected + } + + assertNull(object.mNullImmutableOption); + parser.parse(new String[] {"--null-immutable", update}); + assertEquals(update, object.mNullImmutableOption); + + try { + parser.parse(new String[] {"--null-immutable", update}); + fail("ConfigurationException not thrown when updating an IMMUTABLE option"); + } catch (ConfigurationException e) { + // expected + } + } + + /** + * Setting an option with a namespace alias should work fine + */ + public void testNonGlobalOptionSource_alias() throws Exception { + NonGlobalOptionSource source = new NonGlobalOptionSource(); + ArgsOptionParser parser = new ArgsOptionParser(source); + + assertNull(source.mOption); + parser.parse(new String[] {"--ngos:option"}); + assertTrue(source.mOption); + parser.parse(new String[] {"--ngos:no-option"}); + assertFalse(source.mOption); + } + + /** + * Setting an option with a classname namespace should work fine + */ + public void testNonGlobalOptionSource_className() throws Exception { + NonGlobalOptionSource source = new NonGlobalOptionSource(); + ArgsOptionParser parser = new ArgsOptionParser(source); + + assertNull(source.mOption); + parser.parse(new String[] {String.format("--%s:option", source.getClass().getName())}); + assertTrue(source.mOption); + parser.parse(new String[] {String.format("--%s:no-option", source.getClass().getName())}); + assertFalse(source.mOption); + } + + /** + * Setting an option without a namespace should fail + */ + public void testNonGlobalOptionSource_global() throws Exception { + NonGlobalOptionSource source = new NonGlobalOptionSource(); + ArgsOptionParser parser = new ArgsOptionParser(source); + + assertNull(source.mOption); + try { + parser.parse(new String[] {"--option"}); + fail("ConfigurationException not thrown when assigning a global option to an @Option " + + "field in a non-global-namespace class"); + } catch (ConfigurationException e) { + // expected + } + + try { + parser.parse(new String[] {"--no-option"}); + fail("ConfigurationException not thrown when assigning a global option to an @Option " + + "field in a non-global-namespace class"); + } catch (ConfigurationException e) { + // expected + } + } + + /** + * Test passing an empty argument list for an object that has one option specified. + *

+ * Expected that the option field should retain its default value. + */ + public void testParse_noArg() throws ConfigurationException { + OneOptionSource object = new OneOptionSource(); + ArgsOptionParser parser = new ArgsOptionParser(object); + parser.parse(new String[] {}); + assertEquals(OneOptionSource.DEFAULT_VALUE, object.mMyOption); + } + + /** + * Test passing an single argument for an object that has one option specified. + */ + public void testParse_oneArg() throws ConfigurationException { + OneOptionSource object = new OneOptionSource(); + ArgsOptionParser parser = new ArgsOptionParser(object); + final String expectedValue = "set"; + parser.parse(new String[] {"--my_option", expectedValue}); + assertEquals(expectedValue, object.mMyOption); + } + + /** + * Test passing an single argument for an object that has one option specified. + */ + public void testParse_oneMapArg() throws ConfigurationException { + MapOptionSource object = new MapOptionSource(); + ArgsOptionParser parser = new ArgsOptionParser(object); + final int expectedKey = 13; + final boolean expectedValue = true; + parser.parse(new String[] {"--my_option", Integer.toString(expectedKey), + Boolean.toString(expectedValue)}); + assertNotNull(object.mMyOption); + assertEquals(1, object.mMyOption.size()); + assertEquals(expectedValue, (boolean) object.mMyOption.get(expectedKey)); + } + + /** + * Test passing an single argument for an object that has one option specified. + */ + public void testParseMapArg_mismatchKeyType() throws ConfigurationException { + MapOptionSource object = new MapOptionSource(); + ArgsOptionParser parser = new ArgsOptionParser(object); + final String expectedKey = "istanbul"; + final boolean expectedValue = true; + try { + parser.parse(new String[] {"--my_option", expectedKey, Boolean.toString(expectedValue)}); + fail("ConfigurationException not thrown"); + } catch (ConfigurationException e) { + // expect an exception that explicitly mentions that the "key" is incorrect + assertTrue(String.format("Expected exception message to contain 'key': %s", + e.getMessage()), e.getMessage().contains("key")); + assertTrue(String.format("Expected exception message to contain '%s': %s", + expectedKey, e.getMessage()), e.getMessage().contains(expectedKey)); + } + } + + /** + * Test passing an single argument for an object that has one option specified. + */ + public void testParseMapArg_mismatchValueType() throws ConfigurationException { + MapOptionSource object = new MapOptionSource(); + ArgsOptionParser parser = new ArgsOptionParser(object); + final int expectedKey = 13; + final String expectedValue = "notconstantinople"; + try { + parser.parse(new String[] {"--my_option", Integer.toString(expectedKey), expectedValue}); + fail("ConfigurationException not thrown"); + } catch (ConfigurationException e) { + // expect an exception that explicitly mentions that the "value" is incorrect + assertTrue(String.format("Expected exception message to contain 'value': '%s'", + e.getMessage()), e.getMessage().contains("value")); + assertTrue(String.format("Expected exception message to contain '%s': %s", + expectedValue, e.getMessage()), e.getMessage().contains(expectedValue)); + } + } + + /** + * Test passing an single argument for an object that has one option specified. + */ + public void testParseMapArg_missingKey() throws ConfigurationException { + MapOptionSource object = new MapOptionSource(); + ArgsOptionParser parser = new ArgsOptionParser(object); + try { + parser.parse(new String[] {"--my_option"}); + fail("ConfigurationException not thrown"); + } catch (ConfigurationException e) { + // expect an exception that explicitly mentions that the "key" is incorrect + assertTrue(String.format("Expected exception message to contain 'key': '%s'", + e.getMessage()), e.getMessage().contains("key")); + } + } + + /** + * Test passing an single argument for an object that has one option specified. + */ + public void testParseMapArg_missingValue() throws ConfigurationException { + MapOptionSource object = new MapOptionSource(); + ArgsOptionParser parser = new ArgsOptionParser(object); + final int expectedKey = 13; + try { + parser.parse(new String[] {"--my_option", Integer.toString(expectedKey)}); + fail("ConfigurationException not thrown"); + } catch (ConfigurationException e) { + // expect an exception that explicitly mentions that the "value" is incorrect + assertTrue(String.format("Expected exception message to contain 'value': '%s'", + e.getMessage()), e.getMessage().contains("value")); + } + } + + /** + * Test passing an single argument for an object that has one option specified, using the + * option=value notation. + */ + public void testParse_oneArgEquals() throws ConfigurationException { + OneOptionSource object = new OneOptionSource(); + ArgsOptionParser parser = new ArgsOptionParser(object); + final String expectedValue = "set"; + parser.parse(new String[] {String.format("--my_option=%s", expectedValue)}); + assertEquals(expectedValue, object.mMyOption); + } + + /** + * Test passing a single argument for an object that has one option specified, using the + * short option notation. + */ + public void testParse_oneShortArg() throws ConfigurationException { + OneOptionSource object = new OneOptionSource(); + ArgsOptionParser parser = new ArgsOptionParser(object); + final String expectedValue = "set"; + parser.parse(new String[] {"-o", expectedValue}); + assertEquals(expectedValue, object.mMyOption); + } + + /** + * Test that "--" marks the beginning of positional arguments + */ + public void testParse_posArgs() throws ConfigurationException { + OneOptionSource object = new OneOptionSource(); + ArgsOptionParser parser = new ArgsOptionParser(object); + final String expectedValue = "set"; + // have a position argument with a long option prefix, to try to confuse the parser + final String posArg = "--unused"; + List leftOver = parser.parse(new String[] {"-o", expectedValue, "--", posArg}); + assertEquals(expectedValue, object.mMyOption); + assertTrue(leftOver.contains(posArg)); + } + + /** + * Test passing a single boolean argument. + */ + public void testParse_boolArg() throws ConfigurationException { + BooleanOptionSource object = new BooleanOptionSource(); + ArgsOptionParser parser = new ArgsOptionParser(object); + parser.parse(new String[] {"-b"}); + assertTrue(object.mMyBool); + } + + /** + * Test passing a boolean argument with another short argument. + */ + public void testParse_boolTwoArg() throws ConfigurationException { + BooleanOptionSource object = new BooleanOptionSource(); + ArgsOptionParser parser = new ArgsOptionParser(object); + final String expectedValue = "set"; + parser.parse(new String[] {"-bo", expectedValue}); + assertTrue(object.mMyBool); + assertEquals(expectedValue, object.mMyOption); + } + + /** + * Test passing a boolean argument with another short argument, with value concatenated. + * e.g -bovalue + */ + public void testParse_boolTwoArgValue() throws ConfigurationException { + BooleanOptionSource object = new BooleanOptionSource(); + ArgsOptionParser parser = new ArgsOptionParser(object); + final String expectedValue = "set"; + parser.parse(new String[] {String.format("-bo%s", expectedValue)}); + assertTrue(object.mMyBool); + assertEquals(expectedValue, object.mMyOption); + } + + /** + * Test the "--no-" syntax + */ + public void testParse_boolFalse() throws ConfigurationException { + BooleanTrueOptionSource object = new BooleanTrueOptionSource(); + ArgsOptionParser parser = new ArgsOptionParser(object); + parser.parse(new String[] {"--no-my_boolean"}); + assertFalse(object.mMyBool); + } + + /** + * Test the boolean long option syntax + */ + public void testParse_boolLong() throws ConfigurationException { + BooleanOptionSource object = new BooleanOptionSource(); + ArgsOptionParser parser = new ArgsOptionParser(object); + parser.parse(new String[] {"--my_boolean"}); + assertTrue(object.mMyBool); + } + + /** + * Test passing arg string where value is missing + */ + public void testParse_missingValue() throws ConfigurationException { + OneOptionSource object = new OneOptionSource(); + ArgsOptionParser parser = new ArgsOptionParser(object); + try { + parser.parse(new String[] {"--my_option"}); + fail("ConfigurationException not thrown"); + } catch (ConfigurationException e) { + // expected + } + } + + /** + * Test parsing args for an option that does not exist. + */ + public void testParse_optionNotPresent() throws ConfigurationException { + OneOptionSource object = new OneOptionSource(); + ArgsOptionParser parser = new ArgsOptionParser(object); + try { + parser.parse(new String[] {"--my_option", "set", "--not_here", "value"}); + fail("ConfigurationException not thrown"); + } catch (ConfigurationException e) { + // expected + } + } + + /** + * Test that help text is displayed for all fields + */ + public void testGetOptionHelp() { + String help = ArgsOptionParser.getOptionHelp(false, new InheritedOptionSource()); + assertTrue(help.contains(InheritedOptionSource.OPTION_NAME)); + assertTrue(help.contains(InheritedOptionSource.OPTION_DESC)); + assertTrue(help.contains(OneOptionSource.OPTION_NAME)); + assertTrue(help.contains(OneOptionSource.OPTION_DESC)); + assertTrue(help.contains(OneOptionSource.DEFAULT_VALUE)); + } + + /** + * Test displaying important only help text + */ + public void testGetOptionHelp_important() { + String help = ArgsOptionParser.getOptionHelp(true, new ImportantOptionSource()); + assertTrue(help.contains(ImportantOptionSource.IMPORTANT_OPTION_NAME)); + assertTrue(help.contains(ImportantOptionSource.IMPORTANT_UNSET_OPTION_NAME)); + assertFalse(help.contains(ImportantOptionSource.UNIMPORTANT_OPTION_NAME)); + } + + /** + * Test that {@link Importance#IF_UNSET} {@link Option}s are hidden from help if set. + */ + public void testGetOptionHelp_importantUnset() { + String help = ArgsOptionParser.getOptionHelp(true, new ImportantOptionSource("foo")); + assertTrue(help.contains(ImportantOptionSource.IMPORTANT_OPTION_NAME)); + assertFalse(help.contains(ImportantOptionSource.IMPORTANT_UNSET_OPTION_NAME)); + assertFalse(help.contains(ImportantOptionSource.UNIMPORTANT_OPTION_NAME)); + } + + public void testMandatoryOption_noDefault() throws Exception { + MandatoryOptionSourceNoDefault object = new MandatoryOptionSourceNoDefault(); + ArgsOptionParser parser = new ArgsOptionParser(object); + // expect success + parser.parse(new String[] {}); + try { + parser.validateMandatoryOptions(); + fail("ConfigurationException not thrown"); + } catch (ConfigurationException e) { + // expected + } + } + + public void testMandatoryOption_null() throws Exception { + MandatoryOptionSourceNull object = new MandatoryOptionSourceNull(); + ArgsOptionParser parser = new ArgsOptionParser(object); + parser.parse(new String[] {}); + try { + parser.validateMandatoryOptions(); + fail("ConfigurationException not thrown"); + } catch (ConfigurationException e) { + // expected + } + } + + public void testMandatoryOption_emptyCollection() throws Exception { + MandatoryOptionSourceEmptyCollection object = new MandatoryOptionSourceEmptyCollection(); + ArgsOptionParser parser = new ArgsOptionParser(object); + parser.parse(new String[] {}); + try { + parser.validateMandatoryOptions(); + fail("ConfigurationException not thrown"); + } catch (ConfigurationException e) { + // expected + } + } + + public void testMandatoryOption_emptyMap() throws Exception { + MandatoryOptionSourceEmptyMap object = new MandatoryOptionSourceEmptyMap(); + ArgsOptionParser parser = new ArgsOptionParser(object); + parser.parse(new String[] {}); + try { + parser.validateMandatoryOptions(); + fail("ConfigurationException not thrown"); + } catch (ConfigurationException e) { + // expected + } + } +} diff --git a/javatests/src/com/android/loganalysis/util/config/OptionSetterTest.java b/javatests/src/com/android/loganalysis/util/config/OptionSetterTest.java new file mode 100644 index 0000000..308e895 --- /dev/null +++ b/javatests/src/com/android/loganalysis/util/config/OptionSetterTest.java @@ -0,0 +1,828 @@ +/* + * Copyright (C) 2010 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.util.config; + +import junit.framework.TestCase; + +import java.io.File; +import java.io.IOException; +import java.lang.reflect.Field; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; + +/** + * Unit tests for {@link OptionSetter}. + */ +public class OptionSetterTest extends TestCase { + + /** Option source with generic type. */ + private static class GenericTypeOptionSource { + @Option(name = "my_option", shortName = 'o') + private Collection mMyOption; + } + + /** Option source with unparameterized type. */ + @SuppressWarnings("rawtypes") + private static class CollectionTypeOptionSource { + @Option(name = "my_option", shortName = 'o') + private Collection mMyOption; + } + + private static class MyGeneric { + } + + /** Option source with unparameterized type. */ + private static class NonCollectionGenericTypeOptionSource { + @Option(name = "my_option", shortName = 'o') + private MyGeneric mMyOption; + } + + /** Option source with options with same name. */ + private static class DuplicateOptionSource { + @Option(name = "string", shortName = 's') + private String mMyOption; + + @Option(name = "string", shortName = 's') + private String mMyDuplicateOption; + } + + /** Option source with an option with same name as AllTypesOptionSource. */ + @OptionClass(alias = "shared") + private static class SharedOptionSource { + @Option(name = "string", shortName = 's') + private String mMyOption; + + @Option(name = "enum") + private DefaultEnumClass mEnum = null; + + @Option(name = "string_collection") + private Collection mStringCollection = new ArrayList(); + + @Option(name = "enumMap") + private Map mEnumMap = + new HashMap(); + + @Option(name = "enumCollection") + private Collection mEnumCollection = + new ArrayList(); + } + + /** + * Option source with an option with same name as AllTypesOptionSource, but a different type. + */ + private static class SharedOptionWrongTypeSource { + @Option(name = "string", shortName = 's') + private int mMyOption; + } + + /** option source with all supported types. */ + @OptionClass(alias = "all") + private static class AllTypesOptionSource { + @Option(name = "string_collection") + private final Collection mStringCollection = new ArrayList(); + + @Option(name = "string_string_map") + private Map mStringMap = new HashMap(); + + @Option(name = "string") + private String mString = null; + + @Option(name = "boolean") + private boolean mBool = false; + + @Option(name = "booleanObj") + private Boolean mBooleanObj = false; + + @Option(name = "byte") + private byte mByte = 0; + + @Option(name = "byteObj") + private Byte mByteObj = 0; + + @Option(name = "short") + private short mShort = 0; + + @Option(name = "shortObj") + private Short mShortObj = null; + + @Option(name = "int") + private int mInt = 0; + + @Option(name = "intObj") + private Integer mIntObj = 0; + + @Option(name = "long") + private long mLong = 0; + + @Option(name = "longObj") + private Long mLongObj = null; + + @Option(name = "float") + private float mFloat = 0; + + @Option(name = "floatObj") + private Float mFloatObj = null; + + @Option(name = "double") + private double mDouble = 0; + + @Option(name = "doubleObj") + private Double mDoubleObj = null; + + @Option(name = "file") + private File mFile = null; + + @Option(name = "enum") + private DefaultEnumClass mEnum = null; + + @Option(name = "customEnum") + private CustomEnumClass mCustomEnum = null; + + @Option(name = "enumMap") + private Map mEnumMap = + new HashMap(); + + @Option(name = "enumCollection") + private Collection mEnumCollection = + new ArrayList(); + } + + private static class ParentOptionSource { + @Option(name = "string") + private String mString = null; + + protected String getParentString() { + return mString; + } + } + + private static class ChildOptionSource extends ParentOptionSource { + @Option(name = "child-string") + private String mChildString = null; + } + + /** + * Option source with invalid option name. + */ + private static class BadOptionNameSource { + @Option(name = "bad:string", shortName = 's') + private int mMyOption; + } + + private static enum DefaultEnumClass { + VAL1, VAL3, VAL2; + } + + private static enum CustomEnumClass { + VAL1(42); + + private int mVal; + + CustomEnumClass(int val) { + mVal = val; + } + + public int getVal() { + return mVal; + } + } + + private static class FinalOption { + @Option(name = "final-string", description="final field, not allowed") + private final String mFinal= "foo"; + } + + /** + * Test creating an {@link OptionSetter} for a source with invalid option type. + */ + public void testOptionSetter_noType() { + try { + new OptionSetter(new GenericTypeOptionSource()); + fail("ConfigurationException not thrown"); + } catch (ConfigurationException e) { + // expected + } + } + + /** + * Test creating an {@link OptionSetter} for a source with duplicate option names. + */ + public void testOptionSetter_duplicateOptions() { + try { + new OptionSetter(new DuplicateOptionSource()); + fail("ConfigurationException not thrown"); + } catch (ConfigurationException e) { + // expected + } + } + + /** + * Test option with same name can be used in multiple option sources. + */ + public void testOptionSetter_sharedOptions() throws ConfigurationException { + AllTypesOptionSource object1 = new AllTypesOptionSource(); + SharedOptionSource object2 = new SharedOptionSource(); + OptionSetter setter = new OptionSetter(object1, object2); + setter.setOptionValue("string", "test"); + assertEquals("test", object1.mString); + assertEquals("test", object2.mMyOption); + } + + /** + * Test {@link OptionSetter#setOptionValue(String, String)} for Enums used as the key and value + * of a {@link Map}. + */ + public void testOptionSetter_sharedEnumMap() throws ConfigurationException { + AllTypesOptionSource object1 = new AllTypesOptionSource(); + SharedOptionSource object2 = new SharedOptionSource(); + + final String key = "VAL1"; + final String value = "VAL1"; + final DefaultEnumClass expectedKey = DefaultEnumClass.VAL1; + final CustomEnumClass expectedValue = CustomEnumClass.VAL1; + + // Actually set the key/value pair + OptionSetter parser = new OptionSetter(object1, object2); + parser.setOptionMapValue("enumMap", key, value); + + // verify object1 + assertEquals(1, object1.mEnumMap.size()); + assertNotNull(object1.mEnumMap.get(expectedKey)); + assertEquals(expectedValue, object1.mEnumMap.get(expectedKey)); + + // verify object2 + assertEquals(1, object2.mEnumMap.size()); + assertNotNull(object2.mEnumMap.get(expectedKey)); + assertEquals(expectedValue, object2.mEnumMap.get(expectedKey)); + } + + + /** + * Test {@link OptionSetter#setOptionValue(String, String)} for Enums used as the key and value + * of a {@link Map}. + */ + public void testOptionSetter_sharedEnumCollection() throws ConfigurationException { + AllTypesOptionSource object1 = new AllTypesOptionSource(); + SharedOptionSource object2 = new SharedOptionSource(); + + final String value = "VAL1"; + final DefaultEnumClass expectedValue = DefaultEnumClass.VAL1; + + // Actually add the element + OptionSetter parser = new OptionSetter(object1, object2); + parser.setOptionValue("enumCollection", value); + + // verify object1 + assertEquals(1, object1.mEnumCollection.size()); + assertTrue(object1.mEnumCollection.contains(expectedValue)); + + // verify object2 + assertEquals(1, object2.mEnumCollection.size()); + assertTrue(object2.mEnumCollection.contains(expectedValue)); + } + + + /** + * Test that multiple options with same name must have the same type. + */ + public void testOptionSetter_sharedOptionsDiffType() { + try { + new OptionSetter(new AllTypesOptionSource(), new SharedOptionWrongTypeSource()); + fail("ConfigurationException not thrown"); + } catch (ConfigurationException e) { + // expected + } + } + + /** + * Test namespaced options using class names. + */ + public void testOptionSetter_namespacedClassName() throws ConfigurationException { + AllTypesOptionSource object1 = new AllTypesOptionSource(); + SharedOptionSource object2 = new SharedOptionSource(); + OptionSetter setter = new OptionSetter(object1, object2); + setter.setOptionValue(AllTypesOptionSource.class.getName() + ":string", "alltest"); + setter.setOptionValue(SharedOptionSource.class.getName() + ":string", "sharedtest"); + assertEquals("alltest", object1.mString); + assertEquals("sharedtest", object2.mMyOption); + } + + /** + * Test namespaced options using OptionClass aliases + */ + public void testOptionSetter_namespacedAlias() throws ConfigurationException { + AllTypesOptionSource object1 = new AllTypesOptionSource(); + SharedOptionSource object2 = new SharedOptionSource(); + OptionSetter setter = new OptionSetter(object1, object2); + setter.setOptionValue("all:string", "alltest"); + setter.setOptionValue("shared:string", "sharedtest"); + assertEquals("alltest", object1.mString); + assertEquals("sharedtest", object2.mMyOption); + } + + /** + * Test creating an {@link OptionSetter} for a Collection with no type. + */ + public void testOptionSetter_unparamType() { + try { + new OptionSetter(new CollectionTypeOptionSource()); + fail("ConfigurationException not thrown"); + } catch (ConfigurationException e) { + // expected + } + } + + /** + * Test creating an {@link OptionSetter} for a non collection option with generic type + */ + public void testOptionSetter_genericType() { + try { + new OptionSetter(new NonCollectionGenericTypeOptionSource()); + fail("ConfigurationException not thrown"); + } catch (ConfigurationException e) { + // expected + } + } + + /** + * Test creating an {@link OptionSetter} for class with inherited options + */ + public void testOptionSetter_inheritedOptions() throws ConfigurationException { + ChildOptionSource source = new ChildOptionSource(); + OptionSetter setter = new OptionSetter(source); + setter.setOptionValue("string", "parent"); + setter.setOptionValue("child-string", "child"); + assertEquals("parent", source.getParentString()); + assertEquals("child", source.mChildString); + } + + /** + * Test that options with {@link OptionSetter#NAMESPACE_SEPARATOR} are rejected + */ + public void testOptionSetter_badOptionName() { + try { + new OptionSetter(new BadOptionNameSource()); + fail("ConfigurationException not thrown"); + } catch (ConfigurationException e) { + // expected + } + } + + /** + * Test {@link OptionSetter#isBooleanOption(String)} when passed an unknown option name + */ + public void testIsBooleanOption_unknown() throws ConfigurationException { + OptionSetter parser = new OptionSetter(new AllTypesOptionSource()); + try { + parser.isBooleanOption("unknown"); + fail("ConfigurationException not thrown"); + } catch (ConfigurationException e) { + // expected + } + } + + /** + * Test {@link OptionSetter#isBooleanOption(String)} when passed boolean option name + */ + public void testIsBooleanOption_true() throws ConfigurationException { + OptionSetter parser = new OptionSetter(new AllTypesOptionSource()); + assertTrue(parser.isBooleanOption("boolean")); + } + + /** + * Test {@link OptionSetter#isBooleanOption(String)} when passed boolean option name for a + * Boolean object + */ + public void testIsBooleanOption_objTrue() throws ConfigurationException { + OptionSetter parser = new OptionSetter(new AllTypesOptionSource()); + assertTrue(parser.isBooleanOption("booleanObj")); + } + + /** + * Test {@link OptionSetter#isBooleanOption(String)} when passed non-boolean option + */ + public void testIsBooleanOption_false() throws ConfigurationException { + OptionSetter parser = new OptionSetter(new AllTypesOptionSource()); + assertFalse(parser.isBooleanOption("string")); + } + + /** + * Test {@link OptionSetter#setOptionValue(String, String)} when passed an unknown option name + */ + public void testSetOptionValue_unknown() throws ConfigurationException { + OptionSetter parser = new OptionSetter(new AllTypesOptionSource()); + try { + parser.setOptionValue("unknown", "foo"); + fail("ConfigurationException not thrown"); + } catch (ConfigurationException e) { + // expected + } + } + + /** + * Test setting a value for a option with an unknown generic type. + */ + public void testSetOptionValue_unknownType() throws ConfigurationException { + OptionSetter parser = new OptionSetter(new AllTypesOptionSource()); + try { + parser.setOptionValue("my_option", "foo"); + fail("ConfigurationException not thrown"); + } catch (ConfigurationException e) { + // expected + } + } + + /** + * Test setting a value for a non-parameterized Collection + */ + public void testSetOptionValue_unparameterizedType() throws ConfigurationException { + OptionSetter parser = new OptionSetter(new AllTypesOptionSource()); + try { + parser.setOptionValue("my_option", "foo"); + fail("ConfigurationException not thrown"); + } catch (ConfigurationException e) { + // expected + } + } + + /** + * Test {@link OptionSetter#setOptionValue(String, String)} for a String. + */ + public void testSetOptionValue_string() throws ConfigurationException { + AllTypesOptionSource optionSource = new AllTypesOptionSource(); + final String expectedValue = "stringvalue"; + assertSetOptionValue(optionSource, "string", expectedValue); + assertEquals(expectedValue, optionSource.mString); + } + + /** + * Test {@link OptionSetter#setOptionValue(String, String)} for a Collection. + */ + public void testSetOptionValue_collection() throws ConfigurationException { + AllTypesOptionSource optionSource = new AllTypesOptionSource(); + final String expectedValue = "stringvalue"; + assertSetOptionValue(optionSource, "string_collection", expectedValue); + assertEquals(1, optionSource.mStringCollection.size()); + assertTrue(optionSource.mStringCollection.contains(expectedValue)); + } + + /** + * Test {@link OptionSetter#setOptionValue(String, String)} for a Map. + */ + public void testSetOptionValue_map() throws ConfigurationException { + AllTypesOptionSource optionSource = new AllTypesOptionSource(); + final String expectedKey = "stringkey"; + final String expectedValue = "stringvalue"; + + // Actually set the key/value pair + OptionSetter parser = new OptionSetter(optionSource); + parser.setOptionMapValue("string_string_map", expectedKey, expectedValue); + + assertEquals(1, optionSource.mStringMap.size()); + assertNotNull(optionSource.mStringMap.get(expectedKey)); + assertEquals(expectedValue, optionSource.mStringMap.get(expectedKey)); + } + + /** + * Test {@link OptionSetter#setOptionValue(String, String)} for a boolean. + */ + public void testSetOptionValue_boolean() throws ConfigurationException { + AllTypesOptionSource optionSource = new AllTypesOptionSource(); + assertSetOptionValue(optionSource, "boolean", "true"); + assertEquals(true, optionSource.mBool); + } + + /** + * Test {@link OptionSetter#setOptionValue(String, String)} for a boolean for a non-boolean + * value. + */ + public void testSetOptionValue_booleanInvalid() { + AllTypesOptionSource optionSource = new AllTypesOptionSource(); + assertSetOptionValueInvalid(optionSource, "boolean", "blah"); + } + + /** + * Test {@link OptionSetter#setOptionValue(String, String)} for a Boolean. + */ + public void testSetOptionValue_booleanObj() throws ConfigurationException { + AllTypesOptionSource optionSource = new AllTypesOptionSource(); + assertSetOptionValue(optionSource, "booleanObj", "true"); + assertTrue(optionSource.mBooleanObj); + } + + /** + * Test {@link OptionSetter#setOptionValue(String, String)} for a byte. + */ + public void testSetOptionValue_byte() throws ConfigurationException { + AllTypesOptionSource optionSource = new AllTypesOptionSource(); + assertSetOptionValue(optionSource, "byte", "2"); + assertEquals(2, optionSource.mByte); + } + + /** + * Test {@link OptionSetter#setOptionValue(String, String)} for a byte for an invalid value. + */ + public void testSetOptionValue_byteInvalid() { + AllTypesOptionSource optionSource = new AllTypesOptionSource(); + assertSetOptionValueInvalid(optionSource, "byte", "blah"); + } + + /** + * Test {@link OptionSetter#setOptionValue(String, String)} for a Byte. + */ + public void testSetOptionValue_byteObj() throws ConfigurationException { + AllTypesOptionSource optionSource = new AllTypesOptionSource(); + assertSetOptionValue(optionSource, "byteObj", "2"); + assertTrue(2 == optionSource.mByteObj); + } + + /** + * Test {@link OptionSetter#setOptionValue(String, String)} for a short. + */ + public void testSetOptionValue_short() throws ConfigurationException { + AllTypesOptionSource optionSource = new AllTypesOptionSource(); + assertSetOptionValue(optionSource, "short", "2"); + assertTrue(2 == optionSource.mShort); + } + + /** + * Test {@link OptionSetter#setOptionValue(String, String)} for a Short. + */ + public void testSetOptionValue_shortObj() throws ConfigurationException { + AllTypesOptionSource optionSource = new AllTypesOptionSource(); + assertSetOptionValue(optionSource, "shortObj", "2"); + assertTrue(2 == optionSource.mShortObj); + } + + /** + * Test {@link OptionSetter#setOptionValue(String, String)} for a short for an invalid value. + */ + public void testSetOptionValue_shortInvalid() { + AllTypesOptionSource optionSource = new AllTypesOptionSource(); + assertSetOptionValueInvalid(optionSource, "short", "blah"); + } + + /** + * Test {@link OptionSetter#setOptionValue(String, String)} for a int. + */ + public void testSetOptionValue_int() throws ConfigurationException { + AllTypesOptionSource optionSource = new AllTypesOptionSource(); + assertSetOptionValue(optionSource, "int", "2"); + assertTrue(2 == optionSource.mInt); + } + + /** + * Test {@link OptionSetter#setOptionValue(String, String)} for a Integer. + */ + public void testSetOptionValue_intObj() throws ConfigurationException { + AllTypesOptionSource optionSource = new AllTypesOptionSource(); + assertSetOptionValue(optionSource, "intObj", "2"); + assertTrue(2 == optionSource.mIntObj); + } + + /** + * Test {@link OptionSetter#setOptionValue(String, String)} for a int for an invalid value. + */ + public void testSetOptionValue_intInvalid() { + AllTypesOptionSource optionSource = new AllTypesOptionSource(); + assertSetOptionValueInvalid(optionSource, "int", "blah"); + } + + /** + * Test {@link OptionSetter#setOptionValue(String, String)} for a long. + */ + public void testSetOptionValue_long() throws ConfigurationException { + AllTypesOptionSource optionSource = new AllTypesOptionSource(); + assertSetOptionValue(optionSource, "long", "2"); + assertTrue(2 == optionSource.mLong); + } + + /** + * Test {@link OptionSetter#setOptionValue(String, String)} for a Long. + */ + public void testSetOptionValue_longObj() throws ConfigurationException { + AllTypesOptionSource optionSource = new AllTypesOptionSource(); + assertSetOptionValue(optionSource, "longObj", "2"); + assertTrue(2 == optionSource.mLongObj); + } + + /** + * Test {@link OptionSetter#setOptionValue(String, String)} for a long for an invalid value. + */ + public void testSetOptionValue_longInvalid() { + AllTypesOptionSource optionSource = new AllTypesOptionSource(); + assertSetOptionValueInvalid(optionSource, "long", "blah"); + } + + /** + * Test {@link OptionSetter#setOptionValue(String, String)} for a float. + */ + public void testSetOptionValue_float() throws ConfigurationException { + AllTypesOptionSource optionSource = new AllTypesOptionSource(); + assertSetOptionValue(optionSource, "float", "2.1"); + assertEquals(2.1, optionSource.mFloat, 0.01); + } + + /** + * Test {@link OptionSetter#setOptionValue(String, String)} for a Float. + */ + public void testSetOptionValue_floatObj() throws ConfigurationException { + AllTypesOptionSource optionSource = new AllTypesOptionSource(); + assertSetOptionValue(optionSource, "floatObj", "2.1"); + assertEquals(2.1, optionSource.mFloatObj, 0.01); + } + + /** + * Test {@link OptionSetter#setOptionValue(String, String)} for a float for an invalid value. + */ + public void testSetOptionValue_floatInvalid() { + AllTypesOptionSource optionSource = new AllTypesOptionSource(); + assertSetOptionValueInvalid(optionSource, "float", "blah"); + } + + /** + * Test {@link OptionSetter#setOptionValue(String, String)} for a float. + */ + public void testSetOptionValue_double() throws ConfigurationException { + AllTypesOptionSource optionSource = new AllTypesOptionSource(); + assertSetOptionValue(optionSource, "double", "2.1"); + assertEquals(2.1, optionSource.mDouble, 0.01); + } + + /** + * Test {@link OptionSetter#setOptionValue(String, String)} for a Float. + */ + public void testSetOptionValue_doubleObj() throws ConfigurationException { + AllTypesOptionSource optionSource = new AllTypesOptionSource(); + assertSetOptionValue(optionSource, "doubleObj", "2.1"); + assertEquals(2.1, optionSource.mDoubleObj, 0.01); + } + + /** + * Test {@link OptionSetter#setOptionValue(String, String)} for a double for an invalid value. + */ + public void testSetOptionValue_doubleInvalid() { + AllTypesOptionSource optionSource = new AllTypesOptionSource(); + assertSetOptionValueInvalid(optionSource, "double", "blah"); + } + + /** + * Test {@link OptionSetter#setOptionValue(String, String)} for a File. + */ + public void testSetOptionValue_file() throws ConfigurationException, IOException { + AllTypesOptionSource optionSource = new AllTypesOptionSource(); + File tmpFile = File.createTempFile("testSetOptionValue_file", "txt"); + try { + assertSetOptionValue(optionSource, "file", tmpFile.getAbsolutePath()); + assertEquals(tmpFile.getAbsolutePath(), optionSource.mFile.getAbsolutePath()); + } finally { + tmpFile.delete(); + } + } + + /** + * Test {@link OptionSetter#setOptionValue(String, String)} for an Enum. + */ + public void testSetOptionValue_enum() throws ConfigurationException { + AllTypesOptionSource optionSource = new AllTypesOptionSource(); + assertSetOptionValue(optionSource, "enum", "VAL1"); + assertEquals(DefaultEnumClass.VAL1, optionSource.mEnum); + } + + /** + * Test {@link OptionSetter#setOptionValue(String, String)} for an Enum. Specifically make sure + * that we fall back properly, so that a mixed-case value will be silently mapped to an + * uppercase version, since Enum constants tend to be uppercase by convention. + */ + public void testSetOptionValue_enumMixedCase() throws ConfigurationException { + AllTypesOptionSource optionSource = new AllTypesOptionSource(); + assertSetOptionValue(optionSource, "enum", "Val1"); + assertEquals(DefaultEnumClass.VAL1, optionSource.mEnum); + } + + /** + * Test {@link OptionSetter#setOptionValue(String, String)} for an Enum with custom values. + */ + public void testSetOptionValue_customEnum() throws ConfigurationException { + AllTypesOptionSource optionSource = new AllTypesOptionSource(); + assertSetOptionValue(optionSource, "customEnum", "VAL1"); + assertEquals(CustomEnumClass.VAL1, optionSource.mCustomEnum); + assertEquals(42, optionSource.mCustomEnum.getVal()); + } + + /** + * Test {@link OptionSetter#setOptionValue(String, String)} for Enums used as the key and value + * of a {@link Map}. + */ + public void testSetOptionValue_enumMap() throws ConfigurationException { + AllTypesOptionSource optionSource = new AllTypesOptionSource(); + + final String key = "VAL1"; + final String value = "VAL1"; + final DefaultEnumClass expectedKey = DefaultEnumClass.VAL1; + final CustomEnumClass expectedValue = CustomEnumClass.VAL1; + + // Actually set the key/value pair + OptionSetter parser = new OptionSetter(optionSource); + parser.setOptionMapValue("enumMap", key, value); + + assertEquals(1, optionSource.mEnumMap.size()); + assertNotNull(optionSource.mEnumMap.get(expectedKey)); + assertEquals(expectedValue, optionSource.mEnumMap.get(expectedKey)); + } + + + /** + * Test {@link OptionSetter#setOptionValue(String, String)} for Enums used as the key and value + * of a {@link Map}. + */ + public void testSetOptionValue_enumCollection() throws ConfigurationException { + AllTypesOptionSource optionSource = new AllTypesOptionSource(); + + final String value = "VAL1"; + final DefaultEnumClass expectedValue = DefaultEnumClass.VAL1; + + assertSetOptionValue(optionSource, "enumCollection", value); + + assertEquals(1, optionSource.mEnumCollection.size()); + assertTrue(optionSource.mEnumCollection.contains(expectedValue)); + } + + + /** + * Test {@link OptionSetter#setOptionValue(String, String)} for an Enum. + */ + public void testSetOptionValue_enumBadValue() { + AllTypesOptionSource optionSource = new AllTypesOptionSource(); + try { + assertSetOptionValue(optionSource, "enum", "noexist"); + fail("ConfigurationException not thrown"); + } catch (ConfigurationException e) { + // expected + } + } + + /** + * Make sure that Enum documentation shows the defaults properly + */ + public void testEnumDocs() throws Exception { + // We assume here that the fields are returned in declaration order, as documented in the + // {@link Enum} javadoc. + String expectedValues = " Valid values: [VAL1, VAL3, VAL2]"; + Field field = AllTypesOptionSource.class.getDeclaredField("mEnum"); + String actualValues = OptionSetter.getEnumFieldValuesAsString(field); + assertEquals(expectedValues, actualValues); + } + + /** + * Test {@link OptionSetter} for a final field + */ + public void testOptionSetter_finalField() { + FinalOption optionSource = new FinalOption(); + try { + new OptionSetter(optionSource); + fail("ConfigurationException not thrown"); + } catch (ConfigurationException e) { + // expected + } + } + + /** + * Perform {@link OptionSetter#setOptionValue(String, String)} for a given option. + */ + private void assertSetOptionValue(AllTypesOptionSource optionSource, final String optionName, + final String expectedValue) throws ConfigurationException { + OptionSetter parser = new OptionSetter(optionSource); + parser.setOptionValue(optionName, expectedValue); + } + + /** + * Perform {@link OptionSetter#setOptionValue(String, String)} for a given option, with an + * invalid value for the option type. + */ + private void assertSetOptionValueInvalid(AllTypesOptionSource optionSource, + final String optionName, final String expectedValue) { + try { + assertSetOptionValue(optionSource, optionName, expectedValue); + fail("ConfigurationException not thrown"); + } catch (ConfigurationException e) { + // expected + } + } +} diff --git a/javatests/src/com/android/loganalysis/util/config/OptionUpdateRuleTest.java b/javatests/src/com/android/loganalysis/util/config/OptionUpdateRuleTest.java new file mode 100644 index 0000000..0e899ec --- /dev/null +++ b/javatests/src/com/android/loganalysis/util/config/OptionUpdateRuleTest.java @@ -0,0 +1,88 @@ +/* + * Copyright (C) 2010 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.util.config; + +import junit.framework.TestCase; + +/** + * Unit tests for {@link OptionUpdateRule} + */ +public class OptionUpdateRuleTest extends TestCase { + private static final String OPTION_NAME = "option-name"; + private static final Object CURRENT = "5 current value"; + private static final Object UPDATE = "5 update value"; + private static final Object SMALL_UPDATE = "0 update value"; + private static final Object BIG_UPDATE = "9 update value"; + + public void testFirst_simple() throws Exception { + assertEquals(UPDATE, OptionUpdateRule.FIRST.update(OPTION_NAME, null, UPDATE)); + assertEquals(CURRENT, OptionUpdateRule.FIRST.update(OPTION_NAME, CURRENT, UPDATE)); + } + + public void testLast_simple() throws Exception { + assertEquals(UPDATE, OptionUpdateRule.LAST.update(OPTION_NAME, null, UPDATE)); + assertEquals(UPDATE, OptionUpdateRule.LAST.update(OPTION_NAME, CURRENT, UPDATE)); + } + + public void testGreatest_simple() throws Exception { + assertEquals( + SMALL_UPDATE, OptionUpdateRule.GREATEST.update(OPTION_NAME, null, SMALL_UPDATE)); + assertEquals(CURRENT, OptionUpdateRule.GREATEST.update(OPTION_NAME, CURRENT, SMALL_UPDATE)); + assertEquals( + BIG_UPDATE, OptionUpdateRule.GREATEST.update(OPTION_NAME, CURRENT, BIG_UPDATE)); + } + + public void testLeast_simple() throws Exception { + assertEquals(BIG_UPDATE, OptionUpdateRule.LEAST.update(OPTION_NAME, null, BIG_UPDATE)); + assertEquals( + SMALL_UPDATE, OptionUpdateRule.LEAST.update(OPTION_NAME, CURRENT, SMALL_UPDATE)); + assertEquals(CURRENT, OptionUpdateRule.LEAST.update(OPTION_NAME, CURRENT, BIG_UPDATE)); + } + + public void testImmutable_simple() throws Exception { + assertEquals(UPDATE, OptionUpdateRule.IMMUTABLE.update(OPTION_NAME, null, UPDATE)); + try { + OptionUpdateRule.IMMUTABLE.update(OPTION_NAME, CURRENT, UPDATE); + fail("ConfigurationException not thrown when updating an IMMUTABLE option"); + } catch (ConfigurationException e) { + // expected + } + } + + public void testInvalidComparison() throws Exception { + try { + // Strings aren't comparable with integers + OptionUpdateRule.GREATEST.update(OPTION_NAME, 13, UPDATE); + fail("ConfigurationException not thrown for invalid comparison."); + } catch (ConfigurationException e) { + // Expected. Moreover, the exception should be actionable, so make sure we mention the + // specific mismatching types. + final String msg = e.getMessage(); + assertTrue(msg.contains("Integer")); + assertTrue(msg.contains("String")); + } + } + + public void testNotComparable() throws Exception { + try { + OptionUpdateRule.LEAST.update(OPTION_NAME, new Exception("hi"), UPDATE); + } catch (ConfigurationException e) { + // expected + } + } +} + diff --git a/tests/.classpath b/tests/.classpath deleted file mode 100644 index 55aa5dd..0000000 --- a/tests/.classpath +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - diff --git a/tests/.project b/tests/.project deleted file mode 100644 index f4a1c0b..0000000 --- a/tests/.project +++ /dev/null @@ -1,17 +0,0 @@ - - - loganalysis-tests - - - - - - org.eclipse.jdt.core.javabuilder - - - - - - org.eclipse.jdt.core.javanature - - diff --git a/tests/Android.bp b/tests/Android.bp deleted file mode 100644 index fae1c13..0000000 --- a/tests/Android.bp +++ /dev/null @@ -1,32 +0,0 @@ -// 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 { - default_applicable_licenses: ["Android-Apache-2.0"], -} - -java_test_host { - name: "loganalysis-tests", - defaults: ["tradefed_defaults"], - - // Only compile source java files in this lib. - srcs: ["src/**/*.java"], - - static_libs: [ - "loganalysis", - "json-prebuilt", - "junit", - "guava", - ], -} diff --git a/tests/Android.mk b/tests/Android.mk deleted file mode 100644 index e3958cd..0000000 --- a/tests/Android.mk +++ /dev/null @@ -1,25 +0,0 @@ -# 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. - -LOCAL_PATH := $(call my-dir) - -# makefile rules to copy jars to HOST_OUT/tradefed -# so tradefed.sh can automatically add to classpath - -DEST_JAR := $(HOST_OUT)/tradefed/loganalysis-tests.jar -$(DEST_JAR): $(call intermediates-dir-for,JAVA_LIBRARIES,loganalysis-tests,HOST)/javalib.jar - $(copy-file-to-new-target) - -# this dependency ensure the above rule will be executed if module is built -$(HOST_OUT_JAVA_LIBRARIES)/loganalysis-tests.jar : $(DEST_JAR) diff --git a/tests/src/com/android/loganalysis/item/BatteryDischargeItemTest.java b/tests/src/com/android/loganalysis/item/BatteryDischargeItemTest.java deleted file mode 100644 index 5e27eb2..0000000 --- a/tests/src/com/android/loganalysis/item/BatteryDischargeItemTest.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (C) 2015 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.item; - -import com.android.loganalysis.item.BatteryDischargeItem.BatteryDischargeInfoItem; - -import junit.framework.TestCase; - -import org.json.JSONArray; -import org.json.JSONException; -import org.json.JSONObject; - -import java.util.Calendar; - -/** - * Unit test for {@link BatteryDischargeItem}. - */ -public class BatteryDischargeItemTest extends TestCase { - - /** - * Test that {@link BatteryDischargeItem#toJson()} returns correctly. - */ - public void testToJson() throws JSONException { - BatteryDischargeItem item = new BatteryDischargeItem(); - item.addBatteryDischargeInfo(Calendar.getInstance(),25, 95); - - // Convert to JSON string and back again - JSONObject output = new JSONObject(item.toJson().toString()); - - assertTrue(output.has(BatteryDischargeItem.BATTERY_DISCHARGE)); - assertTrue(output.get(BatteryDischargeItem.BATTERY_DISCHARGE) instanceof JSONArray); - - JSONArray dischargeInfo = output.getJSONArray(BatteryDischargeItem.BATTERY_DISCHARGE); - - assertEquals(1, dischargeInfo.length()); - assertTrue(dischargeInfo.getJSONObject(0).has(BatteryDischargeInfoItem.BATTERY_LEVEL)); - assertTrue(dischargeInfo.getJSONObject(0).has( - BatteryDischargeInfoItem.DISCHARGE_ELAPSED_TIME)); - assertTrue(dischargeInfo.getJSONObject(0).has( - BatteryDischargeInfoItem.CLOCK_TIME_OF_DISCHARGE)); - - } -} diff --git a/tests/src/com/android/loganalysis/item/BatteryUsageItemTest.java b/tests/src/com/android/loganalysis/item/BatteryUsageItemTest.java deleted file mode 100644 index b44a432..0000000 --- a/tests/src/com/android/loganalysis/item/BatteryUsageItemTest.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright (C) 2015 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.item; - -import com.android.loganalysis.item.BatteryUsageItem.BatteryUsageInfoItem; - -import junit.framework.TestCase; - -import org.json.JSONArray; -import org.json.JSONException; -import org.json.JSONObject; - -/** - * Unit test for {@link BatteryUsageItem}. - */ -public class BatteryUsageItemTest extends TestCase { - - /** - * Test that {@link BatteryUsageItem#toJson()} returns correctly. - */ - public void testToJson() throws JSONException { - BatteryUsageItem item = new BatteryUsageItem(); - item.addBatteryUsage("Cell standby", 2925); - item.addBatteryUsage("Uid u0a71", 68.1); - // Convert to JSON string and back again - JSONObject output = new JSONObject(item.toJson().toString()); - - assertTrue(output.has(BatteryUsageItem.BATTERY_CAPACITY)); - assertTrue(output.get(BatteryUsageItem.BATTERY_USAGE) instanceof JSONArray); - - JSONArray usage = output.getJSONArray(BatteryUsageItem.BATTERY_USAGE); - - assertEquals(2, usage.length()); - assertTrue(usage.getJSONObject(0).has(BatteryUsageInfoItem.NAME)); - assertTrue(usage.getJSONObject(0).has(BatteryUsageInfoItem.USAGE)); - - assertTrue(usage.getJSONObject(1).has(BatteryUsageInfoItem.NAME)); - assertTrue(usage.getJSONObject(1).has(BatteryUsageInfoItem.USAGE)); - } -} diff --git a/tests/src/com/android/loganalysis/item/DumpsysPackageStatsItemTest.java b/tests/src/com/android/loganalysis/item/DumpsysPackageStatsItemTest.java deleted file mode 100644 index dd60500..0000000 --- a/tests/src/com/android/loganalysis/item/DumpsysPackageStatsItemTest.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (C) 2017 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.item; - -import junit.framework.TestCase; - -import org.json.JSONException; -import org.json.JSONObject; - -/** Unit test for {@link DumpsysPackageStatsItem}. */ -public class DumpsysPackageStatsItemTest extends TestCase { - - /** Test that {@link DumpsysPackageStatsItem#toJson()} returns correctly. */ - public void testToJson() throws JSONException { - DumpsysPackageStatsItem item = new DumpsysPackageStatsItem(); - - item.put("com.google.android.calculator", new AppVersionItem(73000302, "7.3 (3821978)")); - item.put( - "com.google.android.googlequicksearchbox", - new AppVersionItem(300734793, "6.16.35.26.arm64")); - - // Convert to JSON string and back again - JSONObject output = new JSONObject(item.toJson().toString()); - - assertTrue(output.has(DumpsysPackageStatsItem.APP_VERSIONS)); - - JSONObject appVersionsJson = output.getJSONObject(DumpsysPackageStatsItem.APP_VERSIONS); - - assertEquals(2, appVersionsJson.length()); - final JSONObject calcAppVersionJson = - appVersionsJson.getJSONObject("com.google.android.calculator"); - assertEquals(73000302, calcAppVersionJson.getInt(AppVersionItem.VERSION_CODE)); - assertEquals("7.3 (3821978)", calcAppVersionJson.getString(AppVersionItem.VERSION_NAME)); - final JSONObject gsaAppVersionJson = - appVersionsJson.getJSONObject("com.google.android.googlequicksearchbox"); - assertEquals(300734793, gsaAppVersionJson.getInt(AppVersionItem.VERSION_CODE)); - assertEquals("6.16.35.26.arm64", gsaAppVersionJson.getString(AppVersionItem.VERSION_NAME)); - } -} diff --git a/tests/src/com/android/loganalysis/item/DvmLockSampleItemTest.java b/tests/src/com/android/loganalysis/item/DvmLockSampleItemTest.java deleted file mode 100644 index 5d6054e..0000000 --- a/tests/src/com/android/loganalysis/item/DvmLockSampleItemTest.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * 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.item; - -import junit.framework.TestCase; - -import org.json.JSONException; -import org.json.JSONObject; - -/** - * Unit test for {@link DvmLockSampleItem}. - */ -public class DvmLockSampleItemTest extends TestCase { - /** - * Test that {@link DvmLockSampleItem#toJson()} returns correctly. - */ - public void testToJson() throws JSONException { - DvmLockSampleItem item = new DvmLockSampleItem(); - - item.setAttribute(DvmLockSampleItem.PROCESS_NAME, "android.support.test.aupt"); - item.setAttribute(DvmLockSampleItem.SENSITIVITY_FLAG, false); - item.setAttribute(DvmLockSampleItem.WAITING_THREAD_NAME, "Instr: android.support.test.aupt"); - item.setAttribute(DvmLockSampleItem.WAIT_TIME, 75); - item.setAttribute(DvmLockSampleItem.WAITING_SOURCE_FILE, "AccessibilityCache.java"); - item.setAttribute(DvmLockSampleItem.WAITING_SOURCE_LINE, 256); - item.setAttribute(DvmLockSampleItem.OWNER_FILE_NAME, "-"); - item.setAttribute(DvmLockSampleItem.OWNER_ACQUIRE_SOURCE_LINE, 96); - item.setAttribute(DvmLockSampleItem.SAMPLE_PERCENTAGE, 15); - - // Convert to JSON string and back again - JSONObject output = new JSONObject(item.toJson().toString()); - - // Assert that each field is the expected value - assertEquals("android.support.test.aupt", output.get(DvmLockSampleItem.PROCESS_NAME)); - assertEquals(false, output.get(DvmLockSampleItem.SENSITIVITY_FLAG)); - assertEquals("Instr: android.support.test.aupt", output.get(DvmLockSampleItem.WAITING_THREAD_NAME)); - assertEquals(75, output.get(DvmLockSampleItem.WAIT_TIME)); - assertEquals("AccessibilityCache.java", output.get(DvmLockSampleItem.WAITING_SOURCE_FILE)); - assertEquals(256, output.get(DvmLockSampleItem.WAITING_SOURCE_LINE)); - assertEquals("-", output.get(DvmLockSampleItem.OWNER_FILE_NAME)); - assertEquals(96, output.get(DvmLockSampleItem.OWNER_ACQUIRE_SOURCE_LINE)); - assertEquals(15, output.get(DvmLockSampleItem.SAMPLE_PERCENTAGE)); - } -} diff --git a/tests/src/com/android/loganalysis/item/GenericItemTest.java b/tests/src/com/android/loganalysis/item/GenericItemTest.java deleted file mode 100644 index e9ea31f..0000000 --- a/tests/src/com/android/loganalysis/item/GenericItemTest.java +++ /dev/null @@ -1,266 +0,0 @@ -/* - * Copyright (C) 2011 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.item; - -import junit.framework.TestCase; - -import org.json.JSONException; -import org.json.JSONObject; - -import java.util.Arrays; -import java.util.Date; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; - -/** - * Unit test for {@link GenericItem}. - */ -public class GenericItemTest extends TestCase { - private static final Set ATTRIBUTES = new HashSet(Arrays.asList( - "integer", "string")); - - private String mStringAttribute = "String"; - private Integer mIntegerAttribute = 1; - - /** Empty item with no attributes set */ - private GenericItem mEmptyItem1; - /** Empty item with no attributes set */ - private GenericItem mEmptyItem2; - /** Item with only the string attribute set */ - private GenericItem mStringItem; - /** Item with only the integer attribute set */ - private GenericItem mIntegerItem; - /** Item with both attributes set, product of mStringItem and mIntegerItem */ - private GenericItem mFullItem1; - /** Item with both attributes set, product of mStringItem and mIntegerItem */ - private GenericItem mFullItem2; - /** Item that is inconsistent with the others */ - private GenericItem mInconsistentItem; - - @Override - public void setUp() { - mEmptyItem1 = new GenericItem(ATTRIBUTES); - mEmptyItem2 = new GenericItem(ATTRIBUTES); - mStringItem = new GenericItem(ATTRIBUTES); - mStringItem.setAttribute("string", mStringAttribute); - mIntegerItem = new GenericItem(ATTRIBUTES); - mIntegerItem.setAttribute("integer", mIntegerAttribute); - mFullItem1 = new GenericItem(ATTRIBUTES); - mFullItem1.setAttribute("string", mStringAttribute); - mFullItem1.setAttribute("integer", mIntegerAttribute); - mFullItem2 = new GenericItem(ATTRIBUTES); - mFullItem2.setAttribute("string", mStringAttribute); - mFullItem2.setAttribute("integer", mIntegerAttribute); - mInconsistentItem = new GenericItem(ATTRIBUTES); - mInconsistentItem.setAttribute("string", "gnirts"); - mInconsistentItem.setAttribute("integer", 2); - } - - /** - * Test for {@link GenericItem#mergeAttributes(IItem, Set)}. - */ - public void testMergeAttributes() throws ConflictingItemException { - Map attributes; - - attributes = mEmptyItem1.mergeAttributes(mEmptyItem1, ATTRIBUTES); - assertNull(attributes.get("string")); - assertNull(attributes.get("integer")); - - attributes = mEmptyItem1.mergeAttributes(mEmptyItem2, ATTRIBUTES); - assertNull(attributes.get("string")); - assertNull(attributes.get("integer")); - - attributes = mEmptyItem2.mergeAttributes(mEmptyItem1, ATTRIBUTES); - assertNull(attributes.get("string")); - assertNull(attributes.get("integer")); - - attributes = mEmptyItem1.mergeAttributes(mStringItem, ATTRIBUTES); - assertEquals(mStringAttribute, attributes.get("string")); - assertNull(attributes.get("integer")); - - attributes = mStringItem.mergeAttributes(mEmptyItem1, ATTRIBUTES); - assertEquals(mStringAttribute, attributes.get("string")); - assertNull(attributes.get("integer")); - - attributes = mIntegerItem.mergeAttributes(mStringItem, ATTRIBUTES); - assertEquals(mStringAttribute, attributes.get("string")); - assertEquals(mIntegerAttribute, attributes.get("integer")); - - attributes = mEmptyItem1.mergeAttributes(mFullItem1, ATTRIBUTES); - assertEquals(mStringAttribute, attributes.get("string")); - assertEquals(mIntegerAttribute, attributes.get("integer")); - - attributes = mFullItem1.mergeAttributes(mEmptyItem1, ATTRIBUTES); - assertEquals(mStringAttribute, attributes.get("string")); - assertEquals(mIntegerAttribute, attributes.get("integer")); - - attributes = mFullItem1.mergeAttributes(mFullItem2, ATTRIBUTES); - assertEquals(mStringAttribute, attributes.get("string")); - assertEquals(mIntegerAttribute, attributes.get("integer")); - - try { - mFullItem1.mergeAttributes(mInconsistentItem, ATTRIBUTES); - fail("Expecting a ConflictingItemException"); - } catch (ConflictingItemException e) { - // Expected - } - } - - /** - * Test for {@link GenericItem#isConsistent(IItem)}. - */ - public void testIsConsistent() { - assertTrue(mEmptyItem1.isConsistent(mEmptyItem1)); - assertFalse(mEmptyItem1.isConsistent(null)); - assertTrue(mEmptyItem1.isConsistent(mEmptyItem2)); - assertTrue(mEmptyItem2.isConsistent(mEmptyItem1)); - assertTrue(mEmptyItem1.isConsistent(mStringItem)); - assertTrue(mStringItem.isConsistent(mEmptyItem1)); - assertTrue(mIntegerItem.isConsistent(mStringItem)); - assertTrue(mEmptyItem1.isConsistent(mFullItem1)); - assertTrue(mFullItem1.isConsistent(mEmptyItem1)); - assertTrue(mFullItem1.isConsistent(mFullItem2)); - assertFalse(mFullItem1.isConsistent(mInconsistentItem)); - } - - /** Test {@link GenericItem#equals(Object)}. */ - @SuppressWarnings("SelfEquals") - public void testEquals() { - assertTrue(mEmptyItem1.equals(mEmptyItem1)); - assertFalse(mEmptyItem1.equals(null)); - assertTrue(mEmptyItem1.equals(mEmptyItem2)); - assertTrue(mEmptyItem2.equals(mEmptyItem1)); - assertFalse(mEmptyItem1.equals(mStringItem)); - assertFalse(mStringItem.equals(mEmptyItem1)); - assertFalse(mIntegerItem.equals(mStringItem)); - assertFalse(mEmptyItem1.equals(mFullItem1)); - assertFalse(mFullItem1.equals(mEmptyItem1)); - assertTrue(mFullItem1.equals(mFullItem2)); - assertFalse(mFullItem1.equals(mInconsistentItem)); - } - - /** - * Test for {@link GenericItem#setAttribute(String, Object)} and - * {@link GenericItem#getAttribute(String)}. - */ - public void testAttributes() { - GenericItem item = new GenericItem(ATTRIBUTES); - - assertNull(item.getAttribute("string")); - assertNull(item.getAttribute("integer")); - - item.setAttribute("string", mStringAttribute); - item.setAttribute("integer", mIntegerAttribute); - - assertEquals(mStringAttribute, item.getAttribute("string")); - assertEquals(mIntegerAttribute, item.getAttribute("integer")); - - item.setAttribute("string", null); - item.setAttribute("integer", null); - - assertNull(item.getAttribute("string")); - assertNull(item.getAttribute("integer")); - - try { - item.setAttribute("object", new Object()); - fail("Failed to throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected because "object" is not "string" or "integer". - } - } - - /** - * Test for {@link GenericItem#areEqual(Object, Object)} - */ - public void testAreEqual() { - assertTrue(GenericItem.areEqual(null, null)); - assertTrue(GenericItem.areEqual("test", "test")); - assertFalse(GenericItem.areEqual(null, "test")); - assertFalse(GenericItem.areEqual("test", null)); - assertFalse(GenericItem.areEqual("test", "")); - } - - /** - * Test for {@link GenericItem#areConsistent(Object, Object)} - */ - public void testAreConsistent() { - assertTrue(GenericItem.areConsistent(null, null)); - assertTrue(GenericItem.areConsistent("test", "test")); - assertTrue(GenericItem.areConsistent(null, "test")); - assertTrue(GenericItem.areConsistent("test", null)); - assertFalse(GenericItem.areConsistent("test", "")); - } - - /** - * Test for {@link GenericItem#mergeObjects(Object, Object)} - */ - public void testMergeObjects() throws ConflictingItemException { - assertNull(GenericItem.mergeObjects(null, null)); - assertEquals("test", GenericItem.mergeObjects("test", "test")); - assertEquals("test", GenericItem.mergeObjects(null, "test")); - assertEquals("test", GenericItem.mergeObjects("test", null)); - - try { - assertEquals("test", GenericItem.mergeObjects("test", "")); - fail("Expected ConflictingItemException to be thrown"); - } catch (ConflictingItemException e) { - // Expected because "test" conflicts with "". - } - } - - /** - * Test that {@link GenericItem#toJson()} returns correctly. - */ - public void testToJson() throws JSONException { - GenericItem item = new GenericItem(new HashSet(Arrays.asList( - "string", "date", "object", "integer", "long", "float", "double", "item", "null"))); - Date date = new Date(); - Object object = new Object(); - NativeCrashItem subItem = new NativeCrashItem(); - - item.setAttribute("string", "foo"); - item.setAttribute("date", date); - item.setAttribute("object", object); - item.setAttribute("integer", 0); - item.setAttribute("long", 1L); - item.setAttribute("float", 2.5f); - item.setAttribute("double", 3.5); - item.setAttribute("item", subItem); - item.setAttribute("null", null); - - // Convert to JSON string and back again - JSONObject output = new JSONObject(item.toJson().toString()); - - assertTrue(output.has("string")); - assertEquals("foo", output.get("string")); - assertTrue(output.has("date")); - assertEquals(date.toString(), output.get("date")); - assertTrue(output.has("object")); - assertEquals(object.toString(), output.get("object")); - assertTrue(output.has("integer")); - assertEquals(0, output.get("integer")); - assertTrue(output.has("long")); - assertEquals(1, output.get("long")); - assertTrue(output.has("float")); - assertEquals(2.5, output.get("float")); - assertTrue(output.has("double")); - assertEquals(3.5, output.get("double")); - assertTrue(output.has("item")); - assertTrue(output.get("item") instanceof JSONObject); - assertFalse(output.has("null")); - } -} diff --git a/tests/src/com/android/loganalysis/item/InterruptItemTest.java b/tests/src/com/android/loganalysis/item/InterruptItemTest.java deleted file mode 100644 index 9e9df61..0000000 --- a/tests/src/com/android/loganalysis/item/InterruptItemTest.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright (C) 2015 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.item; - - -import com.android.loganalysis.item.InterruptItem.InterruptInfoItem; - -import junit.framework.TestCase; - -import org.json.JSONArray; -import org.json.JSONException; -import org.json.JSONObject; - -/** - * Unit test for {@link InterruptItem}. - */ -public class InterruptItemTest extends TestCase { - - /** - * Test that {@link InterruptItem#toJson()} returns correctly. - */ - public void testToJson() throws JSONException { - InterruptItem item = new InterruptItem(); - item.addInterrupt("smd-modem",25, InterruptItem.InterruptCategory.ALARM_INTERRUPT); - - // Convert to JSON string and back again - JSONObject output = new JSONObject(item.toJson().toString()); - - assertTrue(output.has(InterruptItem.INTERRUPTS)); - assertTrue(output.get(InterruptItem.INTERRUPTS) instanceof JSONArray); - - JSONArray interruptsInfo = output.getJSONArray(InterruptItem.INTERRUPTS); - - assertEquals(1, interruptsInfo.length()); - assertTrue(interruptsInfo.getJSONObject(0).has(InterruptInfoItem.NAME)); - assertTrue(interruptsInfo.getJSONObject(0).has(InterruptInfoItem.CATEGORY)); - assertTrue(interruptsInfo.getJSONObject(0).has(InterruptInfoItem.INTERRUPT_COUNT)); - - } -} diff --git a/tests/src/com/android/loganalysis/item/LocationDumpsItemTest.java b/tests/src/com/android/loganalysis/item/LocationDumpsItemTest.java deleted file mode 100644 index a96bc0d..0000000 --- a/tests/src/com/android/loganalysis/item/LocationDumpsItemTest.java +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright (C) 2016 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.item; - -import com.android.loganalysis.item.LocationDumpsItem.LocationInfoItem; - -import junit.framework.TestCase; - -import org.json.JSONArray; -import org.json.JSONException; -import org.json.JSONObject; - -/** - * Unit test for {@link LocationDumpsItem}. - */ -public class LocationDumpsItemTest extends TestCase { - - /** - * Test that {@link LocationDumpsItem#toJson()} returns correctly. - */ - public void testToJson() throws JSONException { - LocationDumpsItem item = new LocationDumpsItem(); - item.addLocationClient("com.google.android.gms", 500, 60, 1000, "PRIORITY_ACCURACY", 45); - item.addLocationClient("com.google.android.maps", 0, 0, 0, "PRIORITY_ACCURACY", 55); - - // Convert to JSON string and back again - JSONObject output = new JSONObject(item.toJson().toString()); - - assertTrue(output.has(LocationDumpsItem.LOCATION_CLIENTS)); - assertTrue(output.get(LocationDumpsItem.LOCATION_CLIENTS) instanceof JSONArray); - - JSONArray locationClients = output.getJSONArray(LocationDumpsItem.LOCATION_CLIENTS); - - assertEquals(2, locationClients.length()); - assertTrue(locationClients.getJSONObject(0).has(LocationInfoItem.PACKAGE)); - assertTrue(locationClients.getJSONObject(0).has(LocationInfoItem.EFFECTIVE_INTERVAL)); - assertTrue(locationClients.getJSONObject(0).has(LocationInfoItem.MIN_INTERVAL)); - assertTrue(locationClients.getJSONObject(0).has(LocationInfoItem.MAX_INTERVAL)); - assertTrue(locationClients.getJSONObject(0).has(LocationInfoItem.REQUEST_PRIORITY)); - assertTrue(locationClients.getJSONObject(0).has(LocationInfoItem.LOCATION_DURATION)); - - assertTrue(locationClients.getJSONObject(1).has(LocationInfoItem.PACKAGE)); - assertTrue(locationClients.getJSONObject(1).has(LocationInfoItem.EFFECTIVE_INTERVAL)); - assertTrue(locationClients.getJSONObject(1).has(LocationInfoItem.MIN_INTERVAL)); - assertTrue(locationClients.getJSONObject(1).has(LocationInfoItem.MAX_INTERVAL)); - assertTrue(locationClients.getJSONObject(1).has(LocationInfoItem.REQUEST_PRIORITY)); - assertTrue(locationClients.getJSONObject(1).has(LocationInfoItem.LOCATION_DURATION)); - } - - /** - * Test that {@link LocationDumpsItem#getLocationClients()} returns correctly. - */ - public void testGetLocationDumps() { - LocationDumpsItem item = new LocationDumpsItem(); - item.addLocationClient("com.google.android.gms", 500, 60, 1000, "PRIORITY_ACCURACY", 45); - - assertEquals(item.getLocationClients().size(), 1); - LocationInfoItem client = item.getLocationClients().iterator().next(); - assertNotNull(client); - assertEquals(client.getPackage(), "com.google.android.gms"); - assertEquals(client.getEffectiveInterval(), 500); - assertEquals(client.getMinInterval(), 60); - assertEquals(client.getMaxInterval(), 1000); - assertEquals(client.getPriority(), "PRIORITY_ACCURACY"); - assertEquals(client.getDuration(), 45); - } - -} diff --git a/tests/src/com/android/loganalysis/item/MemInfoItemTest.java b/tests/src/com/android/loganalysis/item/MemInfoItemTest.java deleted file mode 100644 index 7f25fe3..0000000 --- a/tests/src/com/android/loganalysis/item/MemInfoItemTest.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * 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.item; - -import junit.framework.TestCase; - -import org.json.JSONException; -import org.json.JSONObject; - -/** - * Unit test for {@link MemInfoItem}. - */ -public class MemInfoItemTest extends TestCase { - - /** - * Test that {@link MemInfoItem#toJson()} returns correctly. - */ - public void testToJson() throws JSONException { - MemInfoItem item = new MemInfoItem(); - item.put("foo", 123l); - item.put("bar", 456l); - item.setText("foo: 123 kB\nbar: 456 kB"); - - // Convert to JSON string and back again - JSONObject output = new JSONObject(item.toJson().toString()); - - assertTrue(output.has(MemInfoItem.LINES)); - assertTrue(output.get(MemInfoItem.LINES) instanceof JSONObject); - assertTrue(output.has(MemInfoItem.TEXT)); - assertEquals("foo: 123 kB\nbar: 456 kB", output.get(MemInfoItem.TEXT)); - - JSONObject lines = output.getJSONObject(MemInfoItem.LINES); - - assertEquals(2, lines.length()); - - assertEquals(123, lines.get("foo")); - assertEquals(456, lines.get("bar")); - } -} diff --git a/tests/src/com/android/loganalysis/item/MonkeyLogItemTest.java b/tests/src/com/android/loganalysis/item/MonkeyLogItemTest.java deleted file mode 100644 index cc2867c..0000000 --- a/tests/src/com/android/loganalysis/item/MonkeyLogItemTest.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * 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.item; - -import junit.framework.TestCase; - -import org.json.JSONArray; -import org.json.JSONException; -import org.json.JSONObject; - -/** - * Unit test for {@link MonkeyLogItem}. - */ -public class MonkeyLogItemTest extends TestCase { - /** - * Test that {@link MonkeyLogItem#toJson()} returns correctly. - */ - public void testToJson() throws JSONException { - MonkeyLogItem item = new MonkeyLogItem(); - item.addCategory("category1"); - item.addCategory("category2"); - item.addPackage("package1"); - item.addPackage("package2"); - item.addPackage("package3"); - - // Convert to JSON string and back again - JSONObject output = new JSONObject(item.toJson().toString()); - - assertTrue(output.has(MonkeyLogItem.CATEGORIES)); - assertTrue(output.get(MonkeyLogItem.CATEGORIES) instanceof JSONArray); - - JSONArray categories = output.getJSONArray(MonkeyLogItem.CATEGORIES); - - assertEquals(2, categories.length()); - assertTrue(in("category1", categories)); - assertTrue(in("category2", categories)); - - JSONArray packages = output.getJSONArray(MonkeyLogItem.PACKAGES); - - assertEquals(3, packages.length()); - assertTrue(in("package1", packages)); - assertTrue(in("package2", packages)); - assertTrue(in("package3", packages)); - } - - private boolean in(String value, JSONArray array) throws JSONException { - for (int i = 0; i < array.length(); i++) { - if (value.equals(array.get(i))) { - return true; - } - } - return false; - } -} diff --git a/tests/src/com/android/loganalysis/item/ProcrankItemTest.java b/tests/src/com/android/loganalysis/item/ProcrankItemTest.java deleted file mode 100644 index 7f5d309..0000000 --- a/tests/src/com/android/loganalysis/item/ProcrankItemTest.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * 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.item; - -import junit.framework.TestCase; - -import org.json.JSONArray; -import org.json.JSONException; -import org.json.JSONObject; - -/** - * Unit test for {@link ProcrankItem}. - */ -public class ProcrankItemTest extends TestCase { - - /** - * Test that {@link ProcrankItem#toJson()} returns correctly. - */ - public void testToJson() throws JSONException { - ProcrankItem item = new ProcrankItem(); - item.addProcrankLine(0, "process0", 1, 2, 3, 4); - item.addProcrankLine(5, "process1", 6, 7, 8, 9); - item.setText("foo\nbar"); - - // Convert to JSON string and back again - JSONObject output = new JSONObject(item.toJson().toString()); - - assertTrue(output.has(ProcrankItem.LINES)); - assertTrue(output.get(ProcrankItem.LINES) instanceof JSONArray); - assertTrue(output.has(ProcrankItem.TEXT)); - assertEquals("foo\nbar", output.get(ProcrankItem.TEXT)); - - JSONArray lines = output.getJSONArray(ProcrankItem.LINES); - - assertEquals(2, lines.length()); - assertTrue(lines.get(0) instanceof JSONObject); - - JSONObject line = lines.getJSONObject(0); - - assertEquals(0, line.get(ProcrankItem.PID)); - assertEquals("process0", line.get(ProcrankItem.PROCESS_NAME)); - assertEquals(1, line.get(ProcrankItem.VSS)); - assertEquals(2, line.get(ProcrankItem.RSS)); - assertEquals(3, line.get(ProcrankItem.PSS)); - assertEquals(4, line.get(ProcrankItem.USS)); - } -} diff --git a/tests/src/com/android/loganalysis/item/SmartMonkeyLogItemTest.java b/tests/src/com/android/loganalysis/item/SmartMonkeyLogItemTest.java deleted file mode 100644 index 4dd5597..0000000 --- a/tests/src/com/android/loganalysis/item/SmartMonkeyLogItemTest.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * 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.item; - -import junit.framework.TestCase; - -import org.json.JSONArray; -import org.json.JSONException; -import org.json.JSONObject; - -import java.util.Date; - -/** - * Unit test for {@link SmartMonkeyLogItem}. - */ -public class SmartMonkeyLogItemTest extends TestCase { - /** - * Test that {@link SmartMonkeyLogItem#toJson()} returns correctly. - */ - public void testToJson() throws JSONException { - SmartMonkeyLogItem item = new SmartMonkeyLogItem(); - item.addApplication("application1"); - item.addPackage("package1"); - item.addAnrTime(new Date()); - item.addCrashTime(new Date()); - - // Convert to JSON string and back again - JSONObject output = new JSONObject(item.toJson().toString()); - - assertTrue(output.has(SmartMonkeyLogItem.APPLICATIONS)); - assertTrue(output.get(SmartMonkeyLogItem.APPLICATIONS) instanceof JSONArray); - assertTrue(output.has(SmartMonkeyLogItem.PACKAGES)); - assertTrue(output.get(SmartMonkeyLogItem.PACKAGES) instanceof JSONArray); - assertTrue(output.has(SmartMonkeyLogItem.ANR_TIMES)); - assertTrue(output.get(SmartMonkeyLogItem.ANR_TIMES) instanceof JSONArray); - assertTrue(output.has(SmartMonkeyLogItem.CRASH_TIMES)); - assertTrue(output.get(SmartMonkeyLogItem.CRASH_TIMES) instanceof JSONArray); - } -} diff --git a/tests/src/com/android/loganalysis/item/SystemPropsItemTest.java b/tests/src/com/android/loganalysis/item/SystemPropsItemTest.java deleted file mode 100644 index b9b6675..0000000 --- a/tests/src/com/android/loganalysis/item/SystemPropsItemTest.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * 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.item; - -import junit.framework.TestCase; - -import org.json.JSONException; -import org.json.JSONObject; - -/** - * Unit test for {@link SystemPropsItem}. - */ -public class SystemPropsItemTest extends TestCase { - - /** - * Test that {@link SystemPropsItem#toJson()} returns correctly. - */ - public void testToJson() throws JSONException { - SystemPropsItem item = new SystemPropsItem(); - item.put("foo", "123"); - item.put("bar", "456"); - item.setText("[foo]: [123]\n[bar]: [456]"); - - // Convert to JSON string and back again - JSONObject output = new JSONObject(item.toJson().toString()); - - assertTrue(output.has(SystemPropsItem.LINES)); - assertTrue(output.get(SystemPropsItem.LINES) instanceof JSONObject); - assertTrue(output.has(SystemPropsItem.TEXT)); - assertEquals("[foo]: [123]\n[bar]: [456]", output.get(SystemPropsItem.TEXT)); - - JSONObject lines = output.getJSONObject(SystemPropsItem.LINES); - - assertEquals(2, lines.length()); - - assertEquals("123", lines.get("foo")); - assertEquals("456", lines.get("bar")); - } -} diff --git a/tests/src/com/android/loganalysis/item/TopItemTest.java b/tests/src/com/android/loganalysis/item/TopItemTest.java deleted file mode 100644 index 2df01d0..0000000 --- a/tests/src/com/android/loganalysis/item/TopItemTest.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * 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.item; - -import junit.framework.TestCase; - -import org.json.JSONException; -import org.json.JSONObject; - -/** - * Unit test for {@link TopItem}. - */ -public class TopItemTest extends TestCase { - - /** - * Test that {@link TopItem#toJson()} returns correctly. - */ - public void testToJson() throws JSONException { - TopItem item = new TopItem(); - item.setText("User 20%, System 20%, IOW 5%, IRQ 3%"); - - // Convert to JSON string and back again - JSONObject output = new JSONObject(item.toJson().toString()); - - assertTrue(output.has(TopItem.TEXT)); - assertEquals("User 20%, System 20%, IOW 5%, IRQ 3%", output.get(TopItem.TEXT)); - } -} diff --git a/tests/src/com/android/loganalysis/item/WakelockItemTest.java b/tests/src/com/android/loganalysis/item/WakelockItemTest.java deleted file mode 100644 index f570a7b..0000000 --- a/tests/src/com/android/loganalysis/item/WakelockItemTest.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright (C) 2015 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.item; - -import com.android.loganalysis.item.WakelockItem.WakelockInfoItem; - -import junit.framework.TestCase; - -import org.json.JSONArray; -import org.json.JSONException; -import org.json.JSONObject; - -/** - * Unit test for {@link WakelockItem}. - */ -public class WakelockItemTest extends TestCase { - - /** - * Test that {@link WakelockItem#toJson()} returns correctly. - */ - public void testToJson() throws JSONException { - WakelockItem item = new WakelockItem(); - item.addWakeLock("screen","u100", 150000, 25, - WakelockItem.WakeLockCategory.PARTIAL_WAKELOCK); - item.addWakeLock("wlan_rx", 150000, 25, - WakelockItem.WakeLockCategory.KERNEL_WAKELOCK); - - // Convert to JSON string and back again - JSONObject output = new JSONObject(item.toJson().toString()); - - assertTrue(output.has(WakelockItem.WAKELOCKS)); - assertTrue(output.get(WakelockItem.WAKELOCKS) instanceof JSONArray); - - JSONArray wakelockInfo = output.getJSONArray(WakelockItem.WAKELOCKS); - - assertEquals(2, wakelockInfo.length()); - assertTrue(wakelockInfo.getJSONObject(0).has(WakelockInfoItem.NAME)); - assertTrue(wakelockInfo.getJSONObject(0).has(WakelockInfoItem.PROCESS_UID)); - assertTrue(wakelockInfo.getJSONObject(0).has(WakelockInfoItem.HELD_TIME)); - assertTrue(wakelockInfo.getJSONObject(0).has(WakelockInfoItem.LOCKED_COUNT)); - assertTrue(wakelockInfo.getJSONObject(0).has(WakelockInfoItem.CATEGORY)); - - assertTrue(wakelockInfo.getJSONObject(1).has(WakelockInfoItem.NAME)); - assertFalse(wakelockInfo.getJSONObject(1).has(WakelockInfoItem.PROCESS_UID)); - assertTrue(wakelockInfo.getJSONObject(1).has(WakelockInfoItem.HELD_TIME)); - assertTrue(wakelockInfo.getJSONObject(1).has(WakelockInfoItem.LOCKED_COUNT)); - assertTrue(wakelockInfo.getJSONObject(1).has(WakelockInfoItem.CATEGORY)); - - } -} diff --git a/tests/src/com/android/loganalysis/parser/AbstractSectionParserTest.java b/tests/src/com/android/loganalysis/parser/AbstractSectionParserTest.java deleted file mode 100644 index 1092d0e..0000000 --- a/tests/src/com/android/loganalysis/parser/AbstractSectionParserTest.java +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Copyright (C) 2011 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.IItem; - -import junit.framework.TestCase; - -import java.util.ArrayList; -import java.util.List; - -/** - * Unit tests for {@link AbstractSectionParser} - */ -public class AbstractSectionParserTest extends TestCase { - AbstractSectionParser mParser = null; - - @Override - public void setUp() throws Exception { - super.setUp(); - mParser = new AbstractSectionParser() { - @Override - public IItem parse(List lines) { - for (String line : lines) { - parseLine(line); - } - commit(); - return null; - } - }; - } - - private static class FakeBlockParser implements IParser { - private String mExpected = null; - private int mCalls = 0; - - public FakeBlockParser(String expected) { - mExpected = expected; - } - - public int getCalls() { - return mCalls; - } - - @Override - public IItem parse(List input) { - assertEquals(1, input.size()); - assertEquals("parseBlock() got unexpected input!", mExpected, input.get(0)); - mCalls += 1; - return null; - } - } - - /** - * Verifies that {@link AbstractSectionParser} switches between parsers as expected - */ - public void testSwitchParsers() { - final String lineFormat = "howdy, parser %d!"; - final String linePattern = "I spy %d candles"; - final int nParsers = 4; - FakeBlockParser[] parsers = new FakeBlockParser[nParsers]; - final List lines = new ArrayList(2*nParsers); - - for (int i = 0; i < nParsers; ++i) { - String line = String.format(lineFormat, i); - FakeBlockParser parser = new FakeBlockParser(line); - mParser.addSectionParser(parser, String.format(linePattern, i)); - parsers[i] = parser; - - // add the parser trigger - lines.add(String.format(linePattern, i)); - // and then add the line that the parser is expecting - lines.add(String.format(lineFormat, i)); - } - - mParser.parse(lines); - - // Verify that all the parsers were run - for (int i = 0; i < nParsers; ++i) { - assertEquals(String.format("Parser %d has wrong call count!", i), 1, - parsers[i].getCalls()); - } - } -} - diff --git a/tests/src/com/android/loganalysis/parser/ActivityServiceParserTest.java b/tests/src/com/android/loganalysis/parser/ActivityServiceParserTest.java deleted file mode 100644 index 57aff9a..0000000 --- a/tests/src/com/android/loganalysis/parser/ActivityServiceParserTest.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright (C) 2016 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.ActivityServiceItem; - -import junit.framework.TestCase; - -import java.util.Arrays; -import java.util.List; - -/** - * Unit tests for {@link ActivityServiceParser} - */ -public class ActivityServiceParserTest extends TestCase { - - /** - * Test that normal input is parsed. - */ - public void testActivityServiceParser() { - List inputBlock = Arrays.asList( - "SERVICE com.google.android.gms/" - + "com.google.android.location.internal.GoogleLocationManagerService f4c9e9d " - + "pid=1494", - "Client:", - " nothing to dump", - "Location Request History By Package:", - "Interval effective/min/max 1/0/0[s] Duration: 140[minutes] " - + "[com.google.android.gms, PRIORITY_NO_POWER, UserLocationProducer] " - + "Num requests: 2 Active: true", - "Interval effective/min/max 284/285/3600[s] Duration: 140[minutes] " - + "[com.google.android.googlequicksearchbox, PRIORITY_BALANCED_POWER_ACCURACY] " - + "Num requests: 5 Active: true", - "FLP WakeLock Count:", - "SERVICE com.android.server.telecom/.components.BluetoothPhoneService 98ab pid=802", - "Interval effective/min/max 1/0/0[s] Duration: 140[minutes] " - + "[com.google.android.gms, PRIORITY_NO_POWER, UserLocationProducer] " - + "Num requests: 2 Active: true", - ""); - - ActivityServiceItem activityService = new ActivityServiceParser().parse(inputBlock); - assertNotNull(activityService.getLocationDumps()); - assertEquals(activityService.getLocationDumps().getLocationClients().size(), 2); - } -} - diff --git a/tests/src/com/android/loganalysis/parser/AnrParserTest.java b/tests/src/com/android/loganalysis/parser/AnrParserTest.java deleted file mode 100644 index e6afe80..0000000 --- a/tests/src/com/android/loganalysis/parser/AnrParserTest.java +++ /dev/null @@ -1,164 +0,0 @@ -/* - * Copyright (C) 2012 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.AnrItem; -import com.android.loganalysis.util.ArrayUtil; - -import junit.framework.TestCase; - -import java.util.Arrays; -import java.util.List; - -/** - * Unit tests for {@link AnrParser}. - */ -public class AnrParserTest extends TestCase { - - /** - * Test that ANRs are parsed for the header "ANR (application not responding) in process: app" - */ - public void testParse_application_not_responding() { - List lines = Arrays.asList( - "ANR (application not responding) in process: com.android.package", - "Reason: keyDispatchingTimedOut", - "Load: 0.71 / 0.83 / 0.51", - "CPU usage from 4357ms to -1434ms ago:", - " 22% 3378/com.android.package: 19% user + 3.6% kernel / faults: 73 minor 1 major", - " 16% 312/system_server: 12% user + 4.1% kernel / faults: 1082 minor 6 major", - "33% TOTAL: 21% user + 11% kernel + 0.3% iowait", - "CPU usage from 907ms to 1431ms later:", - " 14% 121/mediaserver: 11% user + 3.7% kernel / faults: 17 minor", - " 3.7% 183/AudioOut_2: 3.7% user + 0% kernel", - " 12% 312/system_server: 5.5% user + 7.4% kernel / faults: 6 minor", - " 5.5% 366/InputDispatcher: 0% user + 5.5% kernel", - "18% TOTAL: 11% user + 7.5% kernel"); - - AnrItem anr = new AnrParser().parse(lines); - assertNotNull(anr); - assertEquals("com.android.package", anr.getApp()); - assertEquals("keyDispatchingTimedOut", anr.getReason()); - assertEquals(0.71, anr.getLoad(AnrItem.LoadCategory.LOAD_1)); - assertEquals(0.83, anr.getLoad(AnrItem.LoadCategory.LOAD_5)); - assertEquals(0.51, anr.getLoad(AnrItem.LoadCategory.LOAD_15)); - assertEquals(33.0, anr.getCpuUsage(AnrItem.CpuUsageCategory.TOTAL)); - assertEquals(21.0, anr.getCpuUsage(AnrItem.CpuUsageCategory.USER)); - assertEquals(11.0, anr.getCpuUsage(AnrItem.CpuUsageCategory.KERNEL)); - assertEquals(0.3, anr.getCpuUsage(AnrItem.CpuUsageCategory.IOWAIT)); - assertEquals(ArrayUtil.join("\n", lines), anr.getStack()); - } - - /** - * Test that ANRs are parsed for the header "ANR in app" - */ - public void testParse_anr_in_app() { - List lines = Arrays.asList( - "ANR in com.android.package", - "Reason: keyDispatchingTimedOut", - "Load: 0.71 / 0.83 / 0.51", - "CPU usage from 4357ms to -1434ms ago:", - " 22% 3378/com.android.package: 19% user + 3.6% kernel / faults: 73 minor 1 major", - " 16% 312/system_server: 12% user + 4.1% kernel / faults: 1082 minor 6 major", - "33% TOTAL: 21% user + 11% kernel + 0.3% iowait", - "CPU usage from 907ms to 1431ms later:", - " 14% 121/mediaserver: 11% user + 3.7% kernel / faults: 17 minor", - " 3.7% 183/AudioOut_2: 3.7% user + 0% kernel", - " 12% 312/system_server: 5.5% user + 7.4% kernel / faults: 6 minor", - " 5.5% 366/InputDispatcher: 0% user + 5.5% kernel", - "18% TOTAL: 11% user + 7.5% kernel"); - - AnrItem anr = new AnrParser().parse(lines); - assertNotNull(anr); - assertEquals("com.android.package", anr.getApp()); - assertEquals("keyDispatchingTimedOut", anr.getReason()); - assertEquals(0.71, anr.getLoad(AnrItem.LoadCategory.LOAD_1)); - assertEquals(0.83, anr.getLoad(AnrItem.LoadCategory.LOAD_5)); - assertEquals(0.51, anr.getLoad(AnrItem.LoadCategory.LOAD_15)); - assertEquals(33.0, anr.getCpuUsage(AnrItem.CpuUsageCategory.TOTAL)); - assertEquals(21.0, anr.getCpuUsage(AnrItem.CpuUsageCategory.USER)); - assertEquals(11.0, anr.getCpuUsage(AnrItem.CpuUsageCategory.KERNEL)); - assertEquals(0.3, anr.getCpuUsage(AnrItem.CpuUsageCategory.IOWAIT)); - assertEquals(ArrayUtil.join("\n", lines), anr.getStack()); - } - - /** - * Test that ANRs are parsed for the header "ANR in app (class/package)" - */ - public void testParse_anr_in_app_class_package() { - List lines = Arrays.asList( - "ANR in com.android.package (com.android.package/.Activity)", - "Reason: keyDispatchingTimedOut", - "Load: 0.71 / 0.83 / 0.51", - "CPU usage from 4357ms to -1434ms ago:", - " 22% 3378/com.android.package: 19% user + 3.6% kernel / faults: 73 minor 1 major", - " 16% 312/system_server: 12% user + 4.1% kernel / faults: 1082 minor 6 major", - "33% TOTAL: 21% user + 11% kernel + 0.3% iowait", - "CPU usage from 907ms to 1431ms later:", - " 14% 121/mediaserver: 11% user + 3.7% kernel / faults: 17 minor", - " 3.7% 183/AudioOut_2: 3.7% user + 0% kernel", - " 12% 312/system_server: 5.5% user + 7.4% kernel / faults: 6 minor", - " 5.5% 366/InputDispatcher: 0% user + 5.5% kernel", - "18% TOTAL: 11% user + 7.5% kernel"); - - AnrItem anr = new AnrParser().parse(lines); - assertNotNull(anr); - assertEquals("com.android.package", anr.getApp()); - assertEquals("keyDispatchingTimedOut", anr.getReason()); - assertEquals(0.71, anr.getLoad(AnrItem.LoadCategory.LOAD_1)); - assertEquals(0.83, anr.getLoad(AnrItem.LoadCategory.LOAD_5)); - assertEquals(0.51, anr.getLoad(AnrItem.LoadCategory.LOAD_15)); - assertEquals(33.0, anr.getCpuUsage(AnrItem.CpuUsageCategory.TOTAL)); - assertEquals(21.0, anr.getCpuUsage(AnrItem.CpuUsageCategory.USER)); - assertEquals(11.0, anr.getCpuUsage(AnrItem.CpuUsageCategory.KERNEL)); - assertEquals(0.3, anr.getCpuUsage(AnrItem.CpuUsageCategory.IOWAIT)); - assertEquals(ArrayUtil.join("\n", lines), anr.getStack()); - } - - /** - * Test that ANRs with PID are parsed. - */ - public void testParse_anr_in_app_class_package_pid() { - List lines = Arrays.asList( - "ANR in com.android.package (com.android.package/.Activity)", - "PID: 1234", - "Reason: keyDispatchingTimedOut", - "Load: 0.71 / 0.83 / 0.51", - "CPU usage from 4357ms to -1434ms ago:", - " 22% 3378/com.android.package: 19% user + 3.6% kernel / faults: 73 minor 1 major", - " 16% 312/system_server: 12% user + 4.1% kernel / faults: 1082 minor 6 major", - "33% TOTAL: 21% user + 11% kernel + 0.3% iowait", - "CPU usage from 907ms to 1431ms later:", - " 14% 121/mediaserver: 11% user + 3.7% kernel / faults: 17 minor", - " 3.7% 183/AudioOut_2: 3.7% user + 0% kernel", - " 12% 312/system_server: 5.5% user + 7.4% kernel / faults: 6 minor", - " 5.5% 366/InputDispatcher: 0% user + 5.5% kernel", - "18% TOTAL: 11% user + 7.5% kernel"); - - AnrItem anr = new AnrParser().parse(lines); - assertNotNull(anr); - assertEquals("com.android.package", anr.getApp()); - assertEquals("keyDispatchingTimedOut", anr.getReason()); - assertEquals(1234, anr.getPid().intValue()); - assertEquals(0.71, anr.getLoad(AnrItem.LoadCategory.LOAD_1)); - assertEquals(0.83, anr.getLoad(AnrItem.LoadCategory.LOAD_5)); - assertEquals(0.51, anr.getLoad(AnrItem.LoadCategory.LOAD_15)); - assertEquals(33.0, anr.getCpuUsage(AnrItem.CpuUsageCategory.TOTAL)); - assertEquals(21.0, anr.getCpuUsage(AnrItem.CpuUsageCategory.USER)); - assertEquals(11.0, anr.getCpuUsage(AnrItem.CpuUsageCategory.KERNEL)); - assertEquals(0.3, anr.getCpuUsage(AnrItem.CpuUsageCategory.IOWAIT)); - assertEquals(ArrayUtil.join("\n", lines), anr.getStack()); - } -} diff --git a/tests/src/com/android/loganalysis/parser/BatteryDischargeStatsInfoParserTest.java b/tests/src/com/android/loganalysis/parser/BatteryDischargeStatsInfoParserTest.java deleted file mode 100644 index 691810c..0000000 --- a/tests/src/com/android/loganalysis/parser/BatteryDischargeStatsInfoParserTest.java +++ /dev/null @@ -1,164 +0,0 @@ -/* - * Copyright (C) 2016 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.BatteryDischargeStatsInfoItem; - -import junit.framework.TestCase; - -import java.util.Arrays; -import java.util.List; - -/** - * Unit tests for {@link BatteryDischargeStatsInfoParser} - */ -public class BatteryDischargeStatsInfoParserTest extends TestCase { - - /** - * Test that normal input is parsed correctly. - */ - public void testBatteryDischargeStats() { - List input = Arrays.asList( - " #0: +4m53s738ms to 0 (screen-on, power-save-off, device-idle-off)", - " #1: +4m5s586ms to 1 (screen-on, power-save-off, device-idle-off)", - " #2: +3m0s157ms to 2 (screen-on, power-save-off, device-idle-off)", - " #3: +2m52s243ms to 3 (screen-on, power-save-off, device-idle-off)", - " #4: +2m27s599ms to 4 (screen-on, power-save-off, device-idle-off)", - " #5: +5m0s172ms to 5 (screen-on, power-save-off, device-idle-off)", - " #6: +2m21s664ms to 6 (screen-on, power-save-off, device-idle-off)", - " #7: +5m18s811ms to 7 (screen-on, power-save-off, device-idle-off)", - " #8: +3m35s622ms to 8 (screen-on, power-save-off, device-idle-off)", - " #9: +4m52s605ms to 9 (screen-on, power-save-off, device-idle-off)", - " #10: +4m46s779ms to 10 (screen-on, power-save-off, device-idle-off)", - " #11: +4m0s200ms to 11 (screen-on, power-save-off, device-idle-off)", - " #12: +4m44s941ms to 12 (screen-on, power-save-off, device-idle-off)", - " #13: +3m31s163ms to 13 (screen-on, power-save-off, device-idle-off)", - " #14: +4m17s293ms to 14 (screen-on, power-save-off, device-idle-off)", - " #15: +3m11s584ms to 15 (screen-on, power-save-off, device-idle-off)", - " #16: +5m52s923ms to 16 (screen-on, power-save-off, device-idle-off)", - " #17: +3m7s34ms to 17 (screen-on, power-save-off, device-idle-off)", - " #18: +5m59s810ms to 18 (screen-on, power-save-off, device-idle-off)", - " #19: +6m15s275ms to 19 (screen-on, power-save-off, device-idle-off)", - " #20: +4m0s55ms to 20 (screen-on, power-save-off, device-idle-off)", - " #21: +5m21s911ms to 21 (screen-on, power-save-off, device-idle-off)", - " #22: +4m0s171ms to 22 (screen-on, power-save-off, device-idle-off)", - " #23: +5m22s820ms to 23 (screen-on, power-save-off, device-idle-off)", - " #24: +3m44s752ms to 24 (screen-on, power-save-off, device-idle-off)", - " #25: +4m15s130ms to 25 (screen-on, power-save-off, device-idle-off)", - " #26: +3m48s654ms to 26 (screen-on, power-save-off, device-idle-off)", - " #27: +5m0s294ms to 27 (screen-on, power-save-off, device-idle-off)", - " #28: +3m11s169ms to 28 (screen-on, power-save-off, device-idle-off)", - " #29: +4m48s194ms to 29 (screen-on, power-save-off, device-idle-off)", - " #30: +5m0s319ms to 30 (screen-on, power-save-off, device-idle-off)", - " #31: +2m42s209ms to 31 (screen-on, power-save-off, device-idle-off)", - " #32: +5m29s187ms to 32 (screen-on, power-save-off, device-idle-off)", - " #33: +3m32s392ms to 33 (screen-on, power-save-off, device-idle-off)", - " #34: +5m27s578ms to 34 (screen-on, power-save-off, device-idle-off)", - " #35: +3m47s37ms to 35 (screen-on, power-save-off, device-idle-off)", - " #36: +5m18s916ms to 36 (screen-on, power-save-off, device-idle-off)", - " #37: +2m54s111ms to 37 (screen-on, power-save-off, device-idle-off)", - " #38: +6m32s480ms to 38 (screen-on, power-save-off, device-idle-off)", - " #39: +5m24s906ms to 39 (screen-on, power-save-off, device-idle-off)", - " #40: +3m2s451ms to 40 (screen-on, power-save-off, device-idle-off)", - " #41: +6m29s762ms to 41 (screen-on, power-save-off, device-idle-off)", - " #42: +3m31s933ms to 42 (screen-on, power-save-off, device-idle-off)", - " #43: +4m58s520ms to 43 (screen-on, power-save-off, device-idle-off)", - " #44: +4m31s130ms to 44 (screen-on, power-save-off, device-idle-off)", - " #45: +5m28s870ms to 45 (screen-on, power-save-off, device-idle-off)", - " #46: +3m54s809ms to 46 (screen-on, power-save-off, device-idle-off)", - " #47: +5m5s105ms to 47 (screen-on, power-save-off, device-idle-off)", - " #48: +3m50s427ms to 48 (screen-on, power-save-off, device-idle-off)", - " #49: +6m0s344ms to 49 (screen-on, power-save-off, device-idle-off)", - " #50: +5m2s952ms to 50 (screen-on, power-save-off, device-idle-off)", - " #51: +3m6s120ms to 51 (screen-on, power-save-off, device-idle-off)", - " #52: +5m34s839ms to 52 (screen-on, power-save-off, device-idle-off)", - " #53: +2m33s473ms to 53 (screen-on, power-save-off, device-idle-off)", - " #54: +4m51s873ms to 54 (screen-on, power-save-off, device-idle-off)", - " #55: +3m30s41ms to 55 (screen-on, power-save-off, device-idle-off)", - " #56: +4m29s879ms to 56 (screen-on, power-save-off, device-idle-off)", - " #57: +3m41s722ms to 57 (screen-on, power-save-off, device-idle-off)", - " #58: +4m29s72ms to 58 (screen-on, power-save-off, device-idle-off)", - " #59: +4m49s351ms to 59 (screen-on, power-save-off, device-idle-off)", - " #60: +3m51s605ms to 60 (screen-on, power-save-off, device-idle-off)", - " #61: +5m8s334ms to 61 (screen-on, power-save-off, device-idle-off)", - " #62: +2m53s153ms to 62 (screen-on, power-save-off, device-idle-off)", - " #63: +6m0s234ms to 63 (screen-on, power-save-off, device-idle-off)", - " #64: +3m20s345ms to 64 (screen-on, power-save-off, device-idle-off)", - " #65: +5m46s211ms to 65 (screen-on, power-save-off, device-idle-off)", - " #66: +3m40s147ms to 66 (screen-on, power-save-off, device-idle-off)", - " #67: +5m14s559ms to 67 (screen-on, power-save-off, device-idle-off)", - " #68: +4m0s183ms to 68 (screen-on, power-save-off, device-idle-off)", - " #69: +5m23s334ms to 69 (screen-on, power-save-off, device-idle-off)", - " #70: +5m45s493ms to 70 (screen-on, power-save-off, device-idle-off)", - " #71: +4m0s179ms to 71 (screen-on, power-save-off, device-idle-off)", - " #72: +5m45s462ms to 72 (screen-on, power-save-off, device-idle-off)", - " #73: +3m10s449ms to 73 (screen-on, power-save-off, device-idle-off)", - " #74: +6m29s370ms to 74 (screen-on, power-save-off, device-idle-off)", - " #75: +3m20s414ms to 75 (screen-on, power-save-off, device-idle-off)", - " #76: +5m10s462ms to 76 (screen-on, power-save-off, device-idle-off)", - " #77: +4m20s500ms to 77 (screen-on, power-save-off, device-idle-off)", - " #78: +5m39s504ms to 78 (screen-on, power-save-off, device-idle-off)", - " #79: +5m59s819ms to 79 (screen-on, power-save-off, device-idle-off)", - " #80: +3m0s126ms to 80 (screen-on, power-save-off, device-idle-off)", - " #81: +6m20s912ms to 81 (screen-on, power-save-off, device-idle-off)", - " #82: +4m0s199ms to 82 (screen-on, power-save-off, device-idle-off)", - " #83: +5m23s470ms to 83 (screen-on, power-save-off, device-idle-off)", - " #84: +3m15s368ms to 84 (screen-on, power-save-off, device-idle-off)", - " #85: +6m18s625ms to 85 (screen-on, power-save-off, device-idle-off)", - " #86: +3m41s417ms to 86 (screen-on, power-save-off, device-idle-off)", - " #87: +5m32s257ms to 87 (screen-on, power-save-off, device-idle-off)", - " #88: +4m0s212ms to 88 (screen-on, power-save-off, device-idle-off)", - " #89: +5m41s218ms to 89 (screen-on, power-save-off, device-idle-off)", - " #90: +5m46s333ms to 90 (screen-on, power-save-off, device-idle-off)", - " #91: +3m58s362ms to 91 (screen-on, power-save-off, device-idle-off)", - " #92: +5m1s593ms to 92 (screen-on, power-save-off, device-idle-off)", - " #93: +4m47s33ms to 93 (screen-on, power-save-off, device-idle-off)", - " #94: +6m0s417ms to 94 (screen-on, power-save-off, device-idle-off)", - " #95: +3m9s77ms to 95 (screen-on, power-save-off, device-idle-off)", - " #96: +7m0s308ms to 96 (screen-on, power-save-off, device-idle-off)", - " #97: +3m29s741ms to 97 (screen-on, power-save-off, device-idle-off)", - " #98: +7m12s748ms to 98 (screen-on, power-save-off, device-idle-off)", - " Estimated screen on time: 7h 36m 13s 0ms "); - - BatteryDischargeStatsInfoItem infoItem = new BatteryDischargeStatsInfoParser().parse(input); - assertEquals(99, infoItem.getDischargePercentage()); - assertEquals(27099330, infoItem.getDischargeDuration()); - assertEquals(27207848, infoItem.getProjectedBatteryLife()); - } - - /** - * Test that input with only a few discharge stats. - */ - public void testBatteryDischargeStatsWithTop5Percentages() { - List input = Arrays.asList( - " #95: +3m9s77ms to 95 (screen-on, power-save-off, device-idle-off)", - " #96: +7m0s308ms to 96 (screen-on, power-save-off, device-idle-off)", - " #97: +3m29s741ms to 97 (screen-on, power-save-off, device-idle-off)", - " #98: +7m12s748ms to 98 (screen-on, power-save-off, device-idle-off)", - " Estimated screen on time: 7h 36m 13s 0ms "); - - BatteryDischargeStatsInfoItem infoItem = new BatteryDischargeStatsInfoParser().parse(input); - - try { - infoItem.getProjectedBatteryLife(); - fail("Projected battery life is expected to be undefined when there are not enough" + - " samples of battery discharge below 95 percent."); - } catch (NullPointerException e) { - // NullPointerException expected. - } - } -} diff --git a/tests/src/com/android/loganalysis/parser/BatteryStatsDetailedInfoParserTest.java b/tests/src/com/android/loganalysis/parser/BatteryStatsDetailedInfoParserTest.java deleted file mode 100644 index b176fa2..0000000 --- a/tests/src/com/android/loganalysis/parser/BatteryStatsDetailedInfoParserTest.java +++ /dev/null @@ -1,131 +0,0 @@ -/* - * Copyright (C) 2015 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.BatteryStatsDetailedInfoItem; - -import junit.framework.TestCase; - -import java.util.Arrays; -import java.util.List; - -/** - * Unit tests for {@link BatteryStatsDetailedInfoParser} - */ -public class BatteryStatsDetailedInfoParserTest extends TestCase { - - /** - * Test that normal input is parsed. - */ - public void testBatteryStatsDetailedInfoParser() { - List inputBlock = Arrays.asList( - " Time on battery: 2h 21m 5s 622ms (12.0%) realtime, 7m 54s 146ms (0.7%) uptime", - " Time on battery screen off: 2h 5m 55s 3ms (1%) realtime, 7m 4s 5ms (7%) uptime", - " Total run time: 19h 38m 43s 650ms realtime, 17h 25m 32s 175ms uptime", - " All kernel wake locks:", - " Kernel Wake lock PowerManagerService.WakeLocks: 1h 3m 50s 5ms (8 times) realtime", - " Kernel Wake lock event0-2656 : 3m 49s 268ms (2399 times) realtime", - " Kernel Wake lock wlan_wd_wake: 3m 34s 639ms (1751 times) realtime", - " Kernel Wake lock wlan_rx_wake: 3m 19s 887ms (225 times) realtime", - " Kernel Wake lock wlan_tx_wake: 2m 19s 887ms (225 times) realtime", - " Kernel Wake lock tx_wake: 1m 19s 887ms (225 times) realtime", - " ", - " All partial wake locks:", - " Wake lock u0a7 NlpWakeLock: 8m 13s 203ms (1479 times) realtime", - " Wake lock u0a7 NlpCollectorWakeLock: 6m 29s 18ms (238 times) realtime", - " Wake lock u0a7 GCM_CONN_ALARM: 6m 8s 587ms (239 times) realtime", - " Wake lock 1000 *alarm*: 5m 11s 316ms (1469 times) realtime", - " Wake lock u10 xxx: 4m 11s 316ms (1469 times) realtime", - " Wake lock u30 cst: 2m 11s 316ms (1469 times) realtime", - " ", - " All wakeup reasons:", - " Wakeup reason 200:qcom,smd-rpm:222:fc4: 11m 49s 332ms (0 times) realtime", - " Wakeup reason 200:qcom,smd-rpm: 48s 45ms (0 times) realtime", - " Wakeup reason 2:qcom,smd-rpm:2:f0.qm,mm:22:fc4mi: 3s 417ms (0 times) realtime", - " Wakeup reason 188:qcom,smd-adsp:200:qcom,smd-rpm: 1s 656ms (0 times) realtime", - " Wakeup reason 58:qcom,smsm-modem:2:qcom,smd-rpm: 6m 16s 1ms (5 times) realtime", - " Wakeup reason 57:qcom,smd-modem:200:qcom,smd-rpm: 40s 995ms (0 times) realtime", - " Wakeup reason unknown: 8s 455ms (0 times) realtime", - " Wakeup reason 9:bcmsdh_sdmmc:2:qcomd-rpm:240:mso: 8m 5s 9ms (0 times) realtime", - " ", - " 0:", - " User activity: 2 other", - " Wake lock SCREEN_FROZEN realtime", - " Sensor 0: 9s 908ms realtime (1 times)", - " Sensor 1: 9s 997ms realtime (1 times)", - " Foreground for: 2h 21m 5s 622ms", - " Apk android:", - " 24 wakeup alarms", - " u0a9:", - " Mobile network: 8.1KB received, 1.6KB sent (packets 291 received, 342 sent)", - " Mobile radio active: 3m 43s 890ms (34.2%) 39x @ 354 mspp", - " Sensor 2: 12m 13s 15ms realtime (5 times)", - " Sensor 32: (not used)", - " Sensor 35: (not used)"); - - BatteryStatsDetailedInfoItem stats = new BatteryStatsDetailedInfoParser().parse(inputBlock); - - assertEquals(8465622, stats.getTimeOnBattery()); - assertEquals(910619, stats.getScreenOnTime()); - assertNotNull(stats.getWakelockItem()); - assertNotNull(stats.getInterruptItem()); - assertNotNull(stats.getProcessUsageItem()); - } - - /** - * Test with missing wakelock section - */ - public void testMissingWakelockSection() { - List inputBlock = Arrays.asList( - " Time on battery: 2h 21m 5s 622ms (12.0%) realtime, 7m 54s 146ms (0.7%) uptime", - " Time on battery screen off: 2h 5m 55s 3ms (1%) realtime, 7m 4s 5ms (7%) uptime", - " Total run time: 19h 38m 43s 650ms realtime, 17h 25m 32s 175ms uptime", - " All wakeup reasons:", - " Wakeup reason 200:qcom,smd-rpm:222:fc4: 11m 49s 332ms (0 times) realtime", - " Wakeup reason 200:qcom,smd-rpm: 48s 45ms (0 times) realtime", - " Wakeup reason 2:qcom,smd-rpm:2:f0.qm,mm:22:fc4mi: 3s 417ms (0 times) realtime", - " Wakeup reason 188:qcom,smd-adsp:200:qcom,smd-rpm: 1s 656ms (0 times) realtime", - " Wakeup reason 58:qcom,smsm-modem:2:qcom,smd-rpm: 6m 16s 1ms (5 times) realtime", - " Wakeup reason 57:qcom,smd-modem:200:qcom,smd-rpm: 40s 995ms (0 times) realtime", - " Wakeup reason unknown: 8s 455ms (0 times) realtime", - " Wakeup reason 9:bcmsdh_sdmmc:2:qcomd-rpm:240:mso: 8m 5s 9ms (0 times) realtime", - " ", - " 0:", - " User activity: 2 other", - " Wake lock SCREEN_FROZEN realtime", - " Sensor 0: 9s 908ms realtime (1 times)", - " Sensor 1: 9s 997ms realtime (1 times)", - " Foreground for: 2h 21m 5s 622ms", - " Apk android:", - " 24 wakeup alarms", - " u0a9:", - " Mobile network: 8.1KB received, 1.6KB sent (packets 291 received, 342 sent)", - " Mobile radio active: 3m 43s 890ms (34.2%) 39x @ 354 mspp", - " Sensor 2: 12m 13s 15ms realtime (5 times)", - " Sensor 32: (not used)", - " Sensor 35: (not used)"); - BatteryStatsDetailedInfoItem stats = new BatteryStatsDetailedInfoParser().parse(inputBlock); - - assertEquals(8465622, stats.getTimeOnBattery()); - assertEquals(910619, stats.getScreenOnTime()); - - assertNull(stats.getWakelockItem()); - - assertNotNull(stats.getInterruptItem()); - assertNotNull(stats.getProcessUsageItem()); - } -} - diff --git a/tests/src/com/android/loganalysis/parser/BatteryStatsSummaryInfoParserTest.java b/tests/src/com/android/loganalysis/parser/BatteryStatsSummaryInfoParserTest.java deleted file mode 100644 index c6ba381..0000000 --- a/tests/src/com/android/loganalysis/parser/BatteryStatsSummaryInfoParserTest.java +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Copyright (C) 2015 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.BatteryStatsSummaryInfoItem; - -import junit.framework.TestCase; - -import java.util.Arrays; -import java.util.GregorianCalendar; -import java.util.List; -import java.util.TimeZone; - -/** - * Unit tests for {@link BatteryStatsSummaryInfoParser} - */ -public class BatteryStatsSummaryInfoParserTest extends TestCase { - - /** - * Test that normal input is parsed. - */ - public void testBatteryStatsSummaryInfoParser() { - List inputBlock = Arrays.asList( - "Battery History (37% used, 95KB used of 256KB, 166 strings using 15KB):", - " 0 (9) RESET:TIME: 2014-12-09-11-33-29", - " +1s067ms (1) 100 c0500020 -wifi_full_lock -wifi_scan", - " +3s297ms (2) 100 80400020 -wake_lock -screen", - " +30m02s075ms (1) 100 c0500020 wifi_signal_strength=4 wifi_suppl=completed", - " +30m03s012ms (2) 099 c0500020 temp=306 volt=4217", - " +33m48s967ms (1) 099 f8400020 +wifi_scan", - " +33m49s335ms (2) 098 f0400020 temp=324 -wifi_scan", - " +1h07m27s735ms (1) 098 80400020 -wake_lock", - " +1h07m27s950ms (2) 097 c0400020", - " +1h07m29s000ms (2) 097 c0400020 -sync=u0a41:\"gmail-ls/com.google/a@g", - " +1h25m34s877ms (2) 097 00400020 -running wake_reason=0:200:qcom,smd-rpm", - " +1h25m41s948ms (2) 096 80400020 wifi_suppl=associated", - " +2h13m40s055ms (1) 096 00400018 -running", - " +2h13m40s570ms (2) 095 c0400008 temp=304 volt=4167", - " +2h56m50s792ms (1) 095 80400020 -wake_lock", - " +2h56m50s967ms (2) 094 00400020 temp=317 -running", - " +3h38m57s986ms (2) 094 80400020 +running wake_reason=0:289:bcmsdh_sdmmc", - " +3h38m58s241ms (2) 093 00400020 temp=327 -running", - " +3h56m33s329ms (1) 093 00400020 -running -wake_lock", - " +3h56m43s245ms (2) 092 00400020 -running", - " +4h13m00s551ms (1) 092 00400020 -running -wake_lock", - " +4h13m24s250ms (2) 091 00400020 -running", - " +4h34m52s233ms (2) 091 80400020 +running wake_reason=0:289:bcmsdh_sdmmc", - " +4h34m52s485ms (3) 090 00400020 -running wake_reason=0:200:qcom,smd-rpm", - " +4h57m20s644ms (1) 090 00400020 -running", - " +4h57m38s484ms (2) 089 00400020 -running", - " +5h20m58s226ms (1) 089 80400020 +running wifi_suppl=associated", - " +5h21m03s909ms (1) 088 80400020 -wake_lock -wifi_full_lock", - " +5h40m38s169ms (2) 088 c0500020 +top=u0a19:com.google.android.googlequick", - " +5h40m38s479ms (2) 087 c0500020 volt=4036", - " +6h16m45s248ms (2) 087 d0440020 -sync=u0a41:gmail-ls/com.google/avellore@go", - " +6h16m45s589ms (2) 086 d0440020 volt=4096", - " +6h52m43s316ms (1) 086 80400020 -wake_lock", - " +6h53m18s952ms (2) 085 c0400020", - " +7h24m02s415ms (1) 085 80400020 -wake_lock", - " +7h24m02s904ms (3) 084 c0400020 volt=4105 +wake_lock=u0a7:NlpWakeLock", - " +7h29m10s379ms (1) 084 00400020 -running -wake_lock", - " +7h29m11s841ms (2) 083 00400020 temp=317 volt=4047 -running", - " +7h41m08s963ms (1) 083 00400020 -running", - " +7h41m20s494ms (2) 082 00400020 temp=300 -running", - " +7h54m57s288ms (1) 082 52441420 -running", - " +7h55m00s801ms (1) 081 52441420 -running", - " +8h02m18s594ms (1) 081 50440020 -running", - " +8h02m23s493ms (2) 080 50440020 temp=313 -running"); - - BatteryStatsSummaryInfoItem summary = new BatteryStatsSummaryInfoParser().parse(inputBlock); - - assertEquals("The battery dropped a level 24 mins on average", - summary.getBatteryDischargeRate()); - - // Get the current timezone short name (PST, GMT) to properly output the time as expected. - String timezone = - new GregorianCalendar().getTimeZone().getDisplayName(false, TimeZone.SHORT); - assertEquals( - String.format( - "The peak discharge time was during Tue Dec 09 16:31:07 %s 2014 to " - + "Tue Dec 09 19:35:52 %s 2014 where battery dropped from 89 to 80", - timezone, timezone), - summary.getPeakDischargeTime()); - } - - public void testNoBatteryDischarge() { - List inputBlock = Arrays.asList( - "Battery History (37% used, 95KB used of 256KB, 166 strings using 15KB):", - " 0 (9) RESET:TIME: 2014-12-09-11-33-29"); - BatteryStatsSummaryInfoItem summary = new BatteryStatsSummaryInfoParser().parse(inputBlock); - - assertEquals("The battery did not discharge", summary.getBatteryDischargeRate()); - assertEquals("The battery did not discharge", summary.getPeakDischargeTime()); - } -} - diff --git a/tests/src/com/android/loganalysis/parser/BatteryUsageParserTest.java b/tests/src/com/android/loganalysis/parser/BatteryUsageParserTest.java deleted file mode 100644 index 20a9a2e..0000000 --- a/tests/src/com/android/loganalysis/parser/BatteryUsageParserTest.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (C) 2015 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.BatteryUsageItem; - -import junit.framework.TestCase; - -import java.util.Arrays; -import java.util.List; - -/** - * Unit tests for {@link BatteryUsageParser} - */ -public class BatteryUsageParserTest extends TestCase { - - private static final double EPSILON = 1e-3; - /** - * Test that normal input is parsed. - */ - public void testBatteryUsageParser() { - List inputBlock = Arrays.asList( - " Capacity: 3220, Computed drain: 11.0, actual drain: 0", - " Screen: 8.93", - " Idle: 1.23", - " Uid 0: 0.281", - " Uid u0a36: 0.200", - " Uid 1000: 0.165", - " Uid 1013: 0.0911", - " Uid u0a16: 0.0441"); - - BatteryUsageItem usage = new BatteryUsageParser().parse(inputBlock); - - assertEquals(3220, usage.getBatteryCapacity()); - assertEquals(7, usage.getBatteryUsage().size()); - - assertEquals("Screen", usage.getBatteryUsage().get(0).getName()); - assertEquals(8.93, usage.getBatteryUsage().get(0).getUsage(), EPSILON); - assertEquals("Uid u0a16", usage.getBatteryUsage().get(6).getName()); - assertEquals(0.0441, usage.getBatteryUsage().get(6).getUsage()); - } -} - diff --git a/tests/src/com/android/loganalysis/parser/BugreportParserTest.java b/tests/src/com/android/loganalysis/parser/BugreportParserTest.java deleted file mode 100644 index 5f3fc10..0000000 --- a/tests/src/com/android/loganalysis/parser/BugreportParserTest.java +++ /dev/null @@ -1,766 +0,0 @@ -/* - * Copyright (C) 2011 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.BugreportItem; -import com.android.loganalysis.item.IItem; -import com.android.loganalysis.item.MiscKernelLogItem; -import com.android.loganalysis.util.ArrayUtil; - -import junit.framework.TestCase; - -import java.text.DateFormat; -import java.text.ParseException; -import java.text.SimpleDateFormat; -import java.util.Arrays; -import java.util.Date; -import java.util.List; - -/** - * Unit tests for {@link BugreportParser} - */ -public class BugreportParserTest extends TestCase { - - /** - * Test that a bugreport can be parsed. - */ - public void testParse() throws ParseException { - List lines = - Arrays.asList( - "========================================================", - "== dumpstate: 2012-04-25 20:45:10", - "========================================================", - "------ SECTION ------", - "", - "------ MEMORY INFO (/proc/meminfo) ------", - "MemTotal: 353332 kB", - "MemFree: 65420 kB", - "Buffers: 20800 kB", - "Cached: 86204 kB", - "SwapCached: 0 kB", - "", - "------ CPU INFO (top -n 1 -d 1 -m 30 -t) ------", - "", - "User 3%, System 3%, IOW 0%, IRQ 0%", - "User 33 + Nice 0 + Sys 32 + Idle 929 + IOW 0 + IRQ 0 + SIRQ 0 = 994", - "", - "------ PROCRANK (procrank) ------", - " PID Vss Rss Pss Uss cmdline", - " 178 87136K 81684K 52829K 50012K system_server", - " 1313 78128K 77996K 48603K 45812K com.google.android.apps.maps", - " 3247 61652K 61492K 33122K 30972K com.android.browser", - " ------ ------ ------", - " 203624K 163604K TOTAL", - "RAM: 731448K total, 415804K free, 9016K buffers, 108548K cached", - "[procrank: 1.6s elapsed]", - "", - "------ KERNEL LOG (dmesg) ------", - "<6>[ 0.000000] Initializing cgroup subsys cpu", - "<3>[ 1.000000] benign message", - "", - "", - "------ SYSTEM LOG (logcat -v threadtime -d *:v) ------", - "04-25 09:55:47.799 3064 3082 E AndroidRuntime: java.lang.Exception", - "04-25 09:55:47.799 3064 3082 E AndroidRuntime: \tat class.method1(Class.java:1)", - "04-25 09:55:47.799 3064 3082 E AndroidRuntime: \tat class.method2(Class.java:2)", - "04-25 09:55:47.799 3064 3082 E AndroidRuntime: \tat class.method3(Class.java:3)", - "04-25 17:17:08.445 312 366 E ActivityManager: ANR (application not responding) in process: com.android.package", - "04-25 17:17:08.445 312 366 E ActivityManager: Reason: keyDispatchingTimedOut", - "04-25 17:17:08.445 312 366 E ActivityManager: Load: 0.71 / 0.83 / 0.51", - "04-25 17:17:08.445 312 366 E ActivityManager: 33% TOTAL: 21% user + 11% kernel + 0.3% iowait", - "04-25 18:33:27.273 115 115 I DEBUG : *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***", - "04-25 18:33:27.273 115 115 I DEBUG : Build fingerprint: 'product:build:target'", - "04-25 18:33:27.273 115 115 I DEBUG : pid: 3112, tid: 3112 >>> com.google.android.browser <<<", - "04-25 18:33:27.273 115 115 I DEBUG : signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 00000000", - "", - "------ SYSTEM PROPERTIES ------", - "[dalvik.vm.dexopt-flags]: [m=y]", - "[dalvik.vm.heapgrowthlimit]: [48m]", - "[dalvik.vm.heapsize]: [256m]", - "[gsm.version.ril-impl]: [android moto-ril-multimode 1.0]", - "", - "------ LAST KMSG (/proc/last_kmsg) ------", - "[ 0.000000] Initializing cgroup subsys cpu", - "[ 16.203491] benign message", - "", - "------ SECTION ------", - "", - "------ VM TRACES AT LAST ANR (/data/anr/traces.txt: 2012-04-25 17:17:08) ------", - "", - "", - "----- pid 2887 at 2012-04-25 17:17:08 -----", - "Cmd line: com.android.package", - "", - "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)", - " at class.method2(Class.java:2)", - " at class.method2(Class.java:2)", - "", - "----- end 2887 -----", - "", - "------ SECTION ------", - "", - "------ DUMPSYS (dumpsys) ------", - "DUMP OF SERVICE batterystats:", - "Battery History (0% used, 1636 used of 256KB, 15 strings using 794):", - " 0 (15) RESET:TIME: 1970-01-10-06-23-28", - " +45s702ms (2) 001 80080000 volt=4187", - " +1m15s525ms (2) 001 80080000 temp=299 volt=4155", - "Statistics since last charged:", - " Time on battery: 1h 5m 2s 4ms (9%) realtime, 1h 5m 2s 4ms (9%) uptime", - " Time on battery screen off: 1h 4m 5s 8ms (9%) realtime, 1h 4m 5s 8ms (9%) uptime", - " All kernel wake locks:", - " Kernel Wake lock PowerManagerService.WakeLocks: 5m 10s 6ms (2 times) realtime", - " Kernel Wake lock msm_serial_hs_rx: 2m 13s 612ms (258 times) realtime", - "", - " All partial wake locks:", - " Wake lock 1001 ProxyController: 1h 4m 47s 565ms (4 times) realtime", - " Wake lock 1013 AudioMix: 1s 979ms (3 times) realtime", - "", - " All wakeup reasons:", - " Wakeup reason 2:bcmsdh_sdmmc:2:qcom,smd:2:msmgio: 1m 5s 4ms (2 times) realtime", - " Wakeup reason 2:qcom,smd-rpm:2:fc4c.qcom,spmi: 7m 1s 914ms (7 times) realtime", - "", - "DUMP OF SERVICE package:", - "Package [com.google.android.calculator] (e075c9d):", - " userId=10071", - " secondaryCpuAbi=null", - " versionCode=73000302 minSdk=10000 targetSdk=10000", - " versionName=7.3 (3821978)", - " splits=[base]", - "========================================================", - "== Running Application Services", - "========================================================", - "------ APP SERVICES (dumpsys activity service all) ------", - "SERVICE com.google.android.gms/" - + "com.google.android.location.internal.GoogleLocationManagerService f4c9d pid=14", - " Location Request History By Package:", - "Interval effective/min/max 1/0/0[s] Duration: 140[minutes] [" - + "com.google.android.gms, PRIORITY_NO_POWER, UserLocationProducer] " - + "Num requests: 2 Active: true", - "Interval effective/min/max 284/285/3600[s] Duration: 140[minutes] " - + "[com.google.android.googlequicksearchbox, PRIORITY_BALANCED_POWER_ACCURACY] " - + "Num requests: 5 Active: true"); - - BugreportItem bugreport = new BugreportParser().parse(lines); - assertNotNull(bugreport); - assertEquals(parseTime("2012-04-25 20:45:10.000"), bugreport.getTime()); - - assertNotNull(bugreport.getMemInfo()); - assertEquals(5, bugreport.getMemInfo().size()); - - assertNotNull(bugreport.getTop()); - assertEquals(994, bugreport.getTop().getTotal()); - - assertNotNull(bugreport.getProcrank()); - assertEquals(3, bugreport.getProcrank().getPids().size()); - - assertNotNull(bugreport.getKernelLog()); - assertEquals(1.0, bugreport.getKernelLog().getStopTime(), 0.000005); - - assertNotNull(bugreport.getSystemLog()); - assertEquals(parseTime("2012-04-25 09:55:47.799"), bugreport.getSystemLog().getStartTime()); - assertEquals(parseTime("2012-04-25 18:33:27.273"), bugreport.getSystemLog().getStopTime()); - assertEquals(3, bugreport.getSystemLog().getEvents().size()); - assertEquals(1, bugreport.getSystemLog().getAnrs().size()); - assertNotNull(bugreport.getSystemLog().getAnrs().get(0).getTrace()); - - assertNotNull(bugreport.getLastKmsg()); - assertEquals(16.203491, bugreport.getLastKmsg().getStopTime(), 0.000005); - - assertNotNull(bugreport.getSystemProps()); - assertEquals(4, bugreport.getSystemProps().size()); - - assertNotNull(bugreport.getDumpsys()); - assertNotNull(bugreport.getDumpsys().getBatteryStats()); - assertNotNull(bugreport.getDumpsys().getPackageStats()); - - assertNotNull(bugreport.getActivityService()); - assertNotNull(bugreport.getActivityService().getLocationDumps().getLocationClients()); - assertEquals(bugreport.getActivityService().getLocationDumps().getLocationClients().size(), - 2); - } - - /** - * Test that the logcat year is set correctly from the bugreport timestamp. - */ - public void testParse_set_logcat_year() throws ParseException { - List lines = Arrays.asList( - "========================================================", - "== dumpstate: 1999-01-01 02:03:04", - "========================================================", - "------ SYSTEM LOG (logcat -v threadtime -d *:v) ------", - "01-01 01:02:03.000 1 1 I TAG : message", - "01-01 01:02:04.000 1 1 I TAG : message", - ""); - - BugreportItem bugreport = new BugreportParser().parse(lines); - assertNotNull(bugreport); - assertEquals(parseTime("1999-01-01 02:03:04.000"), bugreport.getTime()); - assertNotNull(bugreport.getSystemLog()); - assertEquals(parseTime("1999-01-01 01:02:03.000"), bugreport.getSystemLog().getStartTime()); - assertEquals(parseTime("1999-01-01 01:02:04.000"), bugreport.getSystemLog().getStopTime()); - } - - /** - * Test that the command line is parsed - */ - public void testParse_command_line() { - List lines = Arrays.asList("Command line:"); - BugreportItem bugreport = new BugreportParser().parse(lines); - assertTrue(bugreport.getCommandLine().isEmpty()); - - lines = Arrays.asList("Command line: key=value"); - bugreport = new BugreportParser().parse(lines); - assertEquals(1, bugreport.getCommandLine().size()); - assertEquals("value", bugreport.getCommandLine().get("key")); - - lines = Arrays.asList("Command line: key1=value1 key2=value2"); - bugreport = new BugreportParser().parse(lines); - assertEquals(2, bugreport.getCommandLine().size()); - assertEquals("value1", bugreport.getCommandLine().get("key1")); - assertEquals("value2", bugreport.getCommandLine().get("key2")); - - // Test a bad strings - lines = Arrays.asList("Command line: key1=value=withequals key2= "); - bugreport = new BugreportParser().parse(lines); - assertEquals(2, bugreport.getCommandLine().size()); - assertEquals("value=withequals", bugreport.getCommandLine().get("key1")); - assertEquals("", bugreport.getCommandLine().get("key2")); - - lines = Arrays.asList("Command line: key1=value1 nonkey key2="); - bugreport = new BugreportParser().parse(lines); - assertEquals(3, bugreport.getCommandLine().size()); - assertEquals("value1", bugreport.getCommandLine().get("key1")); - assertEquals("", bugreport.getCommandLine().get("key2")); - assertNull(bugreport.getCommandLine().get("nonkey")); - } - - /** - * Test that a normal boot triggers a normal boot event and no unknown reason. - */ - public void testParse_bootreason_kernel_good() { - List lines = Arrays.asList( - "========================================================", - "== dumpstate: 1999-01-01 02:03:04", - "========================================================", - "Command line: androidboot.bootreason=reboot", - ""); - BugreportItem bugreport = new BugreportParser().parse(lines); - assertNotNull(bugreport.getLastKmsg()); - assertEquals(1, bugreport.getLastKmsg().getEvents().size()); - assertEquals("Last boot reason: reboot", - bugreport.getLastKmsg().getEvents().get(0).getStack()); - assertEquals("NORMAL_REBOOT", bugreport.getLastKmsg().getEvents().get(0).getCategory()); - } - - /** - * Test that a kernel reset boot triggers a kernel reset event and no unknown reason. - */ - public void testParse_bootreason_kernel_bad() { - List lines = Arrays.asList( - "========================================================", - "== dumpstate: 1999-01-01 02:03:04", - "========================================================", - "Command line: androidboot.bootreason=hw_reset", - ""); - BugreportItem bugreport = new BugreportParser().parse(lines); - assertNotNull(bugreport.getLastKmsg()); - assertEquals(1, bugreport.getLastKmsg().getEvents().size()); - assertEquals("Last boot reason: hw_reset", - bugreport.getLastKmsg().getEvents().get(0).getStack()); - assertEquals("KERNEL_RESET", bugreport.getLastKmsg().getEvents().get(0).getCategory()); - } - - /** - * Test that a normal boot triggers a normal boot event and no unknown reason. - */ - public void testParse_bootreason_prop_good() { - List lines = Arrays.asList( - "========================================================", - "== dumpstate: 1999-01-01 02:03:04", - "========================================================", - "------ SYSTEM PROPERTIES ------", - "[ro.boot.bootreason]: [reboot]", - ""); - BugreportItem bugreport = new BugreportParser().parse(lines); - assertNotNull(bugreport.getLastKmsg()); - assertEquals(1, bugreport.getLastKmsg().getEvents().size()); - assertEquals("Last boot reason: reboot", - bugreport.getLastKmsg().getEvents().get(0).getStack()); - assertEquals("NORMAL_REBOOT", bugreport.getLastKmsg().getEvents().get(0).getCategory()); - } - - /** - * Test that a kernel reset boot triggers a kernel reset event and no unknown reason. - */ - public void testParse_bootreason_prop_bad() { - List lines = Arrays.asList( - "========================================================", - "== dumpstate: 1999-01-01 02:03:04", - "========================================================", - "------ SYSTEM PROPERTIES ------", - "[ro.boot.bootreason]: [hw_reset]", - ""); - BugreportItem bugreport = new BugreportParser().parse(lines); - assertNotNull(bugreport.getLastKmsg()); - assertEquals(1, bugreport.getLastKmsg().getEvents().size()); - assertEquals("Last boot reason: hw_reset", - bugreport.getLastKmsg().getEvents().get(0).getStack()); - assertEquals("KERNEL_RESET", bugreport.getLastKmsg().getEvents().get(0).getCategory()); - assertEquals("", bugreport.getLastKmsg().getEvents().get(0).getPreamble()); - assertEquals(0.0, bugreport.getLastKmsg().getEvents().get(0).getEventTime()); - assertEquals(0.0, bugreport.getLastKmsg().getStartTime()); - assertEquals(0.0, bugreport.getLastKmsg().getStopTime()); - } - - /** - * Test that a kernel panic in the last kmsg and a kernel panic only triggers one kernel reset. - */ - public void testParse_bootreason_duplicate() { - List lines = Arrays.asList( - "========================================================", - "== dumpstate: 1999-01-01 02:03:04", - "========================================================", - "Command line: androidboot.bootreason=hw_reset", - "------ SYSTEM PROPERTIES ------", - "[ro.boot.bootreason]: [hw_reset]", - "", - "------ LAST KMSG (/proc/last_kmsg) ------", - "[ 0.000000] Initializing cgroup subsys cpu", - "[ 16.203491] Kernel panic", - ""); - BugreportItem bugreport = new BugreportParser().parse(lines); - assertNotNull(bugreport.getLastKmsg()); - assertEquals(1, bugreport.getLastKmsg().getEvents().size()); - assertEquals("Kernel panic", bugreport.getLastKmsg().getEvents().get(0).getStack()); - assertEquals("KERNEL_RESET", bugreport.getLastKmsg().getEvents().get(0).getCategory()); - } - - /** - * Test that the trace is set correctly if there is only one ANR. - */ - public void testSetAnrTrace_single() { - List lines = Arrays.asList( - "========================================================", - "== dumpstate: 2012-04-25 20:45:10", - "========================================================", - "------ SYSTEM LOG (logcat -v threadtime -d *:v) ------", - "04-25 17:17:08.445 312 366 E ActivityManager: ANR (application not responding) in process: com.android.package", - "04-25 17:17:08.445 312 366 E ActivityManager: Reason: keyDispatchingTimedOut", - "04-25 17:17:08.445 312 366 E ActivityManager: Load: 0.71 / 0.83 / 0.51", - "04-25 17:17:08.445 312 366 E ActivityManager: 33% TOTAL: 21% user + 11% kernel + 0.3% iowait", - "", - "------ VM TRACES AT LAST ANR (/data/anr/traces.txt: 2012-04-25 17:17:08) ------", - "", - "----- pid 2887 at 2012-04-25 17:17:08 -----", - "Cmd line: com.android.package", - "", - "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)", - " at class.method2(Class.java:2)", - " at class.method2(Class.java:2)", - "", - "----- end 2887 -----", - ""); - - List expectedStack = Arrays.asList( - "\"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)", - " at class.method2(Class.java:2)", - " at class.method2(Class.java:2)"); - - BugreportItem bugreport = new BugreportParser().parse(lines); - - assertNotNull(bugreport.getSystemLog()); - assertEquals(1, bugreport.getSystemLog().getAnrs().size()); - assertEquals(ArrayUtil.join("\n", expectedStack), - bugreport.getSystemLog().getAnrs().get(0).getTrace()); - } - - /** - * Test that the trace is set correctly if there are multiple ANRs. - */ - public void testSetAnrTrace_multiple() { - List lines = Arrays.asList( - "========================================================", - "== dumpstate: 2012-04-25 20:45:10", - "========================================================", - "------ SYSTEM LOG (logcat -v threadtime -d *:v) ------", - "04-25 17:17:08.445 312 366 E ActivityManager: ANR (application not responding) in process: com.android.package", - "04-25 17:17:08.445 312 366 E ActivityManager: Reason: keyDispatchingTimedOut", - "04-25 17:17:08.445 312 366 E ActivityManager: Load: 0.71 / 0.83 / 0.51", - "04-25 17:17:08.445 312 366 E ActivityManager: 33% TOTAL: 21% user + 11% kernel + 0.3% iowait", - "04-25 17:18:08.445 312 366 E ActivityManager: ANR (application not responding) in process: com.android.package", - "04-25 17:18:08.445 312 366 E ActivityManager: Reason: keyDispatchingTimedOut", - "04-25 17:18:08.445 312 366 E ActivityManager: Load: 0.71 / 0.83 / 0.51", - "04-25 17:18:08.445 312 366 E ActivityManager: 33% TOTAL: 21% user + 11% kernel + 0.3% iowait", - "04-25 17:19:08.445 312 366 E ActivityManager: ANR (application not responding) in process: com.android.different.pacakge", - "04-25 17:19:08.445 312 366 E ActivityManager: Reason: keyDispatchingTimedOut", - "04-25 17:19:08.445 312 366 E ActivityManager: Load: 0.71 / 0.83 / 0.51", - "04-25 17:19:08.445 312 366 E ActivityManager: 33% TOTAL: 21% user + 11% kernel + 0.3% iowait", - "", - "------ VM TRACES AT LAST ANR (/data/anr/traces.txt: 2012-04-25 17:18:08) ------", - "", - "----- pid 2887 at 2012-04-25 17:17:08 -----", - "Cmd line: com.android.package", - "", - "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)", - " at class.method2(Class.java:2)", - " at class.method2(Class.java:2)", - "", - "----- end 2887 -----", - ""); - - List expectedStack = Arrays.asList( - "\"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)", - " at class.method2(Class.java:2)", - " at class.method2(Class.java:2)"); - - BugreportItem bugreport = new BugreportParser().parse(lines); - - assertNotNull(bugreport.getSystemLog()); - assertEquals(3, bugreport.getSystemLog().getAnrs().size()); - assertNull(bugreport.getSystemLog().getAnrs().get(0).getTrace()); - assertEquals(ArrayUtil.join("\n", expectedStack), - bugreport.getSystemLog().getAnrs().get(1).getTrace()); - assertNull(bugreport.getSystemLog().getAnrs().get(2).getTrace()); - } - - /** - * Test that the trace is set correctly if there is not traces file. - */ - public void testSetAnrTrace_no_traces() { - List lines = Arrays.asList( - "========================================================", - "== dumpstate: 2012-04-25 20:45:10", - "========================================================", - "------ SYSTEM LOG (logcat -v threadtime -d *:v) ------", - "04-25 17:17:08.445 312 366 E ActivityManager: ANR (application not responding) in process: com.android.package", - "04-25 17:17:08.445 312 366 E ActivityManager: Reason: keyDispatchingTimedOut", - "04-25 17:17:08.445 312 366 E ActivityManager: Load: 0.71 / 0.83 / 0.51", - "04-25 17:17:08.445 312 366 E ActivityManager: 33% TOTAL: 21% user + 11% kernel + 0.3% iowait", - "", - "*** NO ANR VM TRACES FILE (/data/anr/traces.txt): No such file or directory", - ""); - - BugreportItem bugreport = new BugreportParser().parse(lines); - - assertNotNull(bugreport.getSystemLog()); - assertEquals(1, bugreport.getSystemLog().getAnrs().size()); - assertNull(bugreport.getSystemLog().getAnrs().get(0).getTrace()); - } - - /** - * Add a test that ensures that the "new" style of stack dumping works. Traces aren't written to - * a global trace file. Instead, each ANR event is written to a separate trace file (note the - * "/data/anr/anr_4376042170248254515" instead of "/data/anr/traces.txt"). - */ - public void testAnrTraces_not_global_traceFile() { - List lines = - Arrays.asList( - "========================================================", - "== dumpstate: 2017-06-12 16:46:29", - "========================================================", - "------ SYSTEM LOG (logcat -v threadtime -v printable -v uid -d *:v) ------", - "--------- beginning of main ", - "02-18 04:26:31.829 logd 468 468 W auditd : type=2000 audit(0.0:1): initialized", - "02-18 04:26:33.783 logd 468 468 I auditd : type=1403 audit(0.0:2): policy loaded auid=4294967295 ses=4294967295", - "02-18 04:26:33.783 logd 468 468 W auditd : type=1404 audit(0.0:3): enforcing=1 old_enforcing=0 auid=4294967295 ses=4294967295", - "06-12 16:45:47.426 1000 1050 1124 E ActivityManager: ANR in com.example.android.helloactivity (com.example.android.helloactivity/.HelloActivity)", - "06-12 16:45:47.426 1000 1050 1124 E ActivityManager: PID: 7176", - "06-12 16:45:47.426 1000 1050 1124 E ActivityManager: Reason: Input dispatching timed out (Waiting because no window has focus but there is a focused application that may eventually add a window when it finishes starting up.)", - "06-12 16:45:47.426 1000 1050 1124 E ActivityManager: Load: 6.85 / 7.07 / 5.31", - "06-12 16:45:47.426 1000 1050 1124 E ActivityManager: CPU usage from 235647ms to 0ms ago (2017-06-12 16:41:49.415 to 2017-06-12 16:45:45.062):", - "06-12 16:45:47.426 1000 1050 1124 E ActivityManager: 7.7% 1848/com.ustwo.lwp: 4% user + 3.7% kernel / faults: 157 minor", - "06-12 16:45:47.426 1000 1050 1124 E ActivityManager: 7.7% 2536/com.google.android.googlequicksearchbox:search: 5.6% user + 2.1% kernel / faults: 195 minor", - "06-12 16:45:47.426 1000 1050 1124 E ActivityManager: 7.2% 1050/system_server: 4.5% user + 2.6% kernel / faults: 27117 minor ", - "06-12 16:45:47.426 1000 1050 1124 E ActivityManager: 5.3% 489/surfaceflinger: 2.9% user + 2.3% kernel / faults: 15 minor ", - "", - "------ VM TRACES AT LAST ANR (/data/anr/anr_4376042170248254515: 2017-06-12 16:45:47) ------", - "", - "----- pid 7176 at 2017-06-12 16:45:45 -----", - "Cmd line: com.example.android.helloactivity", - "", - "DALVIK THREADS:", - "(mutexes: tll=0 tsl=0 tscl=0 ghl=0)", - "", - "\"main\" daemon prio=5 tid=5 Waiting", - " | group=\"system\" sCount=1 dsCount=0 flags=1 obj=0x140805e8 self=0x7caf4bf400", - " | sysTid=7184 nice=4 cgrp=default sched=0/0 handle=0x7c9b4e44f0", - " | state=S schedstat=( 507031 579062 19 ) utm=0 stm=0 core=3 HZ=100", - " | stack=0x7c9b3e2000-0x7c9b3e4000 stackSize=1037KB", - " | held mutexes=", - " at java.lang.Object.wait(Native method)", - " - waiting on <0x0281f7b7> (a java.lang.Class)", - " at java.lang.Daemons$ReferenceQueueDaemon.runInternal(Daemons.java:178)", - " - locked <0x0281f7b7> (a java.lang.Class)", - " at java.lang.Daemons$Daemon.run(Daemons.java:103)", - " at java.lang.Thread.run(Thread.java:764)", - "", - "----- end 7176 -----"); - - // NOTE: The parser only extracts the main thread from the traces. - List expectedStack = - Arrays.asList( - "\"main\" daemon prio=5 tid=5 Waiting", - " | group=\"system\" sCount=1 dsCount=0 flags=1 obj=0x140805e8 self=0x7caf4bf400", - " | sysTid=7184 nice=4 cgrp=default sched=0/0 handle=0x7c9b4e44f0", - " | state=S schedstat=( 507031 579062 19 ) utm=0 stm=0 core=3 HZ=100", - " | stack=0x7c9b3e2000-0x7c9b3e4000 stackSize=1037KB", - " | held mutexes=", - " at java.lang.Object.wait(Native method)", - " - waiting on <0x0281f7b7> (a java.lang.Class)", - " at java.lang.Daemons$ReferenceQueueDaemon.runInternal(Daemons.java:178)", - " - locked <0x0281f7b7> (a java.lang.Class)", - " at java.lang.Daemons$Daemon.run(Daemons.java:103)", - " at java.lang.Thread.run(Thread.java:764)"); - - BugreportItem bugreport = new BugreportParser().parse(lines); - assertNotNull(bugreport.getSystemLog()); - assertEquals(1, bugreport.getSystemLog().getAnrs().size()); - assertEquals( - ArrayUtil.join("\n", expectedStack), - bugreport.getSystemLog().getAnrs().get(0).getTrace()); - } - - /** - * Test that missing sections in bugreport are set to {@code null}, not empty {@link IItem}s. - */ - public void testNoSections() { - List lines = Arrays.asList( - "========================================================", - "== dumpstate: 2012-04-25 20:45:10", - "========================================================"); - - BugreportItem bugreport = new BugreportParser().parse(lines); - assertNotNull(bugreport); - assertNull(bugreport.getDumpsys()); - assertNull(bugreport.getKernelLog()); - assertNull(bugreport.getMemInfo()); - assertNull(bugreport.getProcrank()); - assertNull(bugreport.getSystemLog()); - assertNull(bugreport.getSystemProps()); - assertNull(bugreport.getTop()); - assertNotNull(bugreport.getLastKmsg()); - List events = bugreport.getLastKmsg().getMiscEvents( - KernelLogParser.KERNEL_RESET); - assertEquals(events.size(), 1); - assertEquals(events.get(0).getStack(), "Unknown reason"); - - lines = Arrays.asList( - "========================================================", - "== dumpstate: 2012-04-25 20:45:10", - "========================================================", - "", - "------ DUMPSYS (dumpsys) ------", - "", - "------ KERNEL LOG (dmesg) ------", - "", - "------ LAST KMSG (/proc/last_kmsg) ------", - "", - "------ MEMORY INFO (/proc/meminfo) ------", - "", - "------ PROCRANK (procrank) ------", - "", - "------ SYSTEM LOG (logcat -v threadtime -d *:v) ------", - "", - "------ SYSTEM PROPERTIES ------", - "", - "------ CPU INFO (top -n 1 -d 1 -m 30 -t) ------", - ""); - - bugreport = new BugreportParser().parse(lines); - assertNotNull(bugreport); - assertNotNull(bugreport.getDumpsys()); - assertNull(bugreport.getKernelLog()); - assertNull(bugreport.getMemInfo()); - assertNull(bugreport.getProcrank()); - assertNull(bugreport.getSystemLog()); - assertNull(bugreport.getSystemProps()); - assertNull(bugreport.getTop()); - assertNotNull(bugreport.getLastKmsg()); - events = bugreport.getLastKmsg().getMiscEvents(KernelLogParser.KERNEL_RESET); - assertEquals(events.size(), 1); - assertEquals(events.get(0).getStack(), "Unknown reason"); - } - - /** - * Test that section headers are correctly parsed. - */ - public void testSectionHeader() { - List lines = - Arrays.asList( - "========================================================", - "== dumpstate: 2012-04-25 20:45:10", - "========================================================", - "------ DUMPSYS (dumpsys) ------", - "DUMP OF SERVICE SurfaceFlinger:", - "--DrmDisplayCompositor[0]: num_frames=1456 num_ms=475440 fps=3.06243", - "---- DrmDisplayCompositor Layers: num=3", - "------ DrmDisplayCompositor Layer: plane=17 crtc=20 crtc[x/y/w/h]=0/0/2560/1800", - "------ DrmDisplayCompositor Layer: plane=21 disabled", - "------ DrmDisplayCompositor Layer: plane=22 disabled", - "DUMP OF SERVICE batterystats:", - "Battery History (0% used, 1636 used of 256KB, 15 strings using 794):", - " 0 (15) RESET:TIME: 1970-01-10-06-23-28", - " +45s702ms (2) 001 80080000 volt=4187", - " +1m15s525ms (2) 001 80080000 temp=299 volt=4155", - "Statistics since last charged:", - " Time on battery: 1h 5m 2s 4ms (9%) realtime, 1h 5m 2s 4ms (9%) uptime", - " Time on battery screen off: 1h 4m 5s 8ms (9%) realtime, 1h 4m 5s 8ms (9%) uptime", - " All kernel wake locks:", - " Kernel Wake lock PowerManagerService.WakeLocks: 5m 10s 6ms (2 times) realtime", - " Kernel Wake lock msm_serial_hs_rx: 2m 13s 612ms (258 times) realtime", - "", - " All partial wake locks:", - " Wake lock 1001 ProxyController: 1h 4m 47s 565ms (4 times) realtime", - " Wake lock 1013 AudioMix: 1s 979ms (3 times) realtime", - "", - " All wakeup reasons:", - " Wakeup reason 2:bcmsdh_sdmmc:2:qcom,smd:2:msmgio: 1m 5s 4ms (2 times) realtime", - " Wakeup reason 2:qcom,smd-rpm:2:fc4c.qcom,spmi: 7m 1s 914ms (7 times) realtime", - "DUMP OF SERVICE package:", - "Package [com.google.android.calculator] (e075c9d):", - " use rId=10071", - " secondaryCpuAbi=null", - " versionCode=73000302 minSdk=10000 targetSdk=10000", - " versionName=7.3 (3821978)", - " splits=[base]", - "DUMP OF SERVICE procstats:", - "COMMITTED STATS FROM 2015-09-30-07-44-54:", - " * system / 1000 / v23:", - " TOTAL: 100% (118MB-118MB-118MB/71MB-71MB-71MB over 1)", - " Persistent: 100% (118MB-118MB-118MB/71MB-71MB-71MB over 1)", - " * com.android.phone / 1001 / v23:", - " TOTAL: 6.7%", - " Persistent: 6.7%", - ""); - BugreportItem bugreport = new BugreportParser().parse(lines); - assertNotNull(bugreport.getDumpsys()); - assertNotNull(bugreport.getDumpsys().getBatteryStats()); - assertNotNull(bugreport.getDumpsys().getPackageStats()); - assertNotNull(bugreport.getDumpsys().getProcStats()); - } - - /** - * Test that an empty input returns {@code null}. - */ - public void testEmptyInput() { - BugreportItem item = new BugreportParser().parse(Arrays.asList("")); - assertNull(item); - } - - /** - * Test that app names from logcat events are populated by matching the logcat PIDs with the - * PIDs from the logcat. - */ - public void testSetAppsFromProcrank() { - List lines = Arrays.asList( - "========================================================", - "== dumpstate: 2012-04-25 20:45:10", - "========================================================", - "------ PROCRANK (procrank) ------", - " PID Vss Rss Pss Uss cmdline", - " 3064 87136K 81684K 52829K 50012K com.android.package1", - " 3066 87136K 81684K 52829K 50012K com.android.package2", - " ------ ------ ------", - " 203624K 163604K TOTAL", - "RAM: 731448K total, 415804K free, 9016K buffers, 108548K cached", - "[procrank: 1.6s elapsed]", - "------ SYSTEM LOG (logcat -v threadtime -d *:v) ------", - "04-25 09:55:47.799 3064 3082 E AndroidRuntime: java.lang.Exception", - "04-25 09:55:47.799 3064 3082 E AndroidRuntime: \tat class.method1(Class.java:1)", - "04-25 09:55:47.799 3064 3082 E AndroidRuntime: \tat class.method2(Class.java:2)", - "04-25 09:55:47.799 3064 3082 E AndroidRuntime: \tat class.method3(Class.java:3)", - "04-25 09:55:47.799 3065 3083 E AndroidRuntime: java.lang.Exception", - "04-25 09:55:47.799 3065 3083 E AndroidRuntime: \tat class.method1(Class.java:1)", - "04-25 09:55:47.799 3065 3083 E AndroidRuntime: \tat class.method2(Class.java:2)", - "04-25 09:55:47.799 3065 3083 E AndroidRuntime: \tat class.method3(Class.java:3)", - "04-25 09:55:47.799 3065 3084 E AndroidRuntime: FATAL EXCEPTION: main", - "04-25 09:55:47.799 3066 3084 E AndroidRuntime: Process: com.android.package3, PID: 1234", - "04-25 09:55:47.799 3066 3084 E AndroidRuntime: java.lang.Exception", - "04-25 09:55:47.799 3066 3084 E AndroidRuntime: \tat class.method1(Class.java:1)", - "04-25 09:55:47.799 3066 3084 E AndroidRuntime: \tat class.method2(Class.java:2)", - "04-25 09:55:47.799 3066 3084 E AndroidRuntime: \tat class.method3(Class.java:3)"); - - BugreportItem bugreport = new BugreportParser().parse(lines); - assertNotNull(bugreport.getSystemLog()); - assertEquals(3, bugreport.getSystemLog().getJavaCrashes().size()); - assertEquals("com.android.package1", - bugreport.getSystemLog().getJavaCrashes().get(0).getApp()); - assertNull(bugreport.getSystemLog().getJavaCrashes().get(1).getApp()); - assertEquals("com.android.package3", - bugreport.getSystemLog().getJavaCrashes().get(2).getApp()); - } - - /** - * Some Android devices refer to SYSTEM LOG as MAIN LOG. Check that parser recognizes this - * alternate syntax. - */ - public void testSystemLogAsMainLog() { - List lines = Arrays.asList( - "------ MAIN LOG (logcat -b main -b system -v threadtime -d *:v) ------", - "--------- beginning of /dev/log/system", - "12-11 19:48:07.945 1484 1508 D BatteryService: update start"); - BugreportItem bugreport = new BugreportParser().parse(lines); - assertNotNull(bugreport.getSystemLog()); - } - - /** - * Some Android devices refer to SYSTEM LOG as MAIN AND SYSTEM LOG. Check that parser - * recognizes this alternate syntax. - */ - public void testSystemAndMainLog() { - List lines = Arrays.asList( - "------ MAIN AND SYSTEM LOG (logcat -b main -b system -v threadtime -d *:v) ------", - "--------- beginning of /dev/log/system", - "12-17 15:15:12.877 1994 2019 D UiModeManager: updateConfigurationLocked: "); - BugreportItem bugreport = new BugreportParser().parse(lines); - assertNotNull(bugreport.getSystemLog()); - } - - private Date parseTime(String timeStr) throws ParseException { - DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS"); - return formatter.parse(timeStr); - } -} diff --git a/tests/src/com/android/loganalysis/parser/CompactMemInfoParserTest.java b/tests/src/com/android/loganalysis/parser/CompactMemInfoParserTest.java deleted file mode 100644 index ed4b39b..0000000 --- a/tests/src/com/android/loganalysis/parser/CompactMemInfoParserTest.java +++ /dev/null @@ -1,205 +0,0 @@ -/* - * Copyright (C) 2014 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.CompactMemInfoItem; - -import junit.framework.TestCase; - -import org.json.JSONArray; -import org.json.JSONException; -import org.json.JSONObject; - -import java.util.Arrays; -import java.util.List; - -public class CompactMemInfoParserTest extends TestCase { - - public void testSingleProcLineWithSwapHasActivities() { - List input = Arrays.asList("proc,cached,com.google.android.youtube1,2964,19345,1005,a"); - - CompactMemInfoItem item = new CompactMemInfoParser().parse(input); - - assertEquals(1, item.getPids().size()); - assertEquals("com.google.android.youtube1", item.getName(2964)); - assertEquals(19345, item.getPss(2964)); - assertEquals(1005, item.getSwap(2964)); - assertEquals("cached", item.getType(2964)); - assertEquals(true, item.hasActivities(2964)); - } - - public void testSingleProcLineWithoutSwapHasActivities() { - List input = Arrays.asList("proc,cached,com.google.android.youtube,2964,19345,a"); - - CompactMemInfoItem item = new CompactMemInfoParser().parse(input); - - assertEquals(1, item.getPids().size()); - assertEquals("com.google.android.youtube", item.getName(2964)); - assertEquals(19345, item.getPss(2964)); - assertEquals(0, item.getSwap(2964)); - assertEquals("cached", item.getType(2964)); - assertEquals(true, item.hasActivities(2964)); - } - - - public void testSingleProcLineWithoutSwapNoActivities() { - List input = Arrays.asList("proc,cached,com.google.android.youtube,2964,19345,e"); - - CompactMemInfoItem item = new CompactMemInfoParser().parse(input); - - assertEquals(1, item.getPids().size()); - assertEquals("com.google.android.youtube", item.getName(2964)); - assertEquals(19345, item.getPss(2964)); - assertEquals(0, item.getSwap(2964)); - assertEquals("cached", item.getType(2964)); - assertEquals(false, item.hasActivities(2964)); - } - - public void testSingleLostRamLine() { - List input = Arrays.asList("lostram,1005"); - CompactMemInfoItem item = new CompactMemInfoParser().parse(input); - assertEquals(1005, item.getLostRam()); - } - - public void testSingleRamLine() { - List input = Arrays.asList("ram,2866484,1221694,1112777"); - CompactMemInfoItem item = new CompactMemInfoParser().parse(input); - assertEquals(1221694, item.getFreeRam()); - } - - public void testSingleZramLine() { - List input = Arrays.asList("zram,5800,520908,491632"); - CompactMemInfoItem item = new CompactMemInfoParser().parse(input); - assertEquals(5800, item.getTotalZram()); - assertEquals(491632, item.getFreeSwapZram()); - } - - public void testSingleTuningLine() { - // With specific configuration - List input1 = Arrays.asList("tuning,192,512,322560,high-end-gfx"); - CompactMemInfoItem item1 = new CompactMemInfoParser().parse(input1); - assertEquals(322560, item1.getTuningLevel()); - // Without specific configuration - List input2 = Arrays.asList("tuning,193,513,322561"); - CompactMemInfoItem item2 = new CompactMemInfoParser().parse(input2); - assertEquals(322561, item2.getTuningLevel()); - } - - public void testSomeMalformedLines() { - List input = - Arrays.asList( - "proc,cached,com.google.android.youtube,a,b,e", - "proc,cached,com.google.android.youtube,2964,c,e", - "proc,cached,com.google.android.youtube,2964,e", - "proc,cached,com.google.android.youtube,2964,19345,a,e", - "lostram,a,1000", - "lostram,1000,a", - "ram,123,345", - "ram,123,345,abc", - "ram,123,345,456,678", - "ram,123,345,456,abc", - "zram,123,345", - "zram,123,345,abc", - "zram,123,345,456,678", - "zram,123,345,456,abc", - "tuning,123,345", - "tuning,123,345,abc"); - - CompactMemInfoItem item = new CompactMemInfoParser().parse(input); - - assertEquals(0, item.getPids().size()); - } - - public void testMultipleLines() { - List input = - Arrays.asList( - "proc,cached,com.google.android.youtube,2964,19345,123,e", - "proc,cached,com.google.android.apps.plus,2877,9604,N/A,e", - "proc,cached,com.google.android.apps.magazines,2009,20111,N/A,e", - "proc,cached,com.google.android.apps.walletnfcrel,10790,11164,100,e", - "proc,cached,com.google.android.incallui,3410,9491,N/A,e", - "lostram,1005", - "ram,2866484,1221694,1112777", - "zram,5800,520908,491632", - "tuning,193,513,322561"); - - CompactMemInfoItem item = new CompactMemInfoParser().parse(input); - - assertEquals(5, item.getPids().size()); - assertEquals("com.google.android.youtube", item.getName(2964)); - assertEquals(19345, item.getPss(2964)); - assertEquals(123, item.getSwap(2964)); - assertEquals("cached", item.getType(2964)); - assertEquals(false, item.hasActivities(2964)); - - assertEquals(1005, item.getLostRam()); - assertEquals(1221694, item.getFreeRam()); - assertEquals(5800, item.getTotalZram()); - assertEquals(491632, item.getFreeSwapZram()); - assertEquals(322561, item.getTuningLevel()); - } - - public void testSkipNonProcLines() { - // Skip lines which does not start with proc - - List input = Arrays.asList( - "oom,cached,141357", - "proc,cached,com.google.android.youtube,2964,19345,54321,e", - "proc,cached,com.google.android.apps.plus,2877,9604,4321,e", - "proc,cached,com.google.android.apps.magazines,2009,20111,321,e", - "proc,cached,com.google.android.apps.walletnfcrel,10790,11164,21,e", - "proc,cached,com.google.android.incallui,3410,9491,1,e", - "cat,Native,63169"); - - CompactMemInfoItem item = new CompactMemInfoParser().parse(input); - - assertEquals(5, item.getPids().size()); - assertEquals("com.google.android.youtube", item.getName(2964)); - assertEquals(19345, item.getPss(2964)); - assertEquals(54321, item.getSwap(2964)); - assertEquals("cached", item.getType(2964)); - assertEquals(false, item.hasActivities(2964)); - } - - public void testJson() throws JSONException { - List input = - Arrays.asList( - "oom,cached,141357", - "proc,cached,com.google.android.youtube,2964,19345,N/A,e", - "proc,cached,com.google.android.apps.plus,2877,9604,50,e", - "proc,cached,com.google.android.apps.magazines,2009,20111,100,e", - "proc,cached,com.google.android.apps.walletnfcrel,10790,11164,0,e", - "proc,cached,com.google.android.incallui,3410,9491,500,e", - "lostram,1005", - "ram,2866484,1221694,1112777", - "zram,5800,520908,491632", - "tuning,193,513,322561", - "cat,Native,63169"); - - CompactMemInfoItem item = new CompactMemInfoParser().parse(input); - JSONObject json = item.toJson(); - assertNotNull(json); - - JSONArray processes = json.getJSONArray("processes"); - assertEquals(5, processes.length()); - - assertEquals(1005, (long)json.get("lostRam")); - assertEquals(1221694, (long) json.get("freeRam")); - assertEquals(5800, (long) json.get("totalZram")); - assertEquals(491632, (long) json.get("freeSwapZram")); - assertEquals(322561, (long) json.get("tuningLevel")); - } -} diff --git a/tests/src/com/android/loganalysis/parser/CpuInfoParserTest.java b/tests/src/com/android/loganalysis/parser/CpuInfoParserTest.java deleted file mode 100644 index 196f6a2..0000000 --- a/tests/src/com/android/loganalysis/parser/CpuInfoParserTest.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (C) 2015 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.CpuInfoItem; - -import junit.framework.TestCase; - -import java.util.Arrays; -import java.util.List; - -public class CpuInfoParserTest extends TestCase { - - public void testSingleLine() { - List input = Arrays.asList(" 0.1% 170/surfaceflinger: 0% user + 0% kernel"); - - CpuInfoItem item = new CpuInfoParser().parse(input); - - assertEquals(1, item.getPids().size()); - assertEquals("surfaceflinger", item.getName(170)); - assertEquals(0.1, item.getPercent(170), 0.0001); - } - - public void testMultipleLines() { - List input = Arrays.asList( - "CPU usage from 35935ms to 26370ms ago:", - " 57% 489/system_server: 37% user + 20% kernel / faults: 39754 minor 57 major", - " 34% 853/com.google.android.leanbacklauncher: 30% user + 4.6% kernel / faults: 7838 minor 14 major", - " 15% 19463/com.google.android.videos: 11% user + 3.3% kernel / faults: 21603 minor 141 major", - " 8.2% 170/surfaceflinger: 3.4% user + 4.8% kernel / faults: 1 minor"); - CpuInfoItem item = new CpuInfoParser().parse(input); - - assertEquals(4, item.getPids().size()); - assertEquals("system_server", item.getName(489)); - assertEquals(57.0, item.getPercent(489), 0.0001); - assertEquals("surfaceflinger", item.getName(170)); - assertEquals(8.2, item.getPercent(170), 0.0001); - } - -} - diff --git a/tests/src/com/android/loganalysis/parser/DmesgParserTest.java b/tests/src/com/android/loganalysis/parser/DmesgParserTest.java deleted file mode 100644 index e4ea7af..0000000 --- a/tests/src/com/android/loganalysis/parser/DmesgParserTest.java +++ /dev/null @@ -1,317 +0,0 @@ -/* - * Copyright (C) 2016 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.DmesgActionInfoItem; -import com.android.loganalysis.item.DmesgItem; -import com.android.loganalysis.item.DmesgServiceInfoItem; -import com.android.loganalysis.item.DmesgStageInfoItem; -import com.android.loganalysis.item.DmesgModuleInfoItem; -import java.io.BufferedReader; -import java.io.ByteArrayInputStream; -import java.io.IOException; -import java.io.InputStreamReader; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import junit.framework.TestCase; - -/** - * Unit tests for {@link DmesgParser}. - */ -public class DmesgParserTest extends TestCase { - - private static final String BOOT_ANIMATION = "bootanim"; - private static final String NETD = "netd"; - private static final String FOO = "foo"; - private static final String BAR = "bar"; - private static final String TOTAL_MODULE = "TOTAL_MODULE"; - private static final String[] LINES = - new String[] { - "[ 0.370107] init: Loading module /lib/modules/foo.ko with args ''", - "[ 0.372497] init: Loaded kernel module /lib/modules/foo.ko", - "[ 0.372500] init: Loading module /lib/modules/bar.ko with args ''", - "[ 1.115467] init: Loaded 198 kernel modules took 748 ms", - "[ 2.471163] init: Wait for property 'apexd.status=ready' took 403ms", - "[ 3.786943] ueventd: Coldboot took 0.701291 seconds", - "[ 22.962730] init: starting service 'bootanim'...", - "[ 23.252321] init: starting service 'netd'...", - "[ 29.331069] ipa-wan ipa_wwan_ioctl:1428 dev(rmnet_data0) register to IPA", - "[ 32.182592] ueventd: fixup /sys/devices/virtual/input/poll_delay 0 1004 660", - "[ 35.642666] SELinux: initialized (dev fuse, type fuse), uses genfs_contexts", - "[ 39.855818] init: Service 'bootanim' (pid 588) exited with status 0", - "[ 41.665818] init: init first stage started!", - "[ 44.942872] init: processing action (early-init) from (/init.rc:13)", - "[ 47.233446] init: processing action (set_mmap_rnd_bits) from (:0)", - "[ 47.240083] init: processing action (set_kptr_restrict) from (:0)", - "[ 47.245778] init: processing action (keychord_init) from (:0)", - "[ 52.361049] init: processing action (persist.sys.usb.config=* boot) from" - + " (:0)", - "[ 52.361108] init: processing action (enable_property_trigger) from (:0)", - "[ 52.361313] init: processing action (security.perf_harden=1) from" - + " (/init.rc:677)", - "[ 52.361495] init: processing action (ro.debuggable=1) from (/init.rc:700)", - "[ 58.298293] init: processing action (sys.boot_completed=1)", - "[ 59.331069] ipa-wan ipa_wwan_ioctl:1428 dev(rmnet_data0) register to IPA", - "[ 62.182592] ueventd: fixup /sys/devices/virtual/input/poll_delay 0 1004 660", - "[ 65.642666] SELinux: initialized (dev fuse, type fuse), uses genfs_contexts", - "[ 69.855818] init: Service 'bootanim' (pid 588) exited with status 0" - }; - - private static final Map EXPECTED_SERVICE_INFO_ITEMS = - getExpectedServiceInfoItems(); - - private static final List EXPECTED_STAGE_INFO_ITEMS = - getExpectedStageInfoItems(); - - private static final List EXPECTED_ACTION_INFO_ITEMS = - getExpectedActionInfoItems(); - - private static final Map EXPECTED_MODULE_INFO_ITEMS = - getExpectedModuleInfoItems(); - - /** - * Test for empty dmesg logs passed to the DmesgParser - */ - public void testEmptyDmesgLog() throws IOException { - String[] lines = new String[] {""}; - try (BufferedReader bufferedReader = new BufferedReader(new InputStreamReader( - new ByteArrayInputStream(String.join("\n", lines).getBytes())))) { - DmesgParser dmesgParser = new DmesgParser(); - dmesgParser.parseInfo(bufferedReader); - assertEquals("Service info items list should be empty", 0, - dmesgParser.getServiceInfoItems().size()); - } - } - - /** - * Test for complete dmesg logs passed as list of strings - */ - public void testCompleteDmesgLog_passedAsList() { - - DmesgParser dmesgParser = new DmesgParser(); - DmesgItem actualDmesgItem = dmesgParser.parse(Arrays.asList(LINES)); - - assertEquals("Service info items list size should be 2", 2, - dmesgParser.getServiceInfoItems().size()); - assertEquals("Stage info items list size should be 3",3, - dmesgParser.getStageInfoItems().size()); - assertEquals("Action info items list size should be 9",9, - dmesgParser.getActionInfoItems().size()); - assertEquals( - "Module info items list size should be 3", - 3, - dmesgParser.getModuleInfoItems().size()); - - assertEquals(EXPECTED_SERVICE_INFO_ITEMS, actualDmesgItem.getServiceInfoItems()); - assertEquals(EXPECTED_STAGE_INFO_ITEMS, actualDmesgItem.getStageInfoItems()); - assertEquals(EXPECTED_ACTION_INFO_ITEMS, actualDmesgItem.getActionInfoItems()); - assertEquals(EXPECTED_MODULE_INFO_ITEMS, actualDmesgItem.getModuleInfoItems()); - } - - /** - * Test for complete dmesg logs passed as buffered input - */ - public void testCompleteDmesgLog_passedAsBufferedInput() throws IOException { - try (BufferedReader bufferedReader = new BufferedReader(new InputStreamReader( - new ByteArrayInputStream(String.join("\n", LINES).getBytes())))) { - DmesgParser dmesgParser = new DmesgParser(); - dmesgParser.parseInfo(bufferedReader); - assertEquals("Service info items list size should be 2", 2, - dmesgParser.getServiceInfoItems().size()); - assertEquals("Stage info items list size should be 3", 3, - dmesgParser.getStageInfoItems().size()); - assertEquals("Action info items list size should be 9",9, - dmesgParser.getActionInfoItems().size()); - assertEquals( - "Module info items list size should be 3", - 3, - dmesgParser.getModuleInfoItems().size()); - } - } - - /** - * Test service which logs both the start and end time - */ - public void testCompleteServiceInfo() { - DmesgParser dmesgParser = new DmesgParser(); - for (String line : LINES) { - dmesgParser.parseServiceInfo(line); - } - - assertEquals("There should be two service infos", 2, - dmesgParser.getServiceInfoItems().size()); - assertEquals(EXPECTED_SERVICE_INFO_ITEMS, dmesgParser.getServiceInfoItems()); - } - - /** - * Test service which logs only the start time - */ - public void testStartServiceInfo() { - DmesgParser dmesgParser = new DmesgParser(); - for (String line : LINES) { - dmesgParser.parseServiceInfo(line); - } - List serviceInfoItems = new ArrayList<>( - dmesgParser.getServiceInfoItems().values()); - assertEquals("There should be exactly two service infos", 2, serviceInfoItems.size()); - assertEquals("Service name is not bootanim", BOOT_ANIMATION, - serviceInfoItems.get(0).getServiceName()); - assertEquals("Service name is not netd", NETD, serviceInfoItems.get(1).getServiceName()); - } - - /** - * Test multiple service info parsed correctly and stored in the same order logged in - * the file. - */ - public void testMultipleServiceInfo() { - DmesgParser dmesgParser = new DmesgParser(); - for (String line : LINES) { - dmesgParser.parseServiceInfo(line); - } - assertEquals("There should be exactly two service info", 2, - dmesgParser.getServiceInfoItems().size()); - assertEquals(EXPECTED_SERVICE_INFO_ITEMS, dmesgParser.getServiceInfoItems()); - } - - /** - * Test invalid patterns on the start and exit service logs - */ - public void testInvalidServiceLogs() { - // Added space at the end of the start and exit of service logs to make it invalid - String[] lines = new String[] { - "[ 22.962730] init: starting service 'bootanim'... ", - "[ 23.252321] init: starting service 'netd'... ", - "[ 29.331069] ipa-wan ipa_wwan_ioctl:1428 dev(rmnet_data0) register to IPA", - "[ 32.182592] ueventd: fixup /sys/devices/virtual/input/poll_delay 0 1004 660", - "[ 35.642666] SELinux: initialized (dev fuse, type fuse), uses genfs_contexts", - "[ 39.855818] init: Service 'bootanim' (pid 588) exited with status 0 "}; - DmesgParser dmesgParser = new DmesgParser(); - for (String line : lines) { - dmesgParser.parseServiceInfo(line); - } - List serviceInfoItems = new ArrayList<>( - dmesgParser.getServiceInfoItems().values()); - assertEquals("No service info should be available", 0, serviceInfoItems.size()); - } - - /** - * Test init stages' start time logs - */ - public void testCompleteStageInfo() { - DmesgParser dmesgParser = new DmesgParser(); - for (String line : LINES) { - dmesgParser.parseStageInfo(line); - } - List stageInfoItems = dmesgParser.getStageInfoItems(); - assertEquals(3, stageInfoItems.size()); - assertEquals(EXPECTED_STAGE_INFO_ITEMS, stageInfoItems); - } - - /** Test processing action start time logs */ - public void testCompleteActionInfo() { - DmesgParser dmesgParser = new DmesgParser(); - for (String line : LINES) { - dmesgParser.parseActionInfo(line); - } - List actualActionInfoItems = dmesgParser.getActionInfoItems(); - assertEquals(9, actualActionInfoItems.size()); - assertEquals(EXPECTED_ACTION_INFO_ITEMS, actualActionInfoItems); - } - - /** Test incomplete module loaded pattern */ - public void testIncompleteModuleInfo() { - DmesgParser dmesgParser = new DmesgParser(); - for (String line : LINES) { - dmesgParser.parseModuleInfo(line); - } - List actualModuleInfoItems = - new ArrayList<>(dmesgParser.getModuleInfoItems().values()); - assertEquals(EXPECTED_MODULE_INFO_ITEMS, dmesgParser.getModuleInfoItems()); - assertEquals(3, actualModuleInfoItems.size()); - assertEquals( - "Duration should be -1L", - Long.valueOf(-1L), - actualModuleInfoItems.get(0).getModuleDuration()); - } - - private static List getExpectedActionInfoItems() { - return Arrays.asList( - new DmesgActionInfoItem("/init.rc:13", "early-init", 44942L), - new DmesgActionInfoItem(":0", "set_mmap_rnd_bits", 47233L), - new DmesgActionInfoItem(":0", "set_kptr_restrict", 47240L), - new DmesgActionInfoItem(":0", "keychord_init", 47245L), - new DmesgActionInfoItem( - ":0", "persist.sys.usb.config=* boot", 52361L), - new DmesgActionInfoItem(":0", "enable_property_trigger", 52361L), - new DmesgActionInfoItem("/init.rc:677", "security.perf_harden=1", 52361L), - new DmesgActionInfoItem("/init.rc:700", "ro.debuggable=1", 52361L), - new DmesgActionInfoItem(null, "sys.boot_completed=1", 58298L)); - } - - private static List getExpectedStageInfoItems() { - return Arrays.asList( - new DmesgStageInfoItem("init_Wait for property 'apexd.status=ready'", null, 403L), - new DmesgStageInfoItem("ueventd_Coldboot", null, 701L), - new DmesgStageInfoItem("first", 41665L, null)); - } - - private static Map getExpectedServiceInfoItems() { - Map serviceInfoItemsMap = new HashMap<>(); - DmesgServiceInfoItem bootanimServiceInfoItem = new DmesgServiceInfoItem(); - bootanimServiceInfoItem.setServiceName(BOOT_ANIMATION); - bootanimServiceInfoItem.setStartTime(22962L); - bootanimServiceInfoItem.setEndTime(69855L); - - DmesgServiceInfoItem netdServiceInfoItem = new DmesgServiceInfoItem(); - netdServiceInfoItem.setServiceName(NETD); - netdServiceInfoItem.setStartTime(23252L); - - serviceInfoItemsMap.put(BOOT_ANIMATION, bootanimServiceInfoItem); - serviceInfoItemsMap.put(NETD, netdServiceInfoItem); - - return serviceInfoItemsMap; - } - - private static Map getExpectedModuleInfoItems() { - Map moduleInfoItemsMap = new HashMap<>(); - DmesgModuleInfoItem fooModuleInfo = new DmesgModuleInfoItem(); - fooModuleInfo.setModuleName(FOO); - fooModuleInfo.setStartTime(370L); - fooModuleInfo.setEndTime(372L); - - DmesgModuleInfoItem barModuleInfo = new DmesgModuleInfoItem(); - barModuleInfo.setModuleName(BAR); - barModuleInfo.setStartTime(372L); - - DmesgModuleInfoItem totalInfoItem = new DmesgModuleInfoItem(); - totalInfoItem.setModuleName(TOTAL_MODULE); - totalInfoItem.setModuleCount("198"); - totalInfoItem.setModuleDuration(748L); - - moduleInfoItemsMap.put(FOO, fooModuleInfo); - moduleInfoItemsMap.put(BAR, barModuleInfo); - moduleInfoItemsMap.put(TOTAL_MODULE, totalInfoItem); - - return moduleInfoItemsMap; - } -} diff --git a/tests/src/com/android/loganalysis/parser/DumpsysBatteryStatsParserTest.java b/tests/src/com/android/loganalysis/parser/DumpsysBatteryStatsParserTest.java deleted file mode 100644 index e96491a..0000000 --- a/tests/src/com/android/loganalysis/parser/DumpsysBatteryStatsParserTest.java +++ /dev/null @@ -1,153 +0,0 @@ -/* - * Copyright (C) 2015 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.DumpsysBatteryStatsItem; - -import junit.framework.TestCase; - -import java.util.Arrays; -import java.util.List; - -/** - * Unit tests for {@link DumpsysBatteryStatsParser} - */ -public class DumpsysBatteryStatsParserTest extends TestCase { - - /** - * Test that normal input is parsed. - */ - public void testBatteryStatsParser() { - List inputBlock = Arrays.asList( - "Battery History (37% used, 95KB used of 256KB, 166 strings using 15KB):", - " 0 (9) RESET:TIME: 2014-12-09-11-33-29", - " +1s067ms (1) 100 c0500020 -wifi_full_lock -wifi_scan", - " +3s297ms (2) 100 80400020 -wake_lock -screen", - " +30m02s075ms (1) 100 c0500020 wifi_signal_strength=4 wifi_suppl=completed", - " +30m03s012ms (2) 099 c0500020 temp=306 volt=4217", - " +33m48s967ms (1) 099 f8400020 +wifi_scan", - " +33m49s335ms (2) 098 f0400020 temp=324 -wifi_scan", - "Statistics since last charge:", - " Time on battery: 2h 21m 5s 622ms (12.0%) realtime, 7m 54s 146ms (0.7%) uptime", - " Time on battery screen off: 2h 5m 55s 3ms (1%) realtime, 7m 4s 5ms (7%) uptime", - " Total run time: 19h 38m 43s 650ms realtime, 17h 25m 32s 175ms uptime", - " All kernel wake locks:", - " Kernel Wake lock PowerManagerService.WakeLocks: 1h 3m 50s 5ms (8 times) realtime", - " Kernel Wake lock event0-2656 : 3m 49s 268ms (2399 times) realtime", - " Kernel Wake lock wlan_wd_wake: 3m 34s 639ms (1751 times) realtime", - " Kernel Wake lock wlan_rx_wake: 3m 19s 887ms (225 times) realtime", - " Kernel Wake lock wlan_tx_wake: 2m 19s 887ms (225 times) realtime", - " Kernel Wake lock tx_wake: 1m 19s 887ms (225 times) realtime", - " ", - " All partial wake locks:", - " Wake lock u0a7 NlpWakeLock: 8m 13s 203ms (1479 times) realtime", - " Wake lock u0a7 NlpCollectorWakeLock: 6m 29s 18ms (238 times) realtime", - " Wake lock u0a7 GCM_CONN_ALARM: 6m 8s 587ms (239 times) realtime", - " Wake lock 1000 *alarm*: 5m 11s 316ms (1469 times) realtime", - " Wake lock u10 xxx: 4m 11s 316ms (1469 times) realtime", - " Wake lock u30 cst: 2m 11s 316ms (1469 times) realtime", - " ", - " All wakeup reasons:", - " Wakeup reason 200:qcom,smd-rpm:222:fc4: 11m 49s 332ms (0 times) realtime", - " Wakeup reason 200:qcom,smd-rpm: 48s 45ms (0 times) realtime", - " Wakeup reason 2:qcom,smd-rpm:2:f0.qm,mm:22:fc4mi: 3s 417ms (0 times) realtime", - " Wakeup reason 188:qcom,smd-adsp:200:qcom,smd-rpm: 1s 656ms (0 times) realtime", - " Wakeup reason 58:qcom,smsm-modem:2:qcom,smd-rpm: 6m 16s 1ms (5 times) realtime", - " Wakeup reason 57:qcom,smd-modem:200:qcom,smd-rpm: 40s 995ms (0 times) realtime", - " Wakeup reason unknown: 8s 455ms (0 times) realtime", - " Wakeup reason 9:bcmsdh_sdmmc:2:qcomd-rpm:240:mso: 8m 5s 9ms (0 times) realtime", - " ", - " 0:", - " User activity: 2 other", - " Wake lock SCREEN_FROZEN realtime", - " Sensor 0: 9s 908ms realtime (1 times)", - " Sensor 1: 9s 997ms realtime (1 times)", - " Foreground for: 2h 21m 5s 622ms", - " Apk android:", - " 24 wakeup alarms", - " u0a9:", - " Mobile network: 8.1KB received, 1.6KB sent (packets 291 received, 342 sent)", - " Mobile radio active: 3m 43s 890ms (34.2%) 39x @ 354 mspp", - " Sensor 2: 12m 13s 15ms realtime (5 times)", - " Sensor 32: (not used)", - " Sensor 35: (not used)"); - - DumpsysBatteryStatsItem batteryStats = new DumpsysBatteryStatsParser().parse(inputBlock); - assertNotNull(batteryStats.getBatteryStatsSummaryItem()); - assertNotNull(batteryStats.getDetailedBatteryStatsItem()); - } - - public void testBatteryStatsWithNoKB() { - List inputBlock = Arrays.asList( - "Battery History (37% used, 95 used of 256KB, 166 strings using 15):", - " 0 (9) RESET:TIME: 2014-12-09-11-33-29", - " +1s067ms (1) 100 c0500020 -wifi_full_lock -wifi_scan", - " +3s297ms (2) 100 80400020 -wake_lock -screen", - " +30m02s075ms (1) 100 c0500020 wifi_signal_strength=4 wifi_suppl=completed", - " +30m03s012ms (2) 099 c0500020 temp=306 volt=4217", - " +33m48s967ms (1) 099 f8400020 +wifi_scan", - " +33m49s335ms (2) 098 f0400020 temp=324 -wifi_scan", - "Statistics since last charge:", - " Time on battery: 2h 21m 5s 622ms (12.0%) realtime, 7m 54s 146ms (0.7%) uptime", - " Time on battery screen off: 2h 5m 55s 3ms (1%) realtime, 7m 4s 5ms (7%) uptime", - " Total run time: 19h 38m 43s 650ms realtime, 17h 25m 32s 175ms uptime", - " All kernel wake locks:", - " Kernel Wake lock PowerManagerService.WakeLocks: 1h 3m 50s 5ms (8 times) realtime", - " Kernel Wake lock event0-2656 : 3m 49s 268ms (2399 times) realtime", - " Kernel Wake lock wlan_wd_wake: 3m 34s 639ms (1751 times) realtime", - " Kernel Wake lock wlan_rx_wake: 3m 19s 887ms (225 times) realtime", - " Kernel Wake lock wlan_tx_wake: 2m 19s 887ms (225 times) realtime", - " Kernel Wake lock tx_wake: 1m 19s 887ms (225 times) realtime", - " ", - " All partial wake locks:", - " Wake lock u0a7 NlpWakeLock: 8m 13s 203ms (1479 times) realtime", - " Wake lock u0a7 NlpCollectorWakeLock: 6m 29s 18ms (238 times) realtime", - " Wake lock u0a7 GCM_CONN_ALARM: 6m 8s 587ms (239 times) realtime", - " Wake lock 1000 *alarm*: 5m 11s 316ms (1469 times) realtime", - " Wake lock u10 xxx: 4m 11s 316ms (1469 times) realtime", - " Wake lock u30 cst: 2m 11s 316ms (1469 times) realtime", - " ", - " All wakeup reasons:", - " Wakeup reason 200:qcom,smd-rpm:222:fc4: 11m 49s 332ms (0 times) realtime", - " Wakeup reason 200:qcom,smd-rpm: 48s 45ms (0 times) realtime", - " Wakeup reason 2:qcom,smd-rpm:2:f0.qm,mm:22:fc4mi: 3s 417ms (0 times) realtime", - " Wakeup reason 188:qcom,smd-adsp:200:qcom,smd-rpm: 1s 656ms (0 times) realtime", - " Wakeup reason 58:qcom,smsm-modem:2:qcom,smd-rpm: 6m 16s 1ms (5 times) realtime", - " Wakeup reason 57:qcom,smd-modem:200:qcom,smd-rpm: 40s 995ms (0 times) realtime", - " Wakeup reason unknown: 8s 455ms (0 times) realtime", - " Wakeup reason 9:bcmsdh_sdmmc:2:qcomd-rpm:240:mso: 8m 5s 9ms (0 times) realtime", - " ", - " 0:", - " User activity: 2 other", - " Wake lock SCREEN_FROZEN realtime", - " Sensor 0: 9s 908ms realtime (1 times)", - " Sensor 1: 9s 997ms realtime (1 times)", - " Foreground for: 2h 21m 5s 622ms", - " Apk android:", - " 24 wakeup alarms", - " u0a9:", - " Mobile network: 8.1KB received, 1.6KB sent (packets 291 received, 342 sent)", - " Mobile radio active: 3m 43s 890ms (34.2%) 39x @ 354 mspp", - " Sensor 2: 12m 13s 15ms realtime (5 times)", - " Sensor 32: (not used)", - " Sensor 35: (not used)"); - - DumpsysBatteryStatsItem batteryStats = new DumpsysBatteryStatsParser().parse(inputBlock); - assertNotNull(batteryStats.getBatteryStatsSummaryItem()); - assertNotNull(batteryStats.getDetailedBatteryStatsItem()); - } -} - diff --git a/tests/src/com/android/loganalysis/parser/DumpsysPackageStatsParserTest.java b/tests/src/com/android/loganalysis/parser/DumpsysPackageStatsParserTest.java deleted file mode 100644 index ee15b78..0000000 --- a/tests/src/com/android/loganalysis/parser/DumpsysPackageStatsParserTest.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright (C) 2017 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.AppVersionItem; -import com.android.loganalysis.item.DumpsysPackageStatsItem; - -import junit.framework.TestCase; - -import java.util.Arrays; -import java.util.List; - -/** Unit tests for {@link DumpsysPackageStatsParser} */ -public class DumpsysPackageStatsParserTest extends TestCase { - - /** Test that normal input is parsed. */ - public void testDumpsysPackageStatsParser() { - List inputBlock = - Arrays.asList( - "DUMP OF SERVICE package:", - "Package [com.google.android.calculator] (e075c9d):", - " userId=10071", - " secondaryCpuAbi=null", - " versionCode=73000302 minSdk=10000 targetSdk=10000", - " versionName=7.3 (3821978)", - " splits=[base]", - " Package [com.google.android.googlequicksearchbox] (607929e):", - " userId=10037", - " pkg=Package{af43294 com.google.android.googlequicksearchbox}", - " versionCode=300734793 minSdk=10000 targetSdk=10000", - " versionName=6.16.35.26.arm64", - " apkSigningVersion=2"); - - final DumpsysPackageStatsItem packagestats = - new DumpsysPackageStatsParser().parse(inputBlock); - assertEquals(2, packagestats.size()); - assertNotNull(packagestats.get("com.google.android.calculator")); - final AppVersionItem calculator = packagestats.get("com.google.android.calculator"); - assertEquals(73000302, calculator.getVersionCode()); - assertEquals("7.3 (3821978)", calculator.getVersionName()); - assertNotNull(packagestats.get("com.google.android.googlequicksearchbox")); - final AppVersionItem googlequicksearchbox = - packagestats.get("com.google.android.googlequicksearchbox"); - assertEquals(300734793, googlequicksearchbox.getVersionCode()); - assertEquals("6.16.35.26.arm64", googlequicksearchbox.getVersionName()); - } -} diff --git a/tests/src/com/android/loganalysis/parser/DumpsysParserTest.java b/tests/src/com/android/loganalysis/parser/DumpsysParserTest.java deleted file mode 100644 index 020c724..0000000 --- a/tests/src/com/android/loganalysis/parser/DumpsysParserTest.java +++ /dev/null @@ -1,143 +0,0 @@ -/* - * Copyright (C) 2015 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.DumpsysItem; - -import junit.framework.TestCase; - -import java.util.Arrays; -import java.util.List; - -/** - * Unit tests for {@link DumpsysParser} - */ -public class DumpsysParserTest extends TestCase { - - /** - * Test that normal input is parsed. - */ - public void testDumpsysParser() { - List inputBlock = - Arrays.asList( - "DUMP OF SERVICE batterystats:", - "Battery History (37% used, 95KB used of 256KB, 166 strings using 15KB):", - " 0 (9) RESET:TIME: 2014-12-09-11-33-29", - " +1s067ms (1) 100 c0500020 -wifi_full_lock -wifi_scan", - " +3s297ms (2) 100 80400020 -wake_lock -screen", - " +30m02s075ms (1) 100 c0500020 wifi_signal_strength=4 wifi_suppl=completed", - " +30m03s012ms (2) 099 c0500020 temp=306 volt=4217", - " +33m48s967ms (1) 099 f8400020 +wifi_scan", - " +33m49s335ms (2) 098 f0400020 temp=324 -wifi_scan", - "Statistics since last charge:", - " Time on battery: 2h 21m 5s 622ms (12.0%) realtime, 7m 54s 146ms (0.7%) uptime", - " Time on battery screen off: 2h 5m 55s 3ms (1%) realtime, 7m 4s 5ms (7%) uptime", - " Total run time: 19h 38m 43s 650ms realtime, 17h 25m 32s 175ms uptime", - " All kernel wake locks:", - " Kernel Wake lock PowerManagerService.WakeLocks: 1h 3m 50s 5ms (8 times) realtime", - " Kernel Wake lock event0-2656 : 3m 49s 268ms (2399 times) realtime", - " Kernel Wake lock wlan_wd_wake: 3m 34s 639ms (1751 times) realtime", - " Kernel Wake lock wlan_rx_wake: 3m 19s 887ms (225 times) realtime", - " Kernel Wake lock wlan_tx_wake: 2m 19s 887ms (225 times) realtime", - " Kernel Wake lock tx_wake: 1m 19s 887ms (225 times) realtime", - " ", - " All partial wake locks:", - " Wake lock u0a7 NlpWakeLock: 8m 13s 203ms (1479 times) realtime", - " Wake lock u0a7 NlpCollectorWakeLock: 6m 29s 18ms (238 times) realtime", - " Wake lock u0a7 GCM_CONN_ALARM: 6m 8s 587ms (239 times) realtime", - " Wake lock 1000 *alarm*: 5m 11s 316ms (1469 times) realtime", - " Wake lock u10 xxx: 4m 11s 316ms (1469 times) realtime", - " Wake lock u30 cst: 2m 11s 316ms (1469 times) realtime", - " ", - " All wakeup reasons:", - " Wakeup reason 200:qcom,smd-rpm:222:fc4: 11m 49s 332ms (0 times) realtime", - " Wakeup reason 200:qcom,smd-rpm: 48s 45ms (0 times) realtime", - " Wakeup reason 2:qcom,smd-rpm:2:f0.qm,mm:22:fc4mi: 3s 417ms (0 times) realtime", - " Wakeup reason 188:qcom,smd-adsp:200:qcom,smd-rpm: 1s 656ms (0 times) realtime", - " Wakeup reason 58:qcom,smsm-modem:2:qcom,smd-rpm: 6m 16s 1ms (5 times) realtime", - " Wakeup reason 57:qcom,smd-modem:200:qcom,smd-rpm: 40s 995ms (0 times) realtime", - " Wakeup reason unknown: 8s 455ms (0 times) realtime", - " Wakeup reason 9:bcmsdh_sdmmc:2:qcomd-rpm:240:mso: 8m 5s 9ms (0 times) realtime", - " ", - " 0:", - " User activity: 2 other", - " Wake lock SCREEN_FROZEN realtime", - " Sensor 0: 9s 908ms realtime (1 times)", - " Sensor 1: 9s 997ms realtime (1 times)", - " Foreground for: 2h 21m 5s 622ms", - " Apk android:", - " 24 wakeup alarms", - " u0a9:", - " Mobile network: 8.1KB received, 1.6KB sent (packets 291 received, 342 sent)", - " Mobile radio active: 3m 43s 890ms (34.2%) 39x @ 354 mspp", - " Sensor 2: 12m 13s 15ms realtime (5 times)", - " Sensor 32: (not used)", - " Sensor 35: (not used)", - "DUMP OF SERVICE package:", - "Package [com.google.android.calculator] (e075c9d):", - " userId=10071", - " secondaryCpuAbi=null", - " versionCode=73000302 minSdk=10000 targetSdk=10000", - " versionName=7.3 (3821978)", - " splits=[base]", - "Package [com.google.android.googlequicksearchbox] (607929e):", - " userId=10037", - " pkg=Package{af43294 com.google.android.googlequicksearchbox}", - " versionCode=300734793 minSdk=10000 targetSdk=10000", - " versionName=6.16.35.26.arm64", - " apkSigningVersion=2", - "DUMP OF SERVICE procstats:", - "COMMITTED STATS FROM 2015-03-20-02-01-02 (checked in):", - " * com.android.systemui / u0a22 / v22:", - " TOTAL: 100% (159MB-160MB-161MB/153MB-153MB-154MB over 13)", - " Persistent: 100% (159MB-160MB-161MB/153MB-153MB-154MB over 13)", - " * com.google.process.gapps / u0a9 / v22:", - " TOTAL: 100% (22MB-24MB-25MB/18MB-19MB-20MB over 13)", - " Imp Fg: 100% (22MB-24MB-25MB/18MB-19MB-20MB over 13)", - "DUMP OF SERVICE wifi:", - "Wi-Fi is enabled", - "rec[0]: time=10-09 00:25:16.737 processed=DefaultState org=DeviceActiveState " - + "dest= what=155654(0x26006)", - "mScreenOff true", - " rec[0]: time=10-08 16:49:55.034 processed=WatchdogEnabledState org=OnlineState " - + "dest=OnlineWatchState what=135170(0x21002)", - "rec[30]: time=10-08 13:06:50.379 processed=DriverStartedState org=ConnectedState " - + "dest= what=131143(0x20047) (1)CMD_START_SCAN rt=4720806/7884852 10013 51 " - + "ic=0 proc(ms):14 onGoing full started:1444334810368,11 cnt=24 rssi=-127 f=-1 " - + "sc=0 link=-1 tx=1.5, 1.7, 0.0 rx=8.4 fiv=20000 [on:3266 tx:65 rx:556 " - + "period:1268] from screen [on:266962 period:266959]", - "rec[357]: time=10-08 13:10:13.199 processed=DriverStartedState org=ConnectedState " - + "dest= what=131143(0x20047) (-2)CMD_START_SCAN rt=4923625/8087671 10013 " - + "175 ic=0 proc(ms):2 onGoing full started:1444335011199,1999 cnt=24 rssi=-127 " - + "f=-1 sc=0 link=-1 tx=8.4, 1.7, 0.0 rx=6.7 fiv=20000 [on:0 tx:0 rx:0 period:990]" - + "from screen [on:467747 period:469779]", - "WifiConfigStore - Log Begin ----", - "10-08 11:09:14.653 - Event [IFNAME=wlan0 CTRL-EVENT-SCAN-STARTED ]", - "10-08 13:06:29.489 - Event [IFNAME=wlan0 CTRL-EVENT-DISCONNECTED " - + "bssid=9c:1c:12:c3:d0:72 reason=0]", - "10-08 13:06:22.280 - Event [IFNAME=wlan0 CTRL-EVENT-SCAN-STARTED ]", - "10-08 13:06:25.363 - Event [IFNAME=wlan0 CTRL-EVENT-SCAN-STARTED ]", - "10-08 13:08:15.018 - Event [IFNAME=wlan0 CTRL-EVENT-DISCONNECTED " - + "bssid=9c:1c:12:e8:72:d2 reason=3 locally_generated=1]", - "10-08 13:08:15.324 - wlan0: 442:IFNAME=wlan0 ENABLE_NETWORK 0 -> true"); - - DumpsysItem dumpsys = new DumpsysParser().parse(inputBlock); - assertNotNull(dumpsys.getBatteryStats()); - assertNotNull(dumpsys.getPackageStats()); - assertNotNull(dumpsys.getProcStats()); - assertNotNull(dumpsys.getWifiStats()); - } -} diff --git a/tests/src/com/android/loganalysis/parser/DumpsysProcStatsParserTest.java b/tests/src/com/android/loganalysis/parser/DumpsysProcStatsParserTest.java deleted file mode 100644 index 27bb7a4..0000000 --- a/tests/src/com/android/loganalysis/parser/DumpsysProcStatsParserTest.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (C) 2015 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.DumpsysProcStatsItem; - -import junit.framework.TestCase; - -import java.util.Arrays; -import java.util.List; - -/** - * Unit tests for {@link DumpsysProcStatsParser} - */ -public class DumpsysProcStatsParserTest extends TestCase { - - /** - * Test that normal input is parsed. - */ - public void testDumpsysProcStatsParser() { - List inputBlock = Arrays.asList( - "COMMITTED STATS FROM 2015-03-20-02-01-02 (checked in):", - " * com.android.systemui / u0a22 / v22:", - " TOTAL: 100% (159MB-160MB-161MB/153MB-153MB-154MB over 13)", - " Persistent: 100% (159MB-160MB-161MB/153MB-153MB-154MB over 13)", - " * com.google.process.gapps / u0a9 / v22:", - " TOTAL: 100% (22MB-24MB-25MB/18MB-19MB-20MB over 13)", - " Imp Fg: 100% (22MB-24MB-25MB/18MB-19MB-20MB over 13)"); - - DumpsysProcStatsItem procstats = new DumpsysProcStatsParser().parse(inputBlock); - assertEquals("com.android.systemui", procstats.get("u0a22")); - assertEquals("com.google.process.gapps", procstats.get("u0a9")); - } -} - diff --git a/tests/src/com/android/loganalysis/parser/DumpsysProcessMeminfoParserTest.java b/tests/src/com/android/loganalysis/parser/DumpsysProcessMeminfoParserTest.java deleted file mode 100644 index b7042d3..0000000 --- a/tests/src/com/android/loganalysis/parser/DumpsysProcessMeminfoParserTest.java +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Copyright (C) 2018 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 static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; - -import com.android.loganalysis.item.DumpsysProcessMeminfoItem; - -import org.junit.Test; - -import java.util.Arrays; -import java.util.List; - -/** Unit tests for {@link DumpsysProcessMeminfoParser} */ -public class DumpsysProcessMeminfoParserTest { - private static final String TEST_INPUT = - "time,28506638,177086152\n" - + "4,938,system_server,11,22,N/A,44,0,0,N/A,0,0,0,N/A,0,27613,14013,176602," - + "218228,0,0,122860,122860,1512,1412,5740,8664,0,0,154924,154924,27568," - + "13972,11916,53456,0,0,123008,123008,0,0,0,0,0,0,0,0,Dalvik Other,3662,0," - + "104,0,3660,0,0,0,Stack,1576,0,8,0,1576,0,0,0,Cursor,0,0,0,0,0,0,0,0," - + "Ashmem,156,0,20,0,148,0,0,0,Gfx dev,100,0,48,0,76,0,0,0,Other dev,116,0," - + "164,0,0,96,0,0,.so mmap,7500,2680,3984,21864,904,2680,0,0,.jar mmap,0,0,0," - + "0,0,0,0,0,.apk mmap,72398,71448,0,11736,0,71448,0,0,.ttf mmap,0,0,0,0,0,0," - + "0,0,.dex mmap,76874,46000,0,83644,40,46000,0,0,.oat mmap,8127,2684,64," - + "26652,0,2684,0,0,.art mmap,1991,48,972,10004,1544,48,0,0,Other mmap,137,0," - + "44,1024,4,52,0,0,EGL mtrack,0,0,0,0,0,0,0,0,GL mtrack,111,222,333,444,555," - + "666,777,888,"; - - private static final String INVALID_TEST_INPUT = "RANDOM,TEST,DATA\n234235345345"; - - // Test that normal input is parsed - @Test - public void testDumpsysProcessMeminfoParser() { - List inputBlock = Arrays.asList(TEST_INPUT.split("\n")); - DumpsysProcessMeminfoItem dump = new DumpsysProcessMeminfoParser().parse(inputBlock); - assertEquals(938, dump.getPid()); - assertEquals("system_server", dump.getProcessName()); - assertEquals( - Long.valueOf(11L), - dump.get(DumpsysProcessMeminfoItem.NATIVE).get(DumpsysProcessMeminfoItem.MAX)); - assertEquals( - Long.valueOf(22L), - dump.get(DumpsysProcessMeminfoItem.DALVIK).get(DumpsysProcessMeminfoItem.MAX)); - assertFalse( - dump.get(DumpsysProcessMeminfoItem.OTHER) - .containsKey(DumpsysProcessMeminfoItem.MAX)); - assertEquals( - Long.valueOf(44L), - dump.get(DumpsysProcessMeminfoItem.TOTAL).get(DumpsysProcessMeminfoItem.MAX)); - assertEquals( - Long.valueOf(218228L), - dump.get(DumpsysProcessMeminfoItem.TOTAL).get(DumpsysProcessMeminfoItem.PSS)); - assertEquals( - Long.valueOf(3662L), dump.get("Dalvik Other").get(DumpsysProcessMeminfoItem.PSS)); - assertEquals(Long.valueOf(111L), dump.get("GL mtrack").get(DumpsysProcessMeminfoItem.PSS)); - assertEquals( - Long.valueOf(222L), - dump.get("GL mtrack").get(DumpsysProcessMeminfoItem.SWAPPABLE_PSS)); - assertEquals( - Long.valueOf(333L), - dump.get("GL mtrack").get(DumpsysProcessMeminfoItem.SHARED_DIRTY)); - assertEquals( - Long.valueOf(444L), - dump.get("GL mtrack").get(DumpsysProcessMeminfoItem.SHARED_CLEAN)); - assertEquals( - Long.valueOf(555L), - dump.get("GL mtrack").get(DumpsysProcessMeminfoItem.PRIVATE_DIRTY)); - assertEquals( - Long.valueOf(666L), - dump.get("GL mtrack").get(DumpsysProcessMeminfoItem.PRIVATE_CLEAN)); - assertEquals( - Long.valueOf(777L), - dump.get("GL mtrack").get(DumpsysProcessMeminfoItem.SWAPPED_OUT)); - assertEquals( - Long.valueOf(888L), - dump.get("GL mtrack").get(DumpsysProcessMeminfoItem.SWAPPED_OUT_PSS)); - } - - // Test that the parser does not crash on invalid input and returns empty data - @Test - public void testDumpsysProcessMeminfoParserInvalid() { - List inputBlock = Arrays.asList(INVALID_TEST_INPUT.split("\n")); - DumpsysProcessMeminfoItem dump = new DumpsysProcessMeminfoParser().parse(inputBlock); - assertNull(dump.getProcessName()); - assertTrue(dump.get(DumpsysProcessMeminfoItem.TOTAL).isEmpty()); - } -} diff --git a/tests/src/com/android/loganalysis/parser/DumpsysWifiStatsParserTest.java b/tests/src/com/android/loganalysis/parser/DumpsysWifiStatsParserTest.java deleted file mode 100644 index f52e432..0000000 --- a/tests/src/com/android/loganalysis/parser/DumpsysWifiStatsParserTest.java +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Copyright (C) 2016 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.DumpsysWifiStatsItem; - -import junit.framework.TestCase; - -import java.util.Arrays; -import java.util.List; - -/** - * Unit tests for {@link DumpsysWifiStatsParser} - */ -public class DumpsysWifiStatsParserTest extends TestCase { - - /** - * Test that normal input is parsed. - */ - public void testDumpsysWifiStatsParser() { - List inputBlock = Arrays.asList( - "Wi-Fi is enabled", - "rec[0]: time=10-09 00:25:16.737 processed=DefaultState org=DeviceActiveState " - + "dest= what=155654(0x26006)", - "mScreenOff true", - " rec[0]: time=10-08 16:49:55.034 processed=WatchdogEnabledState org=OnlineState " - + "dest=OnlineWatchState what=135170(0x21002)", - "rec[30]: time=10-08 13:06:50.379 processed=DriverStartedState org=ConnectedState " - + "dest= what=131143(0x20047) (1)CMD_START_SCAN rt=4720806/7884852 10013 51 " - + "ic=0 proc(ms):14 onGoing full started:1444334810368,11 cnt=24 rssi=-127 f=-1 " - + "sc=0 link=-1 tx=1.5, 1.7, 0.0 rx=8.4 fiv=20000 [on:3266 tx:65 rx:556 " - + "period:1268] from screen [on:266962 period:266959]", - "rec[357]: time=10-08 13:10:13.199 processed=DriverStartedState org=ConnectedState " - + "dest= what=131143(0x20047) (-2)CMD_START_SCAN rt=4923625/8087671 10013 " - + "175 ic=0 proc(ms):2 onGoing full started:1444335011199,1999 cnt=24 rssi=-127 " - + "f=-1 sc=0 link=-1 tx=8.4, 1.7, 0.0 rx=6.7 fiv=20000 [on:0 tx:0 rx:0 period:990] " - + "from screen [on:467747 period:469779]", - "WifiConfigStore - Log Begin ----", - "10-08 11:09:14.653 - Event [IFNAME=wlan0 CTRL-EVENT-SCAN-STARTED ]", - "10-08 13:06:29.489 - Event [IFNAME=wlan0 CTRL-EVENT-DISCONNECTED " - + "bssid=9c:1c:12:c3:d0:72 reason=0]", - "10-08 13:06:22.280 - Event [IFNAME=wlan0 CTRL-EVENT-SCAN-STARTED ]", - "10-08 13:06:25.363 - Event [IFNAME=wlan0 CTRL-EVENT-SCAN-STARTED ]", - "10-08 13:08:15.018 - Event [IFNAME=wlan0 CTRL-EVENT-DISCONNECTED " - + "bssid=9c:1c:12:e8:72:d2 reason=3 locally_generated=1]", - "10-08 13:08:15.324 - wlan0: 442:IFNAME=wlan0 ENABLE_NETWORK 0 -> true", - "01-21 13:17:23.1 - Event [IFNAME=wlan0 Trying to associate with SSID 'WL-power']", - "01-21 13:18:23.1 - Event [IFNAME=wlan0 Trying to associate with SSID 'WL-power']", - "01-21 13:18:23.1 - Event [IFNAME=wlan0 Trying to associate with SSID 'WL-power']"); - - DumpsysWifiStatsItem wifiStats = new DumpsysWifiStatsParser().parse(inputBlock); - assertEquals(2, wifiStats.getNumWifiDisconnects()); - assertEquals(3, wifiStats.getNumWifiScans()); - assertEquals(3, wifiStats.getNumWifiAssociations()); - } - - /** - * Test that input with no wifi disconnect and wifi scans. - */ - public void testDumpsysWifiStatsParser_no_wifi_scan_disconnect() { - List inputBlock = Arrays.asList( - "Wi-Fi is enabled", - "rec[0]: time=10-09 00:25:16.737 processed=DefaultState org=DeviceActiveState " - + "dest= what=155654(0x26006)", - "mScreenOff true", - " rec[0]: time=10-08 16:49:55.034 processed=WatchdogEnabledState org=OnlineState " - + "dest=OnlineWatchState what=135170(0x21002)", - "rec[30]: time=10-08 13:06:50.379 processed=DriverStartedState org=ConnectedState " - + "dest= what=131143(0x20047) (1)CMD_START_SCAN rt=4720806/7884852 10013 51 " - + "ic=0 proc(ms):14 onGoing full started:1444334810368,11 cnt=24 rssi=-127 f=-1 " - + "sc=0 link=-1 tx=1.5, 1.7, 0.0 rx=8.4 fiv=20000 [on:3266 tx:65 rx:556 " - + "period:1268] from screen [on:266962 period:266959]", - "rec[357]: time=10-08 13:10:13.199 processed=DriverStartedState org=ConnectedState " - + "dest= what=131143(0x20047) (-2)CMD_START_SCAN rt=4923625/8087671 10013 " - + "175 ic=0 proc(ms):2 onGoing full started:1444335011199,1999 cnt=24 rssi=-127 " - + "f=-1 sc=0 link=-1 tx=8.4, 1.7, 0.0 rx=6.7 fiv=20000 [on:0 tx:0 rx:0 period:990]" - + "from screen [on:467747 period:469779]", - "WifiConfigStore - Log Begin ----", - "10-08 13:07:37.777 - wlan0: 384:IFNAME=wlan0 ENABLE_NETWORK 4 -> true", - "10-08 13:07:37.789 - wlan0: 388:IFNAME=wlan0 SAVE_CONFIG -> true", - "10-08 13:08:15.065 - wlan0: 427:IFNAME=wlan0 SET ps 1 -> true", - "10-08 13:08:15.179 - wlan0: 432:IFNAME=wlan0 SET pno 1 -> true"); - - DumpsysWifiStatsItem wifiStats = new DumpsysWifiStatsParser().parse(inputBlock); - assertEquals(0, wifiStats.getNumWifiDisconnects()); - assertEquals(0, wifiStats.getNumWifiScans()); - assertEquals(0, wifiStats.getNumWifiAssociations()); - } -} - diff --git a/tests/src/com/android/loganalysis/parser/DvmLockSampleParserTest.java b/tests/src/com/android/loganalysis/parser/DvmLockSampleParserTest.java deleted file mode 100644 index cb85999..0000000 --- a/tests/src/com/android/loganalysis/parser/DvmLockSampleParserTest.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (C) 2014 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.DvmLockSampleItem; -import com.android.loganalysis.parser.DvmLockSampleParser; - -import junit.framework.TestCase; -import java.util.Arrays; -import java.util.List; - -public class DvmLockSampleParserTest extends TestCase { - - /** - * Sanity-check our DVM lock line parser against a single log line - */ - public void testSingleDvmLine() { - List input = Arrays.asList( - "[android.support.test.aupt,0,Instr: android.support.test.aupt,75," + - "AccessibilityCache.java,256,-,96,15]"); - - DvmLockSampleItem item = new DvmLockSampleParser().parse(input); - assertEquals("android.support.test.aupt", item.getAttribute(DvmLockSampleItem.PROCESS_NAME)); - assertEquals(Boolean.FALSE, item.getAttribute(DvmLockSampleItem.SENSITIVITY_FLAG)); - assertEquals("Instr: android.support.test.aupt", item.getAttribute(DvmLockSampleItem.WAITING_THREAD_NAME)); - assertEquals(75, item.getAttribute(DvmLockSampleItem.WAIT_TIME)); - assertEquals("AccessibilityCache.java", item.getAttribute(DvmLockSampleItem.WAITING_SOURCE_FILE)); - assertEquals(256, item.getAttribute(DvmLockSampleItem.WAITING_SOURCE_LINE)); - assertEquals("AccessibilityCache.java", item.getAttribute(DvmLockSampleItem.OWNER_FILE_NAME)); - assertEquals(96, item.getAttribute(DvmLockSampleItem.OWNER_ACQUIRE_SOURCE_LINE)); - assertEquals(15, item.getAttribute(DvmLockSampleItem.SAMPLE_PERCENTAGE)); - } -} diff --git a/tests/src/com/android/loganalysis/parser/EventsLogParserTest.java b/tests/src/com/android/loganalysis/parser/EventsLogParserTest.java deleted file mode 100644 index 6956d16..0000000 --- a/tests/src/com/android/loganalysis/parser/EventsLogParserTest.java +++ /dev/null @@ -1,260 +0,0 @@ -/* - * Copyright (C) 2016 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.LatencyItem; -import com.android.loganalysis.item.TransitionDelayItem; - -import junit.framework.TestCase; - -import java.io.BufferedReader; -import java.io.BufferedWriter; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileWriter; -import java.io.IOException; -import java.io.InputStreamReader; -import java.util.Arrays; -import java.util.List; - -/** - * Unit tests for {@link EventsLogParser}. - */ -public class EventsLogParserTest extends TestCase { - - private File mTempFile = null; - - @Override - protected void tearDown() throws Exception { - mTempFile.delete(); - } - - /** - * Test for empty events logs passed to the transition delay parser - */ - public void testEmptyEventsLog() throws IOException { - List lines = Arrays.asList(""); - List transitionItems = - new EventsLogParser().parseTransitionDelayInfo(readInputBuffer(getTempFile(lines))); - assertEquals("Transition Delay items list should be empty", 0,transitionItems.size()); - } - - /** - * Test for no transition delay info in the events log - */ - public void testNoTransitionDelayInfo() throws IOException { - List lines = Arrays - .asList( - "08-25 12:56:15.850 1152 8968 I am_focused_stack: [0,0,1,appDied setFocusedActivity]", - "08-25 12:56:15.850 1152 8968 I wm_task_moved: [6,1,1]", - "08-25 12:56:15.852 1152 8968 I am_focused_activity: [0,com.google.android.apps.nexuslauncher/.NexusLauncherActivity,appDied]", - "08-25 12:56:15.852 1152 8968 I wm_task_removed: [27,removeTask]", - "08-25 12:56:15.852 1152 8968 I wm_stack_removed: 1"); - List transitionItems = - new EventsLogParser().parseTransitionDelayInfo(readInputBuffer(getTempFile(lines))); - assertEquals("Transition Delay items list should be empty", 0, - transitionItems.size()); - } - - /** - * Test for Cold launch transition delay and starting window delay info - */ - public void testValidColdTransitionDelay() throws IOException { - List lines = Arrays - .asList("09-18 23:56:19.376 1140 1221 I sysui_multi_action: [319,51,321,50,322,190,325,670,757,761,758,7,759,1,806,com.google.android.calculator,871,com.android.calculator2.Calculator,904,com.google.android.apps.nexuslauncher,905,0,945,41]", - "09-18 23:56:19.376 1140 1221 I sysui_multi_action: [319,51,321,50,322,190,325,670,757,761,758,7,759,1,806,com.google.android.calculator,871,com.android.calculator2.Calculator,905,0,945,41]"); - List transitionItems = - new EventsLogParser().parseTransitionDelayInfo(readInputBuffer(getTempFile(lines))); - assertEquals("Startinng Window Delay items list should have two item", 2, - transitionItems.size()); - assertEquals("Component name not parsed correctly", - "com.google.android.calculator/com.android.calculator2.Calculator", - transitionItems.get(0).getComponentName()); - assertEquals("Transition delay is not parsed correctly", Long.valueOf(51), - transitionItems.get(0).getTransitionDelay()); - assertEquals("Starting window delay is not parsed correctly", Long.valueOf(50), - transitionItems.get(0).getStartingWindowDelay()); - assertEquals("Date and time is not parsed correctly", "09-18 23:56:19.376", - transitionItems.get(0).getDateTime()); - } - - /** - * Test for Hot launch transition delay and starting window delay info - */ - public void testValidHotTransitionDelay() throws IOException { - List lines = Arrays - .asList("09-18 23:56:19.376 1140 1221 I sysui_multi_action: [319,51,321,50,322,190,325,670,757,761,758,7,759,1,806,com.google.android.calculator,871,com.android.calculator2.Calculator,904,com.google.android.apps.nexuslauncher,905,0]", - "09-18 23:56:19.376 1140 1221 I sysui_multi_action: [319,51,321,50,322,190,325,670,757,761,758,7,759,1,806,com.google.android.calculator,871,com.android.calculator2.Calculator,905,0]", - "09-19 02:26:30.182 1143 1196 I sysui_multi_action: [319,87,322,75,325,212,757,761,758,9,759,2,806,com.google.android.apps.nexuslauncher,871,com.google.android.apps.nexuslauncher.NexusLauncherActivity,904,com.google.android.apps.nexuslauncher,905,0]", - "09-19 02:26:30.182 1143 1196 I sysui_multi_action: [319,87,322,75,325,212,757,761,758,9,759,2,806,com.google.android.apps.nexuslauncher,871,com.google.android.apps.nexuslauncher.NexusLauncherActivity,905,0]"); - List transitionItems = - new EventsLogParser().parseTransitionDelayInfo(readInputBuffer(getTempFile(lines))); - assertEquals("Transition Delay items list should have four item", 4, - transitionItems.size()); - assertEquals("Component name not parsed correctly", - "com.google.android.calculator/com.android.calculator2.Calculator", - transitionItems.get(0).getComponentName()); - assertEquals("Transition delay is not parsed correctly", Long.valueOf(51), - transitionItems.get(0).getTransitionDelay()); - assertEquals("Date is not parsed correctly", "09-18 23:56:19.376", - transitionItems.get(0).getDateTime()); - } - - /** - * Test for same app transition delay items order after parsing from the events log - */ - public void testTransitionDelayOrder() throws IOException { - List lines = Arrays - .asList("09-18 23:56:19.376 1140 1221 I sysui_multi_action: [319,51,321,59,322,190,325,670,757,761,758,7,759,1,806,com.google.android.calculator,871,com.android.calculator2.Calculator,904,com.google.android.apps.nexuslauncher,905,0,945,41]", - "09-18 23:59:18.380 1140 1221 I sysui_multi_action: [319,55,321,65,322,190,325,670,757,761,758,7,759,1,806,com.google.android.calculator,871,com.android.calculator2.Calculator,905,0,945,41]"); - List transitionItems = - new EventsLogParser().parseTransitionDelayInfo(readInputBuffer(getTempFile(lines))); - assertEquals("Transition Delay items list should have two items", 2, - transitionItems.size()); - assertEquals("Transition delay for the first item is not set correct", Long.valueOf(59), - transitionItems.get(0).getStartingWindowDelay()); - assertEquals("Transition delay for the second item is not set correct", Long.valueOf(65), - transitionItems.get(1).getStartingWindowDelay()); - } - - /** - * Test for two different different apps transition delay items - */ - public void testDifferentAppTransitionDelay() throws IOException { - List lines = Arrays - .asList("09-18 23:56:19.376 1140 1221 I sysui_multi_action: [319,51,321,50,322,190,325,670,757,761,758,7,759,1,806,com.google.android.calculator,871,com.android.calculator2.Calculator,904,com.google.android.apps.nexuslauncher,905,0]", - "09-19 02:26:30.182 1143 1196 I sysui_multi_action: [319,87,322,75,325,212,757,761,758,9,759,2,806,com.google.android.apps.nexuslauncher,871,com.google.android.apps.nexuslauncher.NexusLauncherActivity,904,com.google.android.apps.nexuslauncher,905,0]"); - List transitionItems = - new EventsLogParser().parseTransitionDelayInfo(readInputBuffer(getTempFile(lines))); - assertEquals("Transition Delay items list should have two items", 2, - transitionItems.size()); - assertEquals("Calculator is not the first transition delay item", - "com.google.android.calculator/com.android.calculator2.Calculator", - transitionItems.get(0).getComponentName()); - assertEquals("Maps is not the second transition delay item", - "com.google.android.apps.nexuslauncher/" - + "com.google.android.apps.nexuslauncher.NexusLauncherActivity", - transitionItems.get(1).getComponentName()); - } - - /** - * Test for invalid transition delay items pattern having different code. - */ - public void testInvalidTransitionPattern() throws IOException { - List lines = Arrays - .asList("01-02 08:11:58.691 934 986 I sysui_multi_action: a[319,48,322,82,325,84088,757,761,758,9,759,4,807,com.google.android.calculator,871,com.android.calculator2.Calculator,905,0]", - "01-02 08:12:03.639 934 970 I sysui_multi_action: [757,803,799,window_time_0,802,5]", - "01-02 08:12:10.849 934 986 I sysui_multi_action: 319,42,321,59,322,208,325,84100,757,761,758,9,759,4,806,com.google.android.apps.maps,871,com.google.android.maps.MapsActivity,905,0]", - "01-02 08:12:16.895 1446 1446 I sysui_multi_action: [757,803,799,overview_trigger_nav_btn,802,1]", - "01-02 08:12:16.895 1446 1446 I sysui_multi_action: [757,803,799,overview_source_app,802,1]", - "01-02 08:12:16.895 1446 1446 I sysui_multi_action: [757,804,799,overview_source_app_index,801,8,802,1]"); - List transitionItems = - new EventsLogParser().parseTransitionDelayInfo(readInputBuffer(getTempFile(lines))); - assertEquals("Transition Delay items list should be empty", 0, - transitionItems.size()); - } - - /** - * Test for valid latency item - */ - public void testValidLatencyInfo() throws IOException { - List lines = Arrays - .asList("08-25 13:01:19.412 1152 9031 I am_restart_activity: [com.google.android.gm/.ConversationListActivityGmail,0,85290699,38]", - "08-25 13:01:19.437 1152 1226 I sysui_action: [321,85]", - "08-25 13:01:19.437 1152 1226 I sysui_action: [320,1]", - "08-25 13:01:19.437 1152 1226 I sysui_action: [319,85]", - "08-25 12:56:15.850 1152 8968 I am_focused_stack: [0,0,1,appDied setFocusedActivity]", - "09-19 11:53:16.893 1080 1160 I sysui_latency: [1,50]"); - List latencyItems = - new EventsLogParser().parseLatencyInfo(readInputBuffer(getTempFile(lines))); - assertEquals("One latency item should present in the list", 1, latencyItems.size()); - assertEquals("Action Id is not correct", 1, latencyItems.get(0).getActionId()); - assertEquals("Delay is not correct", 50L, latencyItems.get(0).getDelay()); - } - - /** - * Test for empty delay info - */ - public void testInvalidLatencyInfo() throws IOException { - List lines = Arrays - .asList("08-25 13:01:19.412 1152 9031 I am_restart_activity: [com.google.android.gm/.ConversationListActivityGmail,0,85290699,38]", - "08-25 13:01:19.437 1152 1226 I sysui_action: [321,85]", - "08-25 13:01:19.437 1152 1226 I sysui_action: [320,1]", - "08-25 13:01:19.437 1152 1226 I sysui_action: [319,85]", - "08-25 12:56:15.850 1152 8968 I am_focused_stack: [0,0,1,appDied setFocusedActivity]", - "09-19 11:53:16.893 1080 1160 I sysui_latency: [1]"); - List latencyItems = - new EventsLogParser().parseLatencyInfo(readInputBuffer(getTempFile(lines))); - assertEquals("Latency items list should be empty", 0, latencyItems.size()); - } - - /** - * Test for empty latency info - */ - public void testEmptyLatencyInfo() throws IOException { - List lines = Arrays - .asList("08-25 13:01:19.412 1152 9031 I am_restart_activity: [com.google.android.gm/.ConversationListActivityGmail,0,85290699,38]", - "08-25 13:01:19.437 1152 1226 I sysui_action: [321,85]", - "08-25 13:01:19.437 1152 1226 I sysui_action: [320,1]", - "08-25 13:01:19.437 1152 1226 I sysui_action: [319,85]", - "08-25 12:56:15.850 1152 8968 I am_focused_stack: [0,0,1,appDied setFocusedActivity]", - "09-19 11:53:16.893 1080 1160 I sysui_latency: []"); - List latencyItems = - new EventsLogParser().parseLatencyInfo(readInputBuffer(getTempFile(lines))); - assertEquals("Latency items list should be empty", 0, latencyItems.size()); - } - - - /** - * Test for order of the latency items - */ - public void testLatencyInfoOrder() throws IOException { - List lines = Arrays - .asList("09-19 11:53:16.893 1080 1160 I sysui_latency: [1,50]", - "08-25 13:01:19.437 1152 1226 I sysui_action: [321,85]", - "08-25 13:01:19.437 1152 1226 I sysui_action: [320,1]", - "08-25 13:01:19.437 1152 1226 I sysui_action: [319,85]", - "08-25 12:56:15.850 1152 8968 I am_focused_stack: [0,0,1,appDied setFocusedActivity]", - "09-19 11:53:16.893 1080 1160 I sysui_latency: [2,100]"); - List latencyItems = - new EventsLogParser().parseLatencyInfo(readInputBuffer(getTempFile(lines))); - assertEquals("Latency list should have 2 items", 2, latencyItems.size()); - assertEquals("First latency id is not 1", 1, latencyItems.get(0).getActionId()); - assertEquals("Second latency id is not 2", 2, latencyItems.get(1).getActionId()); - } - - /** - * Write list of strings to file and use it for testing. - */ - public File getTempFile(List sampleEventsLogs) throws IOException { - mTempFile = File.createTempFile("events_logcat", ".txt"); - BufferedWriter out = new BufferedWriter(new FileWriter(mTempFile)); - for (String line : sampleEventsLogs) { - out.write(line); - out.newLine(); - } - out.close(); - return mTempFile; - } - - /** - * Reader to read the input from the given temp file - */ - public BufferedReader readInputBuffer(File tempFile) throws IOException { - return (new BufferedReader(new InputStreamReader(new FileInputStream(tempFile)))); - } -} diff --git a/tests/src/com/android/loganalysis/parser/GfxInfoParserTest.java b/tests/src/com/android/loganalysis/parser/GfxInfoParserTest.java deleted file mode 100644 index fcd053b..0000000 --- a/tests/src/com/android/loganalysis/parser/GfxInfoParserTest.java +++ /dev/null @@ -1,358 +0,0 @@ -/* - * Copyright (C) 2015 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.GfxInfoItem; - -import junit.framework.TestCase; - -import java.util.Arrays; -import java.util.List; - -public class GfxInfoParserTest extends TestCase { - - /** - * Tests gfxinfo output from M with single process. - */ - public void testSingleProcess() { - List input = Arrays.asList( - "** Graphics info for pid 853 [com.google.android.leanbacklauncher] **", - "", - "Stats since: 13370233957ns", - "Total frames rendered: 20391", - "Janky frames: 785 (3.85%)", - "90th percentile: 9ms", - "95th percentile: 14ms", - "99th percentile: 32ms", - "Number Missed Vsync: 155", - "Number High input latency: 0", - "Number Slow UI thread: 469", - "Number Slow bitmap uploads: 65", - "Number Slow issue draw commands: 153", - "", - "Caches:", - "Current memory usage / total memory usage (bytes):", - " TextureCache 16055224 / 50331648", - " LayerCache 0 / 33554432 (numLayers = 0)", - " Layers total 0 (numLayers = 0)", - " RenderBufferCache 0 / 2097152", - " GradientCache 0 / 838860", - " PathCache 0 / 25165824", - " TessellationCache 1048296 / 1048576", - " TextDropShadowCache 0 / 4194304", - " PatchCache 0 / 131072", - " FontRenderer 0 A8 524288 / 524288", - " FontRenderer 0 RGBA 0 / 0", - " FontRenderer 0 total 524288 / 524288", - "Other:", - " FboCache 0 / 0", - "Total memory usage:", - " 17627808 bytes, 16.81 MB", - "", - "Profile data in ms:", - "", - "\tcom.google.android.leanbacklauncher/com.google.android.leanbacklauncher.MainActivity/android.view.ViewRootImpl@8dc465 (visibility=8)", - "Stats since: 13370233957ns", - "Total frames rendered: 20391", - "Janky frames: 785 (3.85%)", - "90th percentile: 9ms", - "95th percentile: 14ms", - "99th percentile: 32ms", - "Number Missed Vsync: 155", - "Number High input latency: 0", - "Number Slow UI thread: 469", - "Number Slow bitmap uploads: 65", - "Number Slow issue draw commands: 153", - "", - "View hierarchy:", - "", - " com.google.android.leanbacklauncher/com.google.android.leanbacklauncher.MainActivity/android.view.ViewRootImpl@8dc465", - " 220 views, 177.61 kB of display lists", - "", - "", - "Total ViewRootImpl: 1", - "Total Views: 220", - "Total DisplayList: 177.61 kB"); - - GfxInfoItem item = new GfxInfoParser().parse(input); - - assertEquals(1, item.getPids().size()); - assertEquals("com.google.android.leanbacklauncher", item.getName(853)); - assertEquals(20391, item.getTotalFrames(853)); - assertEquals(785, item.getJankyFrames(853)); - assertEquals(9, item.getPrecentile90(853)); - assertEquals(14, item.getPrecentile95(853)); - assertEquals(32, item.getPrecentile99(853)); - } - - /** - * Test gfxinfo output from M with multiple processes. - */ - public void testMultipleProcesses() { - List input = Arrays.asList( - "Applications Graphics Acceleration Info:", - "Uptime: 6127679 Realtime: 6127679", - "", - "** Graphics info for pid 844 [com.google.android.leanbacklauncher] **", - "", - "Stats since: 12167093145ns", - "Total frames rendered: 1690", - "Janky frames: 125 (7.40%)", - "90th percentile: 13ms", - "95th percentile: 19ms", - "99th percentile: 48ms", - "Number Missed Vsync: 17", - "Number High input latency: 0", - "Number Slow UI thread: 32", - "Number Slow bitmap uploads: 20", - "Number Slow issue draw commands: 67", - "", - "Caches:", - "Current memory usage / total memory usage (bytes):", - " TextureCache 16550096 / 50331648", - " LayerCache 0 / 33554432 (numLayers = 0)", - " Layers total 0 (numLayers = 0)", - " RenderBufferCache 0 / 2097152", - " GradientCache 0 / 838860", - " PathCache 0 / 25165824", - " TessellationCache 350424 / 1048576", - " TextDropShadowCache 0 / 4194304", - " PatchCache 0 / 131072", - " FontRenderer 0 A8 524288 / 524288", - " FontRenderer 0 RGBA 0 / 0", - " FontRenderer 0 total 524288 / 524288", - "Other:", - " FboCache 0 / 0", - "Total memory usage:", - " 17424808 bytes, 16.62 MB", - "", - "Profile data in ms:", - "", - "\tcom.google.android.leanbacklauncher/com.google.android.leanbacklauncher.MainActivity/android.view.ViewRootImpl@178d02b (visibility=0)", - "Stats since: 12167093145ns", - "Total frames rendered: 1690", - "Janky frames: 125 (7.40%)", - "90th percentile: 13ms", - "95th percentile: 19ms", - "99th percentile: 48ms", - "Number Missed Vsync: 17", - "Number High input latency: 0", - "Number Slow UI thread: 32", - "Number Slow bitmap uploads: 20", - "Number Slow issue draw commands: 67", - "", - "View hierarchy:", - "", - " com.google.android.leanbacklauncher/com.google.android.leanbacklauncher.MainActivity/android.view.ViewRootImpl@178d02b", - " 221 views, 207.24 kB of display lists", - "", - "", - "Total ViewRootImpl: 1", - "Total Views: 221", - "Total DisplayList: 207.24 kB", - "", - "", - "** Graphics info for pid 1881 [com.android.vending] **", - "", - "Stats since: 6092969986095ns", - "Total frames rendered: 693", - "Janky frames: 62 (8.95%)", - "90th percentile: 16ms", - "95th percentile: 26ms", - "99th percentile: 81ms", - "Number Missed Vsync: 17", - "Number High input latency: 0", - "Number Slow UI thread: 30", - "Number Slow bitmap uploads: 4", - "Number Slow issue draw commands: 13", - "", - "Caches:", - "Current memory usage / total memory usage (bytes):", - " TextureCache 7369504 / 50331648", - " LayerCache 0 / 33554432 (numLayers = 0)", - " Layers total 0 (numLayers = 0)", - " RenderBufferCache 0 / 2097152", - " GradientCache 0 / 838860", - " PathCache 0 / 25165824", - " TessellationCache 0 / 1048576", - " TextDropShadowCache 0 / 4194304", - " PatchCache 0 / 131072", - " FontRenderer 0 A8 524288 / 524288", - " FontRenderer 0 RGBA 0 / 0", - " FontRenderer 0 total 524288 / 524288", - "Other:", - " FboCache 0 / 0", - "Total memory usage:", - " 7893792 bytes, 7.53 MB", - "", - "Profile data in ms:", - "", - "\tcom.android.vending/com.google.android.finsky.activities.MainActivity/android.view.ViewRootImpl@5bd0cb2 (visibility=8)", - "Stats since: 6092969986095ns", - "Total frames rendered: 693", - "Janky frames: 62 (8.95%)", - "90th percentile: 16ms", - "95th percentile: 26ms", - "99th percentile: 81ms", - "Number Missed Vsync: 17", - "Number High input latency: 0", - "Number Slow UI thread: 30", - "Number Slow bitmap uploads: 4", - "Number Slow issue draw commands: 13", - "", - "View hierarchy:", - "", - " com.android.vending/com.google.android.finsky.activities.MainActivity/android.view.ViewRootImpl@5bd0cb2", - " 195 views, 157.71 kB of display lists", - "", - "", - "Total ViewRootImpl: 1", - "Total Views: 195", - "Total DisplayList: 157.71 kB", - "", - "", - "** Graphics info for pid 2931 [com.google.android.videos] **", - "", - "Stats since: 6039768250261ns", - "Total frames rendered: 107", - "Janky frames: 42 (39.25%)", - "90th percentile: 48ms", - "95th percentile: 65ms", - "99th percentile: 113ms", - "Number Missed Vsync: 9", - "Number High input latency: 0", - "Number Slow UI thread: 28", - "Number Slow bitmap uploads: 8", - "Number Slow issue draw commands: 20", - "", - "Caches:", - "Current memory usage / total memory usage (bytes):", - " TextureCache 7880000 / 50331648", - " LayerCache 0 / 33554432 (numLayers = 0)", - " Layers total 0 (numLayers = 0)", - " RenderBufferCache 0 / 2097152", - " GradientCache 0 / 838860", - " PathCache 0 / 25165824", - " TessellationCache 0 / 1048576", - " TextDropShadowCache 0 / 4194304", - " PatchCache 0 / 131072", - " FontRenderer 0 A8 524288 / 524288", - " FontRenderer 0 RGBA 0 / 0", - " FontRenderer 0 total 524288 / 524288", - "Other:", - " FboCache 0 / 0", - "Total memory usage:", - " 8404288 bytes, 8.01 MB", - "", - "Profile data in ms:", - "", - "\tcom.google.android.videos/com.google.android.videos.pano.activity.PanoHomeActivity/android.view.ViewRootImpl@3d96e69 (visibility=8)", - "Stats since: 6039768250261ns", - "Total frames rendered: 107", - "Janky frames: 42 (39.25%)", - "90th percentile: 48ms", - "95th percentile: 65ms", - "99th percentile: 113ms", - "Number Missed Vsync: 9", - "Number High input latency: 0", - "Number Slow UI thread: 28", - "Number Slow bitmap uploads: 8", - "Number Slow issue draw commands: 20", - "", - "View hierarchy:", - "", - " com.google.android.videos/com.google.android.videos.pano.activity.PanoHomeActivity/android.view.ViewRootImpl@3d96e69", - " 219 views, 173.57 kB of display lists", - "", - "", - "Total ViewRootImpl: 1", - "Total Views: 219", - "Total DisplayList: 173.57 kB"); - - GfxInfoItem item = new GfxInfoParser().parse(input); - - assertEquals(3, item.getPids().size()); - assertEquals("com.google.android.leanbacklauncher", item.getName(844)); - assertEquals(1690, item.getTotalFrames(844)); - assertEquals(125, item.getJankyFrames(844)); - assertEquals(13, item.getPrecentile90(844)); - assertEquals(19, item.getPrecentile95(844)); - assertEquals(48, item.getPrecentile99(844)); - assertEquals("com.android.vending", item.getName(1881)); - assertEquals(693, item.getTotalFrames(1881)); - assertEquals(62, item.getJankyFrames(1881)); - assertEquals(16, item.getPrecentile90(1881)); - assertEquals(26, item.getPrecentile95(1881)); - assertEquals(81, item.getPrecentile99(1881)); - assertEquals("com.google.android.videos", item.getName(2931)); - assertEquals(107, item.getTotalFrames(2931)); - assertEquals(42, item.getJankyFrames(2931)); - assertEquals(48, item.getPrecentile90(2931)); - assertEquals(65, item.getPrecentile95(2931)); - assertEquals(113, item.getPrecentile99(2931)); - } - - /** - * Test gfxinfo output from L with single process. - * In L, gfxinfo does not contain Jank number information. - * This method tests that GfxInfoParser silently ignores such outputs. - */ - public void testSingleProcessInL() { - List input = Arrays.asList( - "** Graphics info for pid 1924 [com.google.android.leanbacklauncher] **", - "", - "Caches:", - "Current memory usage / total memory usage (bytes):", - " TextureCache 19521592 / 50331648", - " LayerCache 14745600 / 50331648 (numLayers = 5)", - " Layer size 512x512; isTextureLayer()=0; texid=392 fbo=0; refs=1", - " Layer size 512x448; isTextureLayer()=0; texid=377 fbo=0; refs=1", - " Layer size 1920x832; isTextureLayer()=0; texid=360 fbo=0; refs=1", - " Layer size 1920x512; isTextureLayer()=0; texid=14 fbo=0; refs=1", - " Layer size 1920x320; isTextureLayer()=0; texid=393 fbo=0; refs=1", - " Layers total 14745600 (numLayers = 5)", - " RenderBufferCache 0 / 8388608", - " GradientCache 0 / 1048576", - " PathCache 3370264 / 33554432", - " TessellationCache 194928 / 1048576", - " TextDropShadowCache 0 / 6291456", - " PatchCache 0 / 131072", - " FontRenderer 0 A8 1048576 / 1048576", - " FontRenderer 0 RGBA 0 / 0", - " FontRenderer 0 total 1048576 / 1048576", - "Other:", - " FboCache 0 / 0", - "Total memory usage:", - " 38880960 bytes, 37.08 MB", - "", - "Profile data in ms:", - "", - "\tcom.google.android.leanbacklauncher/com.google.android.leanbacklauncher.MainActivity/android.view.ViewRootImpl@355a7923 (visibility=0)", - "View hierarchy:", - "", - " com.google.android.leanbacklauncher/com.google.android.leanbacklauncher.MainActivity/android.view.ViewRootImpl@355a7923", - " 142 views, 136.96 kB of display lists", - "", - "", - "Total ViewRootImpl: 1", - "Total Views: 142", - "Total DisplayList: 136.96 kB"); - - GfxInfoItem item = new GfxInfoParser().parse(input); - - assertEquals(0, item.getPids().size()); - } -} diff --git a/tests/src/com/android/loganalysis/parser/InterruptParserTest.java b/tests/src/com/android/loganalysis/parser/InterruptParserTest.java deleted file mode 100644 index d45f3af..0000000 --- a/tests/src/com/android/loganalysis/parser/InterruptParserTest.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright (C) 2015 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.InterruptItem; - -import junit.framework.TestCase; - -import java.util.Arrays; -import java.util.List; - -/** - * Unit tests for {@link InterruptParser} - */ -public class InterruptParserTest extends TestCase { - - /** - * Test that normal input is parsed. - */ - public void testInterruptParser() { - List inputBlock = Arrays.asList( - " Wakeup reason 200:qcom,smd-rpm:222:fc4: 11m 49s 332ms (0 times) realtime", - " Wakeup reason 200:qcom,smd-rpm: 48s 45ms (0 times) realtime", - " Wakeup reason 2:qcom,smd-rpm:2:f0.qm,mm:22:fc4mi: 3s 417ms (0 times) realtime", - " Wakeup reason 188:qcom,smd-adsp:200:qcom,smd-rpm: 1s 656ms (0 times) realtime", - " Wakeup reason 58:qcom,smsm-modem:2:qcom,smd-rpm: 6m 16s 1ms (5 times) realtime", - " Wakeup reason 57:qcom,smd-modem:200:qcom,smd-rpm: 40s 995ms (0 times) realtime", - " Wakeup reason unknown: 8s 455ms (0 times) realtime", - " Wakeup reason 9:bcmsdh_sdmmc:2:qcomd-rpm:240:mso: 8m 5s 9ms (0 times) realtime"); - - InterruptItem interrupt = new InterruptParser().parse(inputBlock); - - assertEquals(1, interrupt.getInterrupts( - InterruptItem.InterruptCategory.WIFI_INTERRUPT).size()); - - assertEquals("9:bcmsdh_sdmmc:2:qcomd-rpm:240:mso", interrupt.getInterrupts( - InterruptItem.InterruptCategory.WIFI_INTERRUPT).get(0).getName()); - - assertEquals(2, interrupt.getInterrupts( - InterruptItem.InterruptCategory.MODEM_INTERRUPT).size()); - - assertEquals(5, interrupt.getInterrupts(InterruptItem.InterruptCategory.MODEM_INTERRUPT). - get(0).getInterruptCount()); - - } -} - diff --git a/tests/src/com/android/loganalysis/parser/JavaCrashParserTest.java b/tests/src/com/android/loganalysis/parser/JavaCrashParserTest.java deleted file mode 100644 index a7d06b3..0000000 --- a/tests/src/com/android/loganalysis/parser/JavaCrashParserTest.java +++ /dev/null @@ -1,151 +0,0 @@ -/* - * Copyright (C) 2012 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.JavaCrashItem; -import com.android.loganalysis.util.ArrayUtil; - -import junit.framework.TestCase; - -import java.util.Arrays; -import java.util.List; - -/** - * Unit tests for {@link JavaCrashParser}. - */ -public class JavaCrashParserTest extends TestCase { - - /** - * Test that Java crashes are parsed with no message. - */ - public void testParse_no_message() { - List lines = Arrays.asList( - "java.lang.Exception", - "\tat class.method1(Class.java:1)", - "\tat class.method2(Class.java:2)", - "\tat class.method3(Class.java:3)"); - - JavaCrashItem jc = new JavaCrashParser().parse(lines); - assertNotNull(jc); - assertEquals("java.lang.Exception", jc.getException()); - assertNull(jc.getMessage()); - assertEquals(ArrayUtil.join("\n", lines), jc.getStack()); - } - - /** - * Test that Java crashes are parsed with a message. - */ - public void testParse_message() { - List lines = Arrays.asList( - "java.lang.Exception: This is the message", - "\tat class.method1(Class.java:1)", - "\tat class.method2(Class.java:2)", - "\tat class.method3(Class.java:3)"); - - JavaCrashItem jc = new JavaCrashParser().parse(lines); - assertNotNull(jc); - assertEquals("java.lang.Exception", jc.getException()); - assertEquals("This is the message", jc.getMessage()); - assertEquals(ArrayUtil.join("\n", lines), jc.getStack()); - } - - /** - * Test that Java crashes are parsed if the message spans multiple lines. - */ - public void testParse_multiline_message() { - List lines = Arrays.asList( - "java.lang.Exception: This message", - "is many lines", - "long.", - "\tat class.method1(Class.java:1)", - "\tat class.method2(Class.java:2)", - "\tat class.method3(Class.java:3)"); - - JavaCrashItem jc = new JavaCrashParser().parse(lines); - assertNotNull(jc); - assertEquals("java.lang.Exception", jc.getException()); - assertEquals("This message\nis many lines\nlong.", jc.getMessage()); - assertEquals(ArrayUtil.join("\n", lines), jc.getStack()); - } - - /** - * Test that caused by sections of Java crashes are parsed, with no message or single or - * multiline messages. - */ - public void testParse_caused_by() { - List lines = Arrays.asList( - "java.lang.Exception: This is the message", - "\tat class.method1(Class.java:1)", - "\tat class.method2(Class.java:2)", - "\tat class.method3(Class.java:3)", - "Caused by: java.lang.Exception", - "\tat class.method4(Class.java:4)", - "Caused by: java.lang.Exception: This is the caused by message", - "\tat class.method5(Class.java:5)", - "Caused by: java.lang.Exception: This is a multiline", - "caused by message", - "\tat class.method6(Class.java:6)"); - - JavaCrashItem jc = new JavaCrashParser().parse(lines); - assertNotNull(jc); - assertEquals("java.lang.Exception", jc.getException()); - assertEquals("This is the message", jc.getMessage()); - assertEquals(ArrayUtil.join("\n", lines), jc.getStack()); - } - - /** - * Test that the Java crash is cutoff if an unexpected line is handled. - */ - public void testParse_cutoff() { - List lines = Arrays.asList( - "java.lang.Exception: This is the message", - "\tat class.method1(Class.java:1)", - "\tat class.method2(Class.java:2)", - "\tat class.method3(Class.java:3)", - "Invalid line", - "java.lang.Exception: This is the message"); - - JavaCrashItem jc = new JavaCrashParser().parse(lines); - assertNotNull(jc); - assertEquals("java.lang.Exception", jc.getException()); - assertEquals("This is the message", jc.getMessage()); - assertEquals(ArrayUtil.join("\n", lines.subList(0, lines.size()-2)), jc.getStack()); - } - - /** - * Tests that only parts between the markers are parsed. - */ - public void testParse_begin_end_markers() { - List lines = Arrays.asList( - "error: this message has begin and end", - "----- begin exception -----", - "java.lang.Exception: This message", - "is many lines", - "long.", - "\tat class.method1(Class.java:1)", - "\tat class.method2(Class.java:2)", - "\tat class.method3(Class.java:3)", - "----- end exception -----"); - - JavaCrashItem jc = new JavaCrashParser().parse(lines); - assertNotNull(jc); - assertEquals("java.lang.Exception", jc.getException()); - assertEquals("This message\nis many lines\nlong.", jc.getMessage()); - assertNotNull(jc.getStack()); - assertFalse(jc.getStack().contains("begin exception")); - assertFalse(jc.getStack().contains("end exception")); - } -} diff --git a/tests/src/com/android/loganalysis/parser/KernelLogParserTest.java b/tests/src/com/android/loganalysis/parser/KernelLogParserTest.java deleted file mode 100644 index 159a90e..0000000 --- a/tests/src/com/android/loganalysis/parser/KernelLogParserTest.java +++ /dev/null @@ -1,342 +0,0 @@ -/* - * 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.LowMemoryKillerItem; -import com.android.loganalysis.item.MiscKernelLogItem; -import com.android.loganalysis.item.PageAllocationFailureItem; -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 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 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 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 unknown last boot reasons are parsed. - */ - public void testParseUnknownLastMessage() { - List lines = Arrays.asList( - "[ 0.000000] Start", - "[ 2.000000] End", - "Last boot reason: unknown failure"); - - 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()); - assertNotNull(item.getStack()); - } - - public void testParseKnownGoodLastMessage() { - List lines = Arrays.asList( - "[ 0.000000] Start", - "[ 2.000000] End", - "Last boot reason: reboot"); - - KernelLogItem kernelLog = new KernelLogParser().parse(lines); - assertNotNull(kernelLog); - assertEquals(0.0, kernelLog.getStartTime(), 0.0000005); - assertEquals(2.0, kernelLog.getStopTime(), 0.0000005); - assertEquals(0, kernelLog.getEvents().size()); - } - - /** - * Test that reset reasons don't crash if times are set. - */ - public void testNoPreviousLogs() { - List 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 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 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(2, 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()); - } - - /** - * Test that an LowMemoryKiller event can be parsed out of a list of log lines. - */ - public void testLowMemoryKillerParse() { - final String LMK_MESSAGE = "Killing '.qcrilmsgtunnel' (3699), adj 100,"; - List 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", - "<3>[ 43.399164] " + LMK_MESSAGE); - KernelLogItem kernelLog = new KernelLogParser().parse(lines); - - assertNotNull(kernelLog); - assertEquals(0.0, kernelLog.getStartTime(), 0.0000005); - assertEquals(43.399164, kernelLog.getStopTime(), 0.0000005); - assertEquals(2, kernelLog.getEvents().size()); - assertEquals(1, kernelLog.getMiscEvents(KernelLogParser.LOW_MEMORY_KILLER).size()); - assertEquals(1, kernelLog.getLowMemoryKillerEvents().size()); - - MiscKernelLogItem miscItem = kernelLog.getMiscEvents(KernelLogParser.LOW_MEMORY_KILLER) - .get(0); - assertEquals(43.399164, miscItem.getEventTime(), 0.0000005); - assertEquals(KernelLogParser.LOW_MEMORY_KILLER, miscItem.getCategory()); - assertEquals(LMK_MESSAGE, miscItem.getStack()); - - LowMemoryKillerItem lmkItem = kernelLog.getLowMemoryKillerEvents().get(0); - assertEquals(KernelLogParser.LOW_MEMORY_KILLER, lmkItem.getCategory()); - assertEquals(3699, lmkItem.getPid()); - assertEquals(".qcrilmsgtunnel", lmkItem.getProcessName()); - assertEquals(100, lmkItem.getAdjustment()); - assertEquals(LMK_MESSAGE, lmkItem.getStack()); - } - - /** - * Test that page allocation failures can be parsed out of a list of log lines. - */ - public void testPageAllocationFailureParse() { - final String ALLOC_FAILURE = "page allocation failure: order:3, mode:0x10c0d0"; - List 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", - "<3>[ 43.399164] " + ALLOC_FAILURE); - KernelLogItem kernelLog = new KernelLogParser().parse(lines); - - assertNotNull(kernelLog); - assertEquals(0.0, kernelLog.getStartTime(), 0.0000005); - assertEquals(43.399164, kernelLog.getStopTime(), 0.0000005); - assertEquals(2, kernelLog.getEvents().size()); - assertEquals(1, kernelLog.getMiscEvents(KernelLogParser.PAGE_ALLOC_FAILURE).size()); - assertEquals(1, kernelLog.getPageAllocationFailureEvents().size()); - - MiscKernelLogItem miscItem = kernelLog.getMiscEvents(KernelLogParser.PAGE_ALLOC_FAILURE) - .get(0); - assertEquals(43.399164, miscItem.getEventTime(), 0.0000005); - assertEquals(KernelLogParser.PAGE_ALLOC_FAILURE, miscItem.getCategory()); - assertEquals(ALLOC_FAILURE, miscItem.getStack()); - - PageAllocationFailureItem failItem = kernelLog.getPageAllocationFailureEvents().get(0); - assertEquals(KernelLogParser.PAGE_ALLOC_FAILURE, failItem.getCategory()); - assertEquals(3, failItem.getOrder()); - assertEquals(ALLOC_FAILURE, failItem.getStack()); - } - - public void testMantaReset() { - final List 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 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()); - } -} diff --git a/tests/src/com/android/loganalysis/parser/LocationServiceParserTest.java b/tests/src/com/android/loganalysis/parser/LocationServiceParserTest.java deleted file mode 100644 index fc58e45..0000000 --- a/tests/src/com/android/loganalysis/parser/LocationServiceParserTest.java +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Copyright (C) 2016 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.LocationDumpsItem; -import com.android.loganalysis.item.LocationDumpsItem.LocationInfoItem; - -import junit.framework.TestCase; - -import java.util.Arrays; -import java.util.List; - -/** - * Unit tests for {@link LocationServiceParser} - */ -public class LocationServiceParserTest extends TestCase { - - /** - * Test that normal input is parsed. - */ - public void testLocationClientsSize() { - List inputBlock = Arrays.asList( - " Location Request History By Package:", - " Interval effective/min/max 1/0/0[s] Duration: 140[minutes] " - + "[com.google.android.gms, PRIORITY_NO_POWER, UserLocationProducer] " - + "Num requests: 2 Active: true", - " Interval effective/min/max 284/285/3600[s] Duration: 140[minutes] " - + "[com.google.android.googlequicksearchbox, PRIORITY_BALANCED_POWER_ACCURACY] " - + "Num requests: 5 Active: true", - " Interval effective/min/max 0/0/0[s] Duration: 0[minutes] " - + "[com.google.android.apps.walletnfcrel, PRIORITY_BALANCED_POWER_ACCURACY] " - + "Num requests: 1 Active: false", - " ", - " FLP WakeLock Count"); - - LocationDumpsItem locationClients = new LocationServiceParser().parse(inputBlock); - assertNotNull(locationClients.getLocationClients()); - assertEquals(locationClients.getLocationClients().size(), 3); - } - - /** - * Test that normal input is parsed. - */ - public void testLocationClientParser() { - List inputBlock = Arrays.asList( - " Location Request History By Package:", - " Interval effective/min/max 1/0/0[s] Duration: 140[minutes] " - + "[com.google.android.gms, PRIORITY_NO_POWER, UserLocationProducer] " - + "Num requests: 2 Active: true"); - - LocationDumpsItem locationClients = new LocationServiceParser().parse(inputBlock); - assertNotNull(locationClients.getLocationClients()); - LocationInfoItem client = locationClients.getLocationClients().iterator().next(); - assertEquals(client.getPackage(), "com.google.android.gms"); - assertEquals(client.getEffectiveInterval(), 1); - assertEquals(client.getMinInterval(), 0); - assertEquals(client.getMaxInterval(), 0); - assertEquals(client.getPriority(), "PRIORITY_NO_POWER"); - assertEquals(client.getDuration(), 140); - } - - /** - * Test that invalid input is parsed. - */ - public void testLocationClientParserInvalidInput() { - List inputBlock = Arrays.asList( - " Location Request History By Package:", - " Interval effective/min/max 1/0/0[s] Duration: 140[minutes] " - + "[com.google.android.gms PRIORITY_NO_POWER UserLocationProducer] " - + "Num requests: 2 Active: true"); - LocationDumpsItem locationClients = new LocationServiceParser().parse(inputBlock); - assertEquals(locationClients.getLocationClients().size(), 0); - } - -} - diff --git a/tests/src/com/android/loganalysis/parser/LogcatParserTest.java b/tests/src/com/android/loganalysis/parser/LogcatParserTest.java deleted file mode 100644 index 1d4f72c..0000000 --- a/tests/src/com/android/loganalysis/parser/LogcatParserTest.java +++ /dev/null @@ -1,845 +0,0 @@ -/* - * Copyright (C) 2012 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.JavaCrashItem; -import com.android.loganalysis.item.LogcatItem; -import com.android.loganalysis.item.MiscLogcatItem; -import com.android.loganalysis.util.ArrayUtil; - -import junit.framework.TestCase; - -import java.text.DateFormat; -import java.text.ParseException; -import java.text.SimpleDateFormat; -import java.util.Arrays; -import java.util.Date; -import java.util.List; -import java.util.regex.Pattern; - -/** - * Unit tests for {@link LogcatParserTest}. - */ -public class LogcatParserTest extends TestCase { - - /** - * Test that an ANR is parsed in the log. - */ - public void testParse_anr() throws ParseException { - List lines = Arrays.asList( - "04-25 17:17:08.445 312 366 E ActivityManager: ANR (application not responding) in process: com.android.package", - "04-25 17:17:08.445 312 366 E ActivityManager: Reason: keyDispatchingTimedOut", - "04-25 17:17:08.445 312 366 E ActivityManager: Load: 0.71 / 0.83 / 0.51", - "04-25 17:17:08.445 312 366 E ActivityManager: 33% TOTAL: 21% user + 11% kernel + 0.3% iowait"); - - LogcatItem logcat = new LogcatParser("2012").parse(lines); - assertNotNull(logcat); - assertEquals(parseTime("2012-04-25 17:17:08.445"), logcat.getStartTime()); - assertEquals(parseTime("2012-04-25 17:17:08.445"), logcat.getStopTime()); - assertEquals(1, logcat.getEvents().size()); - assertEquals(1, logcat.getAnrs().size()); - assertEquals(312, logcat.getAnrs().get(0).getPid().intValue()); - assertEquals(366, logcat.getAnrs().get(0).getTid().intValue()); - assertEquals("", logcat.getAnrs().get(0).getLastPreamble()); - assertEquals("", logcat.getAnrs().get(0).getProcessPreamble()); - assertEquals(parseTime("2012-04-25 17:17:08.445"), logcat.getAnrs().get(0).getEventTime()); - } - - /** - * Test that an ANR is parsed in the log. - */ - public void testParse_anr_pid() throws ParseException { - List lines = Arrays.asList( - "04-25 17:17:08.445 312 366 E ActivityManager: ANR (application not responding) in process: com.android.package", - "04-25 17:17:08.445 312 366 E ActivityManager: PID: 1234", - "04-25 17:17:08.445 312 366 E ActivityManager: Reason: keyDispatchingTimedOut", - "04-25 17:17:08.445 312 366 E ActivityManager: Load: 0.71 / 0.83 / 0.51", - "04-25 17:17:08.445 312 366 E ActivityManager: 33% TOTAL: 21% user + 11% kernel + 0.3% iowait"); - - LogcatItem logcat = new LogcatParser("2012").parse(lines); - assertNotNull(logcat); - assertEquals(parseTime("2012-04-25 17:17:08.445"), logcat.getStartTime()); - assertEquals(parseTime("2012-04-25 17:17:08.445"), logcat.getStopTime()); - assertEquals(1, logcat.getEvents().size()); - assertEquals(1, logcat.getAnrs().size()); - assertEquals(1234, logcat.getAnrs().get(0).getPid().intValue()); - assertNull(logcat.getAnrs().get(0).getTid()); - assertEquals("", logcat.getAnrs().get(0).getLastPreamble()); - assertEquals("", logcat.getAnrs().get(0).getProcessPreamble()); - assertEquals(parseTime("2012-04-25 17:17:08.445"), logcat.getAnrs().get(0).getEventTime()); - } - - /** - * Test that Java crashes can be parsed. - */ - public void testParse_java_crash() throws ParseException { - List lines = Arrays.asList( - "04-25 09:55:47.799 3064 3082 E AndroidRuntime: java.lang.Exception", - "04-25 09:55:47.799 3064 3082 E AndroidRuntime: \tat class.method1(Class.java:1)", - "04-25 09:55:47.799 3064 3082 E AndroidRuntime: \tat class.method2(Class.java:2)", - "04-25 09:55:47.799 3064 3082 E AndroidRuntime: \tat class.method3(Class.java:3)"); - - LogcatItem logcat = new LogcatParser("2012").parse(lines); - assertNotNull(logcat); - assertEquals(parseTime("2012-04-25 09:55:47.799"), logcat.getStartTime()); - assertEquals(parseTime("2012-04-25 09:55:47.799"), logcat.getStopTime()); - assertEquals(1, logcat.getEvents().size()); - assertEquals(1, logcat.getJavaCrashes().size()); - assertEquals(3064, logcat.getJavaCrashes().get(0).getPid().intValue()); - assertEquals(3082, logcat.getJavaCrashes().get(0).getTid().intValue()); - assertEquals("", logcat.getJavaCrashes().get(0).getLastPreamble()); - assertEquals("", logcat.getJavaCrashes().get(0).getProcessPreamble()); - assertEquals(parseTime("2012-04-25 09:55:47.799"), - logcat.getJavaCrashes().get(0).getEventTime()); - } - - public void testParse_test_exception() { - List lines = Arrays.asList( - "11-25 19:26:53.581 5832 7008 I TestRunner: ----- begin exception -----", - "11-25 19:26:53.589 5832 7008 I TestRunner: ", - "11-25 19:26:53.589 5832 7008 I TestRunner: java.util.concurrent.TimeoutException", - "11-25 19:26:53.589 5832 7008 I TestRunner: at android.support.test.uiautomator.WaitMixin.wait(WaitMixin.java:49)", - "11-25 19:26:53.589 5832 7008 I TestRunner: at android.support.test.uiautomator.WaitMixin.wait(WaitMixin.java:36)", - "11-25 19:26:53.589 5832 7008 I TestRunner: at android.support.test.uiautomator.UiDevice.wait(UiDevice.java:169)", - "11-25 19:26:53.589 5832 7008 I TestRunner: at com.android.test.uiautomator.common.helpers.MapsHelper.doSearch(MapsHelper.java:87)", - "11-25 19:26:53.589 5832 7008 I TestRunner: at com.android.test.uiautomator.aupt.MapsTest.testMaps(MapsTest.java:58)", - "11-25 19:26:53.589 5832 7008 I TestRunner: at java.lang.reflect.Method.invoke(Native Method)", - "11-25 19:26:53.589 5832 7008 I TestRunner: at java.lang.reflect.Method.invoke(Method.java:372)", - "11-25 19:26:53.589 5832 7008 I TestRunner: at android.test.InstrumentationTestCase.runMethod(InstrumentationTestCase.java:214)", - "11-25 19:26:53.589 5832 7008 I TestRunner: at android.test.InstrumentationTestCase.runTest(InstrumentationTestCase.java:199)", - "11-25 19:26:53.589 5832 7008 I TestRunner: at junit.framework.TestCase.runBare(TestCase.java:134)", - "11-25 19:26:53.589 5832 7008 I TestRunner: at junit.framework.TestResult$1.protect(TestResult.java:115)", - "11-25 19:26:53.589 5832 7008 I TestRunner: at junit.framework.TestResult.runProtected(TestResult.java:133)", - "11-25 19:26:53.589 5832 7008 I TestRunner: at junit.framework.TestResult.run(TestResult.java:118)", - "11-25 19:26:53.589 5832 7008 I TestRunner: at junit.framework.TestCase.run(TestCase.java:124)", - "11-25 19:26:53.589 5832 7008 I TestRunner: at android.support.test.aupt.AuptTestRunner$AuptPrivateTestRunner.runTest(AuptTestRunner.java:182)", - "11-25 19:26:53.589 5832 7008 I TestRunner: at android.test.AndroidTestRunner.runTest(AndroidTestRunner.java:176)", - "11-25 19:26:53.589 5832 7008 I TestRunner: at android.test.InstrumentationTestRunner.onStart(InstrumentationTestRunner.java:555)", - "11-25 19:26:53.589 5832 7008 I TestRunner: at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:1848)", - "11-25 19:26:53.589 5832 7008 I TestRunner: ----- end exception -----" - ); - - LogcatParser logcatParser = new LogcatParser("2012"); - logcatParser.addJavaCrashTag("I", "TestRunner", LogcatParser.JAVA_CRASH); - LogcatItem logcat = logcatParser.parse(lines); - assertNotNull(logcat); - assertEquals(1, logcat.getEvents().size()); - assertEquals(1, logcat.getJavaCrashes().size()); - assertEquals(5832, logcat.getJavaCrashes().get(0).getPid().intValue()); - assertEquals(7008, logcat.getJavaCrashes().get(0).getTid().intValue()); - assertEquals("", logcat.getJavaCrashes().get(0).getLastPreamble()); - assertEquals("", logcat.getJavaCrashes().get(0).getProcessPreamble()); - assertEquals(LogcatParser.JAVA_CRASH, logcat.getJavaCrashes().get(0).getCategory()); - } - - public void testParse_test_exception_with_exras() { - List lines = Arrays.asList( - "12-06 17:19:18.746 6598 7960 I TestRunner: failed: testYouTube(com.android.test.uiautomator.aupt.YouTubeTest)", - "12-06 17:19:18.746 6598 7960 I TestRunner: ----- begin exception -----", - "12-06 17:19:18.747 6598 7960 I TestRunner: ", - "12-06 17:19:18.747 6598 7960 I TestRunner: java.util.concurrent.TimeoutException", - "12-06 17:19:18.747 6598 7960 I TestRunner: at android.support.test.uiautomator.WaitMixin.wait(WaitMixin.java:49)", - "12-06 17:19:18.747 6598 7960 I TestRunner: at android.support.test.uiautomator.WaitMixin.wait(WaitMixin.java:36)", - "12-06 17:19:18.747 6598 7960 I TestRunner: at android.support.test.uiautomator.UiDevice.wait(UiDevice.java:169)", - "12-06 17:19:18.747 6598 7960 I TestRunner: at android.support.test.aupt.AppLauncher.launchApp(AppLauncher.java:127)", - "12-06 17:19:18.747 6598 7960 I TestRunner: at com.android.test.uiautomator.common.helpers.YouTubeHelper.open(YouTubeHelper.java:49)", - "12-06 17:19:18.747 6598 7960 I TestRunner: at com.android.test.uiautomator.aupt.YouTubeTest.setUp(YouTubeTest.java:44)", - "12-06 17:19:18.747 6598 7960 I TestRunner: at junit.framework.TestCase.runBare(TestCase.java:132)", - "12-06 17:19:18.747 6598 7960 I TestRunner: at junit.framework.TestResult$1.protect(TestResult.java:115)", - "12-06 17:19:18.747 6598 7960 I TestRunner: at junit.framework.TestResult.runProtected(TestResult.java:133)", - "12-06 17:19:18.747 6598 7960 I TestRunner: at junit.framework.TestResult.run(TestResult.java:118)", - "12-06 17:19:18.747 6598 7960 I TestRunner: at junit.framework.TestCase.run(TestCase.java:124)", - "12-06 17:19:18.747 6598 7960 I TestRunner: at android.support.test.aupt.AuptTestRunner$AuptPrivateTestRunner.runTest(AuptTestRunner.java:182)", - "12-06 17:19:18.747 6598 7960 I TestRunner: at android.test.AndroidTestRunner.runTest(AndroidTestRunner.java:176)", - "12-06 17:19:18.747 6598 7960 I TestRunner: at android.test.InstrumentationTestRunner.onStart(InstrumentationTestRunner.java:555)", - "12-06 17:19:18.747 6598 7960 I TestRunner: at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:1851)", - "12-06 17:19:18.747 6598 7960 I TestRunner: ----- end exception -----" - ); - - LogcatParser logcatParser = new LogcatParser("2012"); - logcatParser.addJavaCrashTag("I", "TestRunner", LogcatParser.JAVA_CRASH); - LogcatItem logcat = logcatParser.parse(lines); - assertNotNull(logcat); - assertEquals(1, logcat.getEvents().size()); - assertEquals(1, logcat.getJavaCrashes().size()); - assertEquals(6598, logcat.getJavaCrashes().get(0).getPid().intValue()); - assertEquals(7960, logcat.getJavaCrashes().get(0).getTid().intValue()); - assertEquals("", logcat.getJavaCrashes().get(0).getLastPreamble()); - assertEquals("", logcat.getJavaCrashes().get(0).getProcessPreamble()); - // Check that lines not related to java crash are absent - assertFalse(logcat.getJavaCrashes().get(0).getStack().contains("begin exception")); - assertFalse(logcat.getJavaCrashes().get(0).getStack().contains("end exception")); - assertFalse(logcat.getJavaCrashes().get(0).getStack().contains("failed: testYouTube")); - //System.out.println(logcat.getJavaCrashes().get(0).getStack()); - } - - /** - * Test that Java crashes from system server can be parsed. - */ - public void testParse_java_crash_system_server() throws ParseException { - List lines = Arrays.asList( - "04-25 09:55:47.799 3064 3082 E AndroidRuntime: *** FATAL EXCEPTION IN SYSTEM PROCESS: message", - "04-25 09:55:47.799 3064 3082 E AndroidRuntime: java.lang.Exception", - "04-25 09:55:47.799 3064 3082 E AndroidRuntime: \tat class.method1(Class.java:1)", - "04-25 09:55:47.799 3064 3082 E AndroidRuntime: \tat class.method2(Class.java:2)", - "04-25 09:55:47.799 3064 3082 E AndroidRuntime: \tat class.method3(Class.java:3)"); - - LogcatItem logcat = new LogcatParser("2012").parse(lines); - assertNotNull(logcat); - assertEquals(parseTime("2012-04-25 09:55:47.799"), logcat.getStartTime()); - assertEquals(parseTime("2012-04-25 09:55:47.799"), logcat.getStopTime()); - assertEquals(1, logcat.getEvents().size()); - assertEquals(1, logcat.getJavaCrashes().size()); - assertEquals("system_server", logcat.getJavaCrashes().get(0).getApp()); - assertEquals(3064, logcat.getJavaCrashes().get(0).getPid().intValue()); - assertEquals(3082, logcat.getJavaCrashes().get(0).getTid().intValue()); - assertEquals("", logcat.getJavaCrashes().get(0).getLastPreamble()); - assertEquals("", logcat.getJavaCrashes().get(0).getProcessPreamble()); - assertEquals(parseTime("2012-04-25 09:55:47.799"), - logcat.getJavaCrashes().get(0).getEventTime()); - } - - /** - * Test that Java crashes with process and pid can be parsed. - */ - public void testParse_java_crash_process_pid() throws ParseException { - List lines = Arrays.asList( - "04-25 09:55:47.799 3064 3082 E AndroidRuntime: FATAL EXCEPTION: main", - "04-25 09:55:47.799 3064 3082 E AndroidRuntime: Process: com.android.package, PID: 1234", - "04-25 09:55:47.799 3064 3082 E AndroidRuntime: java.lang.Exception", - "04-25 09:55:47.799 3064 3082 E AndroidRuntime: \tat class.method1(Class.java:1)", - "04-25 09:55:47.799 3064 3082 E AndroidRuntime: \tat class.method2(Class.java:2)", - "04-25 09:55:47.799 3064 3082 E AndroidRuntime: \tat class.method3(Class.java:3)"); - - LogcatItem logcat = new LogcatParser("2012").parse(lines); - assertNotNull(logcat); - assertEquals(parseTime("2012-04-25 09:55:47.799"), logcat.getStartTime()); - assertEquals(parseTime("2012-04-25 09:55:47.799"), logcat.getStopTime()); - assertEquals(1, logcat.getEvents().size()); - assertEquals(1, logcat.getJavaCrashes().size()); - assertEquals("com.android.package", logcat.getJavaCrashes().get(0).getApp()); - assertEquals(1234, logcat.getJavaCrashes().get(0).getPid().intValue()); - assertNull(logcat.getJavaCrashes().get(0).getTid()); - assertEquals("", logcat.getJavaCrashes().get(0).getLastPreamble()); - assertEquals("", logcat.getJavaCrashes().get(0).getProcessPreamble()); - assertEquals(parseTime("2012-04-25 09:55:47.799"), - logcat.getJavaCrashes().get(0).getEventTime()); - } - - /** - * Test that Java crashes with pid can be parsed. - */ - public void testParse_java_crash_pid() throws ParseException { - List lines = Arrays.asList( - "04-25 09:55:47.799 3064 3082 E AndroidRuntime: FATAL EXCEPTION: main", - "04-25 09:55:47.799 3064 3082 E AndroidRuntime: PID: 1234", - "04-25 09:55:47.799 3064 3082 E AndroidRuntime: java.lang.Exception", - "04-25 09:55:47.799 3064 3082 E AndroidRuntime: \tat class.method1(Class.java:1)", - "04-25 09:55:47.799 3064 3082 E AndroidRuntime: \tat class.method2(Class.java:2)", - "04-25 09:55:47.799 3064 3082 E AndroidRuntime: \tat class.method3(Class.java:3)"); - - LogcatItem logcat = new LogcatParser("2012").parse(lines); - assertNotNull(logcat); - assertEquals(parseTime("2012-04-25 09:55:47.799"), logcat.getStartTime()); - assertEquals(parseTime("2012-04-25 09:55:47.799"), logcat.getStopTime()); - assertEquals(1, logcat.getEvents().size()); - assertEquals(1, logcat.getJavaCrashes().size()); - assertNull(logcat.getJavaCrashes().get(0).getApp()); - assertEquals(1234, logcat.getJavaCrashes().get(0).getPid().intValue()); - assertNull(logcat.getJavaCrashes().get(0).getTid()); - assertEquals("", logcat.getJavaCrashes().get(0).getLastPreamble()); - assertEquals("", logcat.getJavaCrashes().get(0).getProcessPreamble()); - assertEquals(parseTime("2012-04-25 09:55:47.799"), - logcat.getJavaCrashes().get(0).getEventTime()); - } - - /** - * Test that Java crashes with process and pid without stack can be parsed. - */ - public void testParse_java_crash_empty() throws ParseException { - List lines = Arrays.asList( - "04-25 09:55:47.799 3064 3082 E AndroidRuntime: FATAL EXCEPTION: main", - "04-25 09:55:47.799 3064 3082 E AndroidRuntime: PID: 1234"); - - LogcatItem logcat = new LogcatParser("2012").parse(lines); - assertNotNull(logcat); - assertEquals(parseTime("2012-04-25 09:55:47.799"), logcat.getStartTime()); - assertEquals(parseTime("2012-04-25 09:55:47.799"), logcat.getStopTime()); - assertEquals(0, logcat.getEvents().size()); - assertEquals(0, logcat.getJavaCrashes().size()); - } - - /** - * Test that native crashes can be parsed from the info log level. - */ - public void testParse_native_crash_info() throws ParseException { - List lines = Arrays.asList( - "04-25 18:33:27.273 115 115 I DEBUG : Build fingerprint: 'product:build:target'", - "04-25 18:33:27.273 115 115 I DEBUG : pid: 3112, tid: 3112 >>> com.google.android.browser <<<", - "04-25 18:33:27.273 115 115 I DEBUG : signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 00000000"); - - LogcatItem logcat = new LogcatParser("2012").parse(lines); - assertNotNull(logcat); - assertEquals(parseTime("2012-04-25 18:33:27.273"), logcat.getStartTime()); - assertEquals(parseTime("2012-04-25 18:33:27.273"), logcat.getStopTime()); - assertEquals(1, logcat.getEvents().size()); - assertEquals(1, logcat.getNativeCrashes().size()); - assertEquals(3112, logcat.getNativeCrashes().get(0).getPid().intValue()); - assertEquals(3112, logcat.getNativeCrashes().get(0).getTid().intValue()); - assertEquals("com.google.android.browser", logcat.getNativeCrashes().get(0).getApp()); - assertEquals("", logcat.getNativeCrashes().get(0).getLastPreamble()); - assertEquals("", logcat.getNativeCrashes().get(0).getProcessPreamble()); - assertEquals(parseTime("2012-04-25 18:33:27.273"), - logcat.getNativeCrashes().get(0).getEventTime()); - } - - /** - * Test that native crashes can be parsed from the fatal log level. - */ - public void testParse_native_crash_fatal() throws ParseException { - List lines = Arrays.asList( - "04-25 18:33:27.273 115 115 F DEBUG : Build fingerprint: 'product:build:target'", - "04-25 18:33:27.273 115 115 F DEBUG : pid: 3112, tid: 3112, name: Name >>> com.google.android.browser <<<", - "04-25 18:33:27.273 115 115 F DEBUG : signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 00000000"); - - LogcatItem logcat = new LogcatParser("2012").parse(lines); - assertNotNull(logcat); - assertEquals(parseTime("2012-04-25 18:33:27.273"), logcat.getStartTime()); - assertEquals(parseTime("2012-04-25 18:33:27.273"), logcat.getStopTime()); - assertEquals(1, logcat.getEvents().size()); - assertEquals(1, logcat.getNativeCrashes().size()); - assertEquals(3112, logcat.getNativeCrashes().get(0).getPid().intValue()); - assertEquals(3112, logcat.getNativeCrashes().get(0).getTid().intValue()); - assertEquals("com.google.android.browser", logcat.getNativeCrashes().get(0).getApp()); - assertEquals("", logcat.getNativeCrashes().get(0).getLastPreamble()); - assertEquals("", logcat.getNativeCrashes().get(0).getProcessPreamble()); - assertEquals(parseTime("2012-04-25 18:33:27.273"), - logcat.getNativeCrashes().get(0).getEventTime()); - } - - /** - * Test that native crashes can be parsed if they have the same pid/tid. - */ - public void testParse_native_crash_same_pid() throws ParseException { - List lines = Arrays.asList( - "04-25 18:33:27.273 115 115 I DEBUG : *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***", - "04-25 18:33:27.273 115 115 I DEBUG : Build fingerprint: 'product:build:target'", - "04-25 18:33:27.273 115 115 I DEBUG : pid: 3112, tid: 3112 >>> com.google.android.browser <<<", - "04-25 18:33:27.273 115 115 I DEBUG : signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 00000000", - "04-25 18:33:27.273 115 115 I DEBUG : *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***", - "04-25 18:33:27.273 115 115 I DEBUG : Build fingerprint: 'product:build:target'", - "04-25 18:33:27.273 115 115 I DEBUG : pid: 3113, tid: 3113 >>> com.google.android.browser2 <<<", - "04-25 18:33:27.273 115 115 I DEBUG : signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 00000000"); - - LogcatItem logcat = new LogcatParser("2012").parse(lines); - assertNotNull(logcat); - assertEquals(parseTime("2012-04-25 18:33:27.273"), logcat.getStartTime()); - assertEquals(parseTime("2012-04-25 18:33:27.273"), logcat.getStopTime()); - assertEquals(2, logcat.getEvents().size()); - assertEquals(2, logcat.getNativeCrashes().size()); - assertEquals(3112, logcat.getNativeCrashes().get(0).getPid().intValue()); - assertEquals(3112, logcat.getNativeCrashes().get(0).getTid().intValue()); - assertEquals("com.google.android.browser", logcat.getNativeCrashes().get(0).getApp()); - assertEquals(3113, logcat.getNativeCrashes().get(1).getPid().intValue()); - assertEquals(3113, logcat.getNativeCrashes().get(1).getTid().intValue()); - assertEquals("com.google.android.browser2", logcat.getNativeCrashes().get(1).getApp()); - } - - public void testParse_misc_events() throws ParseException { - List lines = Arrays.asList( - "04-25 18:33:27.273 1676 1821 W AudioTrack: obtainBuffer timed out (is the CPU pegged?) 0x361378 user=0000116a, server=00000000", - "04-25 18:33:28.273 7813 7813 E gralloc : GetBufferLock timed out for thread 7813 buffer 0x61 usage 0x200 LockState 1", - "04-25 18:33:29.273 395 637 W Watchdog: *** WATCHDOG KILLING SYSTEM PROCESS: null"); - - LogcatItem logcat = new LogcatParser("2012").parse(lines); - assertNotNull(logcat); - assertEquals(parseTime("2012-04-25 18:33:27.273"), logcat.getStartTime()); - assertEquals(parseTime("2012-04-25 18:33:29.273"), logcat.getStopTime()); - assertEquals(3, logcat.getEvents().size()); - assertEquals(1, logcat.getMiscEvents(LogcatParser.HIGH_CPU_USAGE).size()); - assertEquals(1, logcat.getMiscEvents(LogcatParser.HIGH_MEMORY_USAGE).size()); - assertEquals(1, logcat.getMiscEvents(LogcatParser.RUNTIME_RESTART).size()); - - MiscLogcatItem item = logcat.getMiscEvents(LogcatParser.HIGH_CPU_USAGE).get(0); - - assertEquals(1676, item.getPid().intValue()); - assertEquals(1821, item.getTid().intValue()); - assertEquals(parseTime("2012-04-25 18:33:27.273"), item.getEventTime()); - - item = logcat.getMiscEvents(LogcatParser.HIGH_MEMORY_USAGE).get(0); - - assertEquals(7813, item.getPid().intValue()); - assertEquals(7813, item.getTid().intValue()); - assertEquals(parseTime("2012-04-25 18:33:28.273"), item.getEventTime()); - - item = logcat.getMiscEvents(LogcatParser.RUNTIME_RESTART).get(0); - - assertEquals(395, item.getPid().intValue()); - assertEquals(637, item.getTid().intValue()); - assertEquals(parseTime("2012-04-25 18:33:29.273"), item.getEventTime()); - } - - /** - * Test that multiple events can be parsed. - */ - public void testParse_multiple_events() throws ParseException { - List lines = Arrays.asList( - "04-25 09:55:47.799 3064 3082 E AndroidRuntime: java.lang.Exception", - "04-25 09:55:47.799 3064 3082 E AndroidRuntime: \tat class.method1(Class.java:1)", - "04-25 09:55:47.799 3064 3082 E AndroidRuntime: \tat class.method2(Class.java:2)", - "04-25 09:55:47.799 3064 3082 E AndroidRuntime: \tat class.method3(Class.java:3)", - "04-25 09:55:47.799 3065 3090 E AndroidRuntime: java.lang.Exception", - "04-25 09:55:47.799 3065 3090 E AndroidRuntime: \tat class.method1(Class.java:1)", - "04-25 09:55:47.799 3065 3090 E AndroidRuntime: \tat class.method2(Class.java:2)", - "04-25 09:55:47.799 3065 3090 E AndroidRuntime: \tat class.method3(Class.java:3)", - "04-25 17:17:08.445 312 366 E ActivityManager: ANR (application not responding) in process: com.android.package", - "04-25 17:17:08.445 312 366 E ActivityManager: Reason: keyDispatchingTimedOut", - "04-25 17:17:08.445 312 366 E ActivityManager: Load: 0.71 / 0.83 / 0.51", - "04-25 17:17:08.445 312 366 E ActivityManager: 33% TOTAL: 21% user + 11% kernel + 0.3% iowait", - "04-25 17:17:08.445 312 366 E ActivityManager: ANR (application not responding) in process: com.android.package", - "04-25 17:17:08.445 312 366 E ActivityManager: Reason: keyDispatchingTimedOut", - "04-25 17:17:08.445 312 366 E ActivityManager: Load: 0.71 / 0.83 / 0.51", - "04-25 17:17:08.445 312 366 E ActivityManager: 33% TOTAL: 21% user + 11% kernel + 0.3% iowait", - "04-25 18:33:27.273 115 115 I DEBUG : *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***", - "04-25 18:33:27.273 115 115 I DEBUG : Build fingerprint: 'product:build:target'", - "04-25 18:33:27.273 115 115 I DEBUG : pid: 3112, tid: 3112 >>> com.google.android.browser <<<", - "04-25 18:33:27.273 115 115 I DEBUG : signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 00000000", - "04-25 18:33:27.273 117 117 I DEBUG : *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***", - "04-25 18:33:27.273 117 117 I DEBUG : Build fingerprint: 'product:build:target'", - "04-25 18:33:27.273 117 117 I DEBUG : pid: 3113, tid: 3113 >>> com.google.android.browser <<<", - "04-25 18:33:27.273 117 117 I DEBUG : signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 00000000"); - - - LogcatItem logcat = new LogcatParser("2012").parse(lines); - assertNotNull(logcat); - assertEquals(parseTime("2012-04-25 09:55:47.799"), logcat.getStartTime()); - assertEquals(parseTime("2012-04-25 18:33:27.273"), logcat.getStopTime()); - assertEquals(6, logcat.getEvents().size()); - assertEquals(2, logcat.getAnrs().size()); - assertEquals(2, logcat.getJavaCrashes().size()); - assertEquals(2, logcat.getNativeCrashes().size()); - - assertEquals(312, logcat.getAnrs().get(0).getPid().intValue()); - assertEquals(366, logcat.getAnrs().get(0).getTid().intValue()); - assertEquals(parseTime("2012-04-25 17:17:08.445"), logcat.getAnrs().get(0).getEventTime()); - - assertEquals(312, logcat.getAnrs().get(1).getPid().intValue()); - assertEquals(366, logcat.getAnrs().get(1).getTid().intValue()); - assertEquals(parseTime("2012-04-25 17:17:08.445"), logcat.getAnrs().get(1).getEventTime()); - - assertEquals(3064, logcat.getJavaCrashes().get(0).getPid().intValue()); - assertEquals(3082, logcat.getJavaCrashes().get(0).getTid().intValue()); - assertEquals( - parseTime("2012-04-25 09:55:47.799"), - logcat.getJavaCrashes().get(0).getEventTime()); - - assertEquals(3065, logcat.getJavaCrashes().get(1).getPid().intValue()); - assertEquals(3090, logcat.getJavaCrashes().get(1).getTid().intValue()); - assertEquals( - parseTime("2012-04-25 09:55:47.799"), - logcat.getJavaCrashes().get(1).getEventTime()); - - assertEquals(3112, logcat.getNativeCrashes().get(0).getPid().intValue()); - assertEquals(3112, logcat.getNativeCrashes().get(0).getTid().intValue()); - assertEquals( - parseTime("2012-04-25 18:33:27.273"), - logcat.getNativeCrashes().get(0).getEventTime()); - - assertEquals(3113, logcat.getNativeCrashes().get(1).getPid().intValue()); - assertEquals(3113, logcat.getNativeCrashes().get(1).getTid().intValue()); - assertEquals( - parseTime("2012-04-25 18:33:27.273"), - logcat.getNativeCrashes().get(1).getEventTime()); - } - - /** Test that including extra uid column still parses the logs. */ - public void testParse_uid() throws ParseException { - List lines = - Arrays.asList( - "04-25 09:55:47.799 wifi 3064 3082 E AndroidRuntime: java.lang.Exception", - "04-25 09:55:47.799 wifi 3064 3082 E AndroidRuntime: \tat class.method1(Class.java:1)", - "04-25 09:55:47.799 wifi 3064 3082 E AndroidRuntime: \tat class.method2(Class.java:2)", - "04-25 09:55:47.799 wifi 3064 3082 E AndroidRuntime: \tat class.method3(Class.java:3)", - "04-25 09:55:47.799 wifi 3065 3090 E AndroidRuntime: java.lang.Exception", - "04-25 09:55:47.799 wifi 3065 3090 E AndroidRuntime: \tat class.method1(Class.java:1)", - "04-25 09:55:47.799 wifi 3065 3090 E AndroidRuntime: \tat class.method2(Class.java:2)", - "04-25 09:55:47.799 wifi 3065 3090 E AndroidRuntime: \tat class.method3(Class.java:3)", - "04-25 17:17:08.445 1337 312 366 E ActivityManager: ANR (application not responding) in process: com.android.package", - "04-25 17:17:08.445 1337 312 366 E ActivityManager: Reason: keyDispatchingTimedOut", - "04-25 17:17:08.445 1337 312 366 E ActivityManager: Load: 0.71 / 0.83 / 0.51", - "04-25 17:17:08.445 1337 312 366 E ActivityManager: 33% TOTAL: 21% user + 11% kernel + 0.3% iowait", - "04-25 17:17:08.445 1337 312 366 E ActivityManager: ANR (application not responding) in process: com.android.package", - "04-25 17:17:08.445 1337 312 366 E ActivityManager: Reason: keyDispatchingTimedOut", - "04-25 17:17:08.445 1337 312 366 E ActivityManager: Load: 0.71 / 0.83 / 0.51", - "04-25 17:17:08.445 1337 312 366 E ActivityManager: 33% TOTAL: 21% user + 11% kernel + 0.3% iowait", - "04-25 18:33:27.273 wifi123 115 115 I DEBUG : *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***", - "04-25 18:33:27.273 wifi123 115 115 I DEBUG : Build fingerprint: 'product:build:target'", - "04-25 18:33:27.273 wifi123 115 115 I DEBUG : pid: 3112, tid: 3112 >>> com.google.android.browser <<<", - "04-25 18:33:27.273 wifi123 115 115 I DEBUG : signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 00000000", - "04-25 18:33:27.273 wifi123 117 117 I DEBUG : *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***", - "04-25 18:33:27.273 wifi123 117 117 I DEBUG : Build fingerprint: 'product:build:target'", - "04-25 18:33:27.273 wifi123 117 117 I DEBUG : pid: 3113, tid: 3113 >>> com.google.android.browser <<<", - "04-25 18:33:27.273 wifi123 117 117 I DEBUG : signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 00000000"); - - - LogcatItem logcat = new LogcatParser("2012").parse(lines); - assertNotNull(logcat); - assertEquals(parseTime("2012-04-25 09:55:47.799"), logcat.getStartTime()); - assertEquals(parseTime("2012-04-25 18:33:27.273"), logcat.getStopTime()); - assertEquals(6, logcat.getEvents().size()); - assertEquals(2, logcat.getAnrs().size()); - assertEquals(2, logcat.getJavaCrashes().size()); - assertEquals(2, logcat.getNativeCrashes().size()); - - assertEquals(312, logcat.getAnrs().get(0).getPid().intValue()); - assertEquals(366, logcat.getAnrs().get(0).getTid().intValue()); - assertEquals(parseTime("2012-04-25 17:17:08.445"), logcat.getAnrs().get(0).getEventTime()); - - assertEquals(312, logcat.getAnrs().get(1).getPid().intValue()); - assertEquals(366, logcat.getAnrs().get(1).getTid().intValue()); - assertEquals(parseTime("2012-04-25 17:17:08.445"), logcat.getAnrs().get(1).getEventTime()); - - assertEquals(3064, logcat.getJavaCrashes().get(0).getPid().intValue()); - assertEquals(3082, logcat.getJavaCrashes().get(0).getTid().intValue()); - assertEquals(parseTime("2012-04-25 09:55:47.799"), - logcat.getJavaCrashes().get(0).getEventTime()); - - assertEquals(3065, logcat.getJavaCrashes().get(1).getPid().intValue()); - assertEquals(3090, logcat.getJavaCrashes().get(1).getTid().intValue()); - assertEquals(parseTime("2012-04-25 09:55:47.799"), - logcat.getJavaCrashes().get(1).getEventTime()); - - assertEquals(3112, logcat.getNativeCrashes().get(0).getPid().intValue()); - assertEquals(3112, logcat.getNativeCrashes().get(0).getTid().intValue()); - assertEquals(parseTime("2012-04-25 18:33:27.273"), - logcat.getNativeCrashes().get(0).getEventTime()); - - assertEquals(3113, logcat.getNativeCrashes().get(1).getPid().intValue()); - assertEquals(3113, logcat.getNativeCrashes().get(1).getTid().intValue()); - assertEquals(parseTime("2012-04-25 18:33:27.273"), - logcat.getNativeCrashes().get(1).getEventTime()); - } - - /** - * Test that multiple java crashes and native crashes can be parsed even when interleaved. - */ - public void testParse_multiple_events_interleaved() throws ParseException { - List lines = Arrays.asList( - "04-25 09:55:47.799 3064 3082 E AndroidRuntime: java.lang.Exception", - "04-25 09:55:47.799 3065 3090 E AndroidRuntime: java.lang.Exception", - "04-25 09:55:47.799 115 115 I DEBUG : *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***", - "04-25 09:55:47.799 117 117 I DEBUG : *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***", - "04-25 09:55:47.799 3064 3082 E AndroidRuntime: \tat class.method1(Class.java:1)", - "04-25 09:55:47.799 3065 3090 E AndroidRuntime: \tat class.method1(Class.java:1)", - "04-25 09:55:47.799 115 115 I DEBUG : Build fingerprint: 'product:build:target'", - "04-25 09:55:47.799 117 117 I DEBUG : Build fingerprint: 'product:build:target'", - "04-25 09:55:47.799 3064 3082 E AndroidRuntime: \tat class.method2(Class.java:2)", - "04-25 09:55:47.799 3065 3090 E AndroidRuntime: \tat class.method2(Class.java:2)", - "04-25 09:55:47.799 115 115 I DEBUG : pid: 3112, tid: 3112 >>> com.google.android.browser <<<", - "04-25 09:55:47.799 117 117 I DEBUG : pid: 3113, tid: 3113 >>> com.google.android.browser <<<", - "04-25 09:55:47.799 3064 3082 E AndroidRuntime: \tat class.method3(Class.java:3)", - "04-25 09:55:47.799 3065 3090 E AndroidRuntime: \tat class.method3(Class.java:3)", - "04-25 09:55:47.799 115 115 I DEBUG : signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 00000000", - "04-25 09:55:47.799 117 117 I DEBUG : signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 00000000"); - - LogcatItem logcat = new LogcatParser("2012").parse(lines); - assertNotNull(logcat); - assertEquals(parseTime("2012-04-25 09:55:47.799"), logcat.getStartTime()); - assertEquals(parseTime("2012-04-25 09:55:47.799"), logcat.getStopTime()); - assertEquals(4, logcat.getEvents().size()); - assertEquals(0, logcat.getAnrs().size()); - assertEquals(2, logcat.getJavaCrashes().size()); - assertEquals(2, logcat.getNativeCrashes().size()); - - assertEquals(3064, logcat.getJavaCrashes().get(0).getPid().intValue()); - assertEquals(3082, logcat.getJavaCrashes().get(0).getTid().intValue()); - assertEquals(parseTime("2012-04-25 09:55:47.799"), - logcat.getJavaCrashes().get(0).getEventTime()); - - assertEquals(3065, logcat.getJavaCrashes().get(1).getPid().intValue()); - assertEquals(3090, logcat.getJavaCrashes().get(1).getTid().intValue()); - assertEquals(parseTime("2012-04-25 09:55:47.799"), - logcat.getJavaCrashes().get(1).getEventTime()); - - assertEquals(3112, logcat.getNativeCrashes().get(0).getPid().intValue()); - assertEquals(3112, logcat.getNativeCrashes().get(0).getTid().intValue()); - assertEquals(parseTime("2012-04-25 09:55:47.799"), - logcat.getNativeCrashes().get(0).getEventTime()); - - assertEquals(3113, logcat.getNativeCrashes().get(1).getPid().intValue()); - assertEquals(3113, logcat.getNativeCrashes().get(1).getTid().intValue()); - assertEquals(parseTime("2012-04-25 09:55:47.799"), - logcat.getNativeCrashes().get(1).getEventTime()); - } - - /** - * Test that the preambles are set correctly. - */ - public void testParse_preambles() throws ParseException { - List lines = Arrays.asList( - "04-25 09:15:47.799 123 3082 I tag: message 1", - "04-25 09:20:47.799 3064 3082 I tag: message 2", - "04-25 09:25:47.799 345 3082 I tag: message 3", - "04-25 09:30:47.799 3064 3082 I tag: message 4", - "04-25 09:35:47.799 456 3082 I tag: message 5", - "04-25 09:40:47.799 3064 3082 I tag: message 6", - "04-25 09:45:47.799 567 3082 I tag: message 7", - "04-25 09:50:47.799 3064 3082 I tag: message 8", - "04-25 09:55:47.799 3064 3082 E AndroidRuntime: java.lang.Exception", - "04-25 09:55:47.799 3064 3082 E AndroidRuntime: \tat class.method1(Class.java:1)", - "04-25 09:55:47.799 3064 3082 E AndroidRuntime: \tat class.method2(Class.java:2)", - "04-25 09:55:47.799 3064 3082 E AndroidRuntime: \tat class.method3(Class.java:3)"); - - List expectedLastPreamble = Arrays.asList( - "04-25 09:15:47.799 123 3082 I tag: message 1", - "04-25 09:20:47.799 3064 3082 I tag: message 2", - "04-25 09:25:47.799 345 3082 I tag: message 3", - "04-25 09:30:47.799 3064 3082 I tag: message 4", - "04-25 09:35:47.799 456 3082 I tag: message 5", - "04-25 09:40:47.799 3064 3082 I tag: message 6", - "04-25 09:45:47.799 567 3082 I tag: message 7", - "04-25 09:50:47.799 3064 3082 I tag: message 8"); - - List expectedProcPreamble = Arrays.asList( - "04-25 09:20:47.799 3064 3082 I tag: message 2", - "04-25 09:30:47.799 3064 3082 I tag: message 4", - "04-25 09:40:47.799 3064 3082 I tag: message 6", - "04-25 09:50:47.799 3064 3082 I tag: message 8"); - - LogcatItem logcat = new LogcatParser("2012").parse(lines); - assertNotNull(logcat); - assertEquals(parseTime("2012-04-25 09:15:47.799"), logcat.getStartTime()); - assertEquals(parseTime("2012-04-25 09:55:47.799"), logcat.getStopTime()); - assertEquals(1, logcat.getEvents().size()); - assertEquals(1, logcat.getJavaCrashes().size()); - assertEquals(3064, logcat.getJavaCrashes().get(0).getPid().intValue()); - assertEquals(3082, logcat.getJavaCrashes().get(0).getTid().intValue()); - assertEquals(ArrayUtil.join("\n", expectedLastPreamble), - logcat.getJavaCrashes().get(0).getLastPreamble()); - assertEquals(ArrayUtil.join("\n", expectedProcPreamble), - logcat.getJavaCrashes().get(0).getProcessPreamble()); - assertEquals(parseTime("2012-04-25 09:55:47.799"), - logcat.getJavaCrashes().get(0).getEventTime()); - } - - /** - * Test that events while the device is rebooting are ignored. - */ - public void testParse_reboot() throws ParseException { - List lines = Arrays.asList( - "04-25 09:15:47.799 123 3082 I ShutdownThread: Rebooting, reason: null", - "04-25 09:55:47.799 3064 3082 E AndroidRuntime: java.lang.Exception", - "04-25 09:55:47.799 3064 3082 E AndroidRuntime: \tat class.method1(Class.java:1)", - "04-25 09:55:47.799 3064 3082 E AndroidRuntime: \tat class.method2(Class.java:2)", - "04-25 09:55:47.799 3064 3082 E AndroidRuntime: \tat class.method3(Class.java:3)"); - - LogcatItem logcat = new LogcatParser("2012").parse(lines); - assertNotNull(logcat); - assertEquals(parseTime("2012-04-25 09:15:47.799"), logcat.getStartTime()); - assertEquals(parseTime("2012-04-25 09:55:47.799"), logcat.getStopTime()); - assertEquals(0, logcat.getEvents().size()); - } - - /** - * Test that events while the device is rebooting are ignored, but devices after the reboot are - * captured. - */ - public void testParse_reboot_resume() throws ParseException { - List lines = Arrays.asList( - "04-25 09:15:47.799 123 3082 I ShutdownThread: Rebooting, reason: null", - "04-25 09:55:47.799 3064 3082 E AndroidRuntime: java.lang.Exception", - "04-25 09:55:47.799 3064 3082 E AndroidRuntime: \tat class.method1(Class.java:1)", - "04-25 09:55:47.799 3064 3082 E AndroidRuntime: \tat class.method2(Class.java:2)", - "04-25 09:55:47.799 3064 3082 E AndroidRuntime: \tat class.method3(Class.java:3)", - "logcat interrupted. May see duplicated content in log.--------- beginning of /dev/log/main", - "04-25 09:59:47.799 3064 3082 E AndroidRuntime: java.lang.Exception2", - "04-25 09:59:47.799 3064 3082 E AndroidRuntime: \tat class.method1(Class.java:1)", - "04-25 09:59:47.799 3064 3082 E AndroidRuntime: \tat class.method2(Class.java:2)", - "04-25 09:59:47.799 3064 3082 E AndroidRuntime: \tat class.method3(Class.java:3)"); - - - LogcatItem logcat = new LogcatParser("2012").parse(lines); - assertNotNull(logcat); - assertEquals(parseTime("2012-04-25 09:15:47.799"), logcat.getStartTime()); - assertEquals(parseTime("2012-04-25 09:59:47.799"), logcat.getStopTime()); - assertEquals(1, logcat.getEvents().size()); - assertEquals("java.lang.Exception2", logcat.getJavaCrashes().get(0).getException()); - - lines = Arrays.asList( - "04-25 09:15:47.799 123 3082 I ShutdownThread: Rebooting, reason: null", - "04-25 09:55:47.799 3064 3082 E AndroidRuntime: java.lang.Exception", - "04-25 09:55:47.799 3064 3082 E AndroidRuntime: \tat class.method1(Class.java:1)", - "04-25 09:55:47.799 3064 3082 E AndroidRuntime: \tat class.method2(Class.java:2)", - "04-25 09:55:47.799 3064 3082 E AndroidRuntime: \tat class.method3(Class.java:3)", - "logcat interrupted. May see duplicated content in log.--------- beginning of main", - "04-25 09:59:47.799 3064 3082 E AndroidRuntime: java.lang.Exception2", - "04-25 09:59:47.799 3064 3082 E AndroidRuntime: \tat class.method1(Class.java:1)", - "04-25 09:59:47.799 3064 3082 E AndroidRuntime: \tat class.method2(Class.java:2)", - "04-25 09:59:47.799 3064 3082 E AndroidRuntime: \tat class.method3(Class.java:3)"); - - - logcat = new LogcatParser("2012").parse(lines); - assertNotNull(logcat); - assertEquals(parseTime("2012-04-25 09:15:47.799"), logcat.getStartTime()); - assertEquals(parseTime("2012-04-25 09:59:47.799"), logcat.getStopTime()); - assertEquals(1, logcat.getEvents().size()); - assertEquals("java.lang.Exception2", logcat.getJavaCrashes().get(0).getException()); - } - - /** - * Test that the time logcat format can be parsed. - */ - public void testParse_time() throws ParseException { - List lines = Arrays.asList( - "04-25 09:55:47.799 E/AndroidRuntime(3064): java.lang.Exception", - "04-25 09:55:47.799 E/AndroidRuntime(3064): \tat class.method1(Class.java:1)", - "04-25 09:55:47.799 E/AndroidRuntime(3064): \tat class.method2(Class.java:2)", - "04-25 09:55:47.799 E/AndroidRuntime(3064): \tat class.method3(Class.java:3)"); - - LogcatItem logcat = new LogcatParser("2012").parse(lines); - assertNotNull(logcat); - assertEquals(parseTime("2012-04-25 09:55:47.799"), logcat.getStartTime()); - assertEquals(parseTime("2012-04-25 09:55:47.799"), logcat.getStopTime()); - assertEquals(1, logcat.getEvents().size()); - assertEquals(1, logcat.getJavaCrashes().size()); - assertEquals(3064, logcat.getJavaCrashes().get(0).getPid().intValue()); - assertNull(logcat.getJavaCrashes().get(0).getTid()); - assertEquals(parseTime("2012-04-25 09:55:47.799"), - logcat.getJavaCrashes().get(0).getEventTime()); - } - - /** - * Test that we can add and find custom patterns that match based on logcat Tags only. - */ - public void testAddPattern_byTagOnly() { - List lines = Arrays.asList( - "04-25 18:33:28.273 7813 7813 E HelloTag: Hello everyone!!!1", - "04-25 18:33:29.273 395 637 I Watchdog: find me!", - "04-25 18:33:39.273 395 637 W Watchdog: find me!"); - - LogcatParser parser = new LogcatParser("2012"); - assertNotNull(parser); - parser.addPattern(null, null, "HelloTag", "HelloCategory"); - parser.addPattern(null, null, "Watchdog", "WatchdogCategory"); - LogcatItem logcat = parser.parse(lines); - assertNotNull(logcat); - - /* verify that we find the HelloTag entry */ - List matchedEvents = logcat.getMiscEvents("HelloCategory"); - assertEquals(1, matchedEvents.size()); - assertEquals("HelloTag", matchedEvents.get(0).getTag()); - - /* verify that we find both Watchdog entries */ - matchedEvents = logcat.getMiscEvents("WatchdogCategory"); - assertEquals(2, matchedEvents.size()); - assertEquals("Watchdog", matchedEvents.get(0).getTag()); - } - - /** - * Test that we can add and find custom patterns that match based on Level AND Tag. - */ - public void testAddPattern_byLevelAndTagOnly() { - List lines = Arrays.asList( - "04-25 18:33:28.273 7813 7813 E HelloTag: GetBufferLock timed out for thread 7813 buffer 0x61 usage 0x200 LockState 1", - "04-25 18:33:29.273 395 637 I Watchdog: Info", - "04-25 18:33:29.273 395 637 W Watchdog: Warning"); - - LogcatParser parser = new LogcatParser("2012"); - assertNotNull(parser); - parser.addPattern(null, "I", "Watchdog", "WatchdogCategory"); - LogcatItem logcat = parser.parse(lines); - assertNotNull(logcat); - - List matchedEvents = logcat.getMiscEvents("WatchdogCategory"); - assertEquals(1, matchedEvents.size()); - assertEquals("Watchdog", matchedEvents.get(0).getTag()); - assertEquals("Info", matchedEvents.get(0).getStack()); - } - - /** - * Test that we can add and find custom patterns that match based on Level, Tag, AND Message. - */ - public void testAddPattern_byLevelTagAndMessageOnly() { - List lines = Arrays.asList( - "04-25 18:33:29.273 395 637 W Watchdog: I'm the one you need to find!", - "04-25 18:33:29.273 395 637 W Watchdog: my message doesn't match.", - "04-25 18:33:29.273 395 637 I Watchdog: my Level doesn't match, try and find me!", - "04-25 18:33:29.273 395 637 W NotMe: my Tag doesn't match, try and find me!"); - - LogcatParser parser = new LogcatParser("2012"); - assertNotNull(parser); - parser.addPattern(Pattern.compile(".*find*."), "W", "Watchdog", "WatchdogCategory"); - LogcatItem logcat = parser.parse(lines); - assertNotNull(logcat); - - /* verify that we find the only entry that matches based on Level, Tag, AND Message */ - List matchedEvents = logcat.getMiscEvents("WatchdogCategory"); - assertEquals(1, matchedEvents.size()); - assertEquals("Watchdog", matchedEvents.get(0).getTag()); - assertEquals("I'm the one you need to find!", matchedEvents.get(0).getStack()); - } - - public void testFatalException() { - List lines = Arrays.asList( - "06-05 06:14:51.529 1712 1712 D AndroidRuntime: Calling main entry com.android.commands.input.Input", - "06-05 06:14:51.709 1712 1712 E AndroidRuntime: *** FATAL EXCEPTION IN SYSTEM PROCESS: main", - "06-05 06:14:51.709 1712 1712 E AndroidRuntime: java.lang.NullPointerException", - "06-05 06:14:51.709 1712 1712 E AndroidRuntime: \tat android.hardware.input.InputManager.injectInputEvent(InputManager.java:641)", - "06-05 06:14:51.709 1712 1712 E AndroidRuntime: \tat com.android.commands.input.Input.injectKeyEvent(Input.java:233)", - "06-05 06:14:51.709 1712 1712 E AndroidRuntime: \tat com.android.commands.input.Input.sendKeyEvent(Input.java:184)", - "06-05 06:14:51.709 1712 1712 E AndroidRuntime: \tat com.android.commands.input.Input.run(Input.java:96)", - "06-05 06:14:51.709 1712 1712 E AndroidRuntime: \tat com.android.commands.input.Input.main(Input.java:59)", - "06-05 06:14:51.709 1712 1712 E AndroidRuntime: \tat com.android.internal.os.RuntimeInit.nativeFinishInit(Native Method)", - "06-05 06:14:51.709 1712 1712 E AndroidRuntime: \tat com.android.internal.os.RuntimeInit.main(RuntimeInit.java:243)", - "06-05 06:14:51.709 1712 1712 E AndroidRuntime: \tat dalvik.system.NativeStart.main(Native Method)"); - LogcatParser parser = new LogcatParser("2014"); - LogcatItem logcat = parser.parse(lines); - assertEquals(1, logcat.getJavaCrashes().size()); - JavaCrashItem crash = logcat.getJavaCrashes().get(0); - assertEquals("com.android.commands.input.Input", crash.getApp()); - } - - /** - * Test that an empty input returns {@code null}. - */ - public void testEmptyInput() { - LogcatItem item = new LogcatParser().parse(Arrays.asList("")); - assertNull(item); - } - - /** - * Test that after clearing a parser, reusing it produces a new LogcatItem instead of - * appending to the previous one. - */ - public void testClear() { - List lines = Arrays.asList( - "04-25 18:33:28.273 7813 7813 E HelloTag: GetBufferLock timed out for thread 7813 buffer 0x61 usage 0x200 LockState 1", - "04-25 18:33:28.273 7813 7813 E GoodbyeTag: GetBufferLock timed out for thread 7813 buffer 0x61 usage 0x200 LockState 1" - ); - LogcatParser parser = new LogcatParser(); - LogcatItem l1 = parser.parse(lines.subList(0, 1)); - parser.clear(); - LogcatItem l2 = parser.parse(lines.subList(1, 2)); - assertEquals(l1.getEvents().size(), 1); - assertEquals(l2.getEvents().size(), 1); - assertFalse(l1.getEvents().get(0).getTag().equals(l2.getEvents().get(0).getTag())); - } - - private Date parseTime(String timeStr) throws ParseException { - DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS"); - return formatter.parse(timeStr); - } -} diff --git a/tests/src/com/android/loganalysis/parser/MemHealthParserTest.java b/tests/src/com/android/loganalysis/parser/MemHealthParserTest.java deleted file mode 100644 index 4659b76..0000000 --- a/tests/src/com/android/loganalysis/parser/MemHealthParserTest.java +++ /dev/null @@ -1,184 +0,0 @@ -/* - * Copyright (C) 2015 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.MemoryHealthItem; - -import junit.framework.TestCase; - -import java.util.Arrays; -import java.util.List; -import java.util.Map; - -/** - * Tests for memory health parser. - */ -public class MemHealthParserTest extends TestCase { - public void testOneForegroundProc() { - List lines = Arrays.asList("Foreground", - "com.google.android.gm", - "Average Native Heap: 10910", - "Average Dalvik Heap: 8011", - "Average PSS: 90454", - "Peak Native Heap: 11136", - "Peak Dalvik Heap: 9812", - "Peak PSS: 95161", - "Average Summary Java Heap: 8223", - "Average Summary Native Heap: 3852", - "Average Summary Code: 1804", - "Average Summary Stack: 246", - "Average Summary Graphics: 0", - "Average Summary Other: 855", - "Average Summary System: 9151", - "Average Summary Overall Pss: 24135", - "Count 528" - ); - - MemoryHealthItem item = new MemoryHealthParser().parse(lines); - Map> processes = item.getForeground(); - assertNotNull(processes); - assertNotNull(processes.get("com.google.android.gm")); - Map process = processes.get("com.google.android.gm"); - assertEquals(10910, process.get("native_avg").longValue()); - assertEquals(8011, process.get("dalvik_avg").longValue()); - assertEquals(90454, process.get("pss_avg").longValue()); - assertEquals(11136, process.get("native_peak").longValue()); - assertEquals(9812, process.get("dalvik_peak").longValue()); - assertEquals(95161, process.get("pss_peak").longValue()); - assertEquals(8223, process.get("summary_java_heap_avg").longValue()); - assertEquals(3852, process.get("summary_native_heap_avg").longValue()); - assertEquals(1804, process.get("summary_code_avg").longValue()); - assertEquals(246, process.get("summary_stack_avg").longValue()); - assertEquals(0, process.get("summary_graphics_avg").longValue()); - assertEquals(855, process.get("summary_other_avg").longValue()); - assertEquals(9151, process.get("summary_system_avg").longValue()); - assertEquals(24135, process.get("summary_overall_pss_avg").longValue()); - } - - public void testTwoForegroundProc() { - List lines = Arrays.asList("Foreground", - "com.google.android.gm", - "Average Native Heap: 10910", - "Average Dalvik Heap: 8011", - "Average PSS: 90454", - "Peak Native Heap: 11136", - "Peak Dalvik Heap: 9812", - "Peak PSS: 95161", - "Average Summary Java Heap: 8223", - "Average Summary Native Heap: 3852", - "Average Summary Code: 1804", - "Average Summary Stack: 246", - "Average Summary Graphics: 0", - "Average Summary Other: 855", - "Average Summary System: 9151", - "Average Summary Overall Pss: 24135", - "Count 528", - "com.google.android.music", - "Average Native Heap: 1", - "Average Dalvik Heap: 2", - "Average PSS: 3", - "Peak Native Heap: 4", - "Peak Dalvik Heap: 5", - "Peak PSS: 6", - "Average Summary Java Heap: 7", - "Average Summary Native Heap: 8", - "Average Summary Code: 9", - "Average Summary Stack: 10", - "Average Summary Graphics: 11", - "Average Summary Other: 12", - "Average Summary System: 13", - "Average Summary Overall Pss: 14", - "Count 7" - ); - - MemoryHealthItem item = new MemoryHealthParser().parse(lines); - Map> processes = item.getForeground(); - assertEquals(2, processes.size()); - Map process = processes.get("com.google.android.music"); - assertEquals(1, process.get("native_avg").longValue()); - assertEquals(2, process.get("dalvik_avg").longValue()); - assertEquals(3, process.get("pss_avg").longValue()); - assertEquals(4, process.get("native_peak").longValue()); - assertEquals(5, process.get("dalvik_peak").longValue()); - assertEquals(6, process.get("pss_peak").longValue()); - assertEquals(7, process.get("summary_java_heap_avg").longValue()); - assertEquals(8, process.get("summary_native_heap_avg").longValue()); - assertEquals(9, process.get("summary_code_avg").longValue()); - assertEquals(10, process.get("summary_stack_avg").longValue()); - assertEquals(11, process.get("summary_graphics_avg").longValue()); - assertEquals(12, process.get("summary_other_avg").longValue()); - assertEquals(13, process.get("summary_system_avg").longValue()); - assertEquals(14, process.get("summary_overall_pss_avg").longValue()); - } - - public void testForegroundBackgroundProc() { - List lines = Arrays.asList("Foreground", - "com.google.android.gm", - "Average Native Heap: 10910", - "Average Dalvik Heap: 8011", - "Average PSS: 90454", - "Peak Native Heap: 11136", - "Peak Dalvik Heap: 9812", - "Peak PSS: 95161", - "Average Summary Java Heap: 8223", - "Average Summary Native Heap: 3852", - "Average Summary Code: 1804", - "Average Summary Stack: 246", - "Average Summary Graphics: 0", - "Average Summary Other: 855", - "Average Summary System: 9151", - "Average Summary Overall Pss: 24135", - "Count 528", - "Background", - "com.google.android.music", - "Average Native Heap: 1", - "Average Dalvik Heap: 2", - "Average PSS: 3", - "Peak Native Heap: 4", - "Peak Dalvik Heap: 5", - "Peak PSS: 6", - "Average Summary Java Heap: 7", - "Average Summary Native Heap: 8", - "Average Summary Code: 9", - "Average Summary Stack: 10", - "Average Summary Graphics: 11", - "Average Summary Other: 12", - "Average Summary System: 13", - "Average Summary Overall Pss: 14", - "Count 7" - ); - - MemoryHealthItem item = new MemoryHealthParser().parse(lines); - Map> processes = item.getForeground(); - assertEquals(1, processes.size()); - assertEquals(1, item.getBackground().size()); - Map process = item.getBackground().get("com.google.android.music"); - assertEquals(1, process.get("native_avg").longValue()); - assertEquals(2, process.get("dalvik_avg").longValue()); - assertEquals(3, process.get("pss_avg").longValue()); - assertEquals(4, process.get("native_peak").longValue()); - assertEquals(5, process.get("dalvik_peak").longValue()); - assertEquals(6, process.get("pss_peak").longValue()); - assertEquals(7, process.get("summary_java_heap_avg").longValue()); - assertEquals(8, process.get("summary_native_heap_avg").longValue()); - assertEquals(9, process.get("summary_code_avg").longValue()); - assertEquals(10, process.get("summary_stack_avg").longValue()); - assertEquals(11, process.get("summary_graphics_avg").longValue()); - assertEquals(12, process.get("summary_other_avg").longValue()); - assertEquals(13, process.get("summary_system_avg").longValue()); - assertEquals(14, process.get("summary_overall_pss_avg").longValue()); - } -} diff --git a/tests/src/com/android/loganalysis/parser/MemInfoParserTest.java b/tests/src/com/android/loganalysis/parser/MemInfoParserTest.java deleted file mode 100644 index ab41b33..0000000 --- a/tests/src/com/android/loganalysis/parser/MemInfoParserTest.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright (C) 2011 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.MemInfoItem; -import com.android.loganalysis.util.ArrayUtil; - -import junit.framework.TestCase; - -import java.util.Arrays; -import java.util.List; - -/** - * Unit tests for {@link MemInfoParser} - */ -public class MemInfoParserTest extends TestCase { - - /** - * Test that normal input is parsed. - */ - public void testMemInfoParser() { - List inputBlock = Arrays.asList( - "MemTotal: 353332 kB", - "MemFree: 65420 kB", - "Buffers: 20800 kB", - "Cached: 86204 kB", - "SwapCached: 0 kB", - "Long: 34359640152 kB", - "ExtraLongIgnore: 12345678901234567890 kB"); - - MemInfoItem item = new MemInfoParser().parse(inputBlock); - - assertEquals(6, item.size()); - assertEquals((Long)353332l, item.get("MemTotal")); - assertEquals((Long)65420l, item.get("MemFree")); - assertEquals((Long)20800l, item.get("Buffers")); - assertEquals((Long)86204l, item.get("Cached")); - assertEquals((Long)0l, item.get("SwapCached")); - assertEquals((Long)34359640152l, item.get("Long")); - assertNull(item.get("ExtraLongIgnore")); - assertEquals(ArrayUtil.join("\n", inputBlock), item.getText()); - } - - /** - * Test that an empty input returns {@code null}. - */ - public void testEmptyInput() { - MemInfoItem item = new MemInfoParser().parse(Arrays.asList("")); - assertNull(item); - } -} diff --git a/tests/src/com/android/loganalysis/parser/MonkeyLogParserTest.java b/tests/src/com/android/loganalysis/parser/MonkeyLogParserTest.java deleted file mode 100644 index b7e867d..0000000 --- a/tests/src/com/android/loganalysis/parser/MonkeyLogParserTest.java +++ /dev/null @@ -1,786 +0,0 @@ -/* - * Copyright (C) 2012 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.AnrItem; -import com.android.loganalysis.item.JavaCrashItem; -import com.android.loganalysis.item.MonkeyLogItem; -import com.android.loganalysis.item.MonkeyLogItem.DroppedCategory; -import com.android.loganalysis.item.NativeCrashItem; -import com.android.loganalysis.util.ArrayUtil; - -import junit.framework.TestCase; - -import java.text.DateFormat; -import java.text.ParseException; -import java.text.SimpleDateFormat; -import java.util.Arrays; -import java.util.Date; -import java.util.List; - -/** - * Unit tests for {@link MonkeyLogParser} - */ -public class MonkeyLogParserTest extends TestCase { - - /** - * Test that a monkey can be parsed if there are no crashes. - */ - public void testParse_success() { - List lines = Arrays.asList( - "# Wednesday, 04/25/2012 01:37:12 AM - device uptime = 242.13: Monkey command used for this test:", - "adb shell monkey -p com.google.android.browser -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 528 -v -v -v 10000 ", - "", - ":Monkey: seed=528 count=10000", - ":AllowPackage: com.google.android.browser", - ":IncludeCategory: android.intent.category.LAUNCHER", - ":Switch: #Intent;action=android.intent.action.MAIN;category=android.intent.category.LAUNCHER;launchFlags=0x10200000;component=com.google.android.browser/com.android.browser.BrowserActivity;end", - " // Allowing start of Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] cmp=com.google.android.browser/com.android.browser.BrowserActivity } in package com.google.android.browser", - "Sleeping for 100 milliseconds", - ":Sending Key (ACTION_DOWN): 23 // KEYCODE_DPAD_CENTER", - ":Sending Key (ACTION_UP): 23 // KEYCODE_DPAD_CENTER", - "Sleeping for 100 milliseconds", - ":Sending Trackball (ACTION_MOVE): 0:(-5.0,3.0)", - ":Sending Trackball (ACTION_MOVE): 0:(3.0,3.0)", - ":Sending Trackball (ACTION_MOVE): 0:(-1.0,3.0)", - ":Sending Trackball (ACTION_MOVE): 0:(4.0,-2.0)", - ":Sending Trackball (ACTION_MOVE): 0:(1.0,4.0)", - ":Sending Trackball (ACTION_MOVE): 0:(-4.0,2.0)", - " //[calendar_time:2012-04-25 01:42:20.140 system_uptime:535179]", - " // Sending event #9900", - ":Sending Trackball (ACTION_MOVE): 0:(2.0,-4.0)", - ":Sending Trackball (ACTION_MOVE): 0:(-2.0,0.0)", - ":Sending Trackball (ACTION_MOVE): 0:(2.0,2.0)", - ":Sending Trackball (ACTION_MOVE): 0:(-5.0,4.0)", - "Events injected: 10000", - ":Dropped: keys=5 pointers=6 trackballs=7 flips=8 rotations=9", - "// Monkey finished", - "", - "# Wednesday, 04/25/2012 01:42:09 AM - device uptime = 539.21: Monkey command ran for: 04:57 (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-25 01:37:12"), monkeyLog.getStartTime()); - // assertEquals(parseTime("2012-04-25 01:42:09"), monkeyLog.getStopTime()); - assertEquals(1, monkeyLog.getPackages().size()); - assertTrue(monkeyLog.getPackages().contains("com.google.android.browser")); - assertEquals(1, monkeyLog.getCategories().size()); - assertTrue(monkeyLog.getCategories().contains("android.intent.category.LAUNCHER")); - assertEquals(100, monkeyLog.getThrottle()); - assertEquals(528, monkeyLog.getSeed().intValue()); - assertEquals(10000, monkeyLog.getTargetCount().intValue()); - assertTrue(monkeyLog.getIgnoreSecurityExceptions()); - assertEquals(4 * 60 * 1000 + 57 * 1000, monkeyLog.getTotalDuration().longValue()); - assertEquals(242130, monkeyLog.getStartUptimeDuration().longValue()); - assertEquals(539210, monkeyLog.getStopUptimeDuration().longValue()); - assertTrue(monkeyLog.getIsFinished()); - assertFalse(monkeyLog.getNoActivities()); - assertEquals(9900, monkeyLog.getIntermediateCount()); - assertEquals(10000, monkeyLog.getFinalCount().intValue()); - assertEquals(5, monkeyLog.getDroppedCount(DroppedCategory.KEYS).intValue()); - assertEquals(6, monkeyLog.getDroppedCount(DroppedCategory.POINTERS).intValue()); - assertEquals(7, monkeyLog.getDroppedCount(DroppedCategory.TRACKBALLS).intValue()); - assertEquals(8, monkeyLog.getDroppedCount(DroppedCategory.FLIPS).intValue()); - assertEquals(9, monkeyLog.getDroppedCount(DroppedCategory.ROTATIONS).intValue()); - assertNull(monkeyLog.getCrash()); - } - - /** - * Test that a monkey can be parsed if there is an ANR. - */ - public void testParse_anr() { - List 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 3301)", - "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", - "", - "procrank:", - "// procrank status was 0", - "anr traces:", - "", - "", - "----- pid 2887 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)", - " at class.method2(Class.java:2)", - " at class.method2(Class.java:2)", - "", - "----- end 2887 -----", - "// 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)", - "", - "----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------", - ""); - - List expectedStack = Arrays.asList( - "\"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)", - " at class.method2(Class.java:2)", - " at class.method2(Class.java:2)"); - - 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()); - assertEquals(ArrayUtil.join("\n", expectedStack), - ((AnrItem) monkeyLog.getCrash()).getTrace()); - } - - /** - * Test that a monkey can be parsed if there is a Java crash. - */ - public void testParse_java_crash() { - List lines = Arrays.asList( - "# Tuesday, 04/24/2012 05:05:50 PM - device uptime = 232.65: Monkey command used for this test:", - "adb shell monkey -p com.google.android.apps.maps -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 501 -v -v -v 10000 ", - "", - ":Monkey: seed=501 count=10000", - ":AllowPackage: com.google.android.apps.maps", - ":IncludeCategory: android.intent.category.LAUNCHER", - ":Switch: #Intent;action=android.intent.action.MAIN;category=android.intent.category.LAUNCHER;launchFlags=0x10200000;component=com.google.android.apps.maps/com.google.android.maps.LatitudeActivity;end", - " // Allowing start of Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] cmp=com.google.android.apps.maps/com.google.android.maps.LatitudeActivity } in package com.google.android.apps.maps", - "Sleeping for 100 milliseconds", - ":Sending Touch (ACTION_DOWN): 0:(332.0,70.0)", - ":Sending Touch (ACTION_UP): 0:(332.55292,76.54678)", - " //[calendar_time:2012-04-25 00:06:38.419 system_uptime:280799]", - " // Sending event #1600", - ":Sending Touch (ACTION_MOVE): 0:(1052.2666,677.64594)", - ":Sending Touch (ACTION_UP): 0:(1054.7593,687.3757)", - "Sleeping for 100 milliseconds", - "// CRASH: com.google.android.apps.maps (pid 3161)", - "// Short Msg: java.lang.Exception", - "// Long Msg: java.lang.Exception: This is the message", - "// Build Label: google/yakju/maguro:JellyBean/JRN24B/338896:userdebug/dev-keys", - "// Build Changelist: 338896", - "// Build Time: 1335309051000", - "// java.lang.Exception: This is the message", - "// \tat class.method1(Class.java:1)", - "// \tat class.method2(Class.java:2)", - "// \tat class.method3(Class.java:3)", - "// ", - "** Monkey aborted due to error.", - "Events injected: 1649", - ":Sending rotation degree=0, persist=false", - ":Dropped: keys=0 pointers=0 trackballs=0 flips=0 rotations=0", - "## Network stats: elapsed time=48897ms (0ms mobile, 48897ms wifi, 0ms not connected)", - "** System appears to have crashed at event 1649 of 10000 using seed 501", - "", - "# Tuesday, 04/24/2012 05:06:40 PM - device uptime = 282.53: Monkey command ran for: 00:49 (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:05:50"), monkeyLog.getStartTime()); - // assertEquals(parseTime("2012-04-24 17:06:40"), monkeyLog.getStopTime()); - assertEquals(1, monkeyLog.getPackages().size()); - assertTrue(monkeyLog.getPackages().contains("com.google.android.apps.maps")); - assertEquals(1, monkeyLog.getCategories().size()); - assertTrue(monkeyLog.getCategories().contains("android.intent.category.LAUNCHER")); - assertEquals(100, monkeyLog.getThrottle()); - assertEquals(501, monkeyLog.getSeed().intValue()); - assertEquals(10000, monkeyLog.getTargetCount().intValue()); - assertTrue(monkeyLog.getIgnoreSecurityExceptions()); - assertEquals(49 * 1000, monkeyLog.getTotalDuration().longValue()); - assertEquals(232650, monkeyLog.getStartUptimeDuration().longValue()); - assertEquals(282530, monkeyLog.getStopUptimeDuration().longValue()); - assertFalse(monkeyLog.getIsFinished()); - assertFalse(monkeyLog.getNoActivities()); - assertEquals(1600, monkeyLog.getIntermediateCount()); - assertEquals(1649, monkeyLog.getFinalCount().intValue()); - assertNotNull(monkeyLog.getCrash()); - assertTrue(monkeyLog.getCrash() instanceof JavaCrashItem); - assertEquals("com.google.android.apps.maps", monkeyLog.getCrash().getApp()); - assertEquals(3161, monkeyLog.getCrash().getPid().intValue()); - assertEquals("java.lang.Exception", ((JavaCrashItem) monkeyLog.getCrash()).getException()); - } - - /** - * Test that a monkey can be parsed if there is a Java crash even if monkey lines are mixed in - * the crash. - */ - public void testParse_java_crash_mixed() { - List lines = Arrays.asList( - "# Tuesday, 04/24/2012 05:05:50 PM - device uptime = 232.65: Monkey command used for this test:", - "adb shell monkey -p com.google.android.apps.maps -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 501 -v -v -v 10000 ", - "", - ":Monkey: seed=501 count=10000", - ":AllowPackage: com.google.android.apps.maps", - ":IncludeCategory: android.intent.category.LAUNCHER", - ":Switch: #Intent;action=android.intent.action.MAIN;category=android.intent.category.LAUNCHER;launchFlags=0x10200000;component=com.google.android.apps.maps/com.google.android.maps.LatitudeActivity;end", - " // Allowing start of Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] cmp=com.google.android.apps.maps/com.google.android.maps.LatitudeActivity } in package com.google.android.apps.maps", - "Sleeping for 100 milliseconds", - ":Sending Touch (ACTION_DOWN): 0:(332.0,70.0)", - ":Sending Touch (ACTION_UP): 0:(332.55292,76.54678)", - " //[calendar_time:2012-04-25 00:06:38.419 system_uptime:280799]", - " // Sending event #1600", - ":Sending Touch (ACTION_MOVE): 0:(1052.2666,677.64594)", - "// CRASH: com.google.android.apps.maps (pid 3161)", - "// Short Msg: java.lang.Exception", - ":Sending Touch (ACTION_UP): 0:(1054.7593,687.3757)", - "// Long Msg: java.lang.Exception: This is the message", - "// Build Label: google/yakju/maguro:JellyBean/JRN24B/338896:userdebug/dev-keys", - "// Build Changelist: 338896", - "Sleeping for 100 milliseconds", - "// Build Time: 1335309051000", - "// java.lang.Exception: This is the message", - "// \tat class.method1(Class.java:1)", - "// \tat class.method2(Class.java:2)", - "// \tat class.method3(Class.java:3)", - "// ", - "** Monkey aborted due to error.", - "Events injected: 1649", - ":Sending rotation degree=0, persist=false", - ":Dropped: keys=0 pointers=0 trackballs=0 flips=0 rotations=0", - "## Network stats: elapsed time=48897ms (0ms mobile, 48897ms wifi, 0ms not connected)", - "** System appears to have crashed at event 1649 of 10000 using seed 501", - "", - "# Tuesday, 04/24/2012 05:06:40 PM - device uptime = 282.53: Monkey command ran for: 00:49 (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:05:50"), monkeyLog.getStartTime()); - // assertEquals(parseTime("2012-04-24 17:06:40"), monkeyLog.getStopTime()); - assertEquals(1, monkeyLog.getPackages().size()); - assertTrue(monkeyLog.getPackages().contains("com.google.android.apps.maps")); - assertEquals(1, monkeyLog.getCategories().size()); - assertTrue(monkeyLog.getCategories().contains("android.intent.category.LAUNCHER")); - assertEquals(100, monkeyLog.getThrottle()); - assertEquals(501, monkeyLog.getSeed().intValue()); - assertEquals(10000, monkeyLog.getTargetCount().intValue()); - assertTrue(monkeyLog.getIgnoreSecurityExceptions()); - assertEquals(49 * 1000, monkeyLog.getTotalDuration().longValue()); - assertEquals(232650, monkeyLog.getStartUptimeDuration().longValue()); - assertEquals(282530, monkeyLog.getStopUptimeDuration().longValue()); - assertFalse(monkeyLog.getIsFinished()); - assertFalse(monkeyLog.getNoActivities()); - assertEquals(1600, monkeyLog.getIntermediateCount()); - assertEquals(1649, monkeyLog.getFinalCount().intValue()); - assertNotNull(monkeyLog.getCrash()); - assertTrue(monkeyLog.getCrash() instanceof JavaCrashItem); - assertEquals("com.google.android.apps.maps", monkeyLog.getCrash().getApp()); - assertEquals(3161, monkeyLog.getCrash().getPid().intValue()); - assertEquals("java.lang.Exception", ((JavaCrashItem) monkeyLog.getCrash()).getException()); - } - - - /** - * Test that a monkey can be parsed if there is a native crash. - */ - public void testParse_native_crash() { - List lines = Arrays.asList( - "# Tuesday, 04/24/2012 05:05:50 PM - device uptime = 232.65: Monkey command used for this test:", - "adb shell monkey -p com.google.android.apps.maps -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 501 -v -v -v 10000 ", - "", - ":Monkey: seed=501 count=10000", - ":AllowPackage: com.google.android.apps.maps", - ":IncludeCategory: android.intent.category.LAUNCHER", - ":Switch: #Intent;action=android.intent.action.MAIN;category=android.intent.category.LAUNCHER;launchFlags=0x10200000;component=com.google.android.apps.maps/com.google.android.maps.LatitudeActivity;end", - " // Allowing start of Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] cmp=com.google.android.apps.maps/com.google.android.maps.LatitudeActivity } in package com.google.android.apps.maps", - "Sleeping for 100 milliseconds", - ":Sending Touch (ACTION_DOWN): 0:(332.0,70.0)", - ":Sending Touch (ACTION_UP): 0:(332.55292,76.54678)", - " //[calendar_time:2012-04-25 00:06:38.419 system_uptime:280799]", - " // Sending event #1600", - ":Sending Touch (ACTION_MOVE): 0:(1052.2666,677.64594)", - ":Sending Touch (ACTION_UP): 0:(1054.7593,687.3757)", - "Sleeping for 100 milliseconds", - "// CRASH: com.android.chrome (pid 2162)", - "// Short Msg: Native crash", - "// Long Msg: Native crash: Segmentation fault", - "// Build Label: google/mantaray/manta:JellyBeanMR2/JWR02/624470:userdebug/dev-keys", - "// Build Changelist: 624470", - "// Build Time: 1364920502000", - "// *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***", - "// Build fingerprint: 'google/mantaray/manta:4.1/JRO01/12345:userdebug/dev-keys'", - "// Revision: '7'", - "// pid: 2162, tid: 2216, name: .android.chrome >>> com.android.chrome <<<", - "// signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr deadbaad", - "// r0 00000027 r1 00001000 r2 00000008 r3 deadbaad", - "// r4 00000000 r5 7af65e64 r6 00000000 r7 7af65ea4", - "// r8 401291f4 r9 00200000 sl 7784badc fp 00001401", - "// ip 7af65ea4 sp 7af65e60 lr 400fed6b pc 400fc2d4 cpsr 600f0030", - "// d0 3332303033312034 d1 6361707320737332", - "// d2 632e6c6f6f705f34 d3 205d29383231280a", - "// scr 60000010", - "// ", - "// backtrace:", - "// #00 pc 0001e2d4 /system/lib/libc.so", - "// #01 pc 0001c4bc /system/lib/libc.so (abort+4)", - "// #02 pc 0023a515 /system/lib/libchromeview.so", - "// #03 pc 006f8a27 /system/lib/libchromeview.so", - "// ", - "// stack:", - "// 7af65e20 77856cf8 ", - "// 7af65e24 7af65e64 [stack:2216]", - "// 7af65e28 00000014 ", - "// 7af65e2c 76a88e6c /system/lib/libchromeview.so", - "** Monkey aborted due to error.", - "Events injected: 1649", - ":Sending rotation degree=0, persist=false", - ":Dropped: keys=0 pointers=0 trackballs=0 flips=0 rotations=0", - "## Network stats: elapsed time=48897ms (0ms mobile, 48897ms wifi, 0ms not connected)", - "** System appears to have crashed at event 1649 of 10000 using seed 501", - "", - "# Tuesday, 04/24/2012 05:06:40 PM - device uptime = 282.53: Monkey command ran for: 00:49 (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:05:50"), monkeyLog.getStartTime()); - // assertEquals(parseTime("2012-04-24 17:06:40"), monkeyLog.getStopTime()); - assertEquals(1, monkeyLog.getPackages().size()); - assertTrue(monkeyLog.getPackages().contains("com.google.android.apps.maps")); - assertEquals(1, monkeyLog.getCategories().size()); - assertTrue(monkeyLog.getCategories().contains("android.intent.category.LAUNCHER")); - assertEquals(100, monkeyLog.getThrottle()); - assertEquals(501, monkeyLog.getSeed().intValue()); - assertEquals(10000, monkeyLog.getTargetCount().intValue()); - assertTrue(monkeyLog.getIgnoreSecurityExceptions()); - assertEquals(49 * 1000, monkeyLog.getTotalDuration().longValue()); - assertEquals(232650, monkeyLog.getStartUptimeDuration().longValue()); - assertEquals(282530, monkeyLog.getStopUptimeDuration().longValue()); - assertFalse(monkeyLog.getIsFinished()); - assertFalse(monkeyLog.getNoActivities()); - assertEquals(1600, monkeyLog.getIntermediateCount()); - assertEquals(1649, monkeyLog.getFinalCount().intValue()); - assertNotNull(monkeyLog.getCrash()); - assertTrue(monkeyLog.getCrash() instanceof NativeCrashItem); - assertEquals("com.android.chrome", monkeyLog.getCrash().getApp()); - assertEquals(2162, monkeyLog.getCrash().getPid().intValue()); - assertEquals("google/mantaray/manta:4.1/JRO01/12345:userdebug/dev-keys", - ((NativeCrashItem) monkeyLog.getCrash()).getFingerprint()); - // Make sure that the entire stack is included. - assertEquals(23, ((NativeCrashItem) monkeyLog.getCrash()).getStack().split("\n").length); - } - - /** - * Test that a monkey can be parsed if there is a native crash with extra info at the end. - */ - public void testParse_native_crash_strip_extra() { - List lines = Arrays.asList( - "# Tuesday, 04/24/2012 05:05:50 PM - device uptime = 232.65: Monkey command used for this test:", - "adb shell monkey -p com.google.android.apps.maps -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 501 -v -v -v 10000 ", - "", - ":Monkey: seed=501 count=10000", - ":AllowPackage: com.google.android.apps.maps", - ":IncludeCategory: android.intent.category.LAUNCHER", - ":Switch: #Intent;action=android.intent.action.MAIN;category=android.intent.category.LAUNCHER;launchFlags=0x10200000;component=com.google.android.apps.maps/com.google.android.maps.LatitudeActivity;end", - " // Allowing start of Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] cmp=com.google.android.apps.maps/com.google.android.maps.LatitudeActivity } in package com.google.android.apps.maps", - "Sleeping for 100 milliseconds", - ":Sending Touch (ACTION_DOWN): 0:(332.0,70.0)", - ":Sending Touch (ACTION_UP): 0:(332.55292,76.54678)", - " //[calendar_time:2012-04-25 00:06:38.419 system_uptime:280799]", - " // Sending event #1600", - ":Sending Touch (ACTION_MOVE): 0:(1052.2666,677.64594)", - ":Sending Touch (ACTION_UP): 0:(1054.7593,687.3757)", - "Sleeping for 100 milliseconds", - "// CRASH: com.android.chrome (pid 2162)", - "// Short Msg: Native crash", - "// Long Msg: Native crash: Segmentation fault", - "// Build Label: google/mantaray/manta:JellyBeanMR2/JWR02/624470:userdebug/dev-keys", - "// Build Changelist: 624470", - "// Build Time: 1364920502000", - "// *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***", - "// Build fingerprint: 'google/mantaray/manta:4.1/JRO01/12345:userdebug/dev-keys'", - "// Revision: '7'", - "// pid: 2162, tid: 2216, name: .android.chrome >>> com.android.chrome <<<", - "// signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr deadbaad", - "// r0 00000027 r1 00001000 r2 00000008 r3 deadbaad", - "// r4 00000000 r5 7af65e64 r6 00000000 r7 7af65ea4", - "// r8 401291f4 r9 00200000 sl 7784badc fp 00001401", - "// ip 7af65ea4 sp 7af65e60 lr 400fed6b pc 400fc2d4 cpsr 600f0030", - "// d0 3332303033312034 d1 6361707320737332", - "// d2 632e6c6f6f705f34 d3 205d29383231280a", - "// scr 60000010", - "// ", - "// backtrace:", - "// #00 pc 0001e2d4 /system/lib/libc.so", - "// #01 pc 0001c4bc /system/lib/libc.so (abort+4)", - "// #02 pc 0023a515 /system/lib/libchromeview.so", - "// #03 pc 006f8a27 /system/lib/libchromeview.so", - "// ", - "// stack:", - "// 7af65e20 77856cf8 ", - "// 7af65e24 7af65e64 [stack:2216]", - "// 7af65e28 00000014 ", - "// 7af65e2c 76a88e6c /system/lib/libchromeview.so", - "// ** New native crash detected.", - "** Monkey aborted due to error.", - "Events injected: 1649", - ":Sending rotation degree=0, persist=false", - ":Dropped: keys=0 pointers=0 trackballs=0 flips=0 rotations=0", - "## Network stats: elapsed time=48897ms (0ms mobile, 48897ms wifi, 0ms not connected)", - "** System appears to have crashed at event 1649 of 10000 using seed 501", - "", - "# Tuesday, 04/24/2012 05:06:40 PM - device uptime = 282.53: Monkey command ran for: 00:49 (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:05:50"), monkeyLog.getStartTime()); - // assertEquals(parseTime("2012-04-24 17:06:40"), monkeyLog.getStopTime()); - assertEquals(1, monkeyLog.getPackages().size()); - assertTrue(monkeyLog.getPackages().contains("com.google.android.apps.maps")); - assertEquals(1, monkeyLog.getCategories().size()); - assertTrue(monkeyLog.getCategories().contains("android.intent.category.LAUNCHER")); - assertEquals(100, monkeyLog.getThrottle()); - assertEquals(501, monkeyLog.getSeed().intValue()); - assertEquals(10000, monkeyLog.getTargetCount().intValue()); - assertTrue(monkeyLog.getIgnoreSecurityExceptions()); - assertEquals(49 * 1000, monkeyLog.getTotalDuration().longValue()); - assertEquals(232650, monkeyLog.getStartUptimeDuration().longValue()); - assertEquals(282530, monkeyLog.getStopUptimeDuration().longValue()); - assertFalse(monkeyLog.getIsFinished()); - assertFalse(monkeyLog.getNoActivities()); - assertEquals(1600, monkeyLog.getIntermediateCount()); - assertEquals(1649, monkeyLog.getFinalCount().intValue()); - assertNotNull(monkeyLog.getCrash()); - assertTrue(monkeyLog.getCrash() instanceof NativeCrashItem); - assertEquals("com.android.chrome", monkeyLog.getCrash().getApp()); - assertEquals(2162, monkeyLog.getCrash().getPid().intValue()); - NativeCrashItem nc = (NativeCrashItem) monkeyLog.getCrash(); - assertEquals("google/mantaray/manta:4.1/JRO01/12345:userdebug/dev-keys", - nc.getFingerprint()); - // Make sure that the stack with the last line stripped is included. - assertEquals(23, nc.getStack().split("\n").length); - assertFalse(nc.getStack().contains("New native crash detected")); - } - - /** - * Test that a monkey can be parsed if there is an empty native crash. - */ - public void testParse_native_crash_empty() { - List lines = Arrays.asList( - "# Tuesday, 04/24/2012 05:05:50 PM - device uptime = 232.65: Monkey command used for this test:", - "adb shell monkey -p com.google.android.apps.maps -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 501 -v -v -v 10000 ", - "", - ":Monkey: seed=501 count=10000", - ":AllowPackage: com.google.android.apps.maps", - ":IncludeCategory: android.intent.category.LAUNCHER", - ":Switch: #Intent;action=android.intent.action.MAIN;category=android.intent.category.LAUNCHER;launchFlags=0x10200000;component=com.google.android.apps.maps/com.google.android.maps.LatitudeActivity;end", - " // Allowing start of Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] cmp=com.google.android.apps.maps/com.google.android.maps.LatitudeActivity } in package com.google.android.apps.maps", - "Sleeping for 100 milliseconds", - ":Sending Touch (ACTION_DOWN): 0:(332.0,70.0)", - ":Sending Touch (ACTION_UP): 0:(332.55292,76.54678)", - " //[calendar_time:2012-04-25 00:06:38.419 system_uptime:280799]", - " // Sending event #1600", - ":Sending Touch (ACTION_MOVE): 0:(1052.2666,677.64594)", - ":Sending Touch (ACTION_UP): 0:(1054.7593,687.3757)", - "Sleeping for 100 milliseconds", - "** New native crash detected.", - "** Monkey aborted due to error.", - "Events injected: 1649", - ":Sending rotation degree=0, persist=false", - ":Dropped: keys=0 pointers=0 trackballs=0 flips=0 rotations=0", - "## Network stats: elapsed time=48897ms (0ms mobile, 48897ms wifi, 0ms not connected)", - "** System appears to have crashed at event 1649 of 10000 using seed 501", - "", - "# Tuesday, 04/24/2012 05:06:40 PM - device uptime = 282.53: Monkey command ran for: 00:49 (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:05:50"), monkeyLog.getStartTime()); - // assertEquals(parseTime("2012-04-24 17:06:40"), monkeyLog.getStopTime()); - assertEquals(1, monkeyLog.getPackages().size()); - assertTrue(monkeyLog.getPackages().contains("com.google.android.apps.maps")); - assertEquals(1, monkeyLog.getCategories().size()); - assertTrue(monkeyLog.getCategories().contains("android.intent.category.LAUNCHER")); - assertEquals(100, monkeyLog.getThrottle()); - assertEquals(501, monkeyLog.getSeed().intValue()); - assertEquals(10000, monkeyLog.getTargetCount().intValue()); - assertTrue(monkeyLog.getIgnoreSecurityExceptions()); - assertEquals(49 * 1000, monkeyLog.getTotalDuration().longValue()); - assertEquals(232650, monkeyLog.getStartUptimeDuration().longValue()); - assertEquals(282530, monkeyLog.getStopUptimeDuration().longValue()); - assertFalse(monkeyLog.getIsFinished()); - assertFalse(monkeyLog.getNoActivities()); - assertEquals(1600, monkeyLog.getIntermediateCount()); - assertEquals(1649, monkeyLog.getFinalCount().intValue()); - assertNotNull(monkeyLog.getCrash()); - assertTrue(monkeyLog.getCrash() instanceof NativeCrashItem); - assertNull(monkeyLog.getCrash().getApp()); - assertNull(monkeyLog.getCrash().getPid()); - NativeCrashItem nc = (NativeCrashItem) monkeyLog.getCrash(); - assertNull(nc.getFingerprint()); - assertEquals("", nc.getStack()); - } - - /** - * Test that a monkey can be parsed if there are no activities to run. - */ - public void testParse_no_activities() { - List lines = Arrays.asList( - "# Wednesday, 04/25/2012 01:37:12 AM - device uptime = 242.13: Monkey command used for this test:", - "adb shell monkey -p com.google.android.browser -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 528 -v -v -v 10000 ", - "", - ":Monkey: seed=528 count=10000", - ":AllowPackage: com.google.android.browser", - ":IncludeCategory: android.intent.category.LAUNCHER", - "** No activities found to run, monkey aborted.", - "", - "# Wednesday, 04/25/2012 01:42:09 AM - device uptime = 539.21: Monkey command ran for: 04:57 (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-25 01:37:12"), monkeyLog.getStartTime()); - // assertEquals(parseTime("2012-04-25 01:42:09"), monkeyLog.getStopTime()); - assertEquals(1, monkeyLog.getPackages().size()); - assertTrue(monkeyLog.getPackages().contains("com.google.android.browser")); - assertEquals(1, monkeyLog.getCategories().size()); - assertTrue(monkeyLog.getCategories().contains("android.intent.category.LAUNCHER")); - assertEquals(100, monkeyLog.getThrottle()); - assertEquals(528, monkeyLog.getSeed().intValue()); - assertEquals(10000, monkeyLog.getTargetCount().intValue()); - assertTrue(monkeyLog.getIgnoreSecurityExceptions()); - assertEquals(4 * 60 * 1000 + 57 * 1000, monkeyLog.getTotalDuration().longValue()); - assertEquals(242130, monkeyLog.getStartUptimeDuration().longValue()); - assertEquals(539210, monkeyLog.getStopUptimeDuration().longValue()); - assertFalse(monkeyLog.getIsFinished()); - assertTrue(monkeyLog.getNoActivities()); - assertEquals(0, monkeyLog.getIntermediateCount()); - assertNull(monkeyLog.getFinalCount()); - assertNull(monkeyLog.getDroppedCount(DroppedCategory.KEYS)); - assertNull(monkeyLog.getDroppedCount(DroppedCategory.POINTERS)); - assertNull(monkeyLog.getDroppedCount(DroppedCategory.TRACKBALLS)); - assertNull(monkeyLog.getDroppedCount(DroppedCategory.FLIPS)); - assertNull(monkeyLog.getDroppedCount(DroppedCategory.ROTATIONS)); - assertNull(monkeyLog.getCrash()); - } - - /** - * Test that a monkey can be parsed if there is an ANR in the middle of the traces. - */ - public void testParse_malformed_anr() { - List 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() { - List lines = Arrays.asList( - "# Tue Apr 24 17:05:50 PST 2012 - device uptime = 232.65: Monkey command used for this test:", - "adb shell monkey -p com.google.android.apps.maps -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 501 -v -v -v 10000 ", - "", - "# Tue Apr 24 17:06:40 PST 2012 - device uptime = 282.53: Monkey command ran for: 00:49 (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:05:50"), monkeyLog.getStartTime()); - // assertEquals(parseTime("2012-04-24 17:06:40"), monkeyLog.getStopTime()); - } - - @SuppressWarnings("unused") - private Date parseTime(String timeStr) throws ParseException { - DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); - return formatter.parse(timeStr); - } -} - diff --git a/tests/src/com/android/loganalysis/parser/NativeCrashParserTest.java b/tests/src/com/android/loganalysis/parser/NativeCrashParserTest.java deleted file mode 100644 index 6c5cf98..0000000 --- a/tests/src/com/android/loganalysis/parser/NativeCrashParserTest.java +++ /dev/null @@ -1,192 +0,0 @@ -/* - * Copyright (C) 2012 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.NativeCrashItem; -import com.android.loganalysis.util.ArrayUtil; - -import junit.framework.TestCase; - -import java.util.Arrays; -import java.util.List; - -/** - * Unit tests for {@link NativeCrashParser}. - */ -public class NativeCrashParserTest extends TestCase { - - /** - * Test that native crashes are parsed. - */ - public void testParseage() { - List lines = Arrays.asList( - "Build fingerprint: 'google/soju/crespo:4.0.4/IMM76D/299849:userdebug/test-keys'", - "pid: 2058, tid: 2523 >>> com.google.android.browser <<<", - "signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 00000000", - " r0 00000000 r1 007d9064 r2 007d9063 r3 00000004", - " r4 006bf518 r5 0091e3b0 r6 00000000 r7 9e3779b9", - " r8 000006c1 r9 000006c3 10 00000000 fp 67d246c1", - " ip d2363b58 sp 50ed71d8 lr 4edfc89b pc 4edfc6a0 cpsr 20000030", - " d0 00640065005f0065 d1 0072006f00740069", - " d2 00730075006e006b d3 0066006900670000", - " d4 00e6d48800e6d3b8 d5 02d517a000e6d518", - " d6 0000270f02d51860 d7 0000000002d51a80", - " d8 41d3dc5261e7893b d9 3fa999999999999a", - " d10 0000000000000000 d11 0000000000000000", - " d12 0000000000000000 d13 0000000000000000", - " d14 0000000000000000 d15 0000000000000000", - " d16 4070000000000000 d17 40c3878000000000", - " d18 412310f000000000 d19 3f91800dedacf040", - " d20 0000000000000000 d21 0000000000000000", - " d22 4010000000000000 d23 0000000000000000", - " d24 3ff0000000000000 d25 0000000000000000", - " d26 0000000000000000 d27 8000000000000000", - " d28 0000000000000000 d29 3ff0000000000000", - " d30 0000000000000000 d31 3ff0000000000000", - " scr 20000013", - "", - " #00 pc 001236a0 /system/lib/libwebcore.so", - " #01 pc 00123896 /system/lib/libwebcore.so", - " #02 pc 00123932 /system/lib/libwebcore.so", - " #03 pc 00123e3a /system/lib/libwebcore.so", - " #04 pc 00123e84 /system/lib/libwebcore.so", - " #05 pc 003db92a /system/lib/libwebcore.so", - " #06 pc 003dd01c /system/lib/libwebcore.so", - " #07 pc 002ffb92 /system/lib/libwebcore.so", - " #08 pc 0031c120 /system/lib/libwebcore.so", - " #09 pc 0031c134 /system/lib/libwebcore.so", - " #10 pc 0013fb98 /system/lib/libwebcore.so", - " #11 pc 0015b026 /system/lib/libwebcore.so", - " #12 pc 0015b164 /system/lib/libwebcore.so", - " #13 pc 0015f4cc /system/lib/libwebcore.so", - " #14 pc 00170472 /system/lib/libwebcore.so", - " #15 pc 0016ecb6 /system/lib/libwebcore.so", - " #16 pc 0027120e /system/lib/libwebcore.so", - " #17 pc 0026efec /system/lib/libwebcore.so", - " #18 pc 0026fcd8 /system/lib/libwebcore.so", - " #19 pc 00122efa /system/lib/libwebcore.so", - "", - "code around pc:", - "4edfc680 4a14b5f7 0601f001 23000849 3004f88d ...J....I..#...0", - "4edfc690 460a9200 3006f8ad e00e4603 3a019f00 ...F...0.F.....:", - "4edfc6a0 5c04f833 f83319ed 042c7c02 2cc7ea84 3..\\..3..|,....,", - "4edfc6b0 0405ea8c 24d4eb04 33049400 d1ed2a00 .......$...3.*..", - "4edfc6c0 f830b126 46681021 ff72f7ff f7ff4668 &.0.!.hF..r.hF..", - "", - "code around lr:", - "4edfc878 f9caf7ff 60209e03 9605e037 5b04f856 ...... `7...V..[", - "4edfc888 d0302d00 d13b1c6b 68a8e02d f7ff6869 .-0.k.;.-..hih..", - "4edfc898 6128fef3 b010f8d5 99022500 ea0146aa ..(a.....%...F..", - "4edfc8a8 9b01080b 0788eb03 3028f853 b9bdb90b ........S.(0....", - "4edfc8b8 3301e015 4638d005 f7ff9905 b970ff15 ...3..8F......p.", - "", - "stack:", - " 50ed7198 01d02c08 [heap]", - " 50ed719c 40045881 /system/lib/libc.so", - " 50ed71a0 400784c8", - " 50ed71a4 400784c8", - " 50ed71a8 02b40c68 [heap]", - " 50ed71ac 02b40c90 [heap]", - " 50ed71b0 50ed7290", - " 50ed71b4 006bf518 [heap]", - " 50ed71b8 00010000", - " 50ed71bc 50ed72a4", - " 50ed71c0 7da5a695", - " 50ed71c4 50ed7290", - " 50ed71c8 00000000", - " 50ed71cc 00000008", - " 50ed71d0 df0027ad", - " 50ed71d4 00000000", - "#00 50ed71d8 9e3779b9", - " 50ed71dc 00002000", - " 50ed71e0 00004000", - " 50ed71e4 006bf518 [heap]", - " 50ed71e8 0091e3b0 [heap]", - " 50ed71ec 01d72588 [heap]", - " 50ed71f0 00000000", - " 50ed71f4 4edfc89b /system/lib/libwebcore.so", - "#01 50ed71f8 01d70a78 [heap]", - " 50ed71fc 02b6afa8 [heap]", - " 50ed7200 00003fff", - " 50ed7204 01d70a78 [heap]", - " 50ed7208 00004000", - " 50ed720c 01d72584 [heap]", - " 50ed7210 00000000", - " 50ed7214 00000006", - " 50ed7218 006bf518 [heap]", - " 50ed721c 50ed72a4", - " 50ed7220 7da5a695", - " 50ed7224 50ed7290", - " 50ed7228 000016b8", - " 50ed722c 00000008", - " 50ed7230 01d70a78 [heap]", - " 50ed7234 4edfc937 /system/lib/libwebcore.so", - "debuggerd committing suicide to free the zombie!", - "debuggerd"); - - NativeCrashItem nc = new NativeCrashParser().parse(lines); - assertNotNull(nc); - assertEquals(2058, nc.getPid().intValue()); - assertEquals(2523, nc.getTid().intValue()); - assertEquals("com.google.android.browser", nc.getApp()); - assertEquals("google/soju/crespo:4.0.4/IMM76D/299849:userdebug/test-keys", - nc.getFingerprint()); - assertEquals(ArrayUtil.join("\n", lines), nc.getStack()); - } - - /** - * Test that both types of native crash app lines are parsed. - */ - public void testParseApp() { - List lines = Arrays.asList( - "*** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***", - "Build fingerprint: 'google/soju/crespo:4.0.4/IMM76D/299849:userdebug/test-keys'", - "pid: 2058, tid: 2523 >>> com.google.android.browser <<<", - "signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 00000000"); - - NativeCrashItem nc = new NativeCrashParser().parse(lines); - assertNotNull(nc); - assertEquals(2058, nc.getPid().intValue()); - assertEquals(2523, nc.getTid().intValue()); - assertEquals("com.google.android.browser", nc.getApp()); - - lines = Arrays.asList( - "*** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***", - "Build fingerprint: 'google/soju/crespo:4.0.4/IMM76D/299849:userdebug/test-keys'", - "pid: 2058, tid: 2523, name: com.google.android.browser >>> com.google.android.browser <<<", - "signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 00000000"); - - nc = new NativeCrashParser().parse(lines); - assertNotNull(nc); - - assertEquals(2058, nc.getPid().intValue()); - assertEquals(2523, nc.getTid().intValue()); - assertEquals("com.google.android.browser", nc.getApp()); - - lines = Arrays.asList( - "*** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***", - "Build fingerprint: 'google/soju/crespo:4.0.4/IMM76D/299849:userdebug/test-keys'", - "pid: 2058, tid: 2523, name: Atlas Worker #1 >>> com.google.android.browser <<<", - "signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 00000000"); - - nc = new NativeCrashParser().parse(lines); - assertNotNull(nc); - - assertEquals(2058, nc.getPid().intValue()); - assertEquals(2523, nc.getTid().intValue()); - assertEquals("com.google.android.browser", nc.getApp()); - } -} diff --git a/tests/src/com/android/loganalysis/parser/ProcessUsageParserTest.java b/tests/src/com/android/loganalysis/parser/ProcessUsageParserTest.java deleted file mode 100644 index bfba620..0000000 --- a/tests/src/com/android/loganalysis/parser/ProcessUsageParserTest.java +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright (C) 2015 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.ProcessUsageItem; -import com.android.loganalysis.item.ProcessUsageItem.ProcessUsageInfoItem; -import com.android.loganalysis.item.ProcessUsageItem.SensorInfoItem; - -import junit.framework.TestCase; - -import java.util.Arrays; -import java.util.LinkedList; -import java.util.List; - -/** - * Unit tests for {@link ProcessUsageParser} - */ -public class ProcessUsageParserTest extends TestCase { - - /** - * Test that normal input is parsed. - */ - public void testProcessUsageParser() { - List inputBlock = Arrays.asList( - " 0:", - " Mobile network: 173.70KB received, 102.55KB sent (packets 129)", - " Mobile radio active: 6m 5s 80ms (14.9%) 80x @ 139 mspp", - " 1000:", - " Mobile network: 16.43KB received, 26.26KB sent", - " Mobile radio active: 1m 17s 489ms (3.2%) 61x @ 179 mspp", - " Sensor 44: 27m 18s 207ms realtime (22 times)", - " Sensor 36: 6s 483ms realtime (3 times)", - " Proc servicemanager:", - " CPU: 2s 20ms usr + 4s 60ms krn ; 0ms fg", - " Apk android:", - " 266 wakeup alarms", - " u0a2:", - " Mobile network: 16.43KB received, 26.26KB sent", - " Mobile radio active: 1m 17s 489ms (3.2%) 61x @ 179 mspp", - " Sensor 0: 5s 207ms realtime (2 times)", - " Proc servicemanager:", - " CPU: 2s 20ms usr + 4s 60ms krn ; 0ms fg", - " Apk android:", - " 2 wakeup alarms", - " "); - - ProcessUsageItem processUsage = new ProcessUsageParser().parse(inputBlock); - - assertEquals(3, processUsage.getProcessUsage().size()); - - LinkedList processUsageInfo = - (LinkedList)processUsage.getProcessUsage(); - - assertEquals("1000", processUsageInfo.get(1).getProcessUID()); - assertEquals(266, processUsageInfo.get(1).getAlarmWakeups()); - - LinkedList sensor = processUsageInfo.get(1).getSensorUsage(); - assertEquals("44", sensor.get(0).getSensorName()); - assertEquals("36", sensor.get(1).getSensorName()); - - sensor = processUsageInfo.get(2).getSensorUsage(); - assertEquals("0", sensor.get(0).getSensorName()); - } -} - diff --git a/tests/src/com/android/loganalysis/parser/ProcrankParserTest.java b/tests/src/com/android/loganalysis/parser/ProcrankParserTest.java deleted file mode 100644 index c47b750..0000000 --- a/tests/src/com/android/loganalysis/parser/ProcrankParserTest.java +++ /dev/null @@ -1,105 +0,0 @@ -/* - * Copyright (C) 2011 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.ProcrankItem; -import com.android.loganalysis.util.ArrayUtil; - -import junit.framework.TestCase; - -import java.util.Arrays; -import java.util.List; - -/** - * Unit tests for {@link ProcrankParser} - */ -public class ProcrankParserTest extends TestCase { - - /** - * Test that normal input is parsed. - */ - public void testProcRankParserShortLine() { - List inputBlock = Arrays.asList( - " PID Vss Rss Pss Uss cmdline", - " 178 87136K 81684K 52829K 50012K system_server", - " 1313 78128K 77996K 48603K 45812K com.google.android.apps.maps", - " 3247 61652K 61492K 33122K 30972K com.android.browser", - " 334 55740K 55572K 29629K 28360K com.android.launcher", - " 2072 51348K 51172K 24263K 22812K android.process.acore", - " 1236 51440K 51312K 22911K 20608K com.android.settings", - " 51312K 22911K 20608K invalid.format", - " ------ ------ ------", - " 203624K 163604K TOTAL", - "RAM: 731448K total, 415804K free, 9016K buffers, 108548K cached", - "[procrank: 1.6s elapsed]"); - - ProcrankItem procrank = new ProcrankParser().parse(inputBlock); - - // Ensures that only valid lines are parsed. Only 6 of the 11 lines under the header are - // valid. - assertEquals(6, procrank.getPids().size()); - - // Make sure all expected rows are present, and do a diagonal check of values - assertEquals((Integer) 87136, procrank.getVss(178)); - assertEquals((Integer) 77996, procrank.getRss(1313)); - assertEquals((Integer) 33122, procrank.getPss(3247)); - assertEquals((Integer) 28360, procrank.getUss(334)); - assertEquals("android.process.acore", procrank.getProcessName(2072)); - assertEquals(ArrayUtil.join("\n", inputBlock), procrank.getText()); - } - - /** - * Test that normal input is parsed. - */ - public void testProcRankParserLongLine() { - List inputBlock = Arrays.asList( - " PID Vss Rss Pss Uss Swap PSwap USwap ZSwap cmdline", - " 6711 3454396K 146300K 108431K 105524K 31540K 20522K 20188K 4546K com.google.android.GoogleCamera", - " 1515 2535920K 131984K 93750K 89440K 42676K 31792K 31460K 7043K system_server", - "19906 2439540K 130228K 85418K 69296K 11680K 353K 0K 78K com.android.chrome:sandboxed_process10", - "13790 2596308K 124424K 75673K 69680K 11336K 334K 0K 74K com.google.android.youtube", - " 9288 2437704K 119496K 74288K 69532K 11344K 334K 0K 74K com.google.android.videos", - " 51312K 22911K 20608K 0K 0K 0K invalid.format", - " ------ ------ ------ ------ ------ ------ ------", - " 1061237K 940460K 619796K 225468K 201688K 49950K TOTAL", - "ZRAM: 52892K physical used for 238748K in swap (520908K total swap)", - "RAM: 1857348K total, 51980K free, 3780K buffers, 456272K cached, 29220K shmem, 97560K slab", - "[/system/xbin/su: 3.260s elapsed]"); - - ProcrankItem procrank = new ProcrankParser().parse(inputBlock); - - // Ensures that only valid lines are parsed. Only 6 of the 11 lines under the header are - // valid. - assertEquals(5, procrank.getPids().size()); - - // Make sure all expected rows are present, and do a diagonal check of values - assertEquals((Integer) 3454396, procrank.getVss(6711)); - assertEquals((Integer) 146300, procrank.getRss(6711)); - assertEquals((Integer) 108431, procrank.getPss(6711)); - assertEquals((Integer) 105524, procrank.getUss(6711)); - assertEquals("com.google.android.GoogleCamera", procrank.getProcessName(6711)); - assertEquals(ArrayUtil.join("\n", inputBlock), procrank.getText()); - } - - /** - * Test that an empty input returns {@code null}. - */ - public void testEmptyInput() { - ProcrankItem item = new ProcrankParser().parse(Arrays.asList("")); - assertNull(item); - } -} - diff --git a/tests/src/com/android/loganalysis/parser/QtaguidParserTest.java b/tests/src/com/android/loganalysis/parser/QtaguidParserTest.java deleted file mode 100644 index f9442a6..0000000 --- a/tests/src/com/android/loganalysis/parser/QtaguidParserTest.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright (C) 2015 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.QtaguidItem; - -import junit.framework.TestCase; - -import java.util.Arrays; -import java.util.List; - -public class QtaguidParserTest extends TestCase { - - public void testSingleLine() { - List input = Arrays.asList("12 wlan0 0x0 10009 0 111661 353 258252 484 111661 353 0 0 0 0 258252 484 0 0 0 0"); - - QtaguidItem item = new QtaguidParser().parse(input); - - assertEquals(1, item.getUids().size()); - assertEquals(111661, item.getRxBytes(10009)); - assertEquals(258252, item.getTxBytes(10009)); - } - - public void testMalformedLine() { - List input = Arrays.asList("a b c d", "a b c d e f g h i j k l"); - - QtaguidItem item = new QtaguidParser().parse(input); - - assertEquals(0, item.getUids().size()); - } - - public void testMultipleLines() { - List input = Arrays.asList( - "IDX IFACE ACCT_TAG_HEX UID_TAG_INT CNT_SET RX_BYTES RX_PACKETS TX_BYTES TX_PACKETS " + - "rx_tcp_bytes rx_tcp_packets rx_udp_bytes rx_udp_packets rx_other_bytes rx_other_packets " + - "tx_tcp_bytes tx_tcp_packets tx_udp_bytes tx_udp_packets tx_other_bytes tx_other_packets", - "2 wlan0 0x0 0 0 669013 7534 272120 2851 161253 1606 203916 1228 303844 4700 123336 998 108412 1268 40372 585", - "3 wlan0 0x0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0", - "4 wlan0 0x0 1000 0 104010 860 135166 2090 2304 23 101706 837 0 0 3774 36 85344 843 46048 1211", - "5 wlan0 0x0 1000 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0", - "6 wlan0 0x0 1020 0 68666 162 110566 260 0 0 68666 162 0 0 0 0 110566 260 0 0", - "7 wlan0 0x0 1020 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0", - "8 wlan0 0x0 10000 0 826063 2441 486365 2402 725175 2202 100888 239 0 0 427377 2261 58988 141 0 0", - "9 wlan0 0x0 10000 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0", - "10 wlan0 0x0 10007 0 0 0 640 10 0 0 0 0 0 0 640 10 0 0 0 0", - "11 wlan0 0x0 10007 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0", - "12 wlan0 0x0 10009 0 17773800 18040 6588861 16079 17773800 18040 0 0 0 0 6588861 16079 0 0 0 0", - "13 wlan0 0x0 10009 1 6392090 5092 109907 1235 6392090 5092 0 0 0 0 109907 1235 0 0 0 0", - "14 wlan0 0x0 10010 0 33397 41 5902 59 33397 41 0 0 0 0 5902 59 0 0 0 0", - "15 wlan0 0x0 10010 1 14949782 13336 1099914 12201 14949782 13336 0 0 0 0 1099914 12201 0 0 0 0", - "16 wlan0 0x0 10014 0 54459314 43660 1000730 9780 54459314 43660 0 0 0 0 1000730 9780 0 0 0 0", - "17 wlan0 0x0 10014 1 5411545 4459 416719 4154 5411545 4459 0 0 0 0 416719 4154 0 0 0 0", - "18 wlan0 0x0 10024 0 98775055 80471 3929490 45504 98775055 80471 0 0 0 0 3929490 45504 0 0 0 0", - "19 wlan0 0x0 10024 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0"); - QtaguidItem item = new QtaguidParser().parse(input); - assertEquals(9, item.getUids().size()); - assertEquals(24165890, item.getRxBytes(10009)); - assertEquals(6698768, item.getTxBytes(10009)); - } -} diff --git a/tests/src/com/android/loganalysis/parser/SmartMonkeyLogParserTest.java b/tests/src/com/android/loganalysis/parser/SmartMonkeyLogParserTest.java deleted file mode 100644 index 1249f7c..0000000 --- a/tests/src/com/android/loganalysis/parser/SmartMonkeyLogParserTest.java +++ /dev/null @@ -1,147 +0,0 @@ -/* - * 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.SmartMonkeyLogItem; -import com.android.loganalysis.parser.SmartMonkeyLogParser; - -import java.text.ParseException; -import java.util.Arrays; -import java.util.List; -import junit.framework.TestCase; - -/** - * Unit tests for {@link SmartMonkeyLogParser} and {@link SmartMonkeyLogItem} - */ -public class SmartMonkeyLogParserTest extends TestCase { - - /** - * Test for detecting UI exceptions - * @throws ParseException - */ - public void testExceptions() throws ParseException { - List lines = Arrays.asList( - "2013-03-04 12:33:18.789: Starting [UiAutomator Tests][com.android.cts.uiautomator]", - "2013-03-04 12:33:18.792: Target invocation count: 1000", - "2013-03-04 12:33:18.793: Throttle: 0 ms", - "2013-03-04 12:33:19.795: [ 0](Seq: -1)-Launching UiAutomator Tests", - "2013-03-04 12:33:37.211: [ 0](Seq: 0)-Found 6 candidates. Using index: 1", - "2013-03-04 12:33:37.336: [ 0](Seq: 0)-Clicking: CheckBox (760,194)", - "2013-03-04 12:33:38.443: [ 1](Seq: 0)-Found 6 candidates. Using index: 5", - "2013-03-04 12:33:38.533: [ 1](Seq: 0)-Clicking: Button~Description for Button (723,874)", - "2013-03-04 12:33:39.510: [ 2](Seq: 0)-UI Exception: CRASH: Unfortunately, UiAutomator Test App has stopped.", - "2013-03-04 12:43:39.510: [ 2](Seq: 0)-UI Exception: ANR: UiAutomator is not responding.", - "2013-03-04 12:53:39.513: Invocations requested: 1000", - "2013-03-04 12:53:39.518: Invocations completed: 2", - "2013-03-04 12:53:39.520: Device uptime: 608193 sec, Monkey run duration: 20 sec"); - - SmartMonkeyLogItem monkeyLog = new SmartMonkeyLogParser().parse(lines); - assertNotNull(monkeyLog); - assertEquals(1, monkeyLog.getCrashTimes().size()); - assertEquals(1, monkeyLog.getAnrTimes().size()); - assertEquals(SmartMonkeyLogParser.parseTime("2013-03-04 12:33:39.510"), - monkeyLog.getCrashTimes().toArray()[0]); - assertEquals(SmartMonkeyLogParser.parseTime("2013-03-04 12:43:39.510"), - monkeyLog.getAnrTimes().toArray()[0]); - } - - /** - * Tests for parsing smart monkey log header - * @throws ParseException - */ - public void testHeader() throws ParseException { - List lines = Arrays.asList( - "2013-03-04 12:33:18.789: Starting [UiAutomator Tests|YouTube][com.android.cts.uiautomator|com.google.android.youtube]", - "2013-03-04 12:33:18.792: Target invocation count: 1000", - "2013-03-04 12:33:18.793: Throttle: 1500 ms", - "2013-03-04 12:33:18.793: Device uptime: 608173 sec", - "2013-03-04 12:33:19.795: [ 0](Seq: -1)-Launching UiAutomator Tests", - "2013-03-04 12:33:37.211: [ 0](Seq: 0)-Found 6 candidates. Using index: 1", - "2013-03-04 12:33:37.336: [ 0](Seq: 0)-Clicking: CheckBox (760,194)", - "2013-03-04 12:33:38.443: [ 1](Seq: 0)-Found 6 candidates. Using index: 5", - "2013-03-04 12:33:38.533: [ 1](Seq: 0)-Clicking: Button~Description for Button (723,874)", - "2013-03-04 12:33:39.510: [ 2](Seq: 0)-UI Exception: CRASH: Unfortunately, UiAutomator Test App has stopped.", - "2013-03-04 12:43:39.510: [ 2](Seq: 0)-UI Exception: ANR: UiAutomator is not responding.", - "2013-03-04 12:53:39.513: Invocations requested: 1000", - "2013-03-04 12:53:39.518: Invocations completed: 2", - "2013-03-04 12:53:39.520: Device uptime: 608193 sec, Monkey run duration: 20 sec"); - SmartMonkeyLogItem monkeyLog = new SmartMonkeyLogParser().parse(lines); - assertNotNull(monkeyLog); - assertEquals(2, monkeyLog.getApplications().size()); - assertEquals("UiAutomator Tests", monkeyLog.getApplications().get(0)); - assertEquals("YouTube", monkeyLog.getApplications().get(1)); - assertEquals(2, monkeyLog.getPackages().size()); - assertEquals("com.android.cts.uiautomator", monkeyLog.getPackages().get(0)); - assertEquals("com.google.android.youtube", monkeyLog.getPackages().get(1)); - assertEquals(SmartMonkeyLogParser.parseTime("2013-03-04 12:33:18.789"), - monkeyLog.getStartTime()); - assertEquals(608173, monkeyLog.getStartUptimeDuration()); - assertEquals(1000, monkeyLog.getTargetInvocations()); - assertEquals(1500, monkeyLog.getThrottle()); - } - - /** - * Test for parsing log in flight - * @throws ParseException - */ - public void testIntermidiateStop() throws ParseException { - List lines = Arrays.asList( - "2013-03-04 12:33:18.789: Starting [UiAutomator Tests|YouTube][com.android.cts.uiautomator|com.google.android.youtube]", - "2013-03-04 12:33:18.792: Target invocation count: 1000", - "2013-03-04 12:33:18.793: Throttle: 1500 ms", - "2013-03-04 12:33:19.795: [ 0](Seq: -1)-Launching UiAutomator Tests", - "2013-03-04 12:33:37.211: [ 0](Seq: 0)-Found 6 candidates. Using index: 1", - "2013-03-04 12:33:37.336: [ 0](Seq: 0)-Clicking: CheckBox (760,194)", - "2013-03-04 12:33:38.443: [ 1](Seq: 0)-Found 6 candidates. Using index: 5", - "2013-03-04 12:33:38.533: [ 12](Seq: 3)-Clicking: Button~Description for Button (723,874)", - "2013-03-04 12:33:39.510: [ 12](Seq: 3)-UI Exception: CRASH: Unfortunately, UiAutomator Test App has stopped."); - - SmartMonkeyLogItem monkeyLog = new SmartMonkeyLogParser().parse(lines); - assertNotNull(monkeyLog); - assertEquals(12, monkeyLog.getIntermediateCount()); - assertEquals(SmartMonkeyLogParser.parseTime("2013-03-04 12:33:39.510"), - monkeyLog.getIntermediateTime()); - } - - /** - * Tests for parsing smart monkey log footer - * @throws ParseException - */ - public void testFooter() throws ParseException { - List lines = Arrays.asList( - "2013-03-04 12:33:18.789: Starting [UiAutomator Tests|YouTube][com.android.cts.uiautomator|com.google.android.youtube]", - "2013-03-04 12:33:18.792: Target invocation count: 1000", - "2013-03-04 12:33:18.793: Throttle: 1500 ms", - "2013-03-04 12:33:19.795: [ 0](Seq: -1)-Launching UiAutomator Tests", - "2013-03-04 12:33:37.211: [ 0](Seq: 0)-Found 6 candidates. Using index: 1", - "2013-03-04 12:33:37.336: [ 0](Seq: 0)-Clicking: CheckBox (760,194)", - "2013-03-04 12:33:38.443: [ 1](Seq: 0)-Found 6 candidates. Using index: 5", - "2013-03-04 12:33:38.533: [ 1](Seq: 0)-Clicking: Button~Description for Button (723,874)", - "2013-03-04 12:33:38.443: [ 2](Seq: 0)-Found 6 candidates. Using index: 5", - "2013-03-04 12:33:38.533: [ 2](Seq: 0)-Clicking: Button~Description for Button (723,874)", - "2013-03-04 12:53:39.513: Monkey aborted.", - "2013-03-04 12:53:39.513: Invocations requested: 1000", - "2013-03-04 12:53:39.518: Invocations completed: 999", - "2013-03-04 12:53:39.520: Device uptime: 608193 sec, Monkey run duration: 20 sec"); - - SmartMonkeyLogItem monkeyLog = new SmartMonkeyLogParser().parse(lines); - assertNotNull(monkeyLog); - assertEquals(999, monkeyLog.getFinalCount()); - assertEquals(20, monkeyLog.getTotalDuration()); - assertEquals(608193, monkeyLog.getStopUptimeDuration()); - assertEquals(true, monkeyLog.getIsAborted()); - } -} diff --git a/tests/src/com/android/loganalysis/parser/SystemPropsParserTest.java b/tests/src/com/android/loganalysis/parser/SystemPropsParserTest.java deleted file mode 100644 index f6dc8a1..0000000 --- a/tests/src/com/android/loganalysis/parser/SystemPropsParserTest.java +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright (C) 2011 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.SystemPropsItem; - -import junit.framework.TestCase; - -import java.util.Arrays; -import java.util.List; - -/** - * Unit tests for {@link SystemPropsParser} - */ -public class SystemPropsParserTest extends TestCase { - - /** - * Test that normal input is parsed. - */ - public void testSimpleParse() { - List inputBlock = Arrays.asList( - "[dalvik.vm.dexopt-flags]: [m=y]", - "[dalvik.vm.heapgrowthlimit]: [48m]", - "[dalvik.vm.heapsize]: [256m]", - "[gsm.version.ril-impl]: [android moto-ril-multimode 1.0]"); - - SystemPropsItem map = new SystemPropsParser().parse(inputBlock); - - assertEquals(4, map.size()); - assertEquals("m=y", map.get("dalvik.vm.dexopt-flags")); - assertEquals("48m", map.get("dalvik.vm.heapgrowthlimit")); - assertEquals("256m", map.get("dalvik.vm.heapsize")); - assertEquals("android moto-ril-multimode 1.0", map.get("gsm.version.ril-impl")); - } - - /** - * Make sure that a parse error on one line doesn't prevent the rest of the lines from being - * parsed - */ - public void testParseError() { - List inputBlock = Arrays.asList( - "[dalvik.vm.dexopt-flags]: [m=y]", - "[ends with newline]: [yup", - "]", - "[dalvik.vm.heapsize]: [256m]"); - - SystemPropsItem map = new SystemPropsParser().parse(inputBlock); - - assertEquals(2, map.size()); - assertEquals("m=y", map.get("dalvik.vm.dexopt-flags")); - assertEquals("256m", map.get("dalvik.vm.heapsize")); - } - - /** - * Test that an empty input returns {@code null}. - */ - public void testEmptyInput() { - SystemPropsItem item = new SystemPropsParser().parse(Arrays.asList("")); - assertNull(item); - } -} - diff --git a/tests/src/com/android/loganalysis/parser/TimingsLogParserTest.java b/tests/src/com/android/loganalysis/parser/TimingsLogParserTest.java deleted file mode 100644 index 48881ea..0000000 --- a/tests/src/com/android/loganalysis/parser/TimingsLogParserTest.java +++ /dev/null @@ -1,354 +0,0 @@ -/* - * Copyright (C) 2019 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.GenericTimingItem; -import com.android.loganalysis.item.SystemServicesTimingItem; - -import junit.framework.TestCase; - -import java.io.BufferedReader; -import java.io.ByteArrayInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.util.List; -import java.util.regex.Pattern; - -/** Unit Test for {@link TimingsLogParser} */ -public class TimingsLogParserTest extends TestCase { - - private TimingsLogParser mParser; - - public TimingsLogParserTest() { - mParser = new TimingsLogParser(); - } - - public void testParseGenericTiming_noPattern() throws IOException { - // Test when input is empty - String log = ""; - List items = mParser.parseGenericTimingItems(createBufferedReader(log)); - assertNotNull(items); - assertEquals(0, items.size()); - // Test when input is not empty - log = - String.join( - "\n", - "01-17 01:22:39.513 0 0 I CPU features: detected feature: GIC system register CPU interface", - "01-17 01:22:39.513 0 0 I CPU features: kernel page table isolation forced ON by command line option", - "01-17 01:22:39.513 0 0 I CPU features: detected feature: 32-bit EL0 Support", - "01-17 01:22:59.823 0 0 I init : Service 'bootanim' (pid 1030) exited with status 0", - "01-17 01:22:59.966 0 0 I init : processing action (sys.boot_completed=1) from (/init.rc:796)"); - items = mParser.parseGenericTimingItems(createBufferedReader(log)); - assertNotNull(items); - assertEquals(0, items.size()); - } - - public void testParseGenericTiming_multiplePattern_oneOccurrenceEach() throws IOException { - String log = - String.join( - "\n", - "01-17 01:22:39.503 0 0 I : Linux version 4.4.177 (Kernel Boot Started)", - "01-17 01:22:39.513 0 0 I CPU features: detected feature: GIC system register CPU interface", - "01-17 01:22:39.513 0 0 I CPU features: kernel page table isolation forced ON by command line option", - "01-17 01:22:39.513 0 0 I CPU features: detected feature: 32-bit EL0 Support", - "01-17 01:22:43.634 0 0 I init : starting service 'zygote'...", - "01-17 01:22:48.634 0 0 I init : 'zygote' started", - "01-17 01:22:53.392 0 0 I init : starting service 'fake service'", - "01-17 01:22:59.823 0 0 I init : Service 'bootanim' (pid 1030) exited with status 0", - "01-17 01:22:60.334 0 0 I init : 'fake service' started", - "01-17 01:22:61.362 938 1111 I ActivityManager: my app started", - "01-17 01:22:61.977 938 1111 I ActivityManager: my app displayed"); - - mParser.addDurationPatternPair( - "BootToAnimEnd", - Pattern.compile("Linux version"), - Pattern.compile("Service 'bootanim'")); - mParser.addDurationPatternPair( - "ZygoteStartTime", - Pattern.compile("starting service 'zygote'"), - Pattern.compile("'zygote' started")); - mParser.addDurationPatternPair( - "FakeServiceStartTime", - Pattern.compile("starting service 'fake service'"), - Pattern.compile("'fake service' started")); - mParser.addDurationPatternPair( - "BootToAppStart", - Pattern.compile("Linux version"), - Pattern.compile("my app displayed")); - mParser.addDurationPatternPair( - "AppStartTime", - Pattern.compile("my app started"), - Pattern.compile("my app displayed")); - mParser.addDurationPatternPair( - "ZygoteToApp", - Pattern.compile("'zygote' started"), - Pattern.compile("my app started")); - List items = mParser.parseGenericTimingItems(createBufferedReader(log)); - assertNotNull(items); - assertEquals(6, items.size()); - // 1st item - assertEquals("ZygoteStartTime", items.get(0).getName()); - assertEquals(5000.0, items.get(0).getDuration()); - // 2nd item - assertEquals("BootToAnimEnd", items.get(1).getName()); - assertEquals(20320.0, items.get(1).getDuration()); - // 3rd item - assertEquals("FakeServiceStartTime", items.get(2).getName()); - assertEquals(6942.0, items.get(2).getDuration()); - // 4th item - assertEquals("ZygoteToApp", items.get(3).getName()); - assertEquals(12728.0, items.get(3).getDuration()); - // 5th item - assertEquals("BootToAppStart", items.get(4).getName()); - assertEquals(22474.0, items.get(4).getDuration()); - // 6th item - assertEquals("AppStartTime", items.get(5).getName()); - assertEquals(615.0, items.get(5).getDuration()); - } - - public void testParseGenericTiming_multiplePattern_someNotMatched() throws IOException { - String log = - String.join( - "\n", - "01-17 01:22:39.503 0 0 I : Linux version 4.4.177 (Kernel Boot Started)", - "01-17 01:22:39.513 0 0 I CPU features: detected feature: GIC system register CPU interface", - "01-17 01:22:39.513 0 0 I CPU features: kernel page table isolation forced ON by command line option", - "01-17 01:22:39.513 0 0 I CPU features: detected feature: 32-bit EL0 Support", - "01-17 01:22:43.634 0 0 I init : starting service 'zygote'...", - "01-17 01:22:48.634 0 0 I init : 'zygote' started", - "01-17 01:22:53.392 0 0 I init : starting service 'fake service'", - "01-17 01:22:59.823 0 0 I init : Service 'bootanim' (pid 1030) exited with status 0", - "01-17 01:22:60.334 0 0 I init : 'fake service' started", - "01-17 01:22:61.362 938 1111 I ActivityManager: my app started", - "01-17 01:22:61.977 938 1111 I ActivityManager: my app displayed"); - - mParser.addDurationPatternPair( - "BootToAnimEnd", - Pattern.compile("Linux version"), - Pattern.compile("Service 'bootanim'")); - mParser.addDurationPatternPair( - "ZygoteStartTime", - Pattern.compile("starting service 'zygote'"), - Pattern.compile("End line no there")); - mParser.addDurationPatternPair( - "FakeServiceStartTime", - Pattern.compile("Start line not there"), - Pattern.compile("'fake service' started")); - mParser.addDurationPatternPair( - "AppStartTime", - Pattern.compile("Start line not there"), - Pattern.compile("End line not there")); - - List items = mParser.parseGenericTimingItems(createBufferedReader(log)); - assertNotNull(items); - assertEquals(1, items.size()); - assertEquals("BootToAnimEnd", items.get(0).getName()); - } - - public void testParseGenericTiming_clearExistingPatterns() throws IOException { - String log = - String.join( - "\n", - "01-17 01:22:39.503 0 0 I : Linux version 4.4.177 (Kernel Boot Started)", - "01-17 01:22:53.392 0 0 I init : starting service 'fake service'", - "01-17 01:22:59.823 0 0 I init : Service 'bootanim' (pid 1030) exited with status 0", - "01-17 01:22:60.334 0 0 I init : 'fake service' started", - "01-17 01:22:61.362 938 1111 I ActivityManager: my app started", - "01-17 01:22:61.977 938 1111 I ActivityManager: my app displayed"); - mParser.addDurationPatternPair( - "BootToAnimEnd", - Pattern.compile("Linux version"), - Pattern.compile("Service 'bootanim'")); - List items = mParser.parseGenericTimingItems(createBufferedReader(log)); - assertNotNull(items); - assertEquals(1, items.size()); - - mParser.clearDurationPatterns(); - items = mParser.parseGenericTimingItems(createBufferedReader(log)); - assertNotNull(items); - assertEquals(0, items.size()); - } - - public void testParseGenericTiming_multiplePattern_multipleOccurrence() throws IOException { - String log = - String.join( - "\n", - "01-17 01:22:39.503 0 0 I : Linux version 4.4.177 (Kernel Boot Started)", - "01-17 01:22:39.513 0 0 I CPU features: detected feature: GIC system register CPU interface", - "01-17 01:22:39.513 0 0 I CPU features: kernel page table isolation forced ON by command line option", - "01-17 01:22:39.513 0 0 I CPU features: detected feature: 32-bit EL0 Support", - "01-17 01:22:43.634 0 0 I init : starting service 'zygote'...", - "01-17 01:22:48.634 0 0 I init : 'zygote' started", - "01-17 01:22:53.392 0 0 I init : starting service 'fake service'", - "01-17 01:22:59.823 0 0 I init : 'bootanim' not reported", - "01-17 01:22:60.334 0 0 I init : 'fake service' started", - "01-17 01:32:39.503 0 0 I : Linux version 4.4.177 (Kernel Boot Started)", - "01-17 01:32:39.513 0 0 I CPU features: detected feature: GIC system register CPU interface", - "01-17 01:32:39.513 0 0 I CPU features: kernel page table isolation forced ON by command line option", - "01-17 01:32:39.513 0 0 I CPU features: detected feature: 32-bit EL0 Support", - "01-17 01:32:43.634 0 0 I init : starting service 'zygote'...", - "01-17 01:32:48.634 0 0 I init : 'zygote' started", - "01-17 01:32:53.392 0 0 I init : starting service 'a different service'", - "01-17 01:32:59.823 0 0 I init : Service 'bootanim' (pid 1030) exited with status 0", - "01-17 01:32:60.334 0 0 I init : 'fake service' started", - "01-17 01:32:61.362 938 1111 I ActivityManager: my app started", - "01-17 01:32:61.977 938 1111 I ActivityManager: my app displayed"); - - mParser.addDurationPatternPair( - "BootToAnimEnd", - Pattern.compile("Linux version"), - Pattern.compile("Service 'bootanim'")); - mParser.addDurationPatternPair( - "ZygoteStartTime", - Pattern.compile("starting service 'zygote'"), - Pattern.compile("'zygote' started")); - mParser.addDurationPatternPair( - "FakeServiceStartTime", - Pattern.compile("starting service 'fake service'"), - Pattern.compile("'fake service' started")); - mParser.addDurationPatternPair( - "AppStartTime", - Pattern.compile("my app started"), - Pattern.compile("my app displayed")); - List items = mParser.parseGenericTimingItems(createBufferedReader(log)); - assertNotNull(items); - assertEquals(5, items.size()); - // 1st item - assertEquals("ZygoteStartTime", items.get(0).getName()); - assertEquals(5000.0, items.get(0).getDuration()); - // 2nd item - assertEquals("FakeServiceStartTime", items.get(1).getName()); - assertEquals(6942.0, items.get(1).getDuration()); - // 3rd item - assertEquals("ZygoteStartTime", items.get(2).getName()); - assertEquals(5000.0, items.get(2).getDuration()); - // 4th item - assertEquals("BootToAnimEnd", items.get(3).getName()); - assertEquals(20320.0, items.get(3).getDuration()); - // 5th item - assertEquals("AppStartTime", items.get(4).getName()); - assertEquals(615.0, items.get(4).getDuration()); - } - - public void testParseGenericTiming_wrongTimeFormat() throws IOException { - String log = - String.join( - "\n", - "1234252.234 0 0 I : Linux version 4.4.177 (Kernel Boot Started)", - "1234259.342 0 0 I CPU features: detected feature: GIC system register CPU interface"); - mParser.addDurationPatternPair( - "BootToAnimEnd", - Pattern.compile("Linux version"), - Pattern.compile("Service 'bootanim'")); - try { - List items = - mParser.parseGenericTimingItems(createBufferedReader(log)); - } catch (RuntimeException e) { - assertTrue( - "Test should report ParseException", - e.getCause().toString().startsWith("java.text.ParseException")); - return; - } - fail("Test should throw ParseException"); - } - - /** Test that system services duration can be parsed as expected */ - public void testParseSystemServicesTiming_system_services_duration() throws IOException { - String log = - String.join( - "\n", - "01-10 01:25:57.675 981 981 D SystemServerTiming: StartWatchdog took to complete: 38ms", - "01-10 01:25:57.675 981 981 I SystemServer: Reading configuration...", - "01-10 01:25:57.675 981 981 I SystemServer: ReadingSystemConfig", - "01-10 01:25:57.676 981 981 D SystemServerTiming: ReadingSystemConfig took to complete: 0.53ms", - "01-10 01:25:57.676 981 981 D SystemServerTiming: ReadingSystemConfig took to complete: 0.53ms", // Parser should skip duplicated log line - "01-10 01:25:57.677 465 465 I snet_event_log: [121035042,-1,]", - "01-10 01:25:57.678 900 900 I FakeComponent: FakeSubcomponent wrong format took to complete: 10ms", - "01-10 01:25:57.678 900 900 I FakeComponent: FakeSubcomponent took to complete: 20s", - "01-10 01:25:57.680 981 981 D SystemServerTiming: StartInstaller took to complete: 5ms wrong format", - "01-10 01:25:57.682 981 981 D SystemServerTiming: DeviceIdentifiersPolicyService took to complete: 2ms", - "01-10 01:25:57.682 981 981 D SystemServerTiming: DeviceIdentifiersPolicyService took to complete: 2ms", - "06-06 19:23:54.410 1295 1295 D OtherService : StartTestStack took to complete: 7ms", - "06-06 19:23:55.410 129 129 D FakeService : Validtook to complete: 8ms", - "06-06 19:23:56.410 981 981 D SystemServerTiming: StartWatchdog took to complete: 38ms"); //Parser should parse the same metric at a different time - - List items = - mParser.parseSystemServicesTimingItems(createBufferedReader(log)); - assertNotNull(items); - assertEquals(6, items.size()); - assertEquals("SystemServerTiming", items.get(0).getComponent()); - assertEquals(38.0, items.get(0).getDuration()); - assertNull(items.get(0).getStartTime()); - assertEquals("ReadingSystemConfig", items.get(1).getSubcomponent()); - assertEquals(0.53, items.get(1).getDuration()); - assertNull(items.get(1).getStartTime()); - assertEquals("DeviceIdentifiersPolicyService", items.get(2).getSubcomponent()); - assertEquals("OtherService", items.get(3).getComponent()); - assertEquals("StartTestStack", items.get(3).getSubcomponent()); - assertEquals(7.0, items.get(3).getDuration()); - assertEquals("FakeService", items.get(4).getComponent()); - assertEquals("Valid", items.get(4).getSubcomponent()); - assertEquals(8.0, items.get(4).getDuration()); - assertNull(items.get(4).getStartTime()); - assertEquals("SystemServerTiming", items.get(5).getComponent()); - assertEquals("StartWatchdog", items.get(5).getSubcomponent()); - assertEquals(38.0, items.get(5).getDuration()); - } - - /** Test that system services start time can be parsed as expected */ - public void testParseSystemServicesTiming_system_services_start_time() throws IOException { - String log = - String.join( - "\n", - "01-10 01:24:45.536 1079 1079 D BootAnimation: BootAnimationStartTiming start time: 8611ms", - "01-10 01:24:45.537 1079 1079 D BootAnimation: BootAnimationPreloadTiming start time: 8611ms", - "01-10 01:24:45.556 874 1021 I ServiceManager: Waiting for service 'package_native' on '/dev/binder'...", - "01-10 01:24:45.561 466 466 I snet_event_log: [121035042,-1,]", - "01-10 01:24:45.583 1080 1080 I SystemServer: InitBeforeStartServices start time: 2345ms wrong format", - "01-10 01:25:24.095 1014 1111 D BootAnimation: BootAnimationShownTiming start time: 9191s", - "06-06 19:23:49.299 603 603 E qdmetadata: Unknown paramType 2", - "06-06 19:23:49.299 603 603 I FakeComponent : wrong subcomponent start time: 234ms", - "06-06 19:23:49.299 603 603 D FakeComponent: Subcomponent start time 234ms", - "06-06 19:23:49.299 1079 1079 D BootAnimation: BootAnimationStopTiming start time: 24839ms", - "06-06 19:23:59.299 179 179 D FakeService : Validstart time: 34839ms"); - - List items = - mParser.parseSystemServicesTimingItems(createBufferedReader(log)); - assertNotNull(items); - assertEquals(4, items.size()); - assertEquals("BootAnimation", items.get(0).getComponent()); - assertEquals("BootAnimationStartTiming", items.get(0).getSubcomponent()); - assertEquals(8611.0, items.get(0).getStartTime()); - assertNull(items.get(0).getDuration()); - assertEquals("BootAnimationPreloadTiming", items.get(1).getSubcomponent()); - assertEquals("BootAnimation", items.get(2).getComponent()); - assertEquals("BootAnimationStopTiming", items.get(2).getSubcomponent()); - assertEquals(24839.0, items.get(2).getStartTime()); - assertNull(items.get(2).getDuration()); - assertEquals("FakeService", items.get(3).getComponent()); - assertEquals("Valid", items.get(3).getSubcomponent()); - assertEquals(34839.0, items.get(3).getStartTime()); - assertNull(items.get(3).getDuration()); - } - - private BufferedReader createBufferedReader(String input) { - InputStream inputStream = new ByteArrayInputStream(input.getBytes()); - InputStreamReader reader = new InputStreamReader(inputStream); - return new BufferedReader(reader); - } -} diff --git a/tests/src/com/android/loganalysis/parser/TopParserTest.java b/tests/src/com/android/loganalysis/parser/TopParserTest.java deleted file mode 100644 index 9b2253b..0000000 --- a/tests/src/com/android/loganalysis/parser/TopParserTest.java +++ /dev/null @@ -1,83 +0,0 @@ -/* - * 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.TopItem; -import com.android.loganalysis.util.ArrayUtil; - -import junit.framework.TestCase; - -import java.util.Arrays; -import java.util.List; - -/** - * Unit tests for {@link ProcrankParser} - */ -public class TopParserTest extends TestCase { - - /** - * Test that the output of the top command is parsed. - */ - public void testTopParser() { - List inputBlock = Arrays.asList( - "User 20%, System 20%, IOW 5%, IRQ 3%", - "User 150 + Nice 50 + Sys 200 + Idle 510 + IOW 60 + IRQ 5 + SIRQ 25 = 1000", - "", - " PID TID PR CPU% S VSS RSS PCY UID Thread Proc", - " 4474 4474 0 2% R 1420K 768K shell top top"); - - TopItem item = new TopParser().parse(inputBlock); - - assertEquals(150, item.getUser()); - assertEquals(50, item.getNice()); - assertEquals(200, item.getSystem()); - assertEquals(510, item.getIdle()); - assertEquals(60, item.getIow()); - assertEquals(5, item.getIrq()); - assertEquals(25, item.getSirq()); - assertEquals(1000, item.getTotal()); - assertEquals(ArrayUtil.join("\n", inputBlock), item.getText()); - } - - /** - * Test that the last output is stored. - */ - public void testLastTop() { - List inputBlock = Arrays.asList( - "User 0 + Nice 0 + Sys 0 + Idle 1000 + IOW 0 + IRQ 0 + SIRQ 0 = 1000", - "User 0 + Nice 0 + Sys 0 + Idle 1000 + IOW 0 + IRQ 0 + SIRQ 0 = 1000", - "User 150 + Nice 50 + Sys 200 + Idle 510 + IOW 60 + IRQ 5 + SIRQ 25 = 1000"); - - TopItem item = new TopParser().parse(inputBlock); - - assertEquals(150, item.getUser()); - assertEquals(50, item.getNice()); - assertEquals(200, item.getSystem()); - assertEquals(510, item.getIdle()); - assertEquals(60, item.getIow()); - assertEquals(5, item.getIrq()); - assertEquals(25, item.getSirq()); - assertEquals(1000, item.getTotal()); - } - - /** - * Test that an empty input returns {@code null}. - */ - public void testEmptyInput() { - TopItem item = new TopParser().parse(Arrays.asList("")); - assertNull(item); - } -} diff --git a/tests/src/com/android/loganalysis/parser/TraceFormatParserTest.java b/tests/src/com/android/loganalysis/parser/TraceFormatParserTest.java deleted file mode 100644 index 06ce9ec..0000000 --- a/tests/src/com/android/loganalysis/parser/TraceFormatParserTest.java +++ /dev/null @@ -1,227 +0,0 @@ -/* - * Copyright (C) 2017 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 static org.junit.Assert.fail; - -import com.android.loganalysis.item.TraceFormatItem; - -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.JUnit4; - -import java.util.Arrays; -import java.util.List; -import java.util.regex.Matcher; - -/** Test for {@link TraceFormatParser}. */ -@RunWith(JUnit4.class) -public class TraceFormatParserTest { - private TraceFormatParser mParser; - - // "unwrap" the regex strings so that we can compare with the generated regex - private static final String MATCH_NUM_UNESCAPED = - TraceFormatParser.MATCH_NUM.replaceAll("\\\\\\\\", "\\\\"); - private static final String MATCH_HEX_UNESCAPED = - TraceFormatParser.MATCH_HEX.replaceAll("\\\\\\\\", "\\\\"); - private static final String MATCH_STR_UNESCAPED = - TraceFormatParser.MATCH_STR.replaceAll("\\\\\\\\", "\\\\"); - - @Before - public void setUp() { - mParser = new TraceFormatParser(); - } - - @Test - public void testParseFormatLine() { - List formatLine = - Arrays.asList("print fmt: \"foo=%llu, bar=%s\", REC->foo, REC->bar"); - String expectedRegex = - String.format( - "foo=(?%s), bar=(?%s)", MATCH_NUM_UNESCAPED, MATCH_STR_UNESCAPED); - List expectedParameters = Arrays.asList("foo", "bar"); - List expectedNumericParameters = Arrays.asList("foo"); - List expectedHexParameters = Arrays.asList(); - List expectedStringParameters = Arrays.asList("bar"); - String shouldMatch = "foo=123, bar=enabled"; - - TraceFormatItem parsedItem = mParser.parse(formatLine); - Assert.assertEquals(expectedParameters, parsedItem.getParameters()); - Assert.assertEquals(expectedNumericParameters, parsedItem.getNumericParameters()); - Assert.assertEquals(expectedHexParameters, parsedItem.getHexParameters()); - Assert.assertEquals(expectedStringParameters, parsedItem.getStringParameters()); - Assert.assertEquals(expectedRegex, parsedItem.getRegex().toString()); - Matcher m = parsedItem.getRegex().matcher(shouldMatch); - Assert.assertTrue(m.matches()); - Assert.assertEquals(m.group("foo"), "123"); - Assert.assertEquals(m.group("bar"), "enabled"); - } - - @Test - public void testNoParameters() { - List formatLine = Arrays.asList("print fmt: \"foo\""); - String expectedRegex = "foo"; - List expectedParameters = Arrays.asList(); - String shouldMatch = "foo"; - - TraceFormatItem parsedItem = mParser.parse(formatLine); - Assert.assertEquals(expectedParameters, parsedItem.getParameters()); - Assert.assertEquals(expectedRegex, parsedItem.getRegex().toString()); - Matcher m = parsedItem.getRegex().matcher(shouldMatch); - Assert.assertTrue(m.matches()); - } - - @Test - public void testNullInput() { - try { - mParser.parse(null); - fail("Expected an exception thrown by TraceFormatParser"); - } catch (RuntimeException e) { - // expected - } - } - - @Test - public void testEmptyInput() { - List formatLine = Arrays.asList(""); - try { - mParser.parse(formatLine); - fail("Expected an exception thrown by TraceFormatParser"); - } catch (RuntimeException e) { - // expected - } - } - - @Test - public void testMultiLineInput() { - List formatLine = Arrays.asList("foo", "bar"); - try { - mParser.parse(formatLine); - fail("Expected an exception thrown by TraceFormatParser"); - } catch (RuntimeException e) { - // expected - } - } - - @Test - public void testOneLineInvalidInput() { - List formatLine = Arrays.asList("foo bar"); - try { - mParser.parse(formatLine); - fail("Expected an exception thrown by TraceFormatParser"); - } catch (RuntimeException e) { - // expected - } - } - - @Test - public void testQuoteInParams() { - List formatLine = - Arrays.asList("print fmt: \"foo %s\", REC->foo ? \"online\" : \"offline\""); - String expectedRegex = String.format("foo (?%s)", MATCH_STR_UNESCAPED); - String shouldMatch = "foo online"; - - TraceFormatItem parsedItem = mParser.parse(formatLine); - Assert.assertEquals(expectedRegex, parsedItem.getRegex().toString()); - Matcher m = parsedItem.getRegex().matcher(shouldMatch); - Assert.assertTrue(m.matches()); - Assert.assertEquals(m.group("foo"), "online"); - } - - @Test - public void testCategorizeParameters() { - List formatLine = - Arrays.asList( - "print fmt: \"num1=%lu, num2=%f, hex=%08x, str=%s\", REC->num1, REC->num2, REC->hex, REC->str"); - List expectedNumericParameters = Arrays.asList("num1", "num2"); - List expectedHexParameters = Arrays.asList("hex"); - List expectedStringParameters = Arrays.asList("str"); - - TraceFormatItem parsedItem = mParser.parse(formatLine); - Assert.assertEquals(expectedNumericParameters, parsedItem.getNumericParameters()); - Assert.assertEquals(expectedHexParameters, parsedItem.getHexParameters()); - Assert.assertEquals(expectedStringParameters, parsedItem.getStringParameters()); - } - - @Test - public void testCaseConvertParameterName() { - List formatLine = Arrays.asList("print fmt: \"foo_bar=%llu\", REC->foo_bar"); - List expectedParameters = Arrays.asList("fooBar"); - String shouldMatch = "foo_bar=123"; - - TraceFormatItem parsedItem = mParser.parse(formatLine); - Assert.assertEquals(expectedParameters, parsedItem.getParameters()); - Matcher m = parsedItem.getRegex().matcher(shouldMatch); - Assert.assertTrue(m.matches()); - Assert.assertEquals(m.group("fooBar"), "123"); - } - - @Test - public void testMatchInt() { - List formatLine = - Arrays.asList("print fmt: \"foo=%d, bar=%lu\", REC->foo, REC->bar"); - String shouldMatch = "foo=-123, bar=456"; - - TraceFormatItem parsedItem = mParser.parse(formatLine); - Matcher m = parsedItem.getRegex().matcher(shouldMatch); - Assert.assertTrue(m.matches()); - Assert.assertEquals(m.group("foo"), "-123"); - Assert.assertEquals(m.group("bar"), "456"); - } - - @Test - public void testMatchFloat() { - List formatLine = - Arrays.asList("print fmt: \"foo=%f, bar=%.2f\", REC->foo, REC->bar"); - String shouldMatch = "foo=123.4567, bar=456.78"; - - TraceFormatItem parsedItem = mParser.parse(formatLine); - Matcher m = parsedItem.getRegex().matcher(shouldMatch); - Assert.assertTrue(m.matches()); - Assert.assertEquals(m.group("foo"), "123.4567"); - Assert.assertEquals(m.group("bar"), "456.78"); - } - - @Test - public void testMatchHex() { - List formatLine = - Arrays.asList( - "print fmt: \"foo=0x%04x, bar=0x%08X, baz=%x\", REC->foo, REC->bar, REC->baz"); - String shouldMatch = "foo=0x007b, bar=0x000001C8, baz=7b"; - - TraceFormatItem parsedItem = mParser.parse(formatLine); - Matcher m = parsedItem.getRegex().matcher(shouldMatch); - Assert.assertTrue(m.matches()); - Assert.assertEquals(m.group("foo"), "007b"); - Assert.assertEquals(m.group("bar"), "000001C8"); - Assert.assertEquals(m.group("baz"), "7b"); - } - - @Test - public void testMatchString() { - List formatLine = - Arrays.asList("print fmt: \"foo=%s, bar=%s\", REC->foo, REC->bar"); - String shouldMatch = "foo=oof, bar=123"; - - TraceFormatItem parsedItem = mParser.parse(formatLine); - Matcher m = parsedItem.getRegex().matcher(shouldMatch); - Assert.assertTrue(m.matches()); - Assert.assertEquals(m.group("foo"), "oof"); - Assert.assertEquals(m.group("bar"), "123"); - } -} diff --git a/tests/src/com/android/loganalysis/parser/TracesParserTest.java b/tests/src/com/android/loganalysis/parser/TracesParserTest.java deleted file mode 100644 index c5046e3..0000000 --- a/tests/src/com/android/loganalysis/parser/TracesParserTest.java +++ /dev/null @@ -1,167 +0,0 @@ -/* - * Copyright (C) 2011 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.TracesItem; -import com.android.loganalysis.util.ArrayUtil; - -import junit.framework.TestCase; - -import java.util.Arrays; -import java.util.List; - -/** - * Unit tests for {@link TracesParser} - */ -public class TracesParserTest extends TestCase { - - /** - * Test that the parser parses the correct stack. - */ - public void testTracesParser() { - List lines = Arrays.asList( - "", - "", - "----- pid 2887 at 2012-05-02 16:43:41 -----", - "Cmd line: com.android.package", - "", - "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)", - " at class.method2(Class.java:2)", - " at class.method2(Class.java:2)", - "", - "\"Task_1\" prio=5 tid=27 WAIT", - " | group=\"main\" sCount=1 dsCount=0 obj=0x00000001 self=0x00000001", - " | sysTid=4789 nice=10 sched=0/0 cgrp=bg_non_interactive handle=0000000001", - " | schedstat=( 0 0 0 ) utm=0 stm=0 core=0", - " at class.method1(Class.java:1)", - " - waiting on <0x00000001> (a java.lang.Thread) held by tid=27 (Task_1)", - " at class.method2(Class.java:2)", - " at class.method2(Class.java:2)", - "", - "\"Task_2\" prio=5 tid=26 NATIVE", - " | group=\"main\" sCount=1 dsCount=0 obj=0x00000001 self=0x00000001", - " | sysTid=4343 nice=0 sched=0/0 cgrp=foreground handle=0000000001", - " | schedstat=( 0 0 0 ) utm=6 stm=3 core=0", - " #00 pc 00001234 /system/lib/lib.so (addr+8)", - " #01 pc 00001235 /system/lib/lib.so (addr+16)", - " #02 pc 00001236 /system/lib/lib.so (addr+24)", - " at class.method1(Class.java:1)", - "", - "----- end 2887 -----", - "", - "", - "----- pid 256 at 2012-05-02 16:43:41 -----", - "Cmd line: system", - "", - "DALVIK THREADS:", - "(mutexes: tll=0 tsl=0 tscl=0 ghl=0)", - "", - "\"main\" prio=5 tid=1 NATIVE", - " | group=\"main\" sCount=1 dsCount=0 obj=0x00000001 self=0x00000001", - " | sysTid=256 nice=0 sched=0/0 cgrp=foreground handle=0000000001", - " | schedstat=( 0 0 0 ) utm=175 stm=41 core=0", - " #00 pc 00001234 /system/lib/lib.so (addr+8)", - " #01 pc 00001235 /system/lib/lib.so (addr+16)", - " #02 pc 00001236 /system/lib/lib.so (addr+24)", - " at class.method1(Class.java:1)", - " at class.method2(Class.java:2)", - " at class.method2(Class.java:2)", - "", - "----- end 256 -----", - ""); - - List expectedStack = Arrays.asList( - "\"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)", - " at class.method2(Class.java:2)", - " at class.method2(Class.java:2)"); - - TracesItem traces = new TracesParser().parse(lines); - assertEquals(2887, traces.getPid().intValue()); - assertEquals("com.android.package", traces.getApp()); - assertEquals(ArrayUtil.join("\n", expectedStack), traces.getStack()); - } - - /** - * Test that both forms of cmd line match for the trace. - */ - public void testTracesParser_cmdline() { - List expectedStack = Arrays.asList( - "\"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)", - " at class.method2(Class.java:2)", - " at class.method2(Class.java:2)"); - - List lines = Arrays.asList( - "", - "", - "----- pid 2887 at 2012-05-02 16:43:41 -----", - "Cmd line: com.android.package", - "", - "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)", - " at class.method2(Class.java:2)", - " at class.method2(Class.java:2)", - ""); - - TracesItem traces = new TracesParser().parse(lines); - assertEquals(2887, traces.getPid().intValue()); - assertEquals("com.android.package", traces.getApp()); - assertEquals(ArrayUtil.join("\n", expectedStack), traces.getStack()); - - lines = Arrays.asList( - "", - "", - "----- pid 2887 at 2012-05-02 16:43:41 -----", - "Cmdline: com.android.package Original command line: ", - "", - "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)", - " at class.method2(Class.java:2)", - " at class.method2(Class.java:2)", - ""); - - traces = new TracesParser().parse(lines); - assertEquals(2887, traces.getPid().intValue()); - assertEquals("com.android.package", traces.getApp()); - assertEquals(ArrayUtil.join("\n", expectedStack), traces.getStack()); - } -} diff --git a/tests/src/com/android/loganalysis/parser/WakelockParserTest.java b/tests/src/com/android/loganalysis/parser/WakelockParserTest.java deleted file mode 100644 index eff4ec8..0000000 --- a/tests/src/com/android/loganalysis/parser/WakelockParserTest.java +++ /dev/null @@ -1,127 +0,0 @@ -/* - * Copyright (C) 2015 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.WakelockItem; -import com.android.loganalysis.item.WakelockItem.WakeLockCategory; - -import junit.framework.TestCase; - -import java.util.Arrays; -import java.util.List; - -/** - * Unit tests for {@link WakelockParser} - */ -public class WakelockParserTest extends TestCase { - - /** - * Test that normal input is parsed. - */ - public void testKernelWakelockParser() { - List inputBlock = Arrays.asList( - " All kernel wake locks:", - " Kernel Wake lock PowerManagerService.WakeLocks: 1h 3m 50s 5ms (8 times) realtime", - " Kernel Wake lock event0-2656 : 3m 49s 268ms (2399 times) realtime", - " Kernel Wake lock wlan_wd_wake: 3m 34s 639ms (1751 times) realtime", - " Kernel Wake lock wlan_rx_wake: 3m 19s 887ms (225 times) realtime", - " Kernel Wake lock wlan_tx_wake: 2m 19s 887ms (225 times) realtime", - " Kernel Wake lock tx_wake: 1m 19s 887ms (225 times) realtime", - " " - ); - - WakelockItem wakelock = new WakelockParser().parse(inputBlock); - - assertEquals(WakelockParser.TOP_WAKELOCK_COUNT, - wakelock.getWakeLocks(WakeLockCategory.KERNEL_WAKELOCK).size()); - assertEquals("event0-2656 ", - wakelock.getWakeLocks(WakeLockCategory.KERNEL_WAKELOCK).get(0).getName()); - assertEquals(229268, wakelock.getWakeLocks(WakeLockCategory.KERNEL_WAKELOCK). - get(0).getHeldTime()); - assertEquals(2399, wakelock.getWakeLocks(WakeLockCategory.KERNEL_WAKELOCK). - get(0).getLockedCount()); - } - - public void testPartialWakelockParser() { - List inputBlock = Arrays.asList( - " All partial wake locks:", - " Wake lock u0a7 NlpWakeLock: 8m 13s 203ms (1479 times) max=0 realtime", - " Wake lock u0a7 NlpCollectorWakeLock: 6m 29s 18ms (238 times) max=0 realtime", - " Wake lock u0a7 GCM_CONN_ALARM: 6m 8s 587ms (239 times) max=0 realtime", - " Wake lock 1000 *alarm*: 5m 11s 316ms (1469 times) max=0 realtime", - " Wake lock u10 xxx: 4m 11s 316ms (1469 times) max=0 realtime", - " Wake lock u30 cst: 2m 11s 316ms (1469 times) max=0 realtime", - ""); - - WakelockItem wakelock = new WakelockParser().parse(inputBlock); - - assertEquals(WakelockParser.TOP_WAKELOCK_COUNT, - wakelock.getWakeLocks(WakeLockCategory.PARTIAL_WAKELOCK).size()); - assertEquals("NlpWakeLock", wakelock.getWakeLocks(WakeLockCategory.PARTIAL_WAKELOCK). - get(0).getName()); - assertEquals("u0a7", wakelock.getWakeLocks(WakeLockCategory.PARTIAL_WAKELOCK). - get(0).getProcessUID()); - assertEquals(493203, wakelock.getWakeLocks(WakeLockCategory.PARTIAL_WAKELOCK). - get(0).getHeldTime()); - assertEquals(1479, wakelock.getWakeLocks(WakeLockCategory.PARTIAL_WAKELOCK). - get(0).getLockedCount()); - } - - public void testPartialWakelockParserOnOldFormat() { - List inputBlock = Arrays.asList( - " All partial wake locks:", - " Wake lock u0a7 NlpWakeLock: 8m 13s 203ms (1479 times) realtime", - " Wake lock u0a7 NlpCollectorWakeLock: 6m 29s 18ms (238 times) realtime", - " Wake lock u0a7 GCM_CONN_ALARM: 6m 8s 587ms (239 times) realtime", - " Wake lock 1000 *alarm*: 5m 11s 316ms (1469 times) realtime", - " Wake lock u10 xxx: 4m 11s 316ms (1469 times) realtime", - " Wake lock u30 cst: 2m 11s 316ms (1469 times) realtime", - ""); - - WakelockItem wakelock = new WakelockParser().parse(inputBlock); - - assertEquals(WakelockParser.TOP_WAKELOCK_COUNT, - wakelock.getWakeLocks(WakeLockCategory.PARTIAL_WAKELOCK).size()); - assertEquals("NlpWakeLock", wakelock.getWakeLocks(WakeLockCategory.PARTIAL_WAKELOCK). - get(0).getName()); - assertEquals("u0a7", wakelock.getWakeLocks(WakeLockCategory.PARTIAL_WAKELOCK). - get(0).getProcessUID()); - assertEquals(493203, wakelock.getWakeLocks(WakeLockCategory.PARTIAL_WAKELOCK). - get(0).getHeldTime()); - assertEquals(1479, wakelock.getWakeLocks(WakeLockCategory.PARTIAL_WAKELOCK). - get(0).getLockedCount()); - } - - public void testInvalidInputWakelockParser() { - List inputBlock = Arrays.asList( - " lock PowerManagerService.WakeLocks: 1h 3m 50s 5ms (8 times) realtime", - " lock event0-2656 : 3m 49s 268ms (2399 times) realtime", - " lock wlan_wd_wake: 3m 34s 639ms (1751 times) realtime", - " lock wlan_rx_wake: 3m 19s 887ms (225 times) realtime", - " wlan_tx_wake: 2m 19s 887ms (225 times) realtime", - " tx_wake: 1m 19s 887ms (225 times) realtime", - " " - ); - - WakelockItem wakelock = new WakelockParser().parse(inputBlock); - - assertEquals(0, - wakelock.getWakeLocks(WakeLockCategory.KERNEL_WAKELOCK).size()); - assertEquals(0, - wakelock.getWakeLocks(WakeLockCategory.PARTIAL_WAKELOCK).size()); - } -} - diff --git a/tests/src/com/android/loganalysis/rule/InterruptRuleTest.java b/tests/src/com/android/loganalysis/rule/InterruptRuleTest.java deleted file mode 100644 index 7a08db0..0000000 --- a/tests/src/com/android/loganalysis/rule/InterruptRuleTest.java +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Copyright (C) 2016 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.rule; - -import com.android.loganalysis.item.BatteryStatsDetailedInfoItem; -import com.android.loganalysis.item.BugreportItem; -import com.android.loganalysis.item.DumpsysBatteryStatsItem; -import com.android.loganalysis.item.DumpsysItem; -import com.android.loganalysis.item.InterruptItem; -import com.android.loganalysis.item.InterruptItem.InterruptCategory; - -import junit.framework.TestCase; - -import org.json.JSONObject; - -/** - * Unit tests for {@link InterruptRule} - */ -public class InterruptRuleTest extends TestCase { - - BugreportItem mBugreport; - DumpsysItem mDumpsys; - DumpsysBatteryStatsItem mDumpsysBatteryStats; - BatteryStatsDetailedInfoItem mBatteryStatsDetailedInfo; - - @Override - public void setUp() { - mBugreport = new BugreportItem(); - mDumpsys = new DumpsysItem(); - mDumpsysBatteryStats = new DumpsysBatteryStatsItem(); - mBatteryStatsDetailedInfo = new BatteryStatsDetailedInfoItem(); - - mBatteryStatsDetailedInfo.setTimeOnBattery(3902004); - mDumpsysBatteryStats.setDetailedBatteryStatsItem(mBatteryStatsDetailedInfo); - mDumpsys.setBatteryInfo(mDumpsysBatteryStats); - mBugreport.setDumpsys(mDumpsys); - } - - /** - * Test interrupt analysis - */ - public void testInterruptAnalysis() throws Exception { - InterruptItem interrupt = new InterruptItem(); - interrupt.addInterrupt("2:bcmsdh_sdmmc:2:qcom,smd:2:msmgio", 40, - InterruptCategory.WIFI_INTERRUPT); - interrupt.addInterrupt("2:qcom,smd-rpm:2:fc4c.qcom,spmi", 7, - InterruptCategory.UNKNOWN_INTERRUPT); - - mBatteryStatsDetailedInfo.setInterruptItem(interrupt); - - InterruptRule interruptRule = new InterruptRule(mBugreport); - interruptRule.applyRule(); - JSONObject analysis = interruptRule.getAnalysis(); - assertNotNull(analysis); - assertTrue(analysis.has("INTERRUPT_ANALYSIS")); - assertEquals(analysis.getString("INTERRUPT_ANALYSIS"), - "Frequent interrupts from WIFI_INTERRUPT (2:bcmsdh_sdmmc:2:qcom,smd:2:msmgio)."); - } - - - public void testNoSignificantInterruptAnalysis() throws Exception { - InterruptItem interrupt = new InterruptItem(); - interrupt.addInterrupt("2:bcmsdh_sdmmc:2:qcom,smd:2:msmgio", 5, - InterruptCategory.WIFI_INTERRUPT); - interrupt.addInterrupt("2:qcom,smd-rpm:2:fc4c.qcom,spmi", 7, - InterruptCategory.UNKNOWN_INTERRUPT); - - mBatteryStatsDetailedInfo.setInterruptItem(interrupt); - - InterruptRule interruptRule = new InterruptRule(mBugreport); - interruptRule.applyRule(); - JSONObject analysis = interruptRule.getAnalysis(); - assertNotNull(analysis); - assertTrue(analysis.has("INTERRUPT_ANALYSIS")); - assertEquals(analysis.getString("INTERRUPT_ANALYSIS"), - "No interrupts woke up device more frequent than 120 secs."); - } - - public void testMissingInterruptAnalysis() throws Exception { - InterruptRule interruptRule = new InterruptRule(mBugreport); - interruptRule.applyRule(); - JSONObject analysis = interruptRule.getAnalysis(); - assertNotNull(analysis); - assertTrue(analysis.has("INTERRUPT_ANALYSIS")); - assertEquals(analysis.getString("INTERRUPT_ANALYSIS"), - "No interrupts woke up device more frequent than 120 secs."); - } -} diff --git a/tests/src/com/android/loganalysis/rule/LocationUsageRuleTest.java b/tests/src/com/android/loganalysis/rule/LocationUsageRuleTest.java deleted file mode 100644 index 5dd7e9e..0000000 --- a/tests/src/com/android/loganalysis/rule/LocationUsageRuleTest.java +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright (C) 2016 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.rule; - -import com.android.loganalysis.item.ActivityServiceItem; -import com.android.loganalysis.item.BatteryStatsDetailedInfoItem; -import com.android.loganalysis.item.BugreportItem; -import com.android.loganalysis.item.DumpsysBatteryStatsItem; -import com.android.loganalysis.item.DumpsysItem; -import com.android.loganalysis.item.LocationDumpsItem; - -import junit.framework.TestCase; - -import org.json.JSONObject; - -/** - * Unit tests for {@link LocationUsageRule} - */ -public class LocationUsageRuleTest extends TestCase { - - BugreportItem mBugreport; - DumpsysItem mDumpsys; - DumpsysBatteryStatsItem mDumpsysBatteryStats; - BatteryStatsDetailedInfoItem mBatteryStatsDetailedInfo; - ActivityServiceItem mActivityService; - - @Override - public void setUp() { - mBugreport = new BugreportItem(); - mDumpsys = new DumpsysItem(); - mDumpsysBatteryStats = new DumpsysBatteryStatsItem(); - mBatteryStatsDetailedInfo = new BatteryStatsDetailedInfoItem(); - mActivityService = new ActivityServiceItem(); - - mBatteryStatsDetailedInfo.setTimeOnBattery(3902004); - mDumpsysBatteryStats.setDetailedBatteryStatsItem(mBatteryStatsDetailedInfo); - mDumpsys.setBatteryInfo(mDumpsysBatteryStats); - mBugreport.setDumpsys(mDumpsys); - mBugreport.setActivityService(mActivityService); - } - - /** - * Test location usage analysis - */ - public void testLocationUsageAnalysis() throws Exception { - LocationDumpsItem location = new LocationDumpsItem(); - location.addLocationClient("com.google.android.gms", 1, 0, 0, "PRIORITY_NO_POWER", 140); - location.addLocationClient("com.google.android.gms", 5, 5, 5, - "PRIORITY_BALANCED_POWER_ACCURACY", 140); - mActivityService.setLocationDumps(location); - - LocationUsageRule locationUsageRule = new LocationUsageRule(mBugreport); - locationUsageRule.applyRule(); - JSONObject analysis = locationUsageRule.getAnalysis(); - assertNotNull(analysis); - assertTrue(analysis.has("LOCATION_USAGE_ANALYSIS")); - assertEquals(analysis.getString("LOCATION_USAGE_ANALYSIS"), - "Package com.google.android.gms is requesting for location updates every 5 secs " - + "with priority PRIORITY_BALANCED_POWER_ACCURACY."); - } - - public void testNoSignificantLocationUsageAnalysis() throws Exception { - LocationDumpsItem location = new LocationDumpsItem(); - location.addLocationClient("com.google.android.gms", 1, 0, 0, "PRIORITY_NO_POWER", 140); - location.addLocationClient("com.google.android.gms", 285, 285, 285, - "PRIORITY_BALANCED_POWER_ACCURACY", 140); - mActivityService.setLocationDumps(location); - - LocationUsageRule locationUsageRule = new LocationUsageRule(mBugreport); - locationUsageRule.applyRule(); - JSONObject analysis = locationUsageRule.getAnalysis(); - assertNotNull(analysis); - assertTrue(analysis.has("LOCATION_USAGE_ANALYSIS")); - assertEquals(analysis.getString("LOCATION_USAGE_ANALYSIS"), - "No apps requested for frequent location updates."); - } - - public void testNoLocationUsageAnalysis() throws Exception { - LocationUsageRule locationUsageRule = new LocationUsageRule(mBugreport); - locationUsageRule.applyRule(); - JSONObject analysis = locationUsageRule.getAnalysis(); - assertNotNull(analysis); - assertTrue(analysis.has("LOCATION_USAGE_ANALYSIS")); - assertEquals(analysis.getString("LOCATION_USAGE_ANALYSIS"), - "No apps requested for frequent location updates."); - } -} diff --git a/tests/src/com/android/loganalysis/rule/ProcessUsageRuleTest.java b/tests/src/com/android/loganalysis/rule/ProcessUsageRuleTest.java deleted file mode 100644 index cc322dc..0000000 --- a/tests/src/com/android/loganalysis/rule/ProcessUsageRuleTest.java +++ /dev/null @@ -1,111 +0,0 @@ -/* - * Copyright (C) 2016 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.rule; - -import com.android.loganalysis.item.BatteryStatsDetailedInfoItem; -import com.android.loganalysis.item.BugreportItem; -import com.android.loganalysis.item.DumpsysBatteryStatsItem; -import com.android.loganalysis.item.DumpsysItem; -import com.android.loganalysis.item.ProcessUsageItem; -import com.android.loganalysis.item.ProcessUsageItem.SensorInfoItem; - -import java.util.LinkedList; -import junit.framework.TestCase; - -import org.json.JSONObject; - -/** - * Unit tests for {@link ProcessUsageRule} - */ -public class ProcessUsageRuleTest extends TestCase { - - BugreportItem mBugreport; - DumpsysItem mDumpsys; - DumpsysBatteryStatsItem mDumpsysBatteryStats; - BatteryStatsDetailedInfoItem mBatteryStatsDetailedInfo; - - @Override - public void setUp() { - mBugreport = new BugreportItem(); - mDumpsys = new DumpsysItem(); - mDumpsysBatteryStats = new DumpsysBatteryStatsItem(); - mBatteryStatsDetailedInfo = new BatteryStatsDetailedInfoItem(); - - mBatteryStatsDetailedInfo.setTimeOnBattery(3902004); - mDumpsysBatteryStats.setDetailedBatteryStatsItem(mBatteryStatsDetailedInfo); - mDumpsys.setBatteryInfo(mDumpsysBatteryStats); - mBugreport.setDumpsys(mDumpsys); - } - - /** - * Test alarm usage analysis - */ - public void testAlarmAnalysis() throws Exception { - ProcessUsageItem processUsage = new ProcessUsageItem(); - LinkedList uid0Sensor = new LinkedList(); - uid0Sensor.add(new SensorInfoItem("0", 9908)); - uid0Sensor.add(new SensorInfoItem("1", 9997)); - - LinkedList uidU0a9Sensor = new LinkedList(); - uidU0a9Sensor.add(new SensorInfoItem("2", 1315)); - - processUsage.addProcessUsage("0", 0, uid0Sensor); - processUsage.addProcessUsage("u0a9", 180, uidU0a9Sensor); - processUsage.addProcessUsage("u0a8", 0, null); - - mBatteryStatsDetailedInfo.setProcessUsageItem(processUsage); - ProcessUsageRule usage = new ProcessUsageRule(mBugreport); - usage.applyRule(); - JSONObject analysis = usage.getAnalysis(); - assertNotNull(analysis); - assertTrue(analysis.has("ALARM_USAGE_ANALYSIS")); - assertEquals(analysis.getString("ALARM_USAGE_ANALYSIS"), - "UID u0a9 has requested frequent repeating alarms."); - assertTrue(analysis.has("SENSOR_USAGE_ANALYSIS")); - assertEquals(analysis.getString("SENSOR_USAGE_ANALYSIS"), - "No apps used sensors more than 10% time on battery."); - } - - /** - * Test sensor usage analysis - */ - public void testSensorAnalysis() throws Exception { - ProcessUsageItem processUsage = new ProcessUsageItem(); - LinkedList uid0Sensor = new LinkedList(); - uid0Sensor.add(new SensorInfoItem("0", 9908)); - uid0Sensor.add(new SensorInfoItem("1", 9997)); - - LinkedList uidU0a9Sensor = new LinkedList(); - uidU0a9Sensor.add(new SensorInfoItem("2", 913015)); - - processUsage.addProcessUsage("0", 0, uid0Sensor); - processUsage.addProcessUsage("u0a9", 15, uidU0a9Sensor); - processUsage.addProcessUsage("u0a8", 0, null); - - mBatteryStatsDetailedInfo.setProcessUsageItem(processUsage); - ProcessUsageRule usage = new ProcessUsageRule(mBugreport); - usage.applyRule(); - JSONObject analysis = usage.getAnalysis(); - assertNotNull(analysis); - assertTrue(analysis.has("SENSOR_USAGE_ANALYSIS")); - assertEquals(analysis.getString("SENSOR_USAGE_ANALYSIS"), - "sensor 2 was used for 0d 0h 15m 13s by UID u0a9."); - - assertTrue(analysis.has("ALARM_USAGE_ANALYSIS")); - assertEquals(analysis.getString("ALARM_USAGE_ANALYSIS"), - "No apps requested for alarms more frequent than 60 secs."); - } -} diff --git a/tests/src/com/android/loganalysis/rule/WakelockRuleTest.java b/tests/src/com/android/loganalysis/rule/WakelockRuleTest.java deleted file mode 100644 index 6900c07..0000000 --- a/tests/src/com/android/loganalysis/rule/WakelockRuleTest.java +++ /dev/null @@ -1,108 +0,0 @@ -/* - * Copyright (C) 2016 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.rule; - -import com.android.loganalysis.item.BatteryStatsDetailedInfoItem; -import com.android.loganalysis.item.BugreportItem; -import com.android.loganalysis.item.DumpsysBatteryStatsItem; -import com.android.loganalysis.item.DumpsysItem; -import com.android.loganalysis.item.WakelockItem; -import com.android.loganalysis.item.WakelockItem.WakeLockCategory; - -import junit.framework.TestCase; - -import org.json.JSONObject; - -/** - * Unit tests for {@link WakelockRule} - */ -public class WakelockRuleTest extends TestCase { - - BugreportItem mBugreport; - DumpsysItem mDumpsys; - DumpsysBatteryStatsItem mDumpsysBatteryStats; - BatteryStatsDetailedInfoItem mBatteryStatsDetailedInfo; - - @Override - public void setUp() { - mBugreport = new BugreportItem(); - mDumpsys = new DumpsysItem(); - mDumpsysBatteryStats = new DumpsysBatteryStatsItem(); - mBatteryStatsDetailedInfo = new BatteryStatsDetailedInfoItem(); - - mBatteryStatsDetailedInfo.setTimeOnBattery(3902004); - mDumpsysBatteryStats.setDetailedBatteryStatsItem(mBatteryStatsDetailedInfo); - mDumpsys.setBatteryInfo(mDumpsysBatteryStats); - mBugreport.setDumpsys(mDumpsys); - } - - /** - * Test wakelock analysis - */ - public void testWakelockAnalysis() throws Exception { - WakelockItem wakelock = new WakelockItem(); - wakelock.addWakeLock("PowerManagerService.WakeLocks", 310006, 2, - WakeLockCategory.KERNEL_WAKELOCK); - wakelock.addWakeLock("msm_serial_hs_rx", 133612, 258, - WakeLockCategory.KERNEL_WAKELOCK); - - wakelock.addWakeLock("ProxyController", "1001", 3887565, 4, - WakeLockCategory.PARTIAL_WAKELOCK); - wakelock.addWakeLock("AudioMix", "1013", 1979, 3, - WakeLockCategory.PARTIAL_WAKELOCK); - - mBatteryStatsDetailedInfo.setWakelockItem(wakelock); - WakelockRule wakelockRule = new WakelockRule(mBugreport); - wakelockRule.applyRule(); - JSONObject analysis = wakelockRule.getAnalysis(); - assertNotNull(analysis); - assertTrue(analysis.has("WAKELOCK_ANALYSIS")); - assertEquals(analysis.getString("WAKELOCK_ANALYSIS"), - "ProxyController PARTIAL_WAKELOCK is held for 0d 1h 4m 47s."); - } - - public void testNoSignificantWakelockAnalysis() throws Exception { - WakelockItem wakelock = new WakelockItem(); - wakelock.addWakeLock("PowerManagerService.WakeLocks", 310006, 2, - WakeLockCategory.KERNEL_WAKELOCK); - wakelock.addWakeLock("msm_serial_hs_rx", 133612, 258, - WakeLockCategory.KERNEL_WAKELOCK); - - wakelock.addWakeLock("ProxyController", "1001", 287565, 4, - WakeLockCategory.PARTIAL_WAKELOCK); - wakelock.addWakeLock("AudioMix", "1013", 1979, 3, - WakeLockCategory.PARTIAL_WAKELOCK); - - mBatteryStatsDetailedInfo.setWakelockItem(wakelock); - WakelockRule wakelockRule = new WakelockRule(mBugreport); - wakelockRule.applyRule(); - JSONObject analysis = wakelockRule.getAnalysis(); - assertNotNull(analysis); - assertTrue(analysis.has("WAKELOCK_ANALYSIS")); - assertEquals(analysis.getString("WAKELOCK_ANALYSIS"), - "No wakelocks were held for more than 10% of time on battery."); - } - - public void testNoWakelockAnalysis() throws Exception { - WakelockRule wakelockRule = new WakelockRule(mBugreport); - wakelockRule.applyRule(); - JSONObject analysis = wakelockRule.getAnalysis(); - assertNotNull(analysis); - assertTrue(analysis.has("WAKELOCK_ANALYSIS")); - assertEquals(analysis.getString("WAKELOCK_ANALYSIS"), - "No wakelocks were held for more than 10% of time on battery."); - } -} diff --git a/tests/src/com/android/loganalysis/rule/WifiStatsRuleTest.java b/tests/src/com/android/loganalysis/rule/WifiStatsRuleTest.java deleted file mode 100644 index 984ed20..0000000 --- a/tests/src/com/android/loganalysis/rule/WifiStatsRuleTest.java +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Copyright (C) 2016 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.rule; - -import com.android.loganalysis.item.BatteryStatsDetailedInfoItem; -import com.android.loganalysis.item.BugreportItem; -import com.android.loganalysis.item.DumpsysBatteryStatsItem; -import com.android.loganalysis.item.DumpsysItem; -import com.android.loganalysis.item.DumpsysWifiStatsItem; - -import junit.framework.TestCase; - -import org.json.JSONObject; - -/** - */ -public class WifiStatsRuleTest extends TestCase { - - BugreportItem mBugreport; - DumpsysItem mDumpsys; - DumpsysBatteryStatsItem mDumpsysBatteryStats; - BatteryStatsDetailedInfoItem mBatteryStatsDetailedInfo; - - @Override - public void setUp() { - mBugreport = new BugreportItem(); - mDumpsys = new DumpsysItem(); - mDumpsysBatteryStats = new DumpsysBatteryStatsItem(); - mBatteryStatsDetailedInfo = new BatteryStatsDetailedInfoItem(); - - mBatteryStatsDetailedInfo.setTimeOnBattery(302004); - mDumpsysBatteryStats.setDetailedBatteryStatsItem(mBatteryStatsDetailedInfo); - mDumpsys.setBatteryInfo(mDumpsysBatteryStats); - mBugreport.setDumpsys(mDumpsys); - } - - /** - * Test wifistats analysis - */ - public void testWifiDisconnectAnalysis() throws Exception { - DumpsysWifiStatsItem wifiStats = new DumpsysWifiStatsItem(); - wifiStats.setNumWifiDisconnect(1); - wifiStats.setNumWifiScan(0); - wifiStats.setNumWifiAssociation(0); - - mDumpsys.setWifiStats(wifiStats); - WifiStatsRule wifiStatsRule = new WifiStatsRule(mBugreport); - wifiStatsRule.applyRule(); - JSONObject analysis = wifiStatsRule.getAnalysis(); - assertNotNull(analysis); - assertTrue(analysis.has("WIFI_STATS")); - assertEquals(analysis.getString("WIFI_STATS"), - "No apps requested for frequent wifi scans. Wifi got disconnected 1 times. " - + "No frequent wifi associations were observed."); - } - - public void testWifiScanAnalysis() throws Exception { - DumpsysWifiStatsItem wifiStats = new DumpsysWifiStatsItem(); - wifiStats.setNumWifiDisconnect(0); - wifiStats.setNumWifiScan(3); - wifiStats.setNumWifiAssociation(0); - - mDumpsys.setWifiStats(wifiStats); - WifiStatsRule wifiStatsRule = new WifiStatsRule(mBugreport); - wifiStatsRule.applyRule(); - JSONObject analysis = wifiStatsRule.getAnalysis(); - assertNotNull(analysis); - assertTrue(analysis.has("WIFI_STATS")); - assertEquals(analysis.getString("WIFI_STATS"), - "Wifi scans happened every 100 seconds. No frequent wifi disconnects were " - + "observed. No frequent wifi associations were observed."); - } - - public void testWifiAssociationAnalysis() throws Exception { - DumpsysWifiStatsItem wifiStats = new DumpsysWifiStatsItem(); - wifiStats.setNumWifiDisconnect(0); - wifiStats.setNumWifiScan(0); - wifiStats.setNumWifiAssociation(3); - - mDumpsys.setWifiStats(wifiStats); - WifiStatsRule wifiStatsRule = new WifiStatsRule(mBugreport); - wifiStatsRule.applyRule(); - JSONObject analysis = wifiStatsRule.getAnalysis(); - assertNotNull(analysis); - assertTrue(analysis.has("WIFI_STATS")); - assertEquals(analysis.getString("WIFI_STATS"), - "No apps requested for frequent wifi scans. No frequent wifi disconnects were " - + "observed. Wifi got associated with AP 3 times."); - } -} diff --git a/tests/src/com/android/loganalysis/util/ArrayUtilTest.java b/tests/src/com/android/loganalysis/util/ArrayUtilTest.java deleted file mode 100644 index 98d85e6..0000000 --- a/tests/src/com/android/loganalysis/util/ArrayUtilTest.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright (C) 2011 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.util; - -import junit.framework.TestCase; - -import java.util.Arrays; -import java.util.List; - -/** - * Unit tests for {@link ArrayUtil} - */ -public class ArrayUtilTest extends TestCase { - - /** - * Simple test for {@link ArrayUtil#buildArray(String[][])} - */ - public void testBuildArray_arrays() { - String[] newArray = ArrayUtil.buildArray(new String[] {"1", "2"}, new String[] {"3"}, - new String[] {"4"}); - assertEquals(4, newArray.length); - for (int i = 0; i < 4; i++) { - assertEquals(Integer.toString(i+1), newArray[i]); - } - } - - /** - * Make sure that Collections aren't double-wrapped - */ - public void testJoinCollection() { - List list = Arrays.asList("alpha", "beta", "gamma"); - final String expected = "alpha, beta, gamma"; - String str = ArrayUtil.join(", ", list); - assertEquals(expected, str); - } - - /** - * Make sure that Arrays aren't double-wrapped - */ - public void testJoinArray() { - String[] ary = new String[] {"alpha", "beta", "gamma"}; - final String expected = "alpha, beta, gamma"; - String str = ArrayUtil.join(", ", (Object[]) ary); - assertEquals(expected, str); - } - - /** - * Make sure that join on varargs arrays work as expected - */ - public void testJoinNormal() { - final String expected = "alpha, beta, gamma"; - String str = ArrayUtil.join(", ", "alpha", "beta", "gamma"); - assertEquals(expected, str); - } -} diff --git a/tests/src/com/android/loganalysis/util/LogPatternUtilTest.java b/tests/src/com/android/loganalysis/util/LogPatternUtilTest.java deleted file mode 100644 index 98226d4..0000000 --- a/tests/src/com/android/loganalysis/util/LogPatternUtilTest.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * 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.util; - -import junit.framework.TestCase; - -import java.util.regex.Pattern; - -/** - * Unit tests for {@link LogPatternUtil}. - */ -public class LogPatternUtilTest extends TestCase { - - /** - * Test basic pattern matching. - */ - public void testPatternMatching() { - LogPatternUtil patternUtil = new LogPatternUtil(); - patternUtil.addPattern(Pattern.compile("abc"), "cat1"); - patternUtil.addPattern(Pattern.compile("123"), "cat2"); - - assertNull(patternUtil.checkMessage("xyz")); - assertEquals("cat1", patternUtil.checkMessage("abc")); - assertEquals("cat2", patternUtil.checkMessage("123")); - } - - /** - * Test pattern matching with extras. - */ - public void testExtrasMatching() { - LogPatternUtil patternUtil = new LogPatternUtil(); - patternUtil.addPattern(Pattern.compile("abc"), null, "cat1"); - patternUtil.addPattern(Pattern.compile("123"), "E/tag1", "cat2"); - patternUtil.addPattern(Pattern.compile("123"), "E/tag2", "cat3"); - - assertNull(patternUtil.checkMessage("xyz")); - assertEquals("cat1", patternUtil.checkMessage("abc")); - assertEquals("cat1", patternUtil.checkMessage("abc", "E/tag1")); - assertEquals("cat1", patternUtil.checkMessage("abc", "E/tag2")); - assertNull(patternUtil.checkMessage("123")); - assertEquals("cat2", patternUtil.checkMessage("123", "E/tag1")); - assertEquals("cat3", patternUtil.checkMessage("123", "E/tag2")); - } -} diff --git a/tests/src/com/android/loganalysis/util/LogTailUtilTest.java b/tests/src/com/android/loganalysis/util/LogTailUtilTest.java deleted file mode 100644 index d7316c6..0000000 --- a/tests/src/com/android/loganalysis/util/LogTailUtilTest.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * 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.util; - -import junit.framework.TestCase; - -/** - * Unit tests for {@link LogTailUtil}. - */ -public class LogTailUtilTest extends TestCase { - - /** - * Test that last and id tails of the log are returned correctly. - */ - public void testGetPreambles() { - LogTailUtil preambleUtil = new LogTailUtil(500, 3, 3); - - assertEquals("", preambleUtil.getLastTail()); - assertEquals("", preambleUtil.getIdTail(1)); - - preambleUtil.addLine(1, "line 1"); - preambleUtil.addLine(2, "line 2"); - - assertEquals("line 1\nline 2", preambleUtil.getLastTail()); - assertEquals("line 1", preambleUtil.getIdTail(1)); - - preambleUtil.addLine(1, "line 3"); - preambleUtil.addLine(2, "line 4"); - preambleUtil.addLine(1, "line 5"); - preambleUtil.addLine(2, "line 6"); - preambleUtil.addLine(1, "line 7"); - preambleUtil.addLine(2, "line 8"); - - assertEquals("line 6\nline 7\nline 8", preambleUtil.getLastTail()); - assertEquals("line 3\nline 5\nline 7", preambleUtil.getIdTail(1)); - } - - /** - * Test that the ring buffer is limited to a certain size. - */ - public void testRingBufferSize() { - LogTailUtil preambleUtil = new LogTailUtil(5, 3, 3); - preambleUtil.addLine(1, "line 1"); - preambleUtil.addLine(2, "line 2"); - preambleUtil.addLine(2, "line 3"); - preambleUtil.addLine(2, "line 4"); - preambleUtil.addLine(2, "line 5"); - preambleUtil.addLine(2, "line 6"); - - // The first line should roll off the end of the buffer. - assertEquals("", preambleUtil.getIdTail(1)); - } -} diff --git a/tests/src/com/android/loganalysis/util/RegexTrieTest.java b/tests/src/com/android/loganalysis/util/RegexTrieTest.java deleted file mode 100644 index 4b689b6..0000000 --- a/tests/src/com/android/loganalysis/util/RegexTrieTest.java +++ /dev/null @@ -1,284 +0,0 @@ -/* - * Copyright (C) 2010 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.util; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotEquals; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; - -import com.android.loganalysis.util.RegexTrie.CompPattern; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.JUnit4; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashMap; -import java.util.List; -import java.util.regex.Pattern; - -/** Set of unit tests to verify the behavior of the RegexTrie */ -@RunWith(JUnit4.class) -public class RegexTrieTest { - private RegexTrie mTrie = null; - private static final Integer STORED_VAL = 42; - private static final List NULL_LIST = Arrays.asList((String)null); - - @Before - public void setUp() throws Exception { - mTrie = new RegexTrie(); - } - - @Test - public void testStringPattern() { - mTrie.put(STORED_VAL, "[p]art1", "[p]art2", "[p]art3"); - Integer retrieved = mTrie.retrieve("part1", "part2", "part3"); - assertEquals(STORED_VAL, retrieved); - } - - @Test - public void testAlternation_single() { - mTrie.put(STORED_VAL, "alpha|beta"); - Integer retrieved; - retrieved = mTrie.retrieve("alpha"); - assertEquals(STORED_VAL, retrieved); - retrieved = mTrie.retrieve("beta"); - assertEquals(STORED_VAL, retrieved); - retrieved = mTrie.retrieve("alpha|beta"); - assertNull(retrieved); - retrieved = mTrie.retrieve("gamma"); - assertNull(retrieved); - retrieved = mTrie.retrieve("alph"); - assertNull(retrieved); - } - - @Test - public void testAlternation_multiple() { - mTrie.put(STORED_VAL, "a|alpha", "b|beta"); - Integer retrieved; - retrieved = mTrie.retrieve("a", "b"); - assertEquals(STORED_VAL, retrieved); - retrieved = mTrie.retrieve("a", "beta"); - assertEquals(STORED_VAL, retrieved); - retrieved = mTrie.retrieve("alpha", "b"); - assertEquals(STORED_VAL, retrieved); - retrieved = mTrie.retrieve("alpha", "beta"); - assertEquals(STORED_VAL, retrieved); - - retrieved = mTrie.retrieve("alpha"); - assertNull(retrieved); - retrieved = mTrie.retrieve("beta"); - assertNull(retrieved); - retrieved = mTrie.retrieve("alpha", "bet"); - assertNull(retrieved); - } - - @Test - public void testGroups_fullMatch() { - mTrie.put(STORED_VAL, "a|(alpha)", "b|(beta)"); - Integer retrieved; - List> groups = new ArrayList>(); - - retrieved = mTrie.retrieve(groups, "a", "b"); - assertEquals(STORED_VAL, retrieved); - assertEquals(2, groups.size()); - assertEquals(NULL_LIST, groups.get(0)); - assertEquals(NULL_LIST, groups.get(1)); - - retrieved = mTrie.retrieve(groups, "a", "beta"); - assertEquals(STORED_VAL, retrieved); - assertEquals(2, groups.size()); - assertEquals(NULL_LIST, groups.get(0)); - assertEquals(Arrays.asList("beta"), groups.get(1)); - - retrieved = mTrie.retrieve(groups, "alpha", "b"); - assertEquals(STORED_VAL, retrieved); - assertEquals(2, groups.size()); - assertEquals(Arrays.asList("alpha"), groups.get(0)); - assertEquals(NULL_LIST, groups.get(1)); - - retrieved = mTrie.retrieve(groups, "alpha", "beta"); - assertEquals(STORED_VAL, retrieved); - assertEquals(2, groups.size()); - assertEquals(Arrays.asList("alpha"), groups.get(0)); - assertEquals(Arrays.asList("beta"), groups.get(1)); - } - - @Test - public void testGroups_partialMatch() { - mTrie.put(STORED_VAL, "a|(alpha)", "b|(beta)"); - Integer retrieved; - List> groups = new ArrayList>(); - - retrieved = mTrie.retrieve(groups, "alpha"); - assertNull(retrieved); - assertEquals(1, groups.size()); - assertEquals(Arrays.asList("alpha"), groups.get(0)); - - retrieved = mTrie.retrieve(groups, "beta"); - assertNull(retrieved); - assertEquals(0, groups.size()); - - retrieved = mTrie.retrieve(groups, "alpha", "bet"); - assertNull(retrieved); - assertEquals(1, groups.size()); - assertEquals(Arrays.asList("alpha"), groups.get(0)); - - retrieved = mTrie.retrieve(groups, "alpha", "betar"); - assertNull(retrieved); - assertEquals(1, groups.size()); - assertEquals(Arrays.asList("alpha"), groups.get(0)); - - retrieved = mTrie.retrieve(groups, "alpha", "beta", "gamma"); - assertNull(retrieved); - assertEquals(2, groups.size()); - assertEquals(Arrays.asList("alpha"), groups.get(0)); - assertEquals(Arrays.asList("beta"), groups.get(1)); - } - - /** Make sure that the wildcard functionality works */ - @Test - public void testWildcard() { - mTrie.put(STORED_VAL, "a", null); - Integer retrieved; - List> groups = new ArrayList>(); - - retrieved = mTrie.retrieve(groups, "a", "b", "c"); - assertEquals(STORED_VAL, retrieved); - assertEquals(3, groups.size()); - assertTrue(groups.get(0).isEmpty()); - assertEquals(Arrays.asList("b"), groups.get(1)); - assertEquals(Arrays.asList("c"), groups.get(2)); - - retrieved = mTrie.retrieve(groups, "a"); - assertNull(retrieved); - assertEquals(1, groups.size()); - assertTrue(groups.get(0).isEmpty()); - } - - /** - * Make sure that if a wildcard and a more specific match could both match, that the more - * specific match takes precedence - */ - @Test - public void testWildcard_precedence() { - // Do one before and one after the wildcard to check for ordering effects - mTrie.put(STORED_VAL + 1, "a", "(b)"); - mTrie.put(STORED_VAL, "a", null); - mTrie.put(STORED_VAL + 2, "a", "(c)"); - Integer retrieved; - List> groups = new ArrayList>(); - - retrieved = mTrie.retrieve(groups, "a", "d"); - assertEquals(STORED_VAL, retrieved); - assertEquals(2, groups.size()); - assertTrue(groups.get(0).isEmpty()); - assertEquals(Arrays.asList("d"), groups.get(1)); - - retrieved = mTrie.retrieve(groups, "a", "b"); - assertEquals((Integer)(STORED_VAL + 1), retrieved); - assertEquals(2, groups.size()); - assertTrue(groups.get(0).isEmpty()); - assertEquals(Arrays.asList("b"), groups.get(1)); - - retrieved = mTrie.retrieve(groups, "a", "c"); - assertEquals((Integer)(STORED_VAL + 2), retrieved); - assertEquals(2, groups.size()); - assertTrue(groups.get(0).isEmpty()); - assertEquals(Arrays.asList("c"), groups.get(1)); - } - - /** - * Verify a bugfix: make sure that no NPE results from calling #retrieve with a wildcard but - * without a place to retrieve captures. - */ - @Test - public void testWildcard_noCapture() throws NullPointerException { - mTrie.put(STORED_VAL, "a", null); - String[] key = new String[] {"a", "b", "c"}; - - mTrie.retrieve(key); - mTrie.retrieve(null, key); - // test passes if no exceptions were thrown - } - - @Test - public void testMultiChild() { - mTrie.put(STORED_VAL + 1, "a", "b"); - mTrie.put(STORED_VAL + 2, "a", "c"); - - Object retrieved; - retrieved = mTrie.retrieve("a", "b"); - assertEquals(STORED_VAL + 1, retrieved); - retrieved = mTrie.retrieve("a", "c"); - assertEquals(STORED_VAL + 2, retrieved); - } - - /** - * Make sure that {@link CompPattern#equals} works as expected. Shake a proverbial fist at Java - */ - @Test - public void testCompPattern_equality() { - String regex = "regex"; - Pattern p1 = Pattern.compile(regex); - Pattern p2 = Pattern.compile(regex); - Pattern pOther = Pattern.compile("other"); - CompPattern cp1 = new CompPattern(p1); - CompPattern cp2 = new CompPattern(p2); - CompPattern cpOther = new CompPattern(pOther); - - // This is the problem with Pattern as implemented - assertNotEquals(p1, p2); - assertNotEquals(p2, p1); - - // Make sure that wrapped patterns with the same regex are considered equivalent - assertEquals(cp2, p1); - assertEquals(cp2, p1); - assertEquals(cp2, cp1); - - // And make sure that wrapped patterns with different regexen are still considered different - assertNotEquals(cp2, pOther); - assertNotEquals(cp2, cpOther); - } - - @Test - public void testCompPattern_hashmap() { - HashMap map = new HashMap(); - String regex = "regex"; - Pattern p1 = Pattern.compile(regex); - Pattern p2 = Pattern.compile(regex); - Pattern pOther = Pattern.compile("other"); - CompPattern cp1 = new CompPattern(p1); - CompPattern cp2 = new CompPattern(p2); - CompPattern cpOther = new CompPattern(pOther); - - map.put(cp1, STORED_VAL); - assertTrue(map.containsKey(cp1)); - assertTrue(map.containsKey(cp2)); - assertFalse(map.containsKey(cpOther)); - - map.put(cpOther, STORED_VAL); - assertEquals(map.size(), 2); - assertTrue(map.containsKey(cp1)); - assertTrue(map.containsKey(cp2)); - assertTrue(map.containsKey(cpOther)); - } -} - diff --git a/tests/src/com/android/loganalysis/util/config/ArgsOptionParserTest.java b/tests/src/com/android/loganalysis/util/config/ArgsOptionParserTest.java deleted file mode 100644 index 524cfa0..0000000 --- a/tests/src/com/android/loganalysis/util/config/ArgsOptionParserTest.java +++ /dev/null @@ -1,629 +0,0 @@ -/* - * Copyright (C) 2010 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.util.config; - -import com.android.loganalysis.util.config.Option.Importance; - -import junit.framework.TestCase; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -/** - * Unit tests for {@link ArgsOptionParser}. - */ -@SuppressWarnings("unused") -public class ArgsOptionParserTest extends TestCase { - - /** - * An option source with one {@link Option} specified. - */ - private static class OneOptionSource { - - private static final String DEFAULT_VALUE = "default"; - private static final String OPTION_NAME = "my_option"; - private static final String OPTION_DESC = "option description"; - - @Option(name=OPTION_NAME, shortName='o', description=OPTION_DESC) - private String mMyOption = DEFAULT_VALUE; - } - - /** - * An option source with one {@link Option} specified. - */ - private static class MapOptionSource { - - private static final String OPTION_NAME = "my_option"; - private static final String OPTION_DESC = "option description"; - - @Option(name=OPTION_NAME, shortName='o', description=OPTION_DESC) - private Map mMyOption = new HashMap(); - } - - /** - * An option source with boolean {@link Option} specified. - */ - private static class BooleanOptionSource { - - private static final boolean DEFAULT_BOOL = false; - private static final String DEFAULT_VALUE = "default"; - - @Option(name="my_boolean", shortName='b') - private boolean mMyBool = DEFAULT_BOOL; - - @Option(name="my_option", shortName='o') - protected String mMyOption = DEFAULT_VALUE; - } - - /** - * An option source with boolean {@link Option} specified with default = true. - */ - private static class BooleanTrueOptionSource { - - private static final boolean DEFAULT_BOOL = true; - - @Option(name="my_boolean", shortName='b') - private boolean mMyBool = DEFAULT_BOOL; - } - - /** - * An option source that has a superclass with options - */ - private static class InheritedOptionSource extends OneOptionSource { - - private static final String OPTION_NAME = "my_sub_option"; - private static final String OPTION_DESC = "sub description"; - - @Option(name=OPTION_NAME, description=OPTION_DESC) - private String mMySubOption = ""; - } - - /** - * An option source for testing the {@link Option#importance()} settings - */ - private static class ImportantOptionSource { - - private static final String IMPORTANT_OPTION_NAME = "important_option"; - private static final String IMPORTANT_UNSET_OPTION_NAME = "unset_important_option"; - private static final String UNIMPORTANT_OPTION_NAME = "unimportant_option"; - - @Option(name = IMPORTANT_OPTION_NAME, description = IMPORTANT_OPTION_NAME, - importance = Importance.ALWAYS) - private String mImportantOption = "foo"; - - @Option(name = IMPORTANT_UNSET_OPTION_NAME, description = IMPORTANT_UNSET_OPTION_NAME, - importance = Importance.IF_UNSET) - private String mImportantUnsetOption = null; - - @Option(name = UNIMPORTANT_OPTION_NAME, description = UNIMPORTANT_OPTION_NAME, - importance = Importance.NEVER) - private String mUnimportantOption = null; - - ImportantOptionSource(String setOption) { - mImportantUnsetOption = setOption; - } - - ImportantOptionSource() { - } - } - - /** - * Option source whose options shouldn't end up in the global namespace - */ - @OptionClass(alias = "ngos", global_namespace = false) - private static class NonGlobalOptionSource { - @Option(name = "option") - Boolean mOption = null; - } - - /** - * Option source with mandatory options - */ - private static class MandatoryOptionSourceNoDefault { - @Option(name = "no-default", mandatory = true) - private String mNoDefaultOption; - } - - /** - * Option source with mandatory options - */ - private static class MandatoryOptionSourceNull { - @Option(name = "null", mandatory = true) - private String mNullOption = null; - } - - /** - * Option source with mandatory options - */ - private static class MandatoryOptionSourceEmptyCollection { - @Option(name = "empty-collection", mandatory = true) - private Collection mEmptyCollection = new ArrayList(0); - } - - /** - * Option source with mandatory options - */ - private static class MandatoryOptionSourceEmptyMap { - @Option(name = "empty-map", mandatory = true) - private Map mEmptyMap = new HashMap(); - } - - /** - * An option source that exercises the {@link OptionUpdateRule}s. - */ - private static class OptionUpdateRuleSource { - - public static final String DEFAULT_VALUE = "5 default"; - public static final String BIGGER_VALUE = "9 bigger"; - public static final String SMALLER_VALUE = "0 smaller"; - - @Option(name = "default") - private String mDefaultOption = DEFAULT_VALUE; - - @Option(name = "first", updateRule = OptionUpdateRule.FIRST) - private String mFirstOption = DEFAULT_VALUE; - - @Option(name = "last", updateRule = OptionUpdateRule.LAST) - private String mLastOption = DEFAULT_VALUE; - - @Option(name = "greatest", updateRule = OptionUpdateRule.GREATEST) - private String mGreatestOption = DEFAULT_VALUE; - - @Option(name = "least", updateRule = OptionUpdateRule.LEAST) - private String mLeastOption = DEFAULT_VALUE; - - @Option(name = "immutable", updateRule = OptionUpdateRule.IMMUTABLE) - private String mImmutableOption = DEFAULT_VALUE; - - @Option(name = "null-immutable", updateRule = OptionUpdateRule.IMMUTABLE) - private String mNullImmutableOption = null; - } - - /** - * Verify that {@link OptionUpdateRule}s work properly when the update compares to greater-than - * the default value. - */ - public void testOptionUpdateRule_greater() throws Exception { - OptionUpdateRuleSource object = new OptionUpdateRuleSource(); - ArgsOptionParser parser = new ArgsOptionParser(object); - final String current = OptionUpdateRuleSource.DEFAULT_VALUE; - final String big = OptionUpdateRuleSource.BIGGER_VALUE; - - parser.parse(new String[] {"--default", big, "--first", big, "--last", big, - "--greatest", big, "--least", big}); - assertEquals(current, object.mFirstOption); - assertEquals(big, object.mLastOption); - assertEquals(big, object.mDefaultOption); // default should be LAST - assertEquals(big, object.mGreatestOption); - assertEquals(current, object.mLeastOption); - } - - /** - * Verify that {@link OptionUpdateRule}s work properly when the update compares to greater-than - * the default value. - */ - public void testOptionUpdateRule_lesser() throws Exception { - OptionUpdateRuleSource object = new OptionUpdateRuleSource(); - ArgsOptionParser parser = new ArgsOptionParser(object); - final String current = OptionUpdateRuleSource.DEFAULT_VALUE; - final String small = OptionUpdateRuleSource.SMALLER_VALUE; - - parser.parse(new String[] {"--default", small, "--first", small, "--last", small, - "--greatest", small, "--least", small}); - assertEquals(current, object.mFirstOption); - assertEquals(small, object.mLastOption); - assertEquals(small, object.mDefaultOption); // default should be LAST - assertEquals(current, object.mGreatestOption); - assertEquals(small, object.mLeastOption); - } - - /** - * Verify that {@link OptionUpdateRule}s work properly when the update compares to greater-than - * the default value. - */ - public void testOptionUpdateRule_immutable() throws Exception { - OptionUpdateRuleSource object = new OptionUpdateRuleSource(); - ArgsOptionParser parser = new ArgsOptionParser(object); - final String update = OptionUpdateRuleSource.BIGGER_VALUE; - - try { - parser.parse(new String[] {"--immutable", update}); - fail("ConfigurationException not thrown when updating an IMMUTABLE option"); - } catch (ConfigurationException e) { - // expected - } - - assertNull(object.mNullImmutableOption); - parser.parse(new String[] {"--null-immutable", update}); - assertEquals(update, object.mNullImmutableOption); - - try { - parser.parse(new String[] {"--null-immutable", update}); - fail("ConfigurationException not thrown when updating an IMMUTABLE option"); - } catch (ConfigurationException e) { - // expected - } - } - - /** - * Setting an option with a namespace alias should work fine - */ - public void testNonGlobalOptionSource_alias() throws Exception { - NonGlobalOptionSource source = new NonGlobalOptionSource(); - ArgsOptionParser parser = new ArgsOptionParser(source); - - assertNull(source.mOption); - parser.parse(new String[] {"--ngos:option"}); - assertTrue(source.mOption); - parser.parse(new String[] {"--ngos:no-option"}); - assertFalse(source.mOption); - } - - /** - * Setting an option with a classname namespace should work fine - */ - public void testNonGlobalOptionSource_className() throws Exception { - NonGlobalOptionSource source = new NonGlobalOptionSource(); - ArgsOptionParser parser = new ArgsOptionParser(source); - - assertNull(source.mOption); - parser.parse(new String[] {String.format("--%s:option", source.getClass().getName())}); - assertTrue(source.mOption); - parser.parse(new String[] {String.format("--%s:no-option", source.getClass().getName())}); - assertFalse(source.mOption); - } - - /** - * Setting an option without a namespace should fail - */ - public void testNonGlobalOptionSource_global() throws Exception { - NonGlobalOptionSource source = new NonGlobalOptionSource(); - ArgsOptionParser parser = new ArgsOptionParser(source); - - assertNull(source.mOption); - try { - parser.parse(new String[] {"--option"}); - fail("ConfigurationException not thrown when assigning a global option to an @Option " + - "field in a non-global-namespace class"); - } catch (ConfigurationException e) { - // expected - } - - try { - parser.parse(new String[] {"--no-option"}); - fail("ConfigurationException not thrown when assigning a global option to an @Option " + - "field in a non-global-namespace class"); - } catch (ConfigurationException e) { - // expected - } - } - - /** - * Test passing an empty argument list for an object that has one option specified. - *

- * Expected that the option field should retain its default value. - */ - public void testParse_noArg() throws ConfigurationException { - OneOptionSource object = new OneOptionSource(); - ArgsOptionParser parser = new ArgsOptionParser(object); - parser.parse(new String[] {}); - assertEquals(OneOptionSource.DEFAULT_VALUE, object.mMyOption); - } - - /** - * Test passing an single argument for an object that has one option specified. - */ - public void testParse_oneArg() throws ConfigurationException { - OneOptionSource object = new OneOptionSource(); - ArgsOptionParser parser = new ArgsOptionParser(object); - final String expectedValue = "set"; - parser.parse(new String[] {"--my_option", expectedValue}); - assertEquals(expectedValue, object.mMyOption); - } - - /** - * Test passing an single argument for an object that has one option specified. - */ - public void testParse_oneMapArg() throws ConfigurationException { - MapOptionSource object = new MapOptionSource(); - ArgsOptionParser parser = new ArgsOptionParser(object); - final int expectedKey = 13; - final boolean expectedValue = true; - parser.parse(new String[] {"--my_option", Integer.toString(expectedKey), - Boolean.toString(expectedValue)}); - assertNotNull(object.mMyOption); - assertEquals(1, object.mMyOption.size()); - assertEquals(expectedValue, (boolean) object.mMyOption.get(expectedKey)); - } - - /** - * Test passing an single argument for an object that has one option specified. - */ - public void testParseMapArg_mismatchKeyType() throws ConfigurationException { - MapOptionSource object = new MapOptionSource(); - ArgsOptionParser parser = new ArgsOptionParser(object); - final String expectedKey = "istanbul"; - final boolean expectedValue = true; - try { - parser.parse(new String[] {"--my_option", expectedKey, Boolean.toString(expectedValue)}); - fail("ConfigurationException not thrown"); - } catch (ConfigurationException e) { - // expect an exception that explicitly mentions that the "key" is incorrect - assertTrue(String.format("Expected exception message to contain 'key': %s", - e.getMessage()), e.getMessage().contains("key")); - assertTrue(String.format("Expected exception message to contain '%s': %s", - expectedKey, e.getMessage()), e.getMessage().contains(expectedKey)); - } - } - - /** - * Test passing an single argument for an object that has one option specified. - */ - public void testParseMapArg_mismatchValueType() throws ConfigurationException { - MapOptionSource object = new MapOptionSource(); - ArgsOptionParser parser = new ArgsOptionParser(object); - final int expectedKey = 13; - final String expectedValue = "notconstantinople"; - try { - parser.parse(new String[] {"--my_option", Integer.toString(expectedKey), expectedValue}); - fail("ConfigurationException not thrown"); - } catch (ConfigurationException e) { - // expect an exception that explicitly mentions that the "value" is incorrect - assertTrue(String.format("Expected exception message to contain 'value': '%s'", - e.getMessage()), e.getMessage().contains("value")); - assertTrue(String.format("Expected exception message to contain '%s': %s", - expectedValue, e.getMessage()), e.getMessage().contains(expectedValue)); - } - } - - /** - * Test passing an single argument for an object that has one option specified. - */ - public void testParseMapArg_missingKey() throws ConfigurationException { - MapOptionSource object = new MapOptionSource(); - ArgsOptionParser parser = new ArgsOptionParser(object); - try { - parser.parse(new String[] {"--my_option"}); - fail("ConfigurationException not thrown"); - } catch (ConfigurationException e) { - // expect an exception that explicitly mentions that the "key" is incorrect - assertTrue(String.format("Expected exception message to contain 'key': '%s'", - e.getMessage()), e.getMessage().contains("key")); - } - } - - /** - * Test passing an single argument for an object that has one option specified. - */ - public void testParseMapArg_missingValue() throws ConfigurationException { - MapOptionSource object = new MapOptionSource(); - ArgsOptionParser parser = new ArgsOptionParser(object); - final int expectedKey = 13; - try { - parser.parse(new String[] {"--my_option", Integer.toString(expectedKey)}); - fail("ConfigurationException not thrown"); - } catch (ConfigurationException e) { - // expect an exception that explicitly mentions that the "value" is incorrect - assertTrue(String.format("Expected exception message to contain 'value': '%s'", - e.getMessage()), e.getMessage().contains("value")); - } - } - - /** - * Test passing an single argument for an object that has one option specified, using the - * option=value notation. - */ - public void testParse_oneArgEquals() throws ConfigurationException { - OneOptionSource object = new OneOptionSource(); - ArgsOptionParser parser = new ArgsOptionParser(object); - final String expectedValue = "set"; - parser.parse(new String[] {String.format("--my_option=%s", expectedValue)}); - assertEquals(expectedValue, object.mMyOption); - } - - /** - * Test passing a single argument for an object that has one option specified, using the - * short option notation. - */ - public void testParse_oneShortArg() throws ConfigurationException { - OneOptionSource object = new OneOptionSource(); - ArgsOptionParser parser = new ArgsOptionParser(object); - final String expectedValue = "set"; - parser.parse(new String[] {"-o", expectedValue}); - assertEquals(expectedValue, object.mMyOption); - } - - /** - * Test that "--" marks the beginning of positional arguments - */ - public void testParse_posArgs() throws ConfigurationException { - OneOptionSource object = new OneOptionSource(); - ArgsOptionParser parser = new ArgsOptionParser(object); - final String expectedValue = "set"; - // have a position argument with a long option prefix, to try to confuse the parser - final String posArg = "--unused"; - List leftOver = parser.parse(new String[] {"-o", expectedValue, "--", posArg}); - assertEquals(expectedValue, object.mMyOption); - assertTrue(leftOver.contains(posArg)); - } - - /** - * Test passing a single boolean argument. - */ - public void testParse_boolArg() throws ConfigurationException { - BooleanOptionSource object = new BooleanOptionSource(); - ArgsOptionParser parser = new ArgsOptionParser(object); - parser.parse(new String[] {"-b"}); - assertTrue(object.mMyBool); - } - - /** - * Test passing a boolean argument with another short argument. - */ - public void testParse_boolTwoArg() throws ConfigurationException { - BooleanOptionSource object = new BooleanOptionSource(); - ArgsOptionParser parser = new ArgsOptionParser(object); - final String expectedValue = "set"; - parser.parse(new String[] {"-bo", expectedValue}); - assertTrue(object.mMyBool); - assertEquals(expectedValue, object.mMyOption); - } - - /** - * Test passing a boolean argument with another short argument, with value concatenated. - * e.g -bovalue - */ - public void testParse_boolTwoArgValue() throws ConfigurationException { - BooleanOptionSource object = new BooleanOptionSource(); - ArgsOptionParser parser = new ArgsOptionParser(object); - final String expectedValue = "set"; - parser.parse(new String[] {String.format("-bo%s", expectedValue)}); - assertTrue(object.mMyBool); - assertEquals(expectedValue, object.mMyOption); - } - - /** - * Test the "--no-" syntax - */ - public void testParse_boolFalse() throws ConfigurationException { - BooleanTrueOptionSource object = new BooleanTrueOptionSource(); - ArgsOptionParser parser = new ArgsOptionParser(object); - parser.parse(new String[] {"--no-my_boolean"}); - assertFalse(object.mMyBool); - } - - /** - * Test the boolean long option syntax - */ - public void testParse_boolLong() throws ConfigurationException { - BooleanOptionSource object = new BooleanOptionSource(); - ArgsOptionParser parser = new ArgsOptionParser(object); - parser.parse(new String[] {"--my_boolean"}); - assertTrue(object.mMyBool); - } - - /** - * Test passing arg string where value is missing - */ - public void testParse_missingValue() throws ConfigurationException { - OneOptionSource object = new OneOptionSource(); - ArgsOptionParser parser = new ArgsOptionParser(object); - try { - parser.parse(new String[] {"--my_option"}); - fail("ConfigurationException not thrown"); - } catch (ConfigurationException e) { - // expected - } - } - - /** - * Test parsing args for an option that does not exist. - */ - public void testParse_optionNotPresent() throws ConfigurationException { - OneOptionSource object = new OneOptionSource(); - ArgsOptionParser parser = new ArgsOptionParser(object); - try { - parser.parse(new String[] {"--my_option", "set", "--not_here", "value"}); - fail("ConfigurationException not thrown"); - } catch (ConfigurationException e) { - // expected - } - } - - /** - * Test that help text is displayed for all fields - */ - public void testGetOptionHelp() { - String help = ArgsOptionParser.getOptionHelp(false, new InheritedOptionSource()); - assertTrue(help.contains(InheritedOptionSource.OPTION_NAME)); - assertTrue(help.contains(InheritedOptionSource.OPTION_DESC)); - assertTrue(help.contains(OneOptionSource.OPTION_NAME)); - assertTrue(help.contains(OneOptionSource.OPTION_DESC)); - assertTrue(help.contains(OneOptionSource.DEFAULT_VALUE)); - } - - /** - * Test displaying important only help text - */ - public void testGetOptionHelp_important() { - String help = ArgsOptionParser.getOptionHelp(true, new ImportantOptionSource()); - assertTrue(help.contains(ImportantOptionSource.IMPORTANT_OPTION_NAME)); - assertTrue(help.contains(ImportantOptionSource.IMPORTANT_UNSET_OPTION_NAME)); - assertFalse(help.contains(ImportantOptionSource.UNIMPORTANT_OPTION_NAME)); - } - - /** - * Test that {@link Importance#IF_UNSET} {@link Option}s are hidden from help if set. - */ - public void testGetOptionHelp_importantUnset() { - String help = ArgsOptionParser.getOptionHelp(true, new ImportantOptionSource("foo")); - assertTrue(help.contains(ImportantOptionSource.IMPORTANT_OPTION_NAME)); - assertFalse(help.contains(ImportantOptionSource.IMPORTANT_UNSET_OPTION_NAME)); - assertFalse(help.contains(ImportantOptionSource.UNIMPORTANT_OPTION_NAME)); - } - - public void testMandatoryOption_noDefault() throws Exception { - MandatoryOptionSourceNoDefault object = new MandatoryOptionSourceNoDefault(); - ArgsOptionParser parser = new ArgsOptionParser(object); - // expect success - parser.parse(new String[] {}); - try { - parser.validateMandatoryOptions(); - fail("ConfigurationException not thrown"); - } catch (ConfigurationException e) { - // expected - } - } - - public void testMandatoryOption_null() throws Exception { - MandatoryOptionSourceNull object = new MandatoryOptionSourceNull(); - ArgsOptionParser parser = new ArgsOptionParser(object); - parser.parse(new String[] {}); - try { - parser.validateMandatoryOptions(); - fail("ConfigurationException not thrown"); - } catch (ConfigurationException e) { - // expected - } - } - - public void testMandatoryOption_emptyCollection() throws Exception { - MandatoryOptionSourceEmptyCollection object = new MandatoryOptionSourceEmptyCollection(); - ArgsOptionParser parser = new ArgsOptionParser(object); - parser.parse(new String[] {}); - try { - parser.validateMandatoryOptions(); - fail("ConfigurationException not thrown"); - } catch (ConfigurationException e) { - // expected - } - } - - public void testMandatoryOption_emptyMap() throws Exception { - MandatoryOptionSourceEmptyMap object = new MandatoryOptionSourceEmptyMap(); - ArgsOptionParser parser = new ArgsOptionParser(object); - parser.parse(new String[] {}); - try { - parser.validateMandatoryOptions(); - fail("ConfigurationException not thrown"); - } catch (ConfigurationException e) { - // expected - } - } -} diff --git a/tests/src/com/android/loganalysis/util/config/OptionSetterTest.java b/tests/src/com/android/loganalysis/util/config/OptionSetterTest.java deleted file mode 100644 index 308e895..0000000 --- a/tests/src/com/android/loganalysis/util/config/OptionSetterTest.java +++ /dev/null @@ -1,828 +0,0 @@ -/* - * Copyright (C) 2010 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.util.config; - -import junit.framework.TestCase; - -import java.io.File; -import java.io.IOException; -import java.lang.reflect.Field; -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashMap; -import java.util.Map; - -/** - * Unit tests for {@link OptionSetter}. - */ -public class OptionSetterTest extends TestCase { - - /** Option source with generic type. */ - private static class GenericTypeOptionSource { - @Option(name = "my_option", shortName = 'o') - private Collection mMyOption; - } - - /** Option source with unparameterized type. */ - @SuppressWarnings("rawtypes") - private static class CollectionTypeOptionSource { - @Option(name = "my_option", shortName = 'o') - private Collection mMyOption; - } - - private static class MyGeneric { - } - - /** Option source with unparameterized type. */ - private static class NonCollectionGenericTypeOptionSource { - @Option(name = "my_option", shortName = 'o') - private MyGeneric mMyOption; - } - - /** Option source with options with same name. */ - private static class DuplicateOptionSource { - @Option(name = "string", shortName = 's') - private String mMyOption; - - @Option(name = "string", shortName = 's') - private String mMyDuplicateOption; - } - - /** Option source with an option with same name as AllTypesOptionSource. */ - @OptionClass(alias = "shared") - private static class SharedOptionSource { - @Option(name = "string", shortName = 's') - private String mMyOption; - - @Option(name = "enum") - private DefaultEnumClass mEnum = null; - - @Option(name = "string_collection") - private Collection mStringCollection = new ArrayList(); - - @Option(name = "enumMap") - private Map mEnumMap = - new HashMap(); - - @Option(name = "enumCollection") - private Collection mEnumCollection = - new ArrayList(); - } - - /** - * Option source with an option with same name as AllTypesOptionSource, but a different type. - */ - private static class SharedOptionWrongTypeSource { - @Option(name = "string", shortName = 's') - private int mMyOption; - } - - /** option source with all supported types. */ - @OptionClass(alias = "all") - private static class AllTypesOptionSource { - @Option(name = "string_collection") - private final Collection mStringCollection = new ArrayList(); - - @Option(name = "string_string_map") - private Map mStringMap = new HashMap(); - - @Option(name = "string") - private String mString = null; - - @Option(name = "boolean") - private boolean mBool = false; - - @Option(name = "booleanObj") - private Boolean mBooleanObj = false; - - @Option(name = "byte") - private byte mByte = 0; - - @Option(name = "byteObj") - private Byte mByteObj = 0; - - @Option(name = "short") - private short mShort = 0; - - @Option(name = "shortObj") - private Short mShortObj = null; - - @Option(name = "int") - private int mInt = 0; - - @Option(name = "intObj") - private Integer mIntObj = 0; - - @Option(name = "long") - private long mLong = 0; - - @Option(name = "longObj") - private Long mLongObj = null; - - @Option(name = "float") - private float mFloat = 0; - - @Option(name = "floatObj") - private Float mFloatObj = null; - - @Option(name = "double") - private double mDouble = 0; - - @Option(name = "doubleObj") - private Double mDoubleObj = null; - - @Option(name = "file") - private File mFile = null; - - @Option(name = "enum") - private DefaultEnumClass mEnum = null; - - @Option(name = "customEnum") - private CustomEnumClass mCustomEnum = null; - - @Option(name = "enumMap") - private Map mEnumMap = - new HashMap(); - - @Option(name = "enumCollection") - private Collection mEnumCollection = - new ArrayList(); - } - - private static class ParentOptionSource { - @Option(name = "string") - private String mString = null; - - protected String getParentString() { - return mString; - } - } - - private static class ChildOptionSource extends ParentOptionSource { - @Option(name = "child-string") - private String mChildString = null; - } - - /** - * Option source with invalid option name. - */ - private static class BadOptionNameSource { - @Option(name = "bad:string", shortName = 's') - private int mMyOption; - } - - private static enum DefaultEnumClass { - VAL1, VAL3, VAL2; - } - - private static enum CustomEnumClass { - VAL1(42); - - private int mVal; - - CustomEnumClass(int val) { - mVal = val; - } - - public int getVal() { - return mVal; - } - } - - private static class FinalOption { - @Option(name = "final-string", description="final field, not allowed") - private final String mFinal= "foo"; - } - - /** - * Test creating an {@link OptionSetter} for a source with invalid option type. - */ - public void testOptionSetter_noType() { - try { - new OptionSetter(new GenericTypeOptionSource()); - fail("ConfigurationException not thrown"); - } catch (ConfigurationException e) { - // expected - } - } - - /** - * Test creating an {@link OptionSetter} for a source with duplicate option names. - */ - public void testOptionSetter_duplicateOptions() { - try { - new OptionSetter(new DuplicateOptionSource()); - fail("ConfigurationException not thrown"); - } catch (ConfigurationException e) { - // expected - } - } - - /** - * Test option with same name can be used in multiple option sources. - */ - public void testOptionSetter_sharedOptions() throws ConfigurationException { - AllTypesOptionSource object1 = new AllTypesOptionSource(); - SharedOptionSource object2 = new SharedOptionSource(); - OptionSetter setter = new OptionSetter(object1, object2); - setter.setOptionValue("string", "test"); - assertEquals("test", object1.mString); - assertEquals("test", object2.mMyOption); - } - - /** - * Test {@link OptionSetter#setOptionValue(String, String)} for Enums used as the key and value - * of a {@link Map}. - */ - public void testOptionSetter_sharedEnumMap() throws ConfigurationException { - AllTypesOptionSource object1 = new AllTypesOptionSource(); - SharedOptionSource object2 = new SharedOptionSource(); - - final String key = "VAL1"; - final String value = "VAL1"; - final DefaultEnumClass expectedKey = DefaultEnumClass.VAL1; - final CustomEnumClass expectedValue = CustomEnumClass.VAL1; - - // Actually set the key/value pair - OptionSetter parser = new OptionSetter(object1, object2); - parser.setOptionMapValue("enumMap", key, value); - - // verify object1 - assertEquals(1, object1.mEnumMap.size()); - assertNotNull(object1.mEnumMap.get(expectedKey)); - assertEquals(expectedValue, object1.mEnumMap.get(expectedKey)); - - // verify object2 - assertEquals(1, object2.mEnumMap.size()); - assertNotNull(object2.mEnumMap.get(expectedKey)); - assertEquals(expectedValue, object2.mEnumMap.get(expectedKey)); - } - - - /** - * Test {@link OptionSetter#setOptionValue(String, String)} for Enums used as the key and value - * of a {@link Map}. - */ - public void testOptionSetter_sharedEnumCollection() throws ConfigurationException { - AllTypesOptionSource object1 = new AllTypesOptionSource(); - SharedOptionSource object2 = new SharedOptionSource(); - - final String value = "VAL1"; - final DefaultEnumClass expectedValue = DefaultEnumClass.VAL1; - - // Actually add the element - OptionSetter parser = new OptionSetter(object1, object2); - parser.setOptionValue("enumCollection", value); - - // verify object1 - assertEquals(1, object1.mEnumCollection.size()); - assertTrue(object1.mEnumCollection.contains(expectedValue)); - - // verify object2 - assertEquals(1, object2.mEnumCollection.size()); - assertTrue(object2.mEnumCollection.contains(expectedValue)); - } - - - /** - * Test that multiple options with same name must have the same type. - */ - public void testOptionSetter_sharedOptionsDiffType() { - try { - new OptionSetter(new AllTypesOptionSource(), new SharedOptionWrongTypeSource()); - fail("ConfigurationException not thrown"); - } catch (ConfigurationException e) { - // expected - } - } - - /** - * Test namespaced options using class names. - */ - public void testOptionSetter_namespacedClassName() throws ConfigurationException { - AllTypesOptionSource object1 = new AllTypesOptionSource(); - SharedOptionSource object2 = new SharedOptionSource(); - OptionSetter setter = new OptionSetter(object1, object2); - setter.setOptionValue(AllTypesOptionSource.class.getName() + ":string", "alltest"); - setter.setOptionValue(SharedOptionSource.class.getName() + ":string", "sharedtest"); - assertEquals("alltest", object1.mString); - assertEquals("sharedtest", object2.mMyOption); - } - - /** - * Test namespaced options using OptionClass aliases - */ - public void testOptionSetter_namespacedAlias() throws ConfigurationException { - AllTypesOptionSource object1 = new AllTypesOptionSource(); - SharedOptionSource object2 = new SharedOptionSource(); - OptionSetter setter = new OptionSetter(object1, object2); - setter.setOptionValue("all:string", "alltest"); - setter.setOptionValue("shared:string", "sharedtest"); - assertEquals("alltest", object1.mString); - assertEquals("sharedtest", object2.mMyOption); - } - - /** - * Test creating an {@link OptionSetter} for a Collection with no type. - */ - public void testOptionSetter_unparamType() { - try { - new OptionSetter(new CollectionTypeOptionSource()); - fail("ConfigurationException not thrown"); - } catch (ConfigurationException e) { - // expected - } - } - - /** - * Test creating an {@link OptionSetter} for a non collection option with generic type - */ - public void testOptionSetter_genericType() { - try { - new OptionSetter(new NonCollectionGenericTypeOptionSource()); - fail("ConfigurationException not thrown"); - } catch (ConfigurationException e) { - // expected - } - } - - /** - * Test creating an {@link OptionSetter} for class with inherited options - */ - public void testOptionSetter_inheritedOptions() throws ConfigurationException { - ChildOptionSource source = new ChildOptionSource(); - OptionSetter setter = new OptionSetter(source); - setter.setOptionValue("string", "parent"); - setter.setOptionValue("child-string", "child"); - assertEquals("parent", source.getParentString()); - assertEquals("child", source.mChildString); - } - - /** - * Test that options with {@link OptionSetter#NAMESPACE_SEPARATOR} are rejected - */ - public void testOptionSetter_badOptionName() { - try { - new OptionSetter(new BadOptionNameSource()); - fail("ConfigurationException not thrown"); - } catch (ConfigurationException e) { - // expected - } - } - - /** - * Test {@link OptionSetter#isBooleanOption(String)} when passed an unknown option name - */ - public void testIsBooleanOption_unknown() throws ConfigurationException { - OptionSetter parser = new OptionSetter(new AllTypesOptionSource()); - try { - parser.isBooleanOption("unknown"); - fail("ConfigurationException not thrown"); - } catch (ConfigurationException e) { - // expected - } - } - - /** - * Test {@link OptionSetter#isBooleanOption(String)} when passed boolean option name - */ - public void testIsBooleanOption_true() throws ConfigurationException { - OptionSetter parser = new OptionSetter(new AllTypesOptionSource()); - assertTrue(parser.isBooleanOption("boolean")); - } - - /** - * Test {@link OptionSetter#isBooleanOption(String)} when passed boolean option name for a - * Boolean object - */ - public void testIsBooleanOption_objTrue() throws ConfigurationException { - OptionSetter parser = new OptionSetter(new AllTypesOptionSource()); - assertTrue(parser.isBooleanOption("booleanObj")); - } - - /** - * Test {@link OptionSetter#isBooleanOption(String)} when passed non-boolean option - */ - public void testIsBooleanOption_false() throws ConfigurationException { - OptionSetter parser = new OptionSetter(new AllTypesOptionSource()); - assertFalse(parser.isBooleanOption("string")); - } - - /** - * Test {@link OptionSetter#setOptionValue(String, String)} when passed an unknown option name - */ - public void testSetOptionValue_unknown() throws ConfigurationException { - OptionSetter parser = new OptionSetter(new AllTypesOptionSource()); - try { - parser.setOptionValue("unknown", "foo"); - fail("ConfigurationException not thrown"); - } catch (ConfigurationException e) { - // expected - } - } - - /** - * Test setting a value for a option with an unknown generic type. - */ - public void testSetOptionValue_unknownType() throws ConfigurationException { - OptionSetter parser = new OptionSetter(new AllTypesOptionSource()); - try { - parser.setOptionValue("my_option", "foo"); - fail("ConfigurationException not thrown"); - } catch (ConfigurationException e) { - // expected - } - } - - /** - * Test setting a value for a non-parameterized Collection - */ - public void testSetOptionValue_unparameterizedType() throws ConfigurationException { - OptionSetter parser = new OptionSetter(new AllTypesOptionSource()); - try { - parser.setOptionValue("my_option", "foo"); - fail("ConfigurationException not thrown"); - } catch (ConfigurationException e) { - // expected - } - } - - /** - * Test {@link OptionSetter#setOptionValue(String, String)} for a String. - */ - public void testSetOptionValue_string() throws ConfigurationException { - AllTypesOptionSource optionSource = new AllTypesOptionSource(); - final String expectedValue = "stringvalue"; - assertSetOptionValue(optionSource, "string", expectedValue); - assertEquals(expectedValue, optionSource.mString); - } - - /** - * Test {@link OptionSetter#setOptionValue(String, String)} for a Collection. - */ - public void testSetOptionValue_collection() throws ConfigurationException { - AllTypesOptionSource optionSource = new AllTypesOptionSource(); - final String expectedValue = "stringvalue"; - assertSetOptionValue(optionSource, "string_collection", expectedValue); - assertEquals(1, optionSource.mStringCollection.size()); - assertTrue(optionSource.mStringCollection.contains(expectedValue)); - } - - /** - * Test {@link OptionSetter#setOptionValue(String, String)} for a Map. - */ - public void testSetOptionValue_map() throws ConfigurationException { - AllTypesOptionSource optionSource = new AllTypesOptionSource(); - final String expectedKey = "stringkey"; - final String expectedValue = "stringvalue"; - - // Actually set the key/value pair - OptionSetter parser = new OptionSetter(optionSource); - parser.setOptionMapValue("string_string_map", expectedKey, expectedValue); - - assertEquals(1, optionSource.mStringMap.size()); - assertNotNull(optionSource.mStringMap.get(expectedKey)); - assertEquals(expectedValue, optionSource.mStringMap.get(expectedKey)); - } - - /** - * Test {@link OptionSetter#setOptionValue(String, String)} for a boolean. - */ - public void testSetOptionValue_boolean() throws ConfigurationException { - AllTypesOptionSource optionSource = new AllTypesOptionSource(); - assertSetOptionValue(optionSource, "boolean", "true"); - assertEquals(true, optionSource.mBool); - } - - /** - * Test {@link OptionSetter#setOptionValue(String, String)} for a boolean for a non-boolean - * value. - */ - public void testSetOptionValue_booleanInvalid() { - AllTypesOptionSource optionSource = new AllTypesOptionSource(); - assertSetOptionValueInvalid(optionSource, "boolean", "blah"); - } - - /** - * Test {@link OptionSetter#setOptionValue(String, String)} for a Boolean. - */ - public void testSetOptionValue_booleanObj() throws ConfigurationException { - AllTypesOptionSource optionSource = new AllTypesOptionSource(); - assertSetOptionValue(optionSource, "booleanObj", "true"); - assertTrue(optionSource.mBooleanObj); - } - - /** - * Test {@link OptionSetter#setOptionValue(String, String)} for a byte. - */ - public void testSetOptionValue_byte() throws ConfigurationException { - AllTypesOptionSource optionSource = new AllTypesOptionSource(); - assertSetOptionValue(optionSource, "byte", "2"); - assertEquals(2, optionSource.mByte); - } - - /** - * Test {@link OptionSetter#setOptionValue(String, String)} for a byte for an invalid value. - */ - public void testSetOptionValue_byteInvalid() { - AllTypesOptionSource optionSource = new AllTypesOptionSource(); - assertSetOptionValueInvalid(optionSource, "byte", "blah"); - } - - /** - * Test {@link OptionSetter#setOptionValue(String, String)} for a Byte. - */ - public void testSetOptionValue_byteObj() throws ConfigurationException { - AllTypesOptionSource optionSource = new AllTypesOptionSource(); - assertSetOptionValue(optionSource, "byteObj", "2"); - assertTrue(2 == optionSource.mByteObj); - } - - /** - * Test {@link OptionSetter#setOptionValue(String, String)} for a short. - */ - public void testSetOptionValue_short() throws ConfigurationException { - AllTypesOptionSource optionSource = new AllTypesOptionSource(); - assertSetOptionValue(optionSource, "short", "2"); - assertTrue(2 == optionSource.mShort); - } - - /** - * Test {@link OptionSetter#setOptionValue(String, String)} for a Short. - */ - public void testSetOptionValue_shortObj() throws ConfigurationException { - AllTypesOptionSource optionSource = new AllTypesOptionSource(); - assertSetOptionValue(optionSource, "shortObj", "2"); - assertTrue(2 == optionSource.mShortObj); - } - - /** - * Test {@link OptionSetter#setOptionValue(String, String)} for a short for an invalid value. - */ - public void testSetOptionValue_shortInvalid() { - AllTypesOptionSource optionSource = new AllTypesOptionSource(); - assertSetOptionValueInvalid(optionSource, "short", "blah"); - } - - /** - * Test {@link OptionSetter#setOptionValue(String, String)} for a int. - */ - public void testSetOptionValue_int() throws ConfigurationException { - AllTypesOptionSource optionSource = new AllTypesOptionSource(); - assertSetOptionValue(optionSource, "int", "2"); - assertTrue(2 == optionSource.mInt); - } - - /** - * Test {@link OptionSetter#setOptionValue(String, String)} for a Integer. - */ - public void testSetOptionValue_intObj() throws ConfigurationException { - AllTypesOptionSource optionSource = new AllTypesOptionSource(); - assertSetOptionValue(optionSource, "intObj", "2"); - assertTrue(2 == optionSource.mIntObj); - } - - /** - * Test {@link OptionSetter#setOptionValue(String, String)} for a int for an invalid value. - */ - public void testSetOptionValue_intInvalid() { - AllTypesOptionSource optionSource = new AllTypesOptionSource(); - assertSetOptionValueInvalid(optionSource, "int", "blah"); - } - - /** - * Test {@link OptionSetter#setOptionValue(String, String)} for a long. - */ - public void testSetOptionValue_long() throws ConfigurationException { - AllTypesOptionSource optionSource = new AllTypesOptionSource(); - assertSetOptionValue(optionSource, "long", "2"); - assertTrue(2 == optionSource.mLong); - } - - /** - * Test {@link OptionSetter#setOptionValue(String, String)} for a Long. - */ - public void testSetOptionValue_longObj() throws ConfigurationException { - AllTypesOptionSource optionSource = new AllTypesOptionSource(); - assertSetOptionValue(optionSource, "longObj", "2"); - assertTrue(2 == optionSource.mLongObj); - } - - /** - * Test {@link OptionSetter#setOptionValue(String, String)} for a long for an invalid value. - */ - public void testSetOptionValue_longInvalid() { - AllTypesOptionSource optionSource = new AllTypesOptionSource(); - assertSetOptionValueInvalid(optionSource, "long", "blah"); - } - - /** - * Test {@link OptionSetter#setOptionValue(String, String)} for a float. - */ - public void testSetOptionValue_float() throws ConfigurationException { - AllTypesOptionSource optionSource = new AllTypesOptionSource(); - assertSetOptionValue(optionSource, "float", "2.1"); - assertEquals(2.1, optionSource.mFloat, 0.01); - } - - /** - * Test {@link OptionSetter#setOptionValue(String, String)} for a Float. - */ - public void testSetOptionValue_floatObj() throws ConfigurationException { - AllTypesOptionSource optionSource = new AllTypesOptionSource(); - assertSetOptionValue(optionSource, "floatObj", "2.1"); - assertEquals(2.1, optionSource.mFloatObj, 0.01); - } - - /** - * Test {@link OptionSetter#setOptionValue(String, String)} for a float for an invalid value. - */ - public void testSetOptionValue_floatInvalid() { - AllTypesOptionSource optionSource = new AllTypesOptionSource(); - assertSetOptionValueInvalid(optionSource, "float", "blah"); - } - - /** - * Test {@link OptionSetter#setOptionValue(String, String)} for a float. - */ - public void testSetOptionValue_double() throws ConfigurationException { - AllTypesOptionSource optionSource = new AllTypesOptionSource(); - assertSetOptionValue(optionSource, "double", "2.1"); - assertEquals(2.1, optionSource.mDouble, 0.01); - } - - /** - * Test {@link OptionSetter#setOptionValue(String, String)} for a Float. - */ - public void testSetOptionValue_doubleObj() throws ConfigurationException { - AllTypesOptionSource optionSource = new AllTypesOptionSource(); - assertSetOptionValue(optionSource, "doubleObj", "2.1"); - assertEquals(2.1, optionSource.mDoubleObj, 0.01); - } - - /** - * Test {@link OptionSetter#setOptionValue(String, String)} for a double for an invalid value. - */ - public void testSetOptionValue_doubleInvalid() { - AllTypesOptionSource optionSource = new AllTypesOptionSource(); - assertSetOptionValueInvalid(optionSource, "double", "blah"); - } - - /** - * Test {@link OptionSetter#setOptionValue(String, String)} for a File. - */ - public void testSetOptionValue_file() throws ConfigurationException, IOException { - AllTypesOptionSource optionSource = new AllTypesOptionSource(); - File tmpFile = File.createTempFile("testSetOptionValue_file", "txt"); - try { - assertSetOptionValue(optionSource, "file", tmpFile.getAbsolutePath()); - assertEquals(tmpFile.getAbsolutePath(), optionSource.mFile.getAbsolutePath()); - } finally { - tmpFile.delete(); - } - } - - /** - * Test {@link OptionSetter#setOptionValue(String, String)} for an Enum. - */ - public void testSetOptionValue_enum() throws ConfigurationException { - AllTypesOptionSource optionSource = new AllTypesOptionSource(); - assertSetOptionValue(optionSource, "enum", "VAL1"); - assertEquals(DefaultEnumClass.VAL1, optionSource.mEnum); - } - - /** - * Test {@link OptionSetter#setOptionValue(String, String)} for an Enum. Specifically make sure - * that we fall back properly, so that a mixed-case value will be silently mapped to an - * uppercase version, since Enum constants tend to be uppercase by convention. - */ - public void testSetOptionValue_enumMixedCase() throws ConfigurationException { - AllTypesOptionSource optionSource = new AllTypesOptionSource(); - assertSetOptionValue(optionSource, "enum", "Val1"); - assertEquals(DefaultEnumClass.VAL1, optionSource.mEnum); - } - - /** - * Test {@link OptionSetter#setOptionValue(String, String)} for an Enum with custom values. - */ - public void testSetOptionValue_customEnum() throws ConfigurationException { - AllTypesOptionSource optionSource = new AllTypesOptionSource(); - assertSetOptionValue(optionSource, "customEnum", "VAL1"); - assertEquals(CustomEnumClass.VAL1, optionSource.mCustomEnum); - assertEquals(42, optionSource.mCustomEnum.getVal()); - } - - /** - * Test {@link OptionSetter#setOptionValue(String, String)} for Enums used as the key and value - * of a {@link Map}. - */ - public void testSetOptionValue_enumMap() throws ConfigurationException { - AllTypesOptionSource optionSource = new AllTypesOptionSource(); - - final String key = "VAL1"; - final String value = "VAL1"; - final DefaultEnumClass expectedKey = DefaultEnumClass.VAL1; - final CustomEnumClass expectedValue = CustomEnumClass.VAL1; - - // Actually set the key/value pair - OptionSetter parser = new OptionSetter(optionSource); - parser.setOptionMapValue("enumMap", key, value); - - assertEquals(1, optionSource.mEnumMap.size()); - assertNotNull(optionSource.mEnumMap.get(expectedKey)); - assertEquals(expectedValue, optionSource.mEnumMap.get(expectedKey)); - } - - - /** - * Test {@link OptionSetter#setOptionValue(String, String)} for Enums used as the key and value - * of a {@link Map}. - */ - public void testSetOptionValue_enumCollection() throws ConfigurationException { - AllTypesOptionSource optionSource = new AllTypesOptionSource(); - - final String value = "VAL1"; - final DefaultEnumClass expectedValue = DefaultEnumClass.VAL1; - - assertSetOptionValue(optionSource, "enumCollection", value); - - assertEquals(1, optionSource.mEnumCollection.size()); - assertTrue(optionSource.mEnumCollection.contains(expectedValue)); - } - - - /** - * Test {@link OptionSetter#setOptionValue(String, String)} for an Enum. - */ - public void testSetOptionValue_enumBadValue() { - AllTypesOptionSource optionSource = new AllTypesOptionSource(); - try { - assertSetOptionValue(optionSource, "enum", "noexist"); - fail("ConfigurationException not thrown"); - } catch (ConfigurationException e) { - // expected - } - } - - /** - * Make sure that Enum documentation shows the defaults properly - */ - public void testEnumDocs() throws Exception { - // We assume here that the fields are returned in declaration order, as documented in the - // {@link Enum} javadoc. - String expectedValues = " Valid values: [VAL1, VAL3, VAL2]"; - Field field = AllTypesOptionSource.class.getDeclaredField("mEnum"); - String actualValues = OptionSetter.getEnumFieldValuesAsString(field); - assertEquals(expectedValues, actualValues); - } - - /** - * Test {@link OptionSetter} for a final field - */ - public void testOptionSetter_finalField() { - FinalOption optionSource = new FinalOption(); - try { - new OptionSetter(optionSource); - fail("ConfigurationException not thrown"); - } catch (ConfigurationException e) { - // expected - } - } - - /** - * Perform {@link OptionSetter#setOptionValue(String, String)} for a given option. - */ - private void assertSetOptionValue(AllTypesOptionSource optionSource, final String optionName, - final String expectedValue) throws ConfigurationException { - OptionSetter parser = new OptionSetter(optionSource); - parser.setOptionValue(optionName, expectedValue); - } - - /** - * Perform {@link OptionSetter#setOptionValue(String, String)} for a given option, with an - * invalid value for the option type. - */ - private void assertSetOptionValueInvalid(AllTypesOptionSource optionSource, - final String optionName, final String expectedValue) { - try { - assertSetOptionValue(optionSource, optionName, expectedValue); - fail("ConfigurationException not thrown"); - } catch (ConfigurationException e) { - // expected - } - } -} diff --git a/tests/src/com/android/loganalysis/util/config/OptionUpdateRuleTest.java b/tests/src/com/android/loganalysis/util/config/OptionUpdateRuleTest.java deleted file mode 100644 index 0e899ec..0000000 --- a/tests/src/com/android/loganalysis/util/config/OptionUpdateRuleTest.java +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Copyright (C) 2010 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.util.config; - -import junit.framework.TestCase; - -/** - * Unit tests for {@link OptionUpdateRule} - */ -public class OptionUpdateRuleTest extends TestCase { - private static final String OPTION_NAME = "option-name"; - private static final Object CURRENT = "5 current value"; - private static final Object UPDATE = "5 update value"; - private static final Object SMALL_UPDATE = "0 update value"; - private static final Object BIG_UPDATE = "9 update value"; - - public void testFirst_simple() throws Exception { - assertEquals(UPDATE, OptionUpdateRule.FIRST.update(OPTION_NAME, null, UPDATE)); - assertEquals(CURRENT, OptionUpdateRule.FIRST.update(OPTION_NAME, CURRENT, UPDATE)); - } - - public void testLast_simple() throws Exception { - assertEquals(UPDATE, OptionUpdateRule.LAST.update(OPTION_NAME, null, UPDATE)); - assertEquals(UPDATE, OptionUpdateRule.LAST.update(OPTION_NAME, CURRENT, UPDATE)); - } - - public void testGreatest_simple() throws Exception { - assertEquals( - SMALL_UPDATE, OptionUpdateRule.GREATEST.update(OPTION_NAME, null, SMALL_UPDATE)); - assertEquals(CURRENT, OptionUpdateRule.GREATEST.update(OPTION_NAME, CURRENT, SMALL_UPDATE)); - assertEquals( - BIG_UPDATE, OptionUpdateRule.GREATEST.update(OPTION_NAME, CURRENT, BIG_UPDATE)); - } - - public void testLeast_simple() throws Exception { - assertEquals(BIG_UPDATE, OptionUpdateRule.LEAST.update(OPTION_NAME, null, BIG_UPDATE)); - assertEquals( - SMALL_UPDATE, OptionUpdateRule.LEAST.update(OPTION_NAME, CURRENT, SMALL_UPDATE)); - assertEquals(CURRENT, OptionUpdateRule.LEAST.update(OPTION_NAME, CURRENT, BIG_UPDATE)); - } - - public void testImmutable_simple() throws Exception { - assertEquals(UPDATE, OptionUpdateRule.IMMUTABLE.update(OPTION_NAME, null, UPDATE)); - try { - OptionUpdateRule.IMMUTABLE.update(OPTION_NAME, CURRENT, UPDATE); - fail("ConfigurationException not thrown when updating an IMMUTABLE option"); - } catch (ConfigurationException e) { - // expected - } - } - - public void testInvalidComparison() throws Exception { - try { - // Strings aren't comparable with integers - OptionUpdateRule.GREATEST.update(OPTION_NAME, 13, UPDATE); - fail("ConfigurationException not thrown for invalid comparison."); - } catch (ConfigurationException e) { - // Expected. Moreover, the exception should be actionable, so make sure we mention the - // specific mismatching types. - final String msg = e.getMessage(); - assertTrue(msg.contains("Integer")); - assertTrue(msg.contains("String")); - } - } - - public void testNotComparable() throws Exception { - try { - OptionUpdateRule.LEAST.update(OPTION_NAME, new Exception("hi"), UPDATE); - } catch (ConfigurationException e) { - // expected - } - } -} - -- cgit v1.2.3