summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTreeHugger Robot <treehugger-gerrit@google.com>2021-10-26 21:38:52 +0000
committerAutomerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>2021-10-26 21:38:52 +0000
commit2cbf082f28fb5edadc5e312fe1e0541e07a332b3 (patch)
tree3abfe9d29685f4f65c8de3e140b0d3e0e5f33778
parent3f83f7c8379ccda3845909574b505ac136863818 (diff)
parentcdb4eab63b9a816766e9f5bd95bada4084def9ec (diff)
downloadplatform_testing-2cbf082f28fb5edadc5e312fe1e0541e07a332b3.tar.gz
Merge "CP from aosp/1854065 Move common-compat lib tests near the code." into sc-dev am: cdb4eab63b
Original change: https://googleplex-android-review.googlesource.com/c/platform/platform_testing/+/16058074 Change-Id: I7f25d29d4f516b52076a7460f9dbc42b397c8561
-rw-r--r--libraries/compatibility-common-util/Android.bp1
-rw-r--r--libraries/compatibility-common-util/tests/Android.bp39
-rw-r--r--libraries/compatibility-common-util/tests/assets/arm32_libdl.sobin0 -> 10064 bytes
-rw-r--r--libraries/compatibility-common-util/tests/assets/arm32_libdl.txt271
-rw-r--r--libraries/compatibility-common-util/tests/assets/arm64_libdl.sobin0 -> 67496 bytes
-rw-r--r--libraries/compatibility-common-util/tests/assets/arm64_libdl.txt232
-rw-r--r--libraries/compatibility-common-util/tests/assets/logcat.txt335
-rw-r--r--libraries/compatibility-common-util/tests/assets/x86app_process32bin0 -> 23220 bytes
-rw-r--r--libraries/compatibility-common-util/tests/assets/x86app_process32.txt393
-rw-r--r--libraries/compatibility-common-util/tests/assets/x86app_process64bin0 -> 23896 bytes
-rw-r--r--libraries/compatibility-common-util/tests/assets/x86app_process64.txt422
-rwxr-xr-xlibraries/compatibility-common-util/tests/gen_elf_golden_files.sh14
-rw-r--r--libraries/compatibility-common-util/tests/src/com/android/compatibility/common/util/BackupUtilsTest.java533
-rw-r--r--libraries/compatibility-common-util/tests/src/com/android/compatibility/common/util/BusinessLogicTest.java252
-rw-r--r--libraries/compatibility-common-util/tests/src/com/android/compatibility/common/util/CaseResultTest.java120
-rw-r--r--libraries/compatibility-common-util/tests/src/com/android/compatibility/common/util/CrashUtilsTest.java219
-rw-r--r--libraries/compatibility-common-util/tests/src/com/android/compatibility/common/util/DynamicConfigTest.java125
-rw-r--r--libraries/compatibility-common-util/tests/src/com/android/compatibility/common/util/LightInvocationResultTest.java50
-rw-r--r--libraries/compatibility-common-util/tests/src/com/android/compatibility/common/util/MetricsXmlSerializerTest.java81
-rw-r--r--libraries/compatibility-common-util/tests/src/com/android/compatibility/common/util/MultipartFormTest.java58
-rw-r--r--libraries/compatibility-common-util/tests/src/com/android/compatibility/common/util/ReadElfTest.java302
-rw-r--r--libraries/compatibility-common-util/tests/src/com/android/compatibility/common/util/ReportLogTest.java153
-rw-r--r--libraries/compatibility-common-util/tests/src/com/android/compatibility/common/util/ResultHandlerTest.java750
-rw-r--r--libraries/compatibility-common-util/tests/src/com/android/compatibility/common/util/StatTest.java85
-rw-r--r--libraries/compatibility-common-util/tests/src/com/android/compatibility/common/util/TestResultTest.java48
25 files changed, 4483 insertions, 0 deletions
diff --git a/libraries/compatibility-common-util/Android.bp b/libraries/compatibility-common-util/Android.bp
index 714a681c7..850a8bba1 100644
--- a/libraries/compatibility-common-util/Android.bp
+++ b/libraries/compatibility-common-util/Android.bp
@@ -34,6 +34,7 @@ java_library {
name: "compatibility-common-util-lib",
visibility: [
"//test/suite_harness/common/util",
+ "//platform_testing/libraries/compatibility-common-util/tests",
],
srcs: ["src/**/*.java"],
host_supported: true,
diff --git a/libraries/compatibility-common-util/tests/Android.bp b/libraries/compatibility-common-util/tests/Android.bp
new file mode 100644
index 000000000..5f5865432
--- /dev/null
+++ b/libraries/compatibility-common-util/tests/Android.bp
@@ -0,0 +1,39 @@
+// 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 {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+java_test_host {
+ name: "compatibility-common-util-tests",
+ // Restrict visibility to only those targets that need to access it.
+ visibility: ["//visibility:private"],
+ defaults: ["cts_error_prone_rules"],
+
+ srcs: ["src/**/*.java"],
+ test_options: {
+ unit_test: true,
+ },
+
+ static_libs: [
+ "compatibility-common-util-lib",
+ "junit",
+ "kxml2-2.3.0",
+ "tradefed",
+ ],
+
+ // Holds golden sample files in assets for validation
+ java_resource_dirs: ["assets/"],
+}
diff --git a/libraries/compatibility-common-util/tests/assets/arm32_libdl.so b/libraries/compatibility-common-util/tests/assets/arm32_libdl.so
new file mode 100644
index 000000000..979ab206c
--- /dev/null
+++ b/libraries/compatibility-common-util/tests/assets/arm32_libdl.so
Binary files differ
diff --git a/libraries/compatibility-common-util/tests/assets/arm32_libdl.txt b/libraries/compatibility-common-util/tests/assets/arm32_libdl.txt
new file mode 100644
index 000000000..6a4ccdc47
--- /dev/null
+++ b/libraries/compatibility-common-util/tests/assets/arm32_libdl.txt
@@ -0,0 +1,271 @@
+ELF Header:
+ Magic: 7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00
+ Class: ELF32
+ Data: 2's complement, little endian
+ Version: 1 (current)
+ OS/ABI: UNIX - System V
+ ABI Version: 0
+ Type: DYN (Shared object file)
+ Machine: ARM
+ Version: 0x1
+ Entry point address: 0x0
+ Start of program headers: 52 (bytes into file)
+ Start of section headers: 9304 (bytes into file)
+ Flags: 0x5000200, Version5 EABI, soft-float ABI
+ Size of this header: 52 (bytes)
+ Size of program headers: 32 (bytes)
+ Number of program headers: 8
+ Size of section headers: 40 (bytes)
+ Number of section headers: 19
+ Section header string table index: 18
+
+Section Headers:
+ [Nr] Name Type Addr Off Size ES Flg Lk Inf Al
+ [ 0] NULL 00000000 000000 000000 00 0 0 0
+ [ 1] .note.gnu.build-i NOTE 00000134 000134 000020 00 A 0 0 4
+ [ 2] .dynsym DYNSYM 00000154 000154 0002e0 10 A 3 1 4
+ [ 3] .dynstr STRTAB 00000434 000434 00041e 00 A 0 0 1
+ [ 4] .gnu.hash GNU_HASH 00000854 000854 0000dc 04 A 2 0 4
+ [ 5] .hash HASH 00000930 000930 000154 04 A 2 0 4
+ [ 6] .gnu.version VERSYM 00000a84 000a84 00005c 02 A 2 0 2
+ [ 7] .gnu.version_d VERDEF 00000ae0 000ae0 0000a4 00 A 3 5 4
+ [ 8] .rel.plt REL 00000b84 000b84 000098 08 AI 2 13 4
+ [ 9] .plt PROGBITS 00000c1c 000c1c 0000f8 00 AX 0 0 4
+ [10] .text PROGBITS 00000d14 000d14 0002bc 00 AX 0 0 4
+ [11] .ARM.exidx ARM_EXIDX 00000fd0 000fd0 000030 08 AL 10 0 4
+ [12] .dynamic DYNAMIC 00001ef0 001ef0 0000b8 08 WA 3 0 4
+ [13] .got PROGBITS 00001fa8 001fa8 000058 00 WA 0 0 4
+ [14] .bss NOBITS 00002000 002000 001000 00 WA 0 0 4096
+ [15] .note.gnu.gold-ve NOTE 00000000 002000 00001c 00 0 0 4
+ [16] .ARM.attributes ARM_ATTRIBUTES 00000000 00201c 00004a 00 0 0 1
+ [17] .gnu_debugdata PROGBITS 00000000 002066 000338 00 0 0 1
+ [18] .shstrtab STRTAB 00000000 00239e 0000b7 00 0 0 1
+Key to Flags:
+ W (write), A (alloc), X (execute), M (merge), S (strings), I (info),
+ L (link order), O (extra OS processing required), G (group), T (TLS),
+ C (compressed), x (unknown), o (OS specific), E (exclude),
+ y (purecode), p (processor specific)
+
+There are no section groups in this file.
+
+Program Headers:
+ Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align
+ PHDR 0x000034 0x00000034 0x00000034 0x00100 0x00100 R 0x4
+ LOAD 0x000000 0x00000000 0x00000000 0x01000 0x01000 R E 0x1000
+ LOAD 0x001ef0 0x00001ef0 0x00001ef0 0x00110 0x01110 RW 0x1000
+ DYNAMIC 0x001ef0 0x00001ef0 0x00001ef0 0x000b8 0x000b8 RW 0x4
+ NOTE 0x000134 0x00000134 0x00000134 0x00020 0x00020 R 0x4
+ GNU_STACK 0x000000 0x00000000 0x00000000 0x00000 0x00000 RW 0x10
+ EXIDX 0x000fd0 0x00000fd0 0x00000fd0 0x00030 0x00030 R 0x4
+ GNU_RELRO 0x001ef0 0x00001ef0 0x00001ef0 0x00110 0x00110 RW 0x4
+
+ Section to Segment mapping:
+ Segment Sections...
+ 00
+ 01 .note.gnu.build-id .dynsym .dynstr .gnu.hash .hash .gnu.version .gnu.version_d .rel.plt .plt .text .ARM.exidx
+ 02 .dynamic .got .bss
+ 03 .dynamic
+ 04 .note.gnu.build-id
+ 05
+ 06 .ARM.exidx
+ 07 .dynamic .got
+
+Dynamic section at offset 0x1ef0 contains 18 entries:
+ Tag Type Name/Value
+ 0x00000003 (PLTGOT) 0x1fa8
+ 0x00000002 (PLTRELSZ) 152 (bytes)
+ 0x00000017 (JMPREL) 0xb84
+ 0x00000014 (PLTREL) REL
+ 0x00000006 (SYMTAB) 0x154
+ 0x0000000b (SYMENT) 16 (bytes)
+ 0x00000005 (STRTAB) 0x434
+ 0x0000000a (STRSZ) 1054 (bytes)
+ 0x6ffffef5 (GNU_HASH) 0x854
+ 0x00000004 (HASH) 0x930
+ 0x00000001 (NEEDED) Shared library: [ld-android.so]
+ 0x0000000e (SONAME) Library soname: [libdl.so]
+ 0x0000001e (FLAGS) BIND_NOW
+ 0x6ffffffb (FLAGS_1) Flags: NOW
+ 0x6ffffff0 (VERSYM) 0xa84
+ 0x6ffffffc (VERDEF) 0xae0
+ 0x6ffffffd (VERDEFNUM) 5
+ 0x00000000 (NULL) 0x0
+
+Relocation section '.rel.plt' at offset 0xb84 contains 19 entries:
+ Offset Info Type Sym.Value Sym. Name
+00001fb4 00001016 R_ARM_JUMP_SLOT 00000000 __loader_dlopen
+00001fb8 00000f16 R_ARM_JUMP_SLOT 00000000 __loader_dlerror
+00001fbc 00001116 R_ARM_JUMP_SLOT 00000000 __loader_dlsym
+00001fc0 00001216 R_ARM_JUMP_SLOT 00000000 __loader_dlvsym
+00001fc4 00000d16 R_ARM_JUMP_SLOT 00000000 __loader_dladdr
+00001fc8 00000e16 R_ARM_JUMP_SLOT 00000000 __loader_dlclose
+00001fcc 00000c16 R_ARM_JUMP_SLOT 00000000 __loader_dl_unwind_fin
+00001fd0 00000b16 R_ARM_JUMP_SLOT 00000000 __loader_dl_iterate_ph
+00001fd4 00000416 R_ARM_JUMP_SLOT 00000000 __loader_android_get_L
+00001fd8 00000a16 R_ARM_JUMP_SLOT 00000000 __loader_android_updat
+00001fdc 00000216 R_ARM_JUMP_SLOT 00000000 __loader_android_dlope
+00001fe0 00000916 R_ARM_JUMP_SLOT 00000000 __loader_android_set_a
+00001fe4 00000516 R_ARM_JUMP_SLOT 00000000 __loader_android_get_a
+00001fe8 00000716 R_ARM_JUMP_SLOT 00000000 __loader_android_init_
+00001fec 00000116 R_ARM_JUMP_SLOT 00000000 __loader_android_creat
+00001ff0 00000816 R_ARM_JUMP_SLOT 00000000 __loader_android_link_
+00001ff4 00000316 R_ARM_JUMP_SLOT 00000000 __loader_android_dlwar
+00001ff8 00000616 R_ARM_JUMP_SLOT 00000000 __loader_android_get_e
+00001ffc 00001316 R_ARM_JUMP_SLOT 00000000 __loader_cfi_fail
+
+Unwind section '.ARM.exidx' at offset 0xfd0 contains 6 entries:
+
+0xd14: 0x808408b0
+ Compact model index: 0
+ 0x84 0x08 pop {r7, r14}
+ 0xb0 finish
+
+0xd8c: 0x80058408
+ Compact model index: 0
+ 0x05 vsp = vsp + 24
+ 0x84 0x08 pop {r7, r14}
+
+0xdac: 0x808408b0
+ Compact model index: 0
+ 0x84 0x08 pop {r7, r14}
+ 0xb0 finish
+
+0xdc4: 0x80b0b0b0
+ Compact model index: 0
+ 0xb0 finish
+ 0xb0 finish
+ 0xb0 finish
+
+0xdec: 0x8001a8b0
+ Compact model index: 0
+ 0x01 vsp = vsp + 8
+ 0xa8 pop {r4, r14}
+ 0xb0 finish
+
+0xfd0: 0x1 [cantunwind]
+
+
+Symbol table '.dynsym' contains 46 entries:
+ Num: Value Size Type Bind Vis Ndx Name
+ 0: 00000000 0 NOTYPE LOCAL DEFAULT UND
+ 1: 00000000 0 FUNC WEAK DEFAULT UND __loader_android_create_n
+ 2: 00000000 0 FUNC WEAK DEFAULT UND __loader_android_dlopen_e
+ 3: 00000000 0 FUNC WEAK DEFAULT UND __loader_android_dlwarnin
+ 4: 00000000 0 FUNC WEAK DEFAULT UND __loader_android_get_LD_L
+ 5: 00000000 0 FUNC WEAK DEFAULT UND __loader_android_get_appl
+ 6: 00000000 0 FUNC WEAK DEFAULT UND __loader_android_get_expo
+ 7: 00000000 0 FUNC WEAK DEFAULT UND __loader_android_init_ano
+ 8: 00000000 0 FUNC WEAK DEFAULT UND __loader_android_link_nam
+ 9: 00000000 0 FUNC WEAK DEFAULT UND __loader_android_set_appl
+ 10: 00000000 0 FUNC WEAK DEFAULT UND __loader_android_update_L
+ 11: 00000000 0 FUNC WEAK DEFAULT UND __loader_dl_iterate_phdr
+ 12: 00000000 0 FUNC WEAK DEFAULT UND __loader_dl_unwind_find_e
+ 13: 00000000 0 FUNC WEAK DEFAULT UND __loader_dladdr
+ 14: 00000000 0 FUNC WEAK DEFAULT UND __loader_dlclose
+ 15: 00000000 0 FUNC WEAK DEFAULT UND __loader_dlerror
+ 16: 00000000 0 FUNC WEAK DEFAULT UND __loader_dlopen
+ 17: 00000000 0 FUNC WEAK DEFAULT UND __loader_dlsym
+ 18: 00000000 0 FUNC WEAK DEFAULT UND __loader_dlvsym
+ 19: 00000000 0 FUNC WEAK DEFAULT UND __loader_cfi_fail
+ 20: 00000d6b 10 FUNC WEAK DEFAULT 10 android_dlopen_ext@@LIBC
+ 21: 00000e45 92 FUNC GLOBAL DEFAULT 10 __cfi_slowpath_diag@@LIBC_OMR1
+ 22: 00000d85 8 FUNC WEAK DEFAULT 10 android_init_anonymous_na@@LIBC_PLATFORM
+ 23: 00000d63 8 FUNC WEAK DEFAULT 10 android_update_LD_LIBRARY@@LIBC_PLATFORM
+ 24: 00000dbd 8 FUNC WEAK DEFAULT 10 android_get_exported_name@@LIBC_PLATFORM
+ 25: 00000d75 8 FUNC WEAK DEFAULT 10 android_set_application_t@@LIBC_PLATFORM
+ 26: 00000d27 10 FUNC WEAK DEFAULT 10 dlsym@@LIBC
+ 27: 00000000 0 OBJECT GLOBAL DEFAULT ABS LIBC_N
+ 28: 00000dad 8 FUNC WEAK DEFAULT 10 android_link_namespaces@@LIBC_PLATFORM
+ 29: 00000000 0 OBJECT GLOBAL DEFAULT ABS LIBC
+ 30: 00000000 0 OBJECT GLOBAL DEFAULT ABS LIBC_PLATFORM
+ 31: 00000d1f 8 FUNC WEAK DEFAULT 10 dlerror@@LIBC
+ 32: 00000d15 10 FUNC WEAK DEFAULT 10 dlopen@@LIBC
+ 33: 00000dd9 20 FUNC GLOBAL DEFAULT 10 __cfi_shadow_size@@LIBC_OMR1
+ 34: 00000d43 8 FUNC WEAK DEFAULT 10 dlclose@@LIBC
+ 35: 00000db5 8 FUNC WEAK DEFAULT 10 android_dlwarning@@LIBC_PLATFORM
+ 36: 00000000 0 OBJECT GLOBAL DEFAULT ABS LIBC_OMR1
+ 37: 00000d7d 8 FUNC WEAK DEFAULT 10 android_get_application_t@@LIBC_PLATFORM
+ 38: 00000ded 88 FUNC GLOBAL DEFAULT 10 __cfi_slowpath@@LIBC_OMR1
+ 39: 00000d4b 8 FUNC WEAK DEFAULT 10 dl_unwind_find_exidx@@LIBC
+ 40: 00000d8d 32 FUNC WEAK DEFAULT 10 android_create_namespace@@LIBC_PLATFORM
+ 41: 00000d53 8 FUNC WEAK DEFAULT 10 dl_iterate_phdr@@LIBC
+ 42: 00000d3b 8 FUNC WEAK DEFAULT 10 dladdr@@LIBC
+ 43: 00000d5b 8 FUNC WEAK DEFAULT 10 android_get_LD_LIBRARY_PA@@LIBC_PLATFORM
+ 44: 00000d31 10 FUNC WEAK DEFAULT 10 dlvsym@@LIBC_N
+ 45: 00000dc9 16 FUNC GLOBAL DEFAULT 10 __cfi_init@@LIBC_PLATFORM
+
+Histogram for bucket list length (total of 37 buckets):
+ Length Number % of total Coverage
+ 0 10 ( 27.0%)
+ 1 14 ( 37.8%) 31.1%
+ 2 10 ( 27.0%) 75.6%
+ 3 2 ( 5.4%) 88.9%
+ 4 0 ( 0.0%) 88.9%
+ 5 1 ( 2.7%) 100.0%
+
+Histogram for `.gnu.hash' bucket list length (total of 17 buckets):
+ Length Number % of total Coverage
+ 0 0 ( 0.0%)
+ 1 9 ( 52.9%) 34.6%
+ 2 7 ( 41.2%) 88.5%
+ 3 1 ( 5.9%) 100.0%
+
+Version symbols section '.gnu.version' contains 46 entries:
+ Addr: 0000000000000a84 Offset: 0x000a84 Link: 2 (.dynsym)
+ 000: 0 (*local*) 0 (*local*) 0 (*local*) 0 (*local*)
+ 004: 0 (*local*) 0 (*local*) 0 (*local*) 0 (*local*)
+ 008: 0 (*local*) 0 (*local*) 0 (*local*) 0 (*local*)
+ 00c: 0 (*local*) 0 (*local*) 0 (*local*) 0 (*local*)
+ 010: 0 (*local*) 0 (*local*) 0 (*local*) 0 (*local*)
+ 014: 2 (LIBC) 4 (LIBC_OMR1) 5 (LIBC_PLATFORM) 5 (LIBC_PLATFORM)
+ 018: 5 (LIBC_PLATFORM) 5 (LIBC_PLATFORM) 2 (LIBC) 3 (LIBC_N)
+ 01c: 5 (LIBC_PLATFORM) 2 (LIBC) 5 (LIBC_PLATFORM) 2 (LIBC)
+ 020: 2 (LIBC) 4 (LIBC_OMR1) 2 (LIBC) 5 (LIBC_PLATFORM)
+ 024: 4 (LIBC_OMR1) 5 (LIBC_PLATFORM) 4 (LIBC_OMR1) 2 (LIBC)
+ 028: 5 (LIBC_PLATFORM) 2 (LIBC) 2 (LIBC) 5 (LIBC_PLATFORM)
+ 02c: 3 (LIBC_N) 5 (LIBC_PLATFORM)
+
+Version definition section '.gnu.version_d' contains 5 entries:
+ Addr: 0x0000000000000ae0 Offset: 0x000ae0 Link: 3 (.dynstr)
+ 000000: Rev: 1 Flags: BASE Index: 1 Cnt: 1 Name: libdl.so
+ 0x001c: Rev: 1 Flags: none Index: 2 Cnt: 1 Name: LIBC
+ 0x0038: Rev: 1 Flags: none Index: 3 Cnt: 2 Name: LIBC_N
+ 0x0054: Parent 1: LIBC
+ 0x005c: Rev: 1 Flags: none Index: 4 Cnt: 2 Name: LIBC_OMR1
+ 0x0078: Parent 1: LIBC_N
+ 0x0080: Rev: 1 Flags: none Index: 5 Cnt: 2 Name: LIBC_PLATFORM
+ 0x009c: Parent 1: LIBC_OMR1
+
+Displaying notes found in: .note.gnu.build-id
+ Owner Data size Description
+ GNU 0x00000010 NT_GNU_BUILD_ID (unique build ID bitstring)
+ Build ID: 676a0450f6cc27cf2554a3d1634fc4fe
+
+Displaying notes found in: .note.gnu.gold-version
+ Owner Data size Description
+ GNU 0x00000009 NT_GNU_GOLD_VERSION (gold version)
+ Version: gold 1.12
+Attribute Section: aeabi
+File Attributes
+ Tag_conformance: "2.09"
+ Tag_CPU_name: "cortex-a53"
+ Tag_CPU_arch: v8
+ Tag_CPU_arch_profile: Application
+ Tag_ARM_ISA_use: Yes
+ Tag_THUMB_ISA_use: Thumb-2
+ Tag_Advanced_SIMD_arch: NEON for ARMv8
+ Tag_ABI_PCS_RW_data: PC-relative
+ Tag_ABI_PCS_RO_data: PC-relative
+ Tag_ABI_PCS_GOT_use: GOT-indirect
+ Tag_ABI_PCS_wchar_t: 4
+ Tag_ABI_FP_denormal: Needed
+ Tag_ABI_FP_exceptions: Needed
+ Tag_ABI_FP_number_model: IEEE 754
+ Tag_ABI_align_needed: 8-byte
+ Tag_ABI_align_preserved: 8-byte, except leaf SP
+ Tag_ABI_enum_size: int
+ Tag_CPU_unaligned_access: v6
+ Tag_FP_HP_extension: Allowed
+ Tag_ABI_FP_16bit_format: IEEE 754
+ Tag_MPextension_use: Allowed
+ Tag_Virtualization_use: TrustZone and Virtualization Extensions
diff --git a/libraries/compatibility-common-util/tests/assets/arm64_libdl.so b/libraries/compatibility-common-util/tests/assets/arm64_libdl.so
new file mode 100644
index 000000000..f6e30342e
--- /dev/null
+++ b/libraries/compatibility-common-util/tests/assets/arm64_libdl.so
Binary files differ
diff --git a/libraries/compatibility-common-util/tests/assets/arm64_libdl.txt b/libraries/compatibility-common-util/tests/assets/arm64_libdl.txt
new file mode 100644
index 000000000..d531a9692
--- /dev/null
+++ b/libraries/compatibility-common-util/tests/assets/arm64_libdl.txt
@@ -0,0 +1,232 @@
+ELF Header:
+ Magic: 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00
+ Class: ELF64
+ Data: 2's complement, little endian
+ Version: 1 (current)
+ OS/ABI: UNIX - System V
+ ABI Version: 0
+ Type: DYN (Shared object file)
+ Machine: AArch64
+ Version: 0x1
+ Entry point address: 0x0
+ Start of program headers: 64 (bytes into file)
+ Start of section headers: 66280 (bytes into file)
+ Flags: 0x0
+ Size of this header: 64 (bytes)
+ Size of program headers: 56 (bytes)
+ Number of program headers: 8
+ Size of section headers: 64 (bytes)
+ Number of section headers: 19
+ Section header string table index: 18
+
+Section Headers:
+ [Nr] Name Type Address Offset
+ Size EntSize Flags Link Info Align
+ [ 0] NULL 0000000000000000 00000000
+ 0000000000000000 0000000000000000 0 0 0
+ [ 1] .note.gnu.build-i NOTE 0000000000000200 00000200
+ 0000000000000020 0000000000000000 A 0 0 4
+ [ 2] .dynsym DYNSYM 0000000000000220 00000220
+ 0000000000000420 0000000000000018 A 3 1 8
+ [ 3] .dynstr STRTAB 0000000000000640 00000640
+ 00000000000003eb 0000000000000000 A 0 0 1
+ [ 4] .gnu.hash GNU_HASH 0000000000000a30 00000a30
+ 00000000000000d8 0000000000000000 A 2 0 8
+ [ 5] .gnu.version VERSYM 0000000000000b08 00000b08
+ 0000000000000058 0000000000000002 A 2 0 2
+ [ 6] .gnu.version_d VERDEF 0000000000000b60 00000b60
+ 00000000000000a4 0000000000000000 A 3 5 4
+ [ 7] .rela.plt RELA 0000000000000c08 00000c08
+ 00000000000001b0 0000000000000018 AI 2 14 8
+ [ 8] .plt PROGBITS 0000000000000db8 00000db8
+ 0000000000000140 0000000000000010 AX 0 0 8
+ [ 9] .text PROGBITS 0000000000000ef8 00000ef8
+ 000000000000026c 0000000000000000 AX 0 0 4
+ [10] .eh_frame PROGBITS 0000000000001168 00001168
+ 00000000000002a8 0000000000000000 A 0 0 8
+ [11] .eh_frame_hdr PROGBITS 0000000000001410 00001410
+ 00000000000000b4 0000000000000000 A 0 0 4
+ [12] .dynamic DYNAMIC 000000000001fdf0 0000fdf0
+ 0000000000000160 0000000000000010 WA 3 0 8
+ [13] .got PROGBITS 000000000001ff50 0000ff50
+ 0000000000000008 0000000000000000 WA 0 0 8
+ [14] .got.plt PROGBITS 000000000001ff58 0000ff58
+ 00000000000000a8 0000000000000000 WA 0 0 8
+ [15] .bss NOBITS 0000000000020000 00010000
+ 0000000000001000 0000000000000000 WA 0 0 4096
+ [16] .note.gnu.gold-ve NOTE 0000000000000000 00010000
+ 000000000000001c 0000000000000000 0 0 4
+ [17] .gnu_debugdata PROGBITS 0000000000000000 0001001c
+ 0000000000000208 0000000000000000 0 0 1
+ [18] .shstrtab STRTAB 0000000000000000 00010224
+ 00000000000000be 0000000000000000 0 0 1
+Key to Flags:
+ W (write), A (alloc), X (execute), M (merge), S (strings), I (info),
+ L (link order), O (extra OS processing required), G (group), T (TLS),
+ C (compressed), x (unknown), o (OS specific), E (exclude),
+ p (processor specific)
+
+There are no section groups in this file.
+
+Program Headers:
+ Type Offset VirtAddr PhysAddr
+ FileSiz MemSiz Flags Align
+ PHDR 0x0000000000000040 0x0000000000000040 0x0000000000000040
+ 0x00000000000001c0 0x00000000000001c0 R 0x8
+ LOAD 0x0000000000000000 0x0000000000000000 0x0000000000000000
+ 0x00000000000014c4 0x00000000000014c4 R E 0x10000
+ LOAD 0x000000000000fdf0 0x000000000001fdf0 0x000000000001fdf0
+ 0x0000000000000210 0x0000000000001210 RW 0x10000
+ DYNAMIC 0x000000000000fdf0 0x000000000001fdf0 0x000000000001fdf0
+ 0x0000000000000160 0x0000000000000160 RW 0x8
+ NOTE 0x0000000000000200 0x0000000000000200 0x0000000000000200
+ 0x0000000000000020 0x0000000000000020 R 0x4
+ GNU_EH_FRAME 0x0000000000001410 0x0000000000001410 0x0000000000001410
+ 0x00000000000000b4 0x00000000000000b4 R 0x4
+ GNU_STACK 0x0000000000000000 0x0000000000000000 0x0000000000000000
+ 0x0000000000000000 0x0000000000000000 RW 0x10
+ GNU_RELRO 0x000000000000fdf0 0x000000000001fdf0 0x000000000001fdf0
+ 0x0000000000000210 0x0000000000000210 RW 0x8
+
+ Section to Segment mapping:
+ Segment Sections...
+ 00
+ 01 .note.gnu.build-id .dynsym .dynstr .gnu.hash .gnu.version .gnu.version_d .rela.plt .plt .text .eh_frame .eh_frame_hdr
+ 02 .dynamic .got .got.plt .bss
+ 03 .dynamic
+ 04 .note.gnu.build-id
+ 05 .eh_frame_hdr
+ 06
+ 07 .dynamic .got .got.plt
+
+Dynamic section at offset 0xfdf0 contains 17 entries:
+ Tag Type Name/Value
+ 0x0000000000000003 (PLTGOT) 0x1ff58
+ 0x0000000000000002 (PLTRELSZ) 432 (bytes)
+ 0x0000000000000017 (JMPREL) 0xc08
+ 0x0000000000000014 (PLTREL) RELA
+ 0x0000000000000006 (SYMTAB) 0x220
+ 0x000000000000000b (SYMENT) 24 (bytes)
+ 0x0000000000000005 (STRTAB) 0x640
+ 0x000000000000000a (STRSZ) 1003 (bytes)
+ 0x000000006ffffef5 (GNU_HASH) 0xa30
+ 0x0000000000000001 (NEEDED) Shared library: [ld-android.so]
+ 0x000000000000000e (SONAME) Library soname: [libdl.so]
+ 0x000000000000001e (FLAGS) BIND_NOW
+ 0x000000006ffffffb (FLAGS_1) Flags: NOW
+ 0x000000006ffffff0 (VERSYM) 0xb08
+ 0x000000006ffffffc (VERDEF) 0xb60
+ 0x000000006ffffffd (VERDEFNUM) 5
+ 0x0000000000000000 (NULL) 0x0
+
+Relocation section '.rela.plt' at offset 0xc08 contains 18 entries:
+ Offset Info Type Sym. Value Sym. Name + Addend
+00000001ff70 000f00000402 R_AARCH64_JUMP_SL 0000000000000000 __loader_dlopen + 0
+00000001ff78 000e00000402 R_AARCH64_JUMP_SL 0000000000000000 __loader_dlerror + 0
+00000001ff80 001000000402 R_AARCH64_JUMP_SL 0000000000000000 __loader_dlsym + 0
+00000001ff88 001100000402 R_AARCH64_JUMP_SL 0000000000000000 __loader_dlvsym + 0
+00000001ff90 000c00000402 R_AARCH64_JUMP_SL 0000000000000000 __loader_dladdr + 0
+00000001ff98 000d00000402 R_AARCH64_JUMP_SL 0000000000000000 __loader_dlclose + 0
+00000001ffa0 000b00000402 R_AARCH64_JUMP_SL 0000000000000000 __loader_dl_iterate_ph + 0
+00000001ffa8 000400000402 R_AARCH64_JUMP_SL 0000000000000000 __loader_android_get_L + 0
+00000001ffb0 000a00000402 R_AARCH64_JUMP_SL 0000000000000000 __loader_android_updat + 0
+00000001ffb8 000200000402 R_AARCH64_JUMP_SL 0000000000000000 __loader_android_dlope + 0
+00000001ffc0 000900000402 R_AARCH64_JUMP_SL 0000000000000000 __loader_android_set_a + 0
+00000001ffc8 000500000402 R_AARCH64_JUMP_SL 0000000000000000 __loader_android_get_a + 0
+00000001ffd0 000700000402 R_AARCH64_JUMP_SL 0000000000000000 __loader_android_init_ + 0
+00000001ffd8 000100000402 R_AARCH64_JUMP_SL 0000000000000000 __loader_android_creat + 0
+00000001ffe0 000800000402 R_AARCH64_JUMP_SL 0000000000000000 __loader_android_link_ + 0
+00000001ffe8 000300000402 R_AARCH64_JUMP_SL 0000000000000000 __loader_android_dlwar + 0
+00000001fff0 000600000402 R_AARCH64_JUMP_SL 0000000000000000 __loader_android_get_e + 0
+00000001fff8 001200000402 R_AARCH64_JUMP_SL 0000000000000000 __loader_cfi_fail + 0
+
+The decoding of unwind sections for machine type AArch64 is not currently supported.
+
+Symbol table '.dynsym' contains 44 entries:
+ Num: Value Size Type Bind Vis Ndx Name
+ 0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
+ 1: 0000000000000000 0 FUNC WEAK DEFAULT UND __loader_android_create_n
+ 2: 0000000000000000 0 FUNC WEAK DEFAULT UND __loader_android_dlopen_e
+ 3: 0000000000000000 0 FUNC WEAK DEFAULT UND __loader_android_dlwarnin
+ 4: 0000000000000000 0 FUNC WEAK DEFAULT UND __loader_android_get_LD_L
+ 5: 0000000000000000 0 FUNC WEAK DEFAULT UND __loader_android_get_appl
+ 6: 0000000000000000 0 FUNC WEAK DEFAULT UND __loader_android_get_expo
+ 7: 0000000000000000 0 FUNC WEAK DEFAULT UND __loader_android_init_ano
+ 8: 0000000000000000 0 FUNC WEAK DEFAULT UND __loader_android_link_nam
+ 9: 0000000000000000 0 FUNC WEAK DEFAULT UND __loader_android_set_appl
+ 10: 0000000000000000 0 FUNC WEAK DEFAULT UND __loader_android_update_L
+ 11: 0000000000000000 0 FUNC WEAK DEFAULT UND __loader_dl_iterate_phdr
+ 12: 0000000000000000 0 FUNC WEAK DEFAULT UND __loader_dladdr
+ 13: 0000000000000000 0 FUNC WEAK DEFAULT UND __loader_dlclose
+ 14: 0000000000000000 0 FUNC WEAK DEFAULT UND __loader_dlerror
+ 15: 0000000000000000 0 FUNC WEAK DEFAULT UND __loader_dlopen
+ 16: 0000000000000000 0 FUNC WEAK DEFAULT UND __loader_dlsym
+ 17: 0000000000000000 0 FUNC WEAK DEFAULT UND __loader_dlvsym
+ 18: 0000000000000000 0 FUNC WEAK DEFAULT UND __loader_cfi_fail
+ 19: 0000000000000fb8 24 FUNC WEAK DEFAULT 9 android_dlopen_ext@@LIBC
+ 20: 0000000000000ff8 24 FUNC WEAK DEFAULT 9 android_init_anonymous_na@@LIBC_PLATFORM
+ 21: 0000000000001100 100 FUNC GLOBAL DEFAULT 9 __cfi_slowpath_diag@@LIBC_OMR1
+ 22: 0000000000000fa4 20 FUNC WEAK DEFAULT 9 android_update_LD_LIBRARY@@LIBC_PLATFORM
+ 23: 0000000000001054 20 FUNC WEAK DEFAULT 9 android_get_exported_name@@LIBC_PLATFORM
+ 24: 0000000000000fd0 20 FUNC WEAK DEFAULT 9 android_set_application_t@@LIBC_PLATFORM
+ 25: 0000000000000f24 24 FUNC WEAK DEFAULT 9 dlsym@@LIBC
+ 26: 0000000000000000 0 OBJECT GLOBAL DEFAULT ABS LIBC_N
+ 27: 0000000000001028 24 FUNC WEAK DEFAULT 9 android_link_namespaces@@LIBC_PLATFORM
+ 28: 0000000000000000 0 OBJECT GLOBAL DEFAULT ABS LIBC
+ 29: 0000000000000000 0 OBJECT GLOBAL DEFAULT ABS LIBC_PLATFORM
+ 30: 0000000000000f10 20 FUNC WEAK DEFAULT 9 dlerror@@LIBC
+ 31: 0000000000000ef8 24 FUNC WEAK DEFAULT 9 dlopen@@LIBC
+ 32: 000000000000107c 24 FUNC GLOBAL DEFAULT 9 __cfi_shadow_size@@LIBC_OMR1
+ 33: 0000000000000f68 20 FUNC WEAK DEFAULT 9 dlclose@@LIBC
+ 34: 0000000000001040 20 FUNC WEAK DEFAULT 9 android_dlwarning@@LIBC_PLATFORM
+ 35: 0000000000000000 0 OBJECT GLOBAL DEFAULT ABS LIBC_OMR1
+ 36: 0000000000000fe4 20 FUNC WEAK DEFAULT 9 android_get_application_t@@LIBC_PLATFORM
+ 37: 0000000000001094 108 FUNC GLOBAL DEFAULT 9 __cfi_slowpath@@LIBC_OMR1
+ 38: 0000000000001010 24 FUNC WEAK DEFAULT 9 android_create_namespace@@LIBC_PLATFORM
+ 39: 0000000000000f7c 20 FUNC WEAK DEFAULT 9 dl_iterate_phdr@@LIBC
+ 40: 0000000000000f54 20 FUNC WEAK DEFAULT 9 dladdr@@LIBC
+ 41: 0000000000000f90 20 FUNC WEAK DEFAULT 9 android_get_LD_LIBRARY_PA@@LIBC_PLATFORM
+ 42: 0000000000000f3c 24 FUNC WEAK DEFAULT 9 dlvsym@@LIBC_N
+ 43: 0000000000001068 20 FUNC GLOBAL DEFAULT 9 __cfi_init@@LIBC_PLATFORM
+
+Histogram for `.gnu.hash' bucket list length (total of 17 buckets):
+ Length Number % of total Coverage
+ 0 0 ( 0.0%)
+ 1 10 ( 58.8%) 40.0%
+ 2 6 ( 35.3%) 88.0%
+ 3 1 ( 5.9%) 100.0%
+
+Version symbols section '.gnu.version' contains 44 entries:
+ Addr: 0000000000000b08 Offset: 0x000b08 Link: 2 (.dynsym)
+ 000: 0 (*local*) 0 (*local*) 0 (*local*) 0 (*local*)
+ 004: 0 (*local*) 0 (*local*) 0 (*local*) 0 (*local*)
+ 008: 0 (*local*) 0 (*local*) 0 (*local*) 0 (*local*)
+ 00c: 0 (*local*) 0 (*local*) 0 (*local*) 0 (*local*)
+ 010: 0 (*local*) 0 (*local*) 0 (*local*) 2 (LIBC)
+ 014: 5 (LIBC_PLATFORM) 4 (LIBC_OMR1) 5 (LIBC_PLATFORM) 5 (LIBC_PLATFORM)
+ 018: 5 (LIBC_PLATFORM) 2 (LIBC) 3 (LIBC_N) 5 (LIBC_PLATFORM)
+ 01c: 2 (LIBC) 5 (LIBC_PLATFORM) 2 (LIBC) 2 (LIBC)
+ 020: 4 (LIBC_OMR1) 2 (LIBC) 5 (LIBC_PLATFORM) 4 (LIBC_OMR1)
+ 024: 5 (LIBC_PLATFORM) 4 (LIBC_OMR1) 5 (LIBC_PLATFORM) 2 (LIBC)
+ 028: 2 (LIBC) 5 (LIBC_PLATFORM) 3 (LIBC_N) 5 (LIBC_PLATFORM)
+
+Version definition section '.gnu.version_d' contains 5 entries:
+ Addr: 0x0000000000000b60 Offset: 0x000b60 Link: 3 (.dynstr)
+ 000000: Rev: 1 Flags: BASE Index: 1 Cnt: 1 Name: libdl.so
+ 0x001c: Rev: 1 Flags: none Index: 2 Cnt: 1 Name: LIBC
+ 0x0038: Rev: 1 Flags: none Index: 3 Cnt: 2 Name: LIBC_N
+ 0x0054: Parent 1: LIBC
+ 0x005c: Rev: 1 Flags: none Index: 4 Cnt: 2 Name: LIBC_OMR1
+ 0x0078: Parent 1: LIBC_N
+ 0x0080: Rev: 1 Flags: none Index: 5 Cnt: 2 Name: LIBC_PLATFORM
+ 0x009c: Parent 1: LIBC_OMR1
+
+Displaying notes found in: .note.gnu.build-id
+ Owner Data size Description
+ GNU 0x00000010 NT_GNU_BUILD_ID (unique build ID bitstring)
+ Build ID: 52512b2d7a8b4c6fc4eace5145a3daca
+
+Displaying notes found in: .note.gnu.gold-version
+ Owner Data size Description
+ GNU 0x00000009 NT_GNU_GOLD_VERSION (gold version)
+ Version: gold 1.12
diff --git a/libraries/compatibility-common-util/tests/assets/logcat.txt b/libraries/compatibility-common-util/tests/assets/logcat.txt
new file mode 100644
index 000000000..ffb28ad5c
--- /dev/null
+++ b/libraries/compatibility-common-util/tests/assets/logcat.txt
@@ -0,0 +1,335 @@
+--------- beginning of system
+09-03 17:47:59.490 7039 7054 D AtCkpdCmdHandler: De-queing command
+--------- beginning of crash
+09-03 17:48:05.627 11071 11189 F libc : Fatal signal 11 (SIGSEGV), code 1, fault addr 0xe9380000 in tid 11189 (AudioOut_D)
+09-03 17:48:05.707 359 359 W : debuggerd: handling request: pid=11071 uid=1041 gid=1005 tid=11189
+09-03 17:48:05.796 7072 7072 F DEBUG : *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
+09-03 17:48:05.796 7072 7072 F DEBUG : Build fingerprint: 'google/angler/angler:7.1.1/N4F26T/3687331:userdebug/dev-keys'
+09-03 17:48:05.796 7072 7072 F DEBUG : Revision: '0'
+09-03 17:48:05.796 7072 7072 F DEBUG : ABI: 'arm'
+09-03 17:48:05.796 7072 7072 F DEBUG : pid: 11071, tid: 11189, name: AudioOut_D >>> /system/bin/audioserver <<<
+09-03 17:48:05.797 7072 7072 F DEBUG : signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0xe9380000
+09-03 17:48:05.797 7072 7072 F DEBUG : r0 e9e7a240 r1 e9380000 r2 00000170 r3 00000000
+09-03 17:48:05.797 7072 7072 F DEBUG : r4 00000002 r5 00000000 r6 ec1e1f25 r7 eb6f8000
+09-03 17:48:05.797 7072 7072 F DEBUG : r8 00000000 r9 eb105204 sl 00000000 fp 000003c0
+09-03 17:48:05.797 7072 7072 F DEBUG : ip ebd3df18 sp eaf80688 lr ec1e1f41 pc ebd38dd6 cpsr 20000030
+09-03 17:48:05.805 7072 7072 F DEBUG :
+09-03 17:48:05.805 7072 7072 F DEBUG : backtrace:
+09-03 17:48:05.806 7072 7072 F DEBUG : #00 pc 00002dd6 /system/lib/libaudioutils.so (memcpy_to_float_from_i16+5)
+09-03 17:48:05.806 7072 7072 F DEBUG : #01 pc 00040f3d /system/lib/libaudioflinger.so
+09-03 17:48:05.806 7072 7072 F DEBUG : #02 pc 00040799 /system/lib/libaudioflinger.so
+09-03 17:48:05.806 7072 7072 F DEBUG : #03 pc 00011178 /system/lib/libaudioflinger.so
+09-03 17:48:05.806 7072 7072 F DEBUG : #04 pc 0003180b /system/lib/libaudioflinger.so
+09-03 17:48:05.806 7072 7072 F DEBUG : #05 pc 0002fe57 /system/lib/libaudioflinger.so
+09-03 17:48:05.806 7072 7072 F DEBUG : #06 pc 0000e345 /system/lib/libutils.so (_ZN7android6Thread11_threadLoopEPv+140)
+09-03 17:48:05.806 7072 7072 F DEBUG : #07 pc 000470b3 /system/lib/libc.so (_ZL15__pthread_startPv+22)
+09-03 17:48:05.806 7072 7072 F DEBUG : #08 pc 00019e3d /system/lib/libc.so (__start_thread+6)
+09-03 17:48:05.967 11272 11568 W NativeCrashListener: Couldn't find ProcessRecord for pid 11071
+09-03 17:48:05.969 359 359 W : debuggerd: resuming target 11071
+09-03 17:48:05.981 11272 11307 I BootReceiver: Copying /data/tombstones/tombstone_01 to DropBox (SYSTEM_TOMBSTONE)
+09-03 17:48:06.067 394 394 I ServiceManager: service 'media.sound_trigger_hw' died
+06-15 19:57:33.607 12736 12761 D PermissionCache: checking android.permission.MODIFY_AUDIO_SETTINGS for uid=10197 => granted (698 us)
+--------- beginning of crash
+06-15 19:57:33.607 12736 12761 F libc : Fatal signal 11 (SIGSEGV), code 1, fault addr 0x0 in tid 12761 (Binder:12736_2)
+06-15 19:57:33.608 379 379 W : debuggerd: handling request: pid=12736 uid=1041 gid=1005 tid=12761
+06-15 19:57:33.670 26192 26192 F DEBUG : *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
+06-15 19:57:33.670 26192 26192 F DEBUG : Build fingerprint: 'google/bullhead/bullhead:7.1.2/N2G48C/4104010:userdebug/dev-keys'
+06-15 19:57:33.670 26192 26192 F DEBUG : Revision: 'rev_1.0'
+06-15 19:57:33.670 26192 26192 F DEBUG : ABI: 'arm'
+06-15 19:57:33.670 26192 26192 F DEBUG : pid: 12736, tid: 12761, name: Binder:12736_2 >>> /system/bin/audioserver <<<
+06-15 19:57:33.670 26192 26192 F DEBUG : signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x0
+06-15 19:57:33.670 26192 26192 F DEBUG : r0 00000000 r1 00000000 r2 0000005f r3 00000000
+06-15 19:57:33.670 26192 26192 F DEBUG : r4 ffffffff r5 00000000 r6 f14f9000 r7 00000001
+06-15 19:57:33.670 26192 26192 F DEBUG : r8 00000004 r9 f3353114 sl f3313900 fp 00000000
+06-15 19:57:33.670 26192 26192 F DEBUG : ip f3bd4d88 sp f127d9c8 lr f3b9cbc5 pc f3b65af4 cpsr 60000030
+06-15 19:57:33.676 26192 26192 F DEBUG :
+06-15 19:57:33.676 26192 26192 F DEBUG : backtrace:
+06-15 19:57:33.677 26192 26192 F DEBUG : #00 pc 00018af4 /system/lib/libc.so (strlen+71)
+06-15 19:57:33.677 26192 26192 F DEBUG : #01 pc 0004fbc1 /system/lib/libc.so (__strlen_chk+4)
+06-15 19:57:33.677 26192 26192 F DEBUG : #02 pc 0000c599 /system/lib/libutils.so (_ZN7android7String8C2EPKc+12)
+06-15 19:57:33.677 26192 26192 F DEBUG : #03 pc 0002fdbf /system/lib/libaudiopolicymanagerdefault.so (_ZNK7android18HwModuleCollection19getDeviceDescriptorEjPKcS2_b+458)
+06-15 19:57:33.677 26192 26192 F DEBUG : #04 pc 0001de47 /system/lib/libaudiopolicymanagerdefault.so (_ZN7android18AudioPolicyManager27setDeviceConnectionStateIntEj24audio_policy_dev_state_tPKcS3_+178)
+06-15 19:57:33.677 26192 26192 F DEBUG : #05 pc 0000a009 /system/lib/libaudiopolicyservice.so
+06-15 19:57:33.677 26192 26192 F DEBUG : #06 pc 000a01a5 /system/lib/libmedia.so (_ZN7android20BnAudioPolicyService10onTransactEjRKNS_6ParcelEPS1_j+1256)
+06-15 19:57:33.677 26192 26192 F DEBUG : #07 pc 000359c3 /system/lib/libbinder.so (_ZN7android7BBinder8transactEjRKNS_6ParcelEPS1_j+70)
+06-15 19:57:33.677 26192 26192 F DEBUG : #08 pc 0003d1bb /system/lib/libbinder.so (_ZN7android14IPCThreadState14executeCommandEi+702)
+06-15 19:57:33.677 26192 26192 F DEBUG : #09 pc 0003ce07 /system/lib/libbinder.so (_ZN7android14IPCThreadState20getAndExecuteCommandEv+114)
+06-15 19:57:33.677 26192 26192 F DEBUG : #10 pc 0003d31b /system/lib/libbinder.so (_ZN7android14IPCThreadState14joinThreadPoolEb+46)
+06-15 19:57:33.678 26192 26192 F DEBUG : #11 pc 0004f8c5 /system/lib/libbinder.so
+06-15 19:57:33.678 26192 26192 F DEBUG : #12 pc 0000e345 /system/lib/libutils.so (_ZN7android6Thread11_threadLoopEPv+140)
+06-15 19:57:33.678 26192 26192 F DEBUG : #13 pc 000470b3 /system/lib/libc.so (_ZL15__pthread_startPv+22)
+06-15 19:57:33.678 26192 26192 F DEBUG : #14 pc 00019e3d /system/lib/libc.so (__start_thread+6)
+06-15 19:57:33.839 934 2991 W NativeCrashListener: Couldn't find ProcessRecord for pid 12736
+06-15 19:57:33.846 934 952 I BootReceiver: Copying /data/tombstones/tombstone_01 to DropBox (SYSTEM_TOMBSTONE)
+06-15 19:57:35.130 26201 26227 F libc : Fatal signal 11 (SIGSEGV), code 1, fault addr 0x0 in tid 26227 (Binder:26201_3)
+06-15 19:57:35.130 26201 26228 D PermissionCache: checking android.permission.MODIFY_AUDIO_SETTINGS for uid=1000 => granted (318 us)
+06-15 19:57:35.130 379 379 W : debuggerd: handling request: pid=26201 uid=1041 gid=1005 tid=26227
+06-15 19:57:35.131 26201 26212 D audio_hw_primary: select_devices: changing use case low-latency-playback output device from(0: none, acdb -1) to (2: speaker, acdb 14)
+06-15 19:57:35.191 26230 26230 F DEBUG : *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
+06-15 19:57:35.191 26230 26230 F DEBUG : Build fingerprint: 'google/bullhead/bullhead:7.1.2/N2G48C/4104010:userdebug/dev-keys'
+06-15 19:57:35.191 26230 26230 F DEBUG : Revision: 'rev_1.0'
+06-15 19:57:35.191 26230 26230 F DEBUG : ABI: 'arm'
+06-15 19:57:35.191 26230 26230 F DEBUG : pid: 26201, tid: 26227, name: Binder:26201_3 >>> /system/bin/audioserver <<<
+06-15 19:57:35.191 26230 26230 F DEBUG : signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x0
+06-15 19:57:35.191 26230 26230 F DEBUG : r0 00000000 r1 00000000 r2 0000005f r3 00000000
+06-15 19:57:35.191 26230 26230 F DEBUG : r4 ffffffff r5 00000000 r6 e49bb000 r7 00000001
+06-15 19:57:35.191 26230 26230 F DEBUG : r8 00000004 r9 e6b53114 sl e6b13900 fp 00000000
+06-15 19:57:35.191 26230 26230 F DEBUG : ip e746bd88 sp e4c009c8 lr e7433bc5 pc e73fcaf4 cpsr 60000030
+06-15 19:57:35.195 26230 26230 F DEBUG :
+06-15 19:57:35.195 26230 26230 F DEBUG : backtrace:
+06-15 19:57:35.195 26230 26230 F DEBUG : #00 pc 00018af4 /system/lib/libc.so (strlen+71)
+06-15 19:57:35.195 26230 26230 F DEBUG : #01 pc 0004fbc1 /system/lib/libc.so (__strlen_chk+4)
+06-15 19:57:35.195 26230 26230 F DEBUG : #02 pc 0000c599 /system/lib/libutils.so (_ZN7android7String8C2EPKc+12)
+06-15 19:57:35.195 26230 26230 F DEBUG : #03 pc 0002fdbf /system/lib/libaudiopolicymanagerdefault.so (_ZNK7android18HwModuleCollection19getDeviceDescriptorEjPKcS2_b+458)
+06-15 19:57:35.196 26230 26230 F DEBUG : #04 pc 0001de47 /system/lib/libaudiopolicymanagerdefault.so (_ZN7android18AudioPolicyManager27setDeviceConnectionStateIntEj24audio_policy_dev_state_tPKcS3_+178)
+06-15 19:57:35.196 26230 26230 F DEBUG : #05 pc 0000a009 /system/lib/libaudiopolicyservice.so
+06-15 19:57:35.196 26230 26230 F DEBUG : #06 pc 000a01a5 /system/lib/libmedia.so (_ZN7android20BnAudioPolicyService10onTransactEjRKNS_6ParcelEPS1_j+1256)
+06-15 19:57:35.196 26230 26230 F DEBUG : #07 pc 000359c3 /system/lib/libbinder.so (_ZN7android7BBinder8transactEjRKNS_6ParcelEPS1_j+70)
+06-15 19:57:35.196 26230 26230 F DEBUG : #08 pc 0003d1bb /system/lib/libbinder.so (_ZN7android14IPCThreadState14executeCommandEi+702)
+06-15 19:57:35.196 26230 26230 F DEBUG : #09 pc 0003ce07 /system/lib/libbinder.so (_ZN7android14IPCThreadState20getAndExecuteCommandEv+114)
+06-15 19:57:35.196 26230 26230 F DEBUG : #10 pc 0003d31b /system/lib/libbinder.so (_ZN7android14IPCThreadState14joinThreadPoolEb+46)
+06-15 19:57:35.196 26230 26230 F DEBUG : #11 pc 0004f8c5 /system/lib/libbinder.so
+06-15 19:57:35.196 26230 26230 F DEBUG : #12 pc 0000e345 /system/lib/libutils.so (_ZN7android6Thread11_threadLoopEPv+140)
+06-15 19:57:35.196 26230 26230 F DEBUG : #13 pc 000470b3 /system/lib/libc.so (_ZL15__pthread_startPv+22)
+06-15 19:57:35.196 26230 26230 F DEBUG : #14 pc 00019e3d /system/lib/libc.so (__start_thread+6)
+06-15 19:57:35.346 934 2991 W NativeCrashListener: Couldn't find ProcessRecord for pid 26201
+06-15 19:57:35.346 26230 26230 E : AM data write failed: Broken pipe
+06-15 19:57:40.605 26246 26261 D audio_hw_primary: enable_snd_device: snd_device(78: vi-feedback)
+06-15 19:57:40.606 26246 26261 D audio_hw_primary: enable_audio_route: usecase(21) apply and update mixer path: spkr-vi-record
+06-15 19:57:40.673 26283 26283 F DEBUG : *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
+06-15 19:57:40.674 26283 26283 F DEBUG : Build fingerprint: 'google/bullhead/bullhead:7.1.2/N2G48C/4104010:userdebug/dev-keys'
+06-15 19:57:40.674 26283 26283 F DEBUG : Revision: 'rev_1.0'
+06-15 19:57:40.674 26283 26283 F DEBUG : ABI: 'arm'
+06-15 19:57:40.674 26283 26283 F DEBUG : pid: 26246, tid: 26282, name: Binder:26246_5 >>> /system/bin/audioserver <<<
+06-15 19:57:40.674 26283 26283 F DEBUG : signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x0
+06-15 19:57:40.674 26283 26283 F DEBUG : r0 00000000 r1 00000000 r2 0000005f r3 00000000
+06-15 19:57:40.674 26283 26283 F DEBUG : r4 ffffffff r5 00000000 r6 eb750000 r7 00000001
+06-15 19:57:40.674 26283 26283 F DEBUG : r8 00000004 r9 ed953114 sl ed913900 fp 00000000
+06-15 19:57:40.674 26283 26283 F DEBUG : ip eda8bd88 sp eb4fd9c8 lr eda53bc5 pc eda1caf4 cpsr 60000030
+06-15 19:57:40.679 26283 26283 F DEBUG :
+06-15 19:57:40.679 26283 26283 F DEBUG : backtrace:
+06-15 19:57:40.679 26283 26283 F DEBUG : #00 pc 00018af4 /system/lib/libc.so (strlen+71)
+06-15 19:57:40.679 26283 26283 F DEBUG : #01 pc 0004fbc1 /system/lib/libc.so (__strlen_chk+4)
+06-15 19:57:40.679 26283 26283 F DEBUG : #02 pc 0000c599 /system/lib/libutils.so (_ZN7android7String8C2EPKc+12)
+06-15 19:57:40.679 26283 26283 F DEBUG : #03 pc 0002fdbf /system/lib/libaudiopolicymanagerdefault.so (_ZNK7android18HwModuleCollection19getDeviceDescriptorEjPKcS2_b+458)
+06-15 19:57:40.679 26283 26283 F DEBUG : #04 pc 0001de47 /system/lib/libaudiopolicymanagerdefault.so (_ZN7android18AudioPolicyManager27setDeviceConnectionStateIntEj24audio_policy_dev_state_tPKcS3_+178)
+06-15 19:57:40.679 26283 26283 F DEBUG : #05 pc 0000a009 /system/lib/libaudiopolicyservice.so
+06-15 19:57:40.680 26283 26283 F DEBUG : #06 pc 000a01a5 /system/lib/libmedia.so (_ZN7android20BnAudioPolicyService10onTransactEjRKNS_6ParcelEPS1_j+1256)
+06-15 19:57:40.680 26283 26283 F DEBUG : #07 pc 000359c3 /system/lib/libbinder.so (_ZN7android7BBinder8transactEjRKNS_6ParcelEPS1_j+70)
+06-15 19:57:40.680 26283 26283 F DEBUG : #08 pc 0003d1bb /system/lib/libbinder.so (_ZN7android14IPCThreadState14executeCommandEi+702)
+06-15 19:57:40.680 26283 26283 F DEBUG : #09 pc 0003ce07 /system/lib/libbinder.so (_ZN7android14IPCThreadState20getAndExecuteCommandEv+114)
+06-15 19:57:40.680 26283 26283 F DEBUG : #10 pc 0003d31b /system/lib/libbinder.so (_ZN7android14IPCThreadState14joinThreadPoolEb+46)
+06-15 19:57:40.680 26283 26283 F DEBUG : #11 pc 0004f8c5 /system/lib/libbinder.so
+06-15 19:57:40.680 26283 26283 F DEBUG : #12 pc 0000e345 /system/lib/libutils.so (_ZN7android6Thread11_threadLoopEPv+140)
+06-15 19:57:40.680 26283 26283 F DEBUG : #13 pc 000470b3 /system/lib/libc.so (_ZL15__pthread_startPv+22)
+06-15 19:57:40.680 26283 26283 F DEBUG : #14 pc 00019e3d /system/lib/libc.so (__start_thread+6)
+06-15 19:57:40.882 934 2991 W NativeCrashListener: Couldn't find ProcessRecord for pid 26246
+06-15 19:57:40.889 934 952 I BootReceiver: Copying /data/tombstones/tombstone_03 to DropBox (SYSTEM_TOMBSTONE)
+09-23 01:55:43.022 245 245 F installd: utils.cpp:67] Check failed: is_valid_package_name(package_name) == 0
+--------- beginning of crash
+09-23 01:55:43.022 245 245 F libc : Fatal signal 6 (SIGABRT), code -6 in tid 245 (installd)
+09-23 01:55:43.022 166 166 W : debuggerd: handling request: pid=245 uid=0 gid=0 tid=245
+09-23 01:55:43.026 546 546 E : debuggerd: Unable to connect to activity manager (connect failed: Connection refused)
+09-23 01:55:43.076 546 546 F DEBUG : *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
+09-23 01:55:43.076 546 546 F DEBUG : Build fingerprint: 'google/ryu/dragon:7.1.2/N2G48C/4104010:userdebug/dev-keys'
+09-23 01:55:43.076 546 546 F DEBUG : Revision: '0'
+09-23 01:55:43.076 546 546 F DEBUG : ABI: 'arm64'
+09-23 01:55:43.077 546 546 F DEBUG : pid: 245, tid: 245, name: installd >>> /system/bin/installd <<<
+09-23 01:55:43.077 546 546 F DEBUG : signal 6 (SIGABRT), code -6 (SI_TKILL), fault addr --------
+09-23 01:55:43.077 546 546 F DEBUG : Abort message: 'utils.cpp:67] Check failed: is_valid_package_name(package_name) == 0 '
+09-23 01:55:43.077 546 546 F DEBUG : x0 0000000000000000 x1 00000000000000f5 x2 0000000000000006 x3 0000000000000008
+09-23 01:55:43.078 546 546 F DEBUG : x4 0000000000000000 x5 0000000000000000 x6 00000076a4172000 x7 0000000000000000
+09-23 01:55:43.078 546 546 F DEBUG : x8 0000000000000083 x9 ffffffffffffffdf x10 0000000000000000 x11 0000000000000001
+09-23 01:55:43.078 546 546 F DEBUG : x12 0000000000000018 x13 0000000000000000 x14 0000000000000000 x15 000157de95b365f0
+09-23 01:55:43.078 546 546 F DEBUG : x16 00000076a4099ee0 x17 00000076a4043b24 x18 0000000000000000 x19 00000076a4227b40
+09-23 01:55:43.078 546 546 F DEBUG : x20 0000000000000006 x21 00000076a4227a98 x22 0000000000000014 x23 0000000000000005
+09-23 01:55:43.078 546 546 F DEBUG : x24 00000076a3834040 x25 0000000000000000 x26 0000000000000005 x27 0000000000000006
+09-23 01:55:43.078 546 546 F DEBUG : x28 0000007ff8a77879 x29 0000007ff8a777f0 x30 00000076a4040f50
+09-23 01:55:43.078 546 546 F DEBUG : sp 0000007ff8a777d0 pc 00000076a4043b2c pstate 0000000060000000
+09-23 01:55:43.081 546 546 F DEBUG :
+09-23 01:55:43.081 546 546 F DEBUG : backtrace:
+09-23 01:55:43.081 546 546 F DEBUG : #00 pc 000000000006bb2c /system/lib64/libc.so (tgkill+8)
+09-23 01:55:43.081 546 546 F DEBUG : #01 pc 0000000000068f4c /system/lib64/libc.so (pthread_kill+64)
+09-23 01:55:43.081 546 546 F DEBUG : #02 pc 0000000000023f58 /system/lib64/libc.so (raise+24)
+09-23 01:55:43.081 546 546 F DEBUG : #03 pc 000000000001c810 /system/lib64/libc.so (abort+52)
+09-23 01:55:43.081 546 546 F DEBUG : #04 pc 000000000000609c /system/lib64/libbase.so (_ZN7android4base10LogMessageD1Ev+1084)
+09-23 01:55:43.082 546 546 F DEBUG : #05 pc 000000000001bbd4 /system/bin/installd
+09-23 01:55:43.082 546 546 F DEBUG : #06 pc 000000000001be38 /system/bin/installd
+09-23 01:55:43.082 546 546 F DEBUG : #07 pc 0000000000007f08 /system/bin/installd
+09-23 01:55:43.082 546 546 F DEBUG : #08 pc 0000000000005bd4 /system/bin/installd
+09-23 01:55:43.082 546 546 F DEBUG : #09 pc 000000000001a594 /system/lib64/libc.so (__libc_init+88)
+09-23 01:55:43.082 546 546 F DEBUG : #10 pc 0000000000004818 /system/bin/installd
+09-23 01:55:43.093 166 166 W : debuggerd: resuming target 245
+09-23 01:55:43.132 516 516 E InstallerConnection: read exception
+09-23 01:55:43.132 516 516 I InstallerConnection: disconnecting...
+09-23 01:55:48.494 516 537 W WindowManager: App freeze timeout expired.
+09-23 01:55:52.058 163 163 W auditd : type=1404 audit(0.0:4): enforcing=0 old_enforcing=1 auid=4294967295 ses=4294967295
+--------- beginning of main
+11-03 02:59:48.505 8049 8049 I stagefright: type=1400 audit(0.0:130): avc: denied { read } for path="/data/data/test1.mp4" dev="sda35" ino=868967 scontext=u:r:drmserver:s0 tcontext=u:object_r:system_data_file:s0 tclass=file permissive=1
+11-03 02:59:48.505 3939 3939 I chatty : uid=10040(u0_a40) com.google.android.setupwizard expire 52528 lines
+11-03 02:59:48.559 8049 8054 I OMXClient: Treble IOmx obtained
+--------- beginning of crash
+11-03 02:59:48.892 6371 8072 F DEBUG : *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
+11-03 02:59:48.892 6371 8072 F DEBUG : Build fingerprint: 'google/marlin/marlin:8.0.0/OC/mspect11021711:userdebug/dev-keys'
+11-03 02:59:48.892 6371 8072 F DEBUG : Revision: '0'
+11-03 02:59:48.892 6371 8072 F DEBUG : ABI: 'arm'
+11-03 02:59:48.892 6371 8072 F DEBUG : pid: 6371, tid: 8072, name: media.codec >>> omx@1.0-service <<<
+11-03 02:59:48.892 6371 8072 F DEBUG : signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0xed000000
+11-03 02:59:48.900 6371 8072 F DEBUG : r0 ecffdba0 r1 ed000000 r2 d44854c0 r3 00000070
+11-03 02:59:48.900 6371 8072 F DEBUG : r4 00000070 r5 000021a0 r6 00000070 r7 00000070
+11-03 02:59:48.900 6371 8072 F DEBUG : r8 00000040 r9 ffc2b278 sl ffffde70 fp 00000060
+11-03 02:59:48.900 6371 8072 F DEBUG : ip ffffffa0 sp d2fff620 lr 00004308 pc ed1c0e7c cpsr a00f0010
+11-03 02:59:48.901 6371 8072 F DEBUG :
+11-03 02:59:48.901 6371 8072 F DEBUG : backtrace:
+11-03 02:59:48.901 6371 8072 F DEBUG : #00 pc 00034e7c /system/lib/libstagefright_soft_hevcdec.so
+--------- beginning of system
+11-03 02:59:48.905 1135 1155 I BootReceiver: Copying /data/tombstones/tombstone_03 to DropBox (SYSTEM_TOMBSTONE)
+05-04 21:59:23.695 9363 9363 I crash_dump64: performing dump of process 8373 (target tid = 8414)
+05-04 21:59:23.695 9363 9363 F DEBUG : *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
+05-04 21:59:23.696 9363 9363 F DEBUG : Build fingerprint: 'google/taimen/taimen:8.1.0/OPM2.171026.006.A1/4756228:userdebug/dev-keys'
+05-04 21:59:23.696 9363 9363 F DEBUG : Revision: 'rev_10'
+05-04 21:59:23.696 9363 9363 F DEBUG : ABI: 'arm64'
+05-04 21:59:23.696 9363 9363 F DEBUG : pid: 8373, tid: 8414, name: btu message loo >>> com.android.bluetooth <<<
+05-04 21:59:23.696 9363 9363 F DEBUG : signal 6 (SIGABRT), code -6 (SI_TKILL), fault addr --------
+05-04 21:59:23.700 9363 9363 F DEBUG : Abort message: '[FATAL:allocation_tracker.cc(143)] Check failed: map_entry != allocations.end().
+05-04 21:59:23.700 9363 9363 F DEBUG : '
+05-04 21:59:23.700 9363 9363 F DEBUG : x0 0000000000000000 x1 00000000000020de x2 0000000000000006 x3 0000000000000008
+05-04 21:59:23.701 9363 9363 F DEBUG : x4 613a4c415441465b x5 613a4c415441465b x6 613a4c415441465b x7 6f697461636f6c6c
+05-04 21:59:23.701 9363 9363 F DEBUG : x8 0000000000000083 x9 0000000010000000 x10 000000703a7a7c80 x11 0000000000000001
+05-04 21:59:23.701 9363 9363 F DEBUG : x12 746e655f70616d20 x13 6c61203d21207972 x14 ff00000000000000 x15 ffffffffffffffff
+05-04 21:59:23.701 9363 9363 F DEBUG : x16 0000006380f4afa8 x17 00000070d20af52c x18 0000000000000000 x19 00000000000020b5
+05-04 21:59:23.701 9363 9363 F DEBUG : x20 00000000000020de x21 0000000000000083 x22 000000703a7a9588 x23 000000703b8ee000
+05-04 21:59:23.701 9363 9363 F DEBUG : x24 000000703a7a7d01 x25 000000703a7a9588 x26 000000703bc7d948 x27 00000070484c92d8
+05-04 21:59:23.701 9363 9363 F DEBUG : x28 0000000000000006 x29 000000703a7a7cc0 x30 00000070d2064760
+05-04 21:59:23.701 9363 9363 F DEBUG : sp 000000703a7a7c80 pc 00000070d2064788 pstate 0000000060000000
+05-04 21:59:23.742 9363 9363 F DEBUG :
+05-04 21:59:23.742 9363 9363 F DEBUG : backtrace:
+05-04 21:59:23.743 9363 9363 F DEBUG : #00 pc 000000000001d788 /system/lib64/libc.so (abort+120)
+05-04 21:59:23.743 9363 9363 F DEBUG : #01 pc 0000000000083470 /system/lib64/libchrome.so (base::debug::BreakDebugger()+20)
+05-04 21:59:23.743 9363 9363 F DEBUG : #02 pc 000000000009affc /system/lib64/libchrome.so (logging::LogMessage::~LogMessage()+1068)
+05-04 21:59:23.743 9363 9363 F DEBUG : #03 pc 0000000000199130 /system/lib64/hw/bluetooth.default.so (allocation_tracker_notify_free(unsigned char, void*)+720)
+05-04 21:59:23.743 9363 9363 F DEBUG : #04 pc 000000000019984c /system/lib64/hw/bluetooth.default.so (osi_free(void*)+20)
+05-04 21:59:23.743 9363 9363 F DEBUG : #05 pc 0000000000163f1c /system/lib64/hw/bluetooth.default.so (l2c_fcr_cleanup(t_l2c_ccb*)+92)
+05-04 21:59:23.743 9363 9363 F DEBUG : #06 pc 000000000016adc8 /system/lib64/hw/bluetooth.default.so (l2cu_release_ccb(t_l2c_ccb*)+176)
+05-04 21:59:23.743 9363 9363 F DEBUG : #07 pc 0000000000162ea0 /system/lib64/hw/bluetooth.default.so (l2c_csm_execute(t_l2c_ccb*, unsigned short, void*)+1852)
+05-04 21:59:23.743 9363 9363 F DEBUG : #08 pc 000000000015e4f4 /system/lib64/hw/bluetooth.default.so (L2CA_DisconnectRsp(unsigned short)+92)
+05-04 21:59:23.743 9363 9363 F DEBUG : #09 pc 00000000001838b0 /system/lib64/hw/bluetooth.default.so (sdp_disconnect_ind(unsigned short, bool)+52)
+05-04 21:59:23.743 9363 9363 F DEBUG : #10 pc 0000000000163574 /system/lib64/hw/bluetooth.default.so (l2c_csm_execute(t_l2c_ccb*, unsigned short, void*)+3600)
+05-04 21:59:23.743 9363 9363 F DEBUG : #11 pc 0000000000169f94 /system/lib64/hw/bluetooth.default.so (l2c_rcv_acl_data(BT_HDR*)+3980)
+05-04 21:59:23.743 9363 9363 F DEBUG : #12 pc 00000000000849cc /system/lib64/libchrome.so (base::debug::TaskAnnotator::RunTask(char const*, base::PendingTask const&)+188)
+05-04 21:59:23.743 9363 9363 F DEBUG : #13 pc 000000000009efa4 /system/lib64/libchrome.so (base::MessageLoop::RunTask(base::PendingTask const&)+444)
+05-04 21:59:23.743 9363 9363 F DEBUG : #14 pc 000000000009f26c /system/lib64/libchrome.so (base::MessageLoop::DeferOrRunPendingTask(base::PendingTask)+52)
+05-04 21:59:23.743 9363 9363 F DEBUG : #15 pc 000000000009f698 /system/lib64/libchrome.so (base::MessageLoop::DoWork()+356)
+05-04 21:59:23.743 9363 9363 F DEBUG : #16 pc 00000000000a08a8 /system/lib64/libchrome.so (base::MessagePumpDefault::Run(base::MessagePump::Delegate*)+220)
+05-04 21:59:23.743 9363 9363 F DEBUG : #17 pc 00000000000ba124 /system/lib64/libchrome.so (base::RunLoop::Run()+136)
+05-04 21:59:23.743 9363 9363 F DEBUG : #18 pc 0000000000138660 /system/lib64/hw/bluetooth.default.so (btu_message_loop_run(void*)+248)
+05-04 21:59:23.743 9363 9363 F DEBUG : #19 pc 00000000001a24fc /system/lib64/hw/bluetooth.default.so (work_queue_read_cb(void*)+92)
+05-04 21:59:23.743 9363 9363 F DEBUG : #20 pc 00000000001a0758 /system/lib64/hw/bluetooth.default.so (run_reactor(reactor_t*, int)+320)
+05-04 21:59:23.743 9363 9363 F DEBUG : #21 pc 00000000001a05ec /system/lib64/hw/bluetooth.default.so (reactor_start(reactor_t*)+84)
+05-04 21:59:23.743 9363 9363 F DEBUG : #22 pc 00000000001a1f94 /system/lib64/hw/bluetooth.default.so (run_thread(void*)+184)
+05-04 21:59:23.743 9363 9363 F DEBUG : #23 pc 0000000000067d80 /system/lib64/libc.so (__pthread_start(void*)+36)
+05-04 21:59:23.743 9363 9363 F DEBUG : #24 pc 000000000001ec18 /system/lib64/libc.so (__start_thread+68)
+11-25 19:47:35.417 8080 11665 F libc : Fatal signal 6 (SIGABRT), code -6 in tid 11665 (generic)
+11-25 19:47:35.487 940 940 F DEBUG : *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
+11-25 19:47:35.487 940 940 F DEBUG : Build fingerprint: 'samsung/hero2qltezc/hero2qltechn:6.0.1/MMB29M/G9350ZCU2APJ6:user/release-keys'
+11-25 19:47:35.487 940 940 F DEBUG : Revision: '15'
+11-25 19:47:35.487 940 940 F DEBUG : ABI: 'arm'
+11-25 19:47:35.487 940 940 F DEBUG : pid: 8080, tid: 11665, name: generic >>> /system/bin/mediaserver <<<
+11-25 19:47:35.487 940 940 F DEBUG : signal 6 (SIGABRT), code -6 (SI_TKILL), fault addr --------
+11-25 19:47:35.577 940 940 F DEBUG : Abort message: 'frameworks/av/media/libstagefright/MPEG4Extractor.cpp:6853 CHECK_EQ( (unsigned)ptr[0],1u) failed: 129 vs. 1'
+11-25 19:47:35.577 940 940 F DEBUG : r0 00000000 r1 00002d91 r2 00000006 r3 eb23f978
+11-25 19:47:35.577 940 940 F DEBUG : r4 eb23f980 r5 eb23f930 r6 00000009 r7 0000010c
+11-25 19:47:35.577 940 940 F DEBUG : r8 e9e91140 r9 00000000 sl 00000000 fp 000003d3
+11-25 19:47:35.577 940 940 F DEBUG : ip 00000006 sp eb23db70 lr f701313d pc f7015538 cpsr 40010010
+11-25 19:47:35.597 940 940 F DEBUG :
+11-25 19:47:35.597 940 940 F DEBUG : backtrace:
+11-25 19:47:35.597 940 940 F DEBUG : #00 pc 00042538 /system/lib/libc.so (tgkill+12)
+11-25 19:47:35.597 940 940 F DEBUG : #01 pc 00040139 /system/lib/libc.so (pthread_kill+32)
+11-25 19:47:35.597 940 940 F DEBUG : #02 pc 0001c783 /system/lib/libc.so (raise+10)
+11-25 19:47:35.597 940 940 F DEBUG : #03 pc 000199f1 /system/lib/libc.so (__libc_android_abort+34)
+11-25 19:47:35.597 940 940 F DEBUG : #04 pc 000175ac /system/lib/libc.so (abort+4)
+11-25 19:47:35.597 940 940 F DEBUG : #05 pc 000085e7 /system/lib/libcutils.so (__android_log_assert+86)
+11-25 19:47:35.597 940 940 F DEBUG : #06 pc 000c1f49 /system/lib/libstagefright.so (_ZN7android14MPEG4Extractor25avcc_getCodecSpecificInfoERNS_2spINS_7ABufferEEEPKcj+392)
+11-25 19:47:35.597 940 940 F DEBUG : #07 pc 000c213f /system/lib/libstagefright.so (_ZN7android14MPEG4Extractor15checkConfigDataEjRKNS_2spINS_8MetaDataEEE+218)
+11-25 19:47:35.597 940 940 F DEBUG : #08 pc 000bbd25 /system/lib/libstagefright.so (_ZN7android14MPEG4Extractor12checkSupportEjRKNS_2spINS_8MetaDataEEE+136)
+11-25 19:47:35.597 940 940 F DEBUG : #09 pc 000ba555 /system/lib/libstagefright.so (_ZN7android14MPEG4Extractor10parseChunkEPxi+13060)
+11-25 19:47:35.597 940 940 F DEBUG : #10 pc 000ba32d /system/lib/libstagefright.so (_ZN7android14MPEG4Extractor10parseChunkEPxi+12508)
+11-25 19:47:35.597 940 940 F DEBUG : #11 pc 000b8a6f /system/lib/libstagefright.so (_ZN7android14MPEG4Extractor10parseChunkEPxi+6174)
+11-25 19:47:35.597 940 940 F DEBUG : #12 pc 000b8a6f /system/lib/libstagefright.so (_ZN7android14MPEG4Extractor10parseChunkEPxi+6174)
+11-25 19:47:35.597 940 940 F DEBUG : #13 pc 000b8a6f /system/lib/libstagefright.so (_ZN7android14MPEG4Extractor10parseChunkEPxi+6174)
+11-25 19:47:35.597 940 940 F DEBUG : #14 pc 000b8a6f /system/lib/libstagefright.so (_ZN7android14MPEG4Extractor10parseChunkEPxi+6174)
+11-25 19:47:35.597 940 940 F DEBUG : #15 pc 000b8a6f /system/lib/libstagefright.so (_ZN7android14MPEG4Extractor10parseChunkEPxi+6174)
+11-25 19:47:35.597 940 940 F DEBUG : #16 pc 000b6e3b /system/lib/libstagefright.so (_ZN7android14MPEG4Extractor12readMetaDataEv+94)
+11-25 19:47:35.597 940 940 F DEBUG : #17 pc 000b6daf /system/lib/libstagefright.so (_ZN7android14MPEG4Extractor11getMetaDataEv+10)
+11-25 19:47:35.597 940 940 F DEBUG : #18 pc 00088c53 /system/lib/libmediaplayerservice.so (_ZN7android8NuPlayer13GenericSource18initFromDataSourceEv+386)
+11-25 19:47:35.597 940 940 F DEBUG : #19 pc 00089b43 /system/lib/libmediaplayerservice.so (_ZN7android8NuPlayer13GenericSource14onPrepareAsyncEv+238)
+11-25 19:47:35.597 940 940 F DEBUG : #20 pc 0000b405 /system/lib/libstagefright_foundation.so (_ZN7android8AHandler14deliverMessageERKNS_2spINS_8AMessageEEE+16)
+11-25 19:47:35.597 940 940 F DEBUG : #21 pc 0000d423 /system/lib/libstagefright_foundation.so (_ZN7android8AMessage7deliverEv+54)
+11-25 19:47:35.597 940 940 F DEBUG : #22 pc 0000be29 /system/lib/libstagefright_foundation.so (_ZN7android7ALooper4loopEv+224)
+11-25 19:47:35.597 940 940 F DEBUG : #23 pc 0001011d /system/lib/libutils.so (_ZN7android6Thread11_threadLoopEPv+112)
+11-25 19:47:35.597 940 940 F DEBUG : #24 pc 0003fa3b /system/lib/libc.so (_ZL15__pthread_startPv+30)
+11-25 19:47:35.597 940 940 F DEBUG : #25 pc 0001a085 /system/lib/libc.so (__start_thread+6)
+11-25 19:47:35.837 940 940 F DEBUG :
+11-25 19:47:35.837 940 940 F DEBUG : Tombstone written to: /data/tombstones/tombstone_01
+--------- beginning of crash
+09-03 17:48:05.627 11071 11189 F libc : Fatal signal 11 (SIGSEGV), code 1, fault addr 0xe9380000 in tid 11189 (synthetic_thread)
+09-03 17:48:05.707 359 359 W : debuggerd: handling request: pid=11071 uid=1041 gid=1005 tid=11189
+09-03 17:48:05.796 7072 7072 F DEBUG : *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
+09-03 17:48:05.796 7072 7072 F DEBUG : Build fingerprint: 'google/angler/angler:7.1.1/N4F26T/3687331:userdebug/dev-keys'
+09-03 17:48:05.796 7072 7072 F DEBUG : Revision: '0'
+09-03 17:48:05.796 7072 7072 F DEBUG : ABI: 'arm'
+09-03 17:48:05.796 7072 7072 F DEBUG : pid: 11071, tid: 11189, name: synthetic_thread >>> synthetic_process_0 <<<
+09-03 17:48:05.797 7072 7072 F DEBUG : signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0xe9380000
+09-03 17:48:05.797 7072 7072 F DEBUG : r0 e9e7a240 r1 e9380000 r2 00000170 r3 00000000
+09-03 17:48:05.797 7072 7072 F DEBUG : r4 00000002 r5 00000000 r6 ec1e1f25 r7 eb6f8000
+09-03 17:48:05.797 7072 7072 F DEBUG : r8 00000000 r9 eb105204 sl 00000000 fp 000003c0
+09-03 17:48:05.797 7072 7072 F DEBUG : ip ebd3df18 sp eaf80688 lr ec1e1f41 pc ebd38dd6 cpsr 20000030
+09-03 17:48:05.805 7072 7072 F DEBUG :
+09-03 17:48:05.805 7072 7072 F DEBUG : backtrace:
+09-03 17:48:05.806 7072 7072 F DEBUG : #00 pc 00002dd6 /system/lib/libaudioutils.so (memcpy_to_float_from_i16+5)
+09-03 17:48:05.806 7072 7072 F DEBUG : #01 pc 00040f3d /system/lib/libaudioflinger.so
+09-03 17:48:05.806 7072 7072 F DEBUG : #02 pc 00040799 /system/lib/libaudioflinger.so
+09-03 17:48:05.806 7072 7072 F DEBUG : #03 pc 00011178 /system/lib/libaudioflinger.so
+09-03 17:48:05.806 7072 7072 F DEBUG : #04 pc 0003180b /system/lib/libaudioflinger.so
+09-03 17:48:05.806 7072 7072 F DEBUG : #05 pc 0002fe57 /system/lib/libaudioflinger.so
+09-03 17:48:05.806 7072 7072 F DEBUG : #06 pc 0000e345 /system/lib/libutils.so (_ZN7android6Thread11_threadLoopEPv+140)
+09-03 17:48:05.806 7072 7072 F DEBUG : #07 pc 000470b3 /system/lib/libc.so (_ZL15__pthread_startPv+22)
+09-03 17:48:05.806 7072 7072 F DEBUG : #08 pc 00019e3d /system/lib/libc.so (__start_thread+6)
+09-03 17:48:05.967 11272 11568 W NativeCrashListener: Couldn't find ProcessRecord for pid 11071
+09-03 17:48:05.969 359 359 W : debuggerd: resuming target 11071
+09-03 17:48:05.981 11272 11307 I BootReceiver: Copying /data/tombstones/tombstone_01 to DropBox (SYSTEM_TOMBSTONE)
+09-03 17:48:06.067 394 394 I ServiceManager: service 'media.sound_trigger_hw' died
+06-15 19:57:33.607 12736 12761 D PermissionCache: checking android.permission.MODIFY_AUDIO_SETTINGS for uid=10197 => granted (698 us)
+--------- beginning of crash
+06-15 19:57:33.607 12736 12761 F libc : Fatal signal 11 (SIGSEGV), code 1, fault addr 0x0 in tid 12761 (synthetic_thread)
+06-15 19:57:33.608 379 379 W : debuggerd: handling request: pid=12736 uid=1041 gid=1005 tid=12761
+06-15 19:57:33.670 26192 26192 F DEBUG : *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
+06-15 19:57:33.670 26192 26192 F DEBUG : Build fingerprint: 'google/bullhead/bullhead:7.1.2/N2G48C/4104010:userdebug/dev-keys'
+06-15 19:57:33.670 26192 26192 F DEBUG : Revision: 'rev_1.0'
+06-15 19:57:33.670 26192 26192 F DEBUG : ABI: 'arm'
+06-15 19:57:33.670 26192 26192 F DEBUG : pid: 12736, tid: 12761, name: synthetic_thread >>> synthetic_process_1 <<<
+06-15 19:57:33.670 26192 26192 F DEBUG : signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x0
+06-15 19:57:33.670 26192 26192 F DEBUG : r0 00000000 r1 00000000 r2 0000005f r3 00000000
+06-15 19:57:33.670 26192 26192 F DEBUG : r4 ffffffff r5 00000000 r6 f14f9000 r7 00000001
+06-15 19:57:33.670 26192 26192 F DEBUG : r8 00000004 r9 f3353114 sl f3313900 fp 00000000
+06-15 19:57:33.670 26192 26192 F DEBUG : ip f3bd4d88 sp f127d9c8 lr f3b9cbc5 pc f3b65af4 cpsr 60000030
+06-15 19:57:33.676 26192 26192 F DEBUG :
+06-15 19:57:33.676 26192 26192 F DEBUG : backtrace:
+06-15 19:57:33.677 26192 26192 F DEBUG : #00 pc 00018af4 /system/lib/libc.so (strlen+71)
+06-15 19:57:33.677 26192 26192 F DEBUG : #01 pc 0004fbc1 /system/lib/libc.so (__strlen_chk+4)
+06-15 19:57:33.677 26192 26192 F DEBUG : #02 pc 0000c599 /system/lib/libutils.so (_ZN7android7String8C2EPKc+12)
+06-15 19:57:33.677 26192 26192 F DEBUG : #03 pc 0002fdbf /system/lib/libaudiopolicymanagerdefault.so (_ZNK7android18HwModuleCollection19getDeviceDescriptorEjPKcS2_b+458)
+06-15 19:57:33.677 26192 26192 F DEBUG : #04 pc 0001de47 /system/lib/libaudiopolicymanagerdefault.so (_ZN7android18AudioPolicyManager27setDeviceConnectionStateIntEj24audio_policy_dev_state_tPKcS3_+178)
+06-15 19:57:33.677 26192 26192 F DEBUG : #05 pc 0000a009 /system/lib/libaudiopolicyservice.so
+06-15 19:57:33.677 26192 26192 F DEBUG : #06 pc 000a01a5 /system/lib/libmedia.so (_ZN7android20BnAudioPolicyService10onTransactEjRKNS_6ParcelEPS1_j+1256)
+06-15 19:57:33.677 26192 26192 F DEBUG : #07 pc 000359c3 /system/lib/libbinder.so (_ZN7android7BBinder8transactEjRKNS_6ParcelEPS1_j+70)
+06-15 19:57:33.677 26192 26192 F DEBUG : #08 pc 0003d1bb /system/lib/libbinder.so (_ZN7android14IPCThreadState14executeCommandEi+702)
+06-15 19:57:33.677 26192 26192 F DEBUG : #09 pc 0003ce07 /system/lib/libbinder.so (_ZN7android14IPCThreadState20getAndExecuteCommandEv+114)
+06-15 19:57:33.677 26192 26192 F DEBUG : #10 pc 0003d31b /system/lib/libbinder.so (_ZN7android14IPCThreadState14joinThreadPoolEb+46)
+06-15 19:57:33.678 26192 26192 F DEBUG : #11 pc 0004f8c5 /system/lib/libbinder.so
+06-15 19:57:33.678 26192 26192 F DEBUG : #12 pc 0000e345 /system/lib/libutils.so (_ZN7android6Thread11_threadLoopEPv+140)
+06-15 19:57:33.678 26192 26192 F DEBUG : #13 pc 000470b3 /system/lib/libc.so (_ZL15__pthread_startPv+22)
+06-15 19:57:33.678 26192 26192 F DEBUG : #14 pc 00019e3d /system/lib/libc.so (__start_thread+6)
+06-15 19:57:33.839 934 2991 W NativeCrashListener: Couldn't find ProcessRecord for pid 12736
+06-15 19:57:33.846 934 952 I BootReceiver: Copying /data/tombstones/tombstone_01 to DropBox (SYSTEM_TOMBSTONE)
+
diff --git a/libraries/compatibility-common-util/tests/assets/x86app_process32 b/libraries/compatibility-common-util/tests/assets/x86app_process32
new file mode 100644
index 000000000..d02fcd7a7
--- /dev/null
+++ b/libraries/compatibility-common-util/tests/assets/x86app_process32
Binary files differ
diff --git a/libraries/compatibility-common-util/tests/assets/x86app_process32.txt b/libraries/compatibility-common-util/tests/assets/x86app_process32.txt
new file mode 100644
index 000000000..f0ff7fb42
--- /dev/null
+++ b/libraries/compatibility-common-util/tests/assets/x86app_process32.txt
@@ -0,0 +1,393 @@
+ELF Header:
+ Magic: 7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00
+ Class: ELF32
+ Data: 2's complement, little endian
+ Version: 1 (current)
+ OS/ABI: UNIX - System V
+ ABI Version: 0
+ Type: DYN (Shared object file)
+ Machine: Intel 80386
+ Version: 0x1
+ Entry point address: 0x1530
+ Start of program headers: 52 (bytes into file)
+ Start of section headers: 22140 (bytes into file)
+ Flags: 0x0
+ Size of this header: 52 (bytes)
+ Size of program headers: 32 (bytes)
+ Number of program headers: 9
+ Size of section headers: 40 (bytes)
+ Number of section headers: 27
+ Section header string table index: 26
+
+Section Headers:
+ [Nr] Name Type Addr Off Size ES Flg Lk Inf Al
+ [ 0] NULL 00000000 000000 000000 00 0 0 0
+ [ 1] .interp PROGBITS 00000154 000154 000013 00 A 0 0 1
+ [ 2] .note.android.ide NOTE 00000168 000168 000018 00 A 0 0 4
+ [ 3] .note.gnu.build-i NOTE 00000180 000180 000020 00 A 0 0 4
+ [ 4] .dynsym DYNSYM 000001a0 0001a0 0004c0 10 A 5 1 4
+ [ 5] .dynstr STRTAB 00000660 000660 000718 00 A 0 0 1
+ [ 6] .gnu.hash GNU_HASH 00000d78 000d78 000048 04 A 4 0 4
+ [ 7] .gnu.version VERSYM 00000dc0 000dc0 000098 02 A 4 0 2
+ [ 8] .gnu.version_r VERNEED 00000e58 000e58 000050 00 A 5 2 4
+ [ 9] .rel.dyn REL 00000ea8 000ea8 000088 08 A 4 0 4
+ [10] .rel.plt REL 00000f30 000f30 0001f8 08 AI 4 22 4
+ [11] .plt PROGBITS 00001130 001130 000400 04 AX 0 0 16
+ [12] .text PROGBITS 00001530 001530 002125 00 AX 0 0 16
+ [13] .rodata PROGBITS 00003655 003655 000484 00 A 0 0 1
+ [14] .eh_frame PROGBITS 00003adc 003adc 000488 00 A 0 0 4
+ [15] .eh_frame_hdr PROGBITS 00003f64 003f64 00012c 00 A 0 0 4
+ [16] .preinit_array PREINIT_ARRAY 00005d34 004d34 000008 04 WA 0 0 4
+ [17] .init_array INIT_ARRAY 00005d3c 004d3c 00000c 04 WA 0 0 4
+ [18] .fini_array FINI_ARRAY 00005d48 004d48 000008 04 WA 0 0 4
+ [19] .data.rel.ro PROGBITS 00005d50 004d50 000048 00 WA 0 0 4
+ [20] .dynamic DYNAMIC 00005d98 004d98 000158 08 WA 5 0 4
+ [21] .got PROGBITS 00005ef0 004ef0 000008 00 WA 0 0 4
+ [22] .got.plt PROGBITS 00005ef8 004ef8 000108 00 WA 0 0 4
+ [23] .bss NOBITS 00006000 005000 000e90 00 WA 0 0 4
+ [24] .note.gnu.gold-ve NOTE 00000000 005000 00001c 00 0 0 4
+ [25] .gnu_debugdata PROGBITS 00000000 00501c 000540 00 0 0 1
+ [26] .shstrtab STRTAB 00000000 00555c 00011e 00 0 0 1
+Key to Flags:
+ W (write), A (alloc), X (execute), M (merge), S (strings), I (info),
+ L (link order), O (extra OS processing required), G (group), T (TLS),
+ C (compressed), x (unknown), o (OS specific), E (exclude),
+ p (processor specific)
+
+There are no section groups in this file.
+
+Program Headers:
+ Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align
+ PHDR 0x000034 0x00000034 0x00000034 0x00120 0x00120 R 0x4
+ INTERP 0x000154 0x00000154 0x00000154 0x00013 0x00013 R 0x1
+ [Requesting program interpreter: /system/bin/linker]
+ LOAD 0x000000 0x00000000 0x00000000 0x04090 0x04090 R E 0x1000
+ LOAD 0x004d34 0x00005d34 0x00005d34 0x002cc 0x0115c RW 0x1000
+ DYNAMIC 0x004d98 0x00005d98 0x00005d98 0x00158 0x00158 RW 0x4
+ NOTE 0x000168 0x00000168 0x00000168 0x00038 0x00038 R 0x4
+ GNU_EH_FRAME 0x003f64 0x00003f64 0x00003f64 0x0012c 0x0012c R 0x4
+ GNU_STACK 0x000000 0x00000000 0x00000000 0x00000 0x00000 RW 0x10
+ GNU_RELRO 0x004d34 0x00005d34 0x00005d34 0x002cc 0x002cc RW 0x4
+
+ Section to Segment mapping:
+ Segment Sections...
+ 00
+ 01 .interp
+ 02 .interp .note.android.ident .note.gnu.build-id .dynsym .dynstr .gnu.hash .gnu.version .gnu.version_r .rel.dyn .rel.plt .plt .text .rodata .eh_frame .eh_frame_hdr
+ 03 .preinit_array .init_array .fini_array .data.rel.ro .dynamic .got .got.plt .bss
+ 04 .dynamic
+ 05 .note.android.ident .note.gnu.build-id
+ 06 .eh_frame_hdr
+ 07
+ 08 .preinit_array .init_array .fini_array .data.rel.ro .dynamic .got .got.plt
+
+Dynamic section at offset 0x4d98 contains 38 entries:
+ Tag Type Name/Value
+ 0x00000003 (PLTGOT) 0x5ef8
+ 0x00000002 (PLTRELSZ) 504 (bytes)
+ 0x00000017 (JMPREL) 0xf30
+ 0x00000014 (PLTREL) REL
+ 0x00000011 (REL) 0xea8
+ 0x00000012 (RELSZ) 136 (bytes)
+ 0x00000013 (RELENT) 8 (bytes)
+ 0x6ffffffa (RELCOUNT) 15
+ 0x00000015 (DEBUG) 0x0
+ 0x00000006 (SYMTAB) 0x1a0
+ 0x0000000b (SYMENT) 16 (bytes)
+ 0x00000005 (STRTAB) 0x660
+ 0x0000000a (STRSZ) 1816 (bytes)
+ 0x6ffffef5 (GNU_HASH) 0xd78
+ 0x00000001 (NEEDED) Shared library: [libandroid_runtime.so]
+ 0x00000001 (NEEDED) Shared library: [libbinder.so]
+ 0x00000001 (NEEDED) Shared library: [libcutils.so]
+ 0x00000001 (NEEDED) Shared library: [libhwbinder.so]
+ 0x00000001 (NEEDED) Shared library: [liblog.so]
+ 0x00000001 (NEEDED) Shared library: [libnativeloader.so]
+ 0x00000001 (NEEDED) Shared library: [libutils.so]
+ 0x00000001 (NEEDED) Shared library: [libwilhelm.so]
+ 0x00000001 (NEEDED) Shared library: [libc++.so]
+ 0x00000001 (NEEDED) Shared library: [libc.so]
+ 0x00000001 (NEEDED) Shared library: [libm.so]
+ 0x00000001 (NEEDED) Shared library: [libdl.so]
+ 0x00000020 (PREINIT_ARRAY) 0x5d34
+ 0x00000021 (PREINIT_ARRAYSZ) 0x8
+ 0x00000019 (INIT_ARRAY) 0x5d3c
+ 0x0000001b (INIT_ARRAYSZ) 12 (bytes)
+ 0x0000001a (FINI_ARRAY) 0x5d48
+ 0x0000001c (FINI_ARRAYSZ) 8 (bytes)
+ 0x0000001e (FLAGS) BIND_NOW
+ 0x6ffffffb (FLAGS_1) Flags: NOW
+ 0x6ffffff0 (VERSYM) 0xdc0
+ 0x6ffffffe (VERNEED) 0xe58
+ 0x6fffffff (VERNEEDNUM) 2
+ 0x00000000 (NULL) 0x0
+
+Relocation section '.rel.dyn' at offset 0xea8 contains 17 entries:
+ Offset Info Type Sym.Value Sym. Name
+00005d40 00000008 R_386_RELATIVE
+00005d58 00000008 R_386_RELATIVE
+00005d5c 00000008 R_386_RELATIVE
+00005d60 00000008 R_386_RELATIVE
+00005d64 00000008 R_386_RELATIVE
+00005d68 00000008 R_386_RELATIVE
+00005d6c 00000008 R_386_RELATIVE
+00005d78 00000008 R_386_RELATIVE
+00005d7c 00000008 R_386_RELATIVE
+00005d80 00000008 R_386_RELATIVE
+00005d84 00000008 R_386_RELATIVE
+00005d88 00000008 R_386_RELATIVE
+00005d8c 00000008 R_386_RELATIVE
+00005d90 00000008 R_386_RELATIVE
+00005d94 00000008 R_386_RELATIVE
+00005ef4 00001706 R_386_GLOB_DAT 00000000 stderr@LIBC
+00005ef0 00003a06 R_386_GLOB_DAT 00000000 __stack_chk_guard@LIBC
+
+Relocation section '.rel.plt' at offset 0xf30 contains 63 entries:
+ Offset Info Type Sym.Value Sym. Name
+00005f04 00000307 R_386_JUMP_SLOT 00000000 __libc_init@LIBC
+00005f08 00000407 R_386_JUMP_SLOT 00000000 __register_atfork@LIBC
+00005f0c 00001d07 R_386_JUMP_SLOT 00000000 strlen@LIBC
+00005f10 00001607 R_386_JUMP_SLOT 00000000 _ZN7android14AndroidRu
+00005f14 00002907 R_386_JUMP_SLOT 00000000 _ZN7android7String8C1E
+00005f18 00000a07 R_386_JUMP_SLOT 00000000 _ZN7android10VectorImp
+00005f1c 00001207 R_386_JUMP_SLOT 00000000 strcmp@LIBC
+00005f20 00001407 R_386_JUMP_SLOT 00000000 strdup@LIBC
+00005f24 00001507 R_386_JUMP_SLOT 00000000 _ZN7android14AndroidRu
+00005f28 00001907 R_386_JUMP_SLOT 00000000 strncmp@LIBC
+00005f2c 00001f07 R_386_JUMP_SLOT 00000000 _ZN7android7String85se
+00005f30 00003407 R_386_JUMP_SLOT 00000000 _ZNK7android7String86l
+00005f34 00002c07 R_386_JUMP_SLOT 00000000 getenv@LIBC
+00005f38 00002807 R_386_JUMP_SLOT 00000000 mkdir@LIBC
+00005f3c 00003907 R_386_JUMP_SLOT 00000000 __errno@LIBC
+00005f40 00001e07 R_386_JUMP_SLOT 00000000 chown@LIBC
+00005f44 00002407 R_386_JUMP_SLOT 00000000 chmod@LIBC
+00005f48 00002507 R_386_JUMP_SLOT 00000000 _ZN7android7String8C1E
+00005f4c 00000907 R_386_JUMP_SLOT 00000000 _ZN7android10VectorImp
+00005f50 00002b07 R_386_JUMP_SLOT 00000000 _ZN7android7String8D1E
+00005f54 00003b07 R_386_JUMP_SLOT 00000000 property_get
+00005f58 00002307 R_386_JUMP_SLOT 00000000 _ZN7android7String86ap
+00005f5c 00002107 R_386_JUMP_SLOT 00000000 _ZN7android7String85se
+00005f60 00001307 R_386_JUMP_SLOT 00000000 _ZN7android14AndroidRu
+00005f64 00001007 R_386_JUMP_SLOT 00000000 _ZN7android14AndroidRu
+00005f68 00000807 R_386_JUMP_SLOT 00000000 _ZN7android10VectorImp
+00005f6c 00000b07 R_386_JUMP_SLOT 00000000 _ZN7android10VectorImp
+00005f70 00001807 R_386_JUMP_SLOT 00000000 _ZN7android14AndroidRu
+00005f74 00000607 R_386_JUMP_SLOT 00000000 __stack_chk_fail@LIBC
+00005f78 00002a07 R_386_JUMP_SLOT 00000000 fwrite@LIBC
+00005f7c 00003607 R_386_JUMP_SLOT 00000000 __android_log_assert
+00005f80 00001c07 R_386_JUMP_SLOT 00000000 strerror@LIBC
+00005f84 00003507 R_386_JUMP_SLOT 00000000 _ZdlPv
+00005f88 00000f07 R_386_JUMP_SLOT 00000000 _ZN7android14AndroidRu
+00005f8c 00003807 R_386_JUMP_SLOT 00000000 __android_log_print
+00005f90 00002007 R_386_JUMP_SLOT 00000000 free@LIBC
+00005f94 00000d07 R_386_JUMP_SLOT 00000000 _ZN7android12ProcessSt
+00005f98 00000c07 R_386_JUMP_SLOT 00000000 _ZN7android12ProcessSt
+00005f9c 00000e07 R_386_JUMP_SLOT 00000000 _ZN7android14AndroidRu
+00005fa0 00001107 R_386_JUMP_SLOT 00000000 _ZN7android14AndroidRu
+00005fa4 00001b07 R_386_JUMP_SLOT 00000000 _ZN7android14IPCThread
+00005fa8 00001a07 R_386_JUMP_SLOT 00000000 _ZN7android14IPCThread
+00005fac 00002f07 R_386_JUMP_SLOT 00000000 _ZN7android8hardware14
+00005fb0 00002d07 R_386_JUMP_SLOT 00000000 _ZN7android8hardware14
+00005fb4 00003307 R_386_JUMP_SLOT 00000000 _ZNK7android7RefBase9d
+00005fb8 00002207 R_386_JUMP_SLOT 00000000 __vsnprintf_chk@LIBC
+00005fbc 00002707 R_386_JUMP_SLOT 00000000 _ZN7android7String8C1E
+00005fc0 00002607 R_386_JUMP_SLOT 00000000 memmove@LIBC
+00005fc4 00003c07 R_386_JUMP_SLOT 00000000 _ZNSt3__111__call_once
+00005fc8 00002e07 R_386_JUMP_SLOT 00000000 pthread_getspecific@LIBC
+00005fcc 00004007 R_386_JUMP_SLOT 00000000 sigemptyset64@LIBC_P
+00005fd0 00004207 R_386_JUMP_SLOT 00000000 sigismember64@LIBC_P
+00005fd4 00003e07 R_386_JUMP_SLOT 00000000 sigaddset64@LIBC_P
+00005fd8 00003207 R_386_JUMP_SLOT 00000000 pthread_setspecific@LIBC
+00005fdc 00003707 R_386_JUMP_SLOT 00000000 abort@LIBC
+00005fe0 00003d07 R_386_JUMP_SLOT 00000000 __android_log_write
+00005fe4 00000207 R_386_JUMP_SLOT 00000000 sigemptyset@LIBC
+00005fe8 00000707 R_386_JUMP_SLOT 00000000 sigismember@LIBC
+00005fec 00000507 R_386_JUMP_SLOT 00000000 sigdelset@LIBC
+00005ff0 00003f07 R_386_JUMP_SLOT 00000000 sigdelset64@LIBC_P
+00005ff4 00004107 R_386_JUMP_SLOT 00000000 sigfillset64@LIBC_P
+00005ff8 00003007 R_386_JUMP_SLOT 00000000 pthread_key_create@LIBC
+00005ffc 00003107 R_386_JUMP_SLOT 00000000 dlsym@LIBC
+
+The decoding of unwind sections for machine type Intel 80386 is not currently supported.
+
+Symbol table '.dynsym' contains 76 entries:
+ Num: Value Size Type Bind Vis Ndx Name
+ 0: 00000000 0 NOTYPE LOCAL DEFAULT UND
+ 1: 00000000 0 FUNC GLOBAL DEFAULT UND __cxa_atexit@LIBC (2)
+ 2: 00000000 0 FUNC GLOBAL DEFAULT UND sigemptyset@LIBC (2)
+ 3: 00000000 0 FUNC GLOBAL DEFAULT UND __libc_init@LIBC (2)
+ 4: 00000000 0 FUNC GLOBAL DEFAULT UND __register_atfork@LIBC (2)
+ 5: 00000000 0 FUNC GLOBAL DEFAULT UND sigdelset@LIBC (2)
+ 6: 00000000 0 FUNC GLOBAL DEFAULT UND __stack_chk_fail@LIBC (2)
+ 7: 00000000 0 FUNC GLOBAL DEFAULT UND sigismember@LIBC (2)
+ 8: 00000000 0 FUNC GLOBAL DEFAULT UND _ZN7android10VectorImpl13
+ 9: 00000000 0 FUNC GLOBAL DEFAULT UND _ZN7android10VectorImpl3a
+ 10: 00000000 0 FUNC GLOBAL DEFAULT UND _ZN7android10VectorImplC2
+ 11: 00000000 0 FUNC GLOBAL DEFAULT UND _ZN7android10VectorImplD2
+ 12: 00000000 0 FUNC GLOBAL DEFAULT UND _ZN7android12ProcessState
+ 13: 00000000 0 FUNC GLOBAL DEFAULT UND _ZN7android12ProcessState
+ 14: 00000000 0 FUNC GLOBAL DEFAULT UND _ZN7android14AndroidRunti
+ 15: 00000000 0 FUNC GLOBAL DEFAULT UND _ZN7android14AndroidRunti
+ 16: 00000000 0 FUNC GLOBAL DEFAULT UND _ZN7android14AndroidRunti
+ 17: 00000000 0 FUNC GLOBAL DEFAULT UND _ZN7android14AndroidRunti
+ 18: 00000000 0 FUNC GLOBAL DEFAULT UND strcmp@LIBC (2)
+ 19: 00000000 0 FUNC GLOBAL DEFAULT UND _ZN7android14AndroidRunti
+ 20: 00000000 0 FUNC GLOBAL DEFAULT UND strdup@LIBC (2)
+ 21: 00000000 0 FUNC GLOBAL DEFAULT UND _ZN7android14AndroidRunti
+ 22: 00000000 0 FUNC GLOBAL DEFAULT UND _ZN7android14AndroidRunti
+ 23: 00000000 0 OBJECT GLOBAL DEFAULT UND stderr@LIBC (2)
+ 24: 00000000 0 FUNC GLOBAL DEFAULT UND _ZN7android14AndroidRunti
+ 25: 00000000 0 FUNC GLOBAL DEFAULT UND strncmp@LIBC (2)
+ 26: 00000000 0 FUNC GLOBAL DEFAULT UND _ZN7android14IPCThreadSta
+ 27: 00000000 0 FUNC GLOBAL DEFAULT UND _ZN7android14IPCThreadSta
+ 28: 00000000 0 FUNC GLOBAL DEFAULT UND strerror@LIBC (2)
+ 29: 00000000 0 FUNC GLOBAL DEFAULT UND strlen@LIBC (2)
+ 30: 00000000 0 FUNC GLOBAL DEFAULT UND chown@LIBC (2)
+ 31: 00000000 0 FUNC GLOBAL DEFAULT UND _ZN7android7String85setTo
+ 32: 00000000 0 FUNC GLOBAL DEFAULT UND free@LIBC (2)
+ 33: 00000000 0 FUNC GLOBAL DEFAULT UND _ZN7android7String85setTo
+ 34: 00000000 0 FUNC GLOBAL DEFAULT UND __vsnprintf_chk@LIBC (2)
+ 35: 00000000 0 FUNC GLOBAL DEFAULT UND _ZN7android7String86appen
+ 36: 00000000 0 FUNC GLOBAL DEFAULT UND chmod@LIBC (2)
+ 37: 00000000 0 FUNC GLOBAL DEFAULT UND _ZN7android7String8C1EPKc
+ 38: 00000000 0 FUNC GLOBAL DEFAULT UND memmove@LIBC (2)
+ 39: 00000000 0 FUNC GLOBAL DEFAULT UND _ZN7android7String8C1ERKS
+ 40: 00000000 0 FUNC GLOBAL DEFAULT UND mkdir@LIBC (2)
+ 41: 00000000 0 FUNC GLOBAL DEFAULT UND _ZN7android7String8C1Ev
+ 42: 00000000 0 FUNC GLOBAL DEFAULT UND fwrite@LIBC (2)
+ 43: 00000000 0 FUNC GLOBAL DEFAULT UND _ZN7android7String8D1Ev
+ 44: 00000000 0 FUNC GLOBAL DEFAULT UND getenv@LIBC (2)
+ 45: 00000000 0 FUNC GLOBAL DEFAULT UND _ZN7android8hardware14IPC
+ 46: 00000000 0 FUNC GLOBAL DEFAULT UND pthread_getspecific@LIBC (2)
+ 47: 00000000 0 FUNC GLOBAL DEFAULT UND _ZN7android8hardware14IPC
+ 48: 00000000 0 FUNC GLOBAL DEFAULT UND pthread_key_create@LIBC (2)
+ 49: 00000000 0 FUNC GLOBAL DEFAULT UND dlsym@LIBC (4)
+ 50: 00000000 0 FUNC GLOBAL DEFAULT UND pthread_setspecific@LIBC (2)
+ 51: 00000000 0 FUNC GLOBAL DEFAULT UND _ZNK7android7RefBase9decS
+ 52: 00000000 0 FUNC GLOBAL DEFAULT UND _ZNK7android7String86leng
+ 53: 00000000 0 FUNC GLOBAL DEFAULT UND _ZdlPv
+ 54: 00000000 0 FUNC GLOBAL DEFAULT UND __android_log_assert
+ 55: 00000000 0 FUNC GLOBAL DEFAULT UND abort@LIBC (2)
+ 56: 00000000 0 FUNC GLOBAL DEFAULT UND __android_log_print
+ 57: 00000000 0 FUNC GLOBAL DEFAULT UND __errno@LIBC (2)
+ 58: 00000000 0 OBJECT GLOBAL DEFAULT UND __stack_chk_guard@LIBC (2)
+ 59: 00000000 0 FUNC GLOBAL DEFAULT UND property_get
+ 60: 00000000 0 FUNC GLOBAL DEFAULT UND _ZNSt3__111__call_onceERV
+ 61: 00000000 0 FUNC GLOBAL DEFAULT UND __android_log_write
+ 62: 00000000 0 FUNC GLOBAL DEFAULT UND sigaddset64@LIBC_P (3)
+ 63: 00000000 0 FUNC GLOBAL DEFAULT UND sigdelset64@LIBC_P (3)
+ 64: 00000000 0 FUNC GLOBAL DEFAULT UND sigemptyset64@LIBC_P (3)
+ 65: 00000000 0 FUNC GLOBAL DEFAULT UND sigfillset64@LIBC_P (3)
+ 66: 00000000 0 FUNC GLOBAL DEFAULT UND sigismember64@LIBC_P (3)
+ 67: 00003150 334 FUNC GLOBAL PROTECTED 12 AddSpecialSignalHandlerFn
+ 68: 00002d20 134 FUNC GLOBAL PROTECTED 12 bsd_signal
+ 69: 00002940 359 FUNC GLOBAL PROTECTED 12 sigaction
+ 70: 00002ab0 265 FUNC GLOBAL PROTECTED 12 sigaction64
+ 71: 00002db0 144 FUNC GLOBAL PROTECTED 12 sigprocmask
+ 72: 00002f80 144 FUNC GLOBAL PROTECTED 12 sigprocmask64
+ 73: 00002bc0 351 FUNC GLOBAL PROTECTED 12 signal
+ 74: 000032a0 244 FUNC GLOBAL PROTECTED 12 RemoveSpecialSignalHandle
+ 75: 000033a0 282 FUNC GLOBAL PROTECTED 12 EnsureFrontOfChain
+
+Histogram for `.gnu.hash' bucket list length (total of 3 buckets):
+ Length Number % of total Coverage
+ 0 0 ( 0.0%)
+ 1 1 ( 33.3%) 11.1%
+ 2 1 ( 33.3%) 33.3%
+ 3 0 ( 0.0%) 33.3%
+ 4 0 ( 0.0%) 33.3%
+ 5 0 ( 0.0%) 33.3%
+ 6 1 ( 33.3%) 100.0%
+
+Version symbols section '.gnu.version' contains 76 entries:
+ Addr: 0000000000000dc0 Offset: 0x000dc0 Link: 4 (.dynsym)
+ 000: 0 (*local*) 2 (LIBC) 2 (LIBC) 2 (LIBC)
+ 004: 2 (LIBC) 2 (LIBC) 2 (LIBC) 2 (LIBC)
+ 008: 0 (*local*) 0 (*local*) 0 (*local*) 0 (*local*)
+ 00c: 0 (*local*) 0 (*local*) 0 (*local*) 0 (*local*)
+ 010: 0 (*local*) 0 (*local*) 2 (LIBC) 0 (*local*)
+ 014: 2 (LIBC) 0 (*local*) 0 (*local*) 2 (LIBC)
+ 018: 0 (*local*) 2 (LIBC) 0 (*local*) 0 (*local*)
+ 01c: 2 (LIBC) 2 (LIBC) 2 (LIBC) 0 (*local*)
+ 020: 2 (LIBC) 0 (*local*) 2 (LIBC) 0 (*local*)
+ 024: 2 (LIBC) 0 (*local*) 2 (LIBC) 0 (*local*)
+ 028: 2 (LIBC) 0 (*local*) 2 (LIBC) 0 (*local*)
+ 02c: 2 (LIBC) 0 (*local*) 2 (LIBC) 0 (*local*)
+ 030: 2 (LIBC) 4 (LIBC) 2 (LIBC) 0 (*local*)
+ 034: 0 (*local*) 0 (*local*) 0 (*local*) 2 (LIBC)
+ 038: 0 (*local*) 2 (LIBC) 2 (LIBC) 0 (*local*)
+ 03c: 0 (*local*) 0 (*local*) 3 (LIBC_P) 3 (LIBC_P)
+ 040: 3 (LIBC_P) 3 (LIBC_P) 3 (LIBC_P) 1 (*global*)
+ 044: 1 (*global*) 1 (*global*) 1 (*global*) 1 (*global*)
+ 048: 1 (*global*) 1 (*global*) 1 (*global*) 1 (*global*)
+
+Version needs section '.gnu.version_r' contains 2 entries:
+ Addr: 0x0000000000000e58 Offset: 0x000e58 Link: 5 (.dynstr)
+ 000000: Version: 1 File: libc.so Cnt: 2
+ 0x0010: Name: LIBC Flags: none Version: 2
+ 0x0020: Name: LIBC_P Flags: none Version: 3
+ 0x0030: Version: 1 File: libdl.so Cnt: 1
+ 0x0040: Name: LIBC Flags: none Version: 4
+
+String dump of section '.rodata':
+ [ 0] -cp
+ [ 4] -classpath
+ [ f] --zygote
+ [ 18] --start-system-server
+ [ 2e] --application
+ [ 3c] --nice-name=
+ [ 49] --
+ [ 4c] application
+ [ 58] tool
+ [ 5d] start-system-server
+ [ 71] appproc
+ [ 79] app_process: Unable to determine ABI list from property %s.
+ [ b5] --abi-list=
+ [ c1] com.android.internal.os.ZygoteInit
+ [ e4] com.android.internal.os.RuntimeInit
+ [ 108] Error: no class name or --zygote supplied.^J
+ [ 134] app_process: no class name or --zygote supplied.
+ [ 165] ERROR: could not find class '%s'^J
+ [ 187] ANDROID_DATA
+ [ 194] androidRoot == NULL
+ [ 1a8] ANDROID_DATA environment variable unset
+ [ 1d0] %s/dalvik-cache/%s
+ [ 1e3] (numChars >= PATH_MAX || numChars < 0)
+ [ 20a] Error constructing dalvik cache : %s
+ [ 22f] (result < 0 && errno != EEXIST)
+ [ 24f] Error creating cache dir %s : %s
+ [ 270] (result < 0)
+ [ 27d] Error changing dalvik-cache ownership : %s
+ [ 2a8] Error changing dalvik-cache permissions : %s
+ [ 2d5] Usage: app_process [java-options] cmd-dir start-class-name [options]^J
+ [ 31b] exiting due to SIG_DFL handler for signal %d
+ [ 348] Invalid signal %d
+ [ 35a] Warning: Unexpected sigaction action found %p^J
+ [ 389] failed to create sigchain pthread key: %s
+ [ 3b3] libsigchain
+ [ 3bf] too many special signal handlers
+ [ 3e0] failed to find special handler to remove
+ [ 409] sigaction
+ [ 413] sigprocmask
+ [ 41f] sigaction64
+ [ 42b] sigprocmask64
+ [ 439] Unable to find next %s in signal chain
+ [ 460] zygote
+ [ 467] ro.product.cpu.abilist32
+ [ 480] x86
+
+
+Displaying notes found in: .note.android.ident
+ Owner Data size Description
+ Android 0x00000004 NT_VERSION (version)
+ description data: 1c 00 00 00
+
+Displaying notes found in: .note.gnu.build-id
+ Owner Data size Description
+ GNU 0x00000010 NT_GNU_BUILD_ID (unique build ID bitstring)
+ Build ID: 2bb7d95d208fcf19b7cca6e41929753b
+
+Displaying notes found in: .note.gnu.gold-version
+ Owner Data size Description
+ GNU 0x00000009 NT_GNU_GOLD_VERSION (gold version)
+ Version: gold 1.12
diff --git a/libraries/compatibility-common-util/tests/assets/x86app_process64 b/libraries/compatibility-common-util/tests/assets/x86app_process64
new file mode 100644
index 000000000..4fbe6eb80
--- /dev/null
+++ b/libraries/compatibility-common-util/tests/assets/x86app_process64
Binary files differ
diff --git a/libraries/compatibility-common-util/tests/assets/x86app_process64.txt b/libraries/compatibility-common-util/tests/assets/x86app_process64.txt
new file mode 100644
index 000000000..a517cbe0d
--- /dev/null
+++ b/libraries/compatibility-common-util/tests/assets/x86app_process64.txt
@@ -0,0 +1,422 @@
+ELF Header:
+ Magic: 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00
+ Class: ELF64
+ Data: 2's complement, little endian
+ Version: 1 (current)
+ OS/ABI: UNIX - System V
+ ABI Version: 0
+ Type: DYN (Shared object file)
+ Machine: Advanced Micro Devices X86-64
+ Version: 0x1
+ Entry point address: 0x1c50
+ Start of program headers: 64 (bytes into file)
+ Start of section headers: 22168 (bytes into file)
+ Flags: 0x0
+ Size of this header: 64 (bytes)
+ Size of program headers: 56 (bytes)
+ Number of program headers: 9
+ Size of section headers: 64 (bytes)
+ Number of section headers: 27
+ Section header string table index: 26
+
+Section Headers:
+ [Nr] Name Type Address Offset
+ Size EntSize Flags Link Info Align
+ [ 0] NULL 0000000000000000 00000000
+ 0000000000000000 0000000000000000 0 0 0
+ [ 1] .interp PROGBITS 0000000000000238 00000238
+ 0000000000000015 0000000000000000 A 0 0 1
+ [ 2] .note.android.ide NOTE 0000000000000250 00000250
+ 0000000000000018 0000000000000000 A 0 0 4
+ [ 3] .note.gnu.build-i NOTE 0000000000000268 00000268
+ 0000000000000020 0000000000000000 A 0 0 4
+ [ 4] .dynsym DYNSYM 0000000000000288 00000288
+ 00000000000006a8 0000000000000018 A 5 1 8
+ [ 5] .dynstr STRTAB 0000000000000930 00000930
+ 00000000000006d1 0000000000000000 A 0 0 1
+ [ 6] .gnu.hash GNU_HASH 0000000000001008 00001008
+ 0000000000000044 0000000000000000 A 4 0 8
+ [ 7] .gnu.version VERSYM 000000000000104c 0000104c
+ 000000000000008e 0000000000000002 A 4 0 2
+ [ 8] .gnu.version_r VERNEED 00000000000010dc 000010dc
+ 0000000000000050 0000000000000000 A 5 2 4
+ [ 9] .rela.dyn RELA 0000000000001130 00001130
+ 00000000000001b0 0000000000000018 A 4 0 8
+ [10] .rela.plt RELA 00000000000012e0 000012e0
+ 00000000000005a0 0000000000000018 AI 4 22 8
+ [11] .plt PROGBITS 0000000000001880 00001880
+ 00000000000003d0 0000000000000010 AX 0 0 16
+ [12] .text PROGBITS 0000000000001c50 00001c50
+ 0000000000001d8f 0000000000000000 AX 0 0 16
+ [13] .rodata PROGBITS 00000000000039e0 000039e0
+ 0000000000000490 0000000000000000 A 0 0 16
+ [14] .eh_frame PROGBITS 0000000000003e70 00003e70
+ 0000000000000494 0000000000000000 A 0 0 8
+ [15] .eh_frame_hdr PROGBITS 0000000000004304 00004304
+ 000000000000011c 0000000000000000 A 0 0 4
+ [16] .preinit_array PREINIT_ARRAY 0000000000005a78 00004a78
+ 0000000000000010 0000000000000008 WA 0 0 8
+ [17] .init_array INIT_ARRAY 0000000000005a88 00004a88
+ 0000000000000018 0000000000000008 WA 0 0 8
+ [18] .fini_array FINI_ARRAY 0000000000005aa0 00004aa0
+ 0000000000000010 0000000000000008 WA 0 0 8
+ [19] .data.rel.ro PROGBITS 0000000000005ab0 00004ab0
+ 0000000000000090 0000000000000000 WA 0 0 8
+ [20] .dynamic DYNAMIC 0000000000005b40 00004b40
+ 00000000000002b0 0000000000000010 WA 5 0 8
+ [21] .got PROGBITS 0000000000005df0 00004df0
+ 0000000000000018 0000000000000000 WA 0 0 8
+ [22] .got.plt PROGBITS 0000000000005e08 00004e08
+ 00000000000001f8 0000000000000000 WA 0 0 8
+ [23] .bss NOBITS 0000000000006000 00005000
+ 00000000000016f0 0000000000000000 WA 0 0 16
+ [24] .note.gnu.gold-ve NOTE 0000000000000000 00005000
+ 000000000000001c 0000000000000000 0 0 4
+ [25] .gnu_debugdata PROGBITS 0000000000000000 0000501c
+ 0000000000000558 0000000000000000 0 0 1
+ [26] .shstrtab STRTAB 0000000000000000 00005574
+ 0000000000000120 0000000000000000 0 0 1
+Key to Flags:
+ W (write), A (alloc), X (execute), M (merge), S (strings), I (info),
+ L (link order), O (extra OS processing required), G (group), T (TLS),
+ C (compressed), x (unknown), o (OS specific), E (exclude),
+ l (large), p (processor specific)
+
+There are no section groups in this file.
+
+Program Headers:
+ Type Offset VirtAddr PhysAddr
+ FileSiz MemSiz Flags Align
+ PHDR 0x0000000000000040 0x0000000000000040 0x0000000000000040
+ 0x00000000000001f8 0x00000000000001f8 R 0x8
+ INTERP 0x0000000000000238 0x0000000000000238 0x0000000000000238
+ 0x0000000000000015 0x0000000000000015 R 0x1
+ [Requesting program interpreter: /system/bin/linker64]
+ LOAD 0x0000000000000000 0x0000000000000000 0x0000000000000000
+ 0x0000000000004420 0x0000000000004420 R E 0x1000
+ LOAD 0x0000000000004a78 0x0000000000005a78 0x0000000000005a78
+ 0x0000000000000588 0x0000000000001c78 RW 0x1000
+ DYNAMIC 0x0000000000004b40 0x0000000000005b40 0x0000000000005b40
+ 0x00000000000002b0 0x00000000000002b0 RW 0x8
+ NOTE 0x0000000000000250 0x0000000000000250 0x0000000000000250
+ 0x0000000000000038 0x0000000000000038 R 0x4
+ GNU_EH_FRAME 0x0000000000004304 0x0000000000004304 0x0000000000004304
+ 0x000000000000011c 0x000000000000011c R 0x4
+ GNU_STACK 0x0000000000000000 0x0000000000000000 0x0000000000000000
+ 0x0000000000000000 0x0000000000000000 RW 0x10
+ GNU_RELRO 0x0000000000004a78 0x0000000000005a78 0x0000000000005a78
+ 0x0000000000000588 0x0000000000000588 RW 0x8
+
+ Section to Segment mapping:
+ Segment Sections...
+ 00
+ 01 .interp
+ 02 .interp .note.android.ident .note.gnu.build-id .dynsym .dynstr .gnu.hash .gnu.version .gnu.version_r .rela.dyn .rela.plt .plt .text .rodata .eh_frame .eh_frame_hdr
+ 03 .preinit_array .init_array .fini_array .data.rel.ro .dynamic .got .got.plt .bss
+ 04 .dynamic
+ 05 .note.android.ident .note.gnu.build-id
+ 06 .eh_frame_hdr
+ 07
+ 08 .preinit_array .init_array .fini_array .data.rel.ro .dynamic .got .got.plt
+
+Dynamic section at offset 0x4b40 contains 38 entries:
+ Tag Type Name/Value
+ 0x0000000000000003 (PLTGOT) 0x5e08
+ 0x0000000000000002 (PLTRELSZ) 1440 (bytes)
+ 0x0000000000000017 (JMPREL) 0x12e0
+ 0x0000000000000014 (PLTREL) RELA
+ 0x0000000000000007 (RELA) 0x1130
+ 0x0000000000000008 (RELASZ) 432 (bytes)
+ 0x0000000000000009 (RELAENT) 24 (bytes)
+ 0x000000006ffffff9 (RELACOUNT) 17
+ 0x0000000000000015 (DEBUG) 0x0
+ 0x0000000000000006 (SYMTAB) 0x288
+ 0x000000000000000b (SYMENT) 24 (bytes)
+ 0x0000000000000005 (STRTAB) 0x930
+ 0x000000000000000a (STRSZ) 1745 (bytes)
+ 0x000000006ffffef5 (GNU_HASH) 0x1008
+ 0x0000000000000001 (NEEDED) Shared library: [libandroid_runtime.so]
+ 0x0000000000000001 (NEEDED) Shared library: [libbinder.so]
+ 0x0000000000000001 (NEEDED) Shared library: [libcutils.so]
+ 0x0000000000000001 (NEEDED) Shared library: [libhwbinder.so]
+ 0x0000000000000001 (NEEDED) Shared library: [liblog.so]
+ 0x0000000000000001 (NEEDED) Shared library: [libnativeloader.so]
+ 0x0000000000000001 (NEEDED) Shared library: [libutils.so]
+ 0x0000000000000001 (NEEDED) Shared library: [libwilhelm.so]
+ 0x0000000000000001 (NEEDED) Shared library: [libc++.so]
+ 0x0000000000000001 (NEEDED) Shared library: [libc.so]
+ 0x0000000000000001 (NEEDED) Shared library: [libm.so]
+ 0x0000000000000001 (NEEDED) Shared library: [libdl.so]
+ 0x0000000000000020 (PREINIT_ARRAY) 0x5a78
+ 0x0000000000000021 (PREINIT_ARRAYSZ) 0x10
+ 0x0000000000000019 (INIT_ARRAY) 0x5a88
+ 0x000000000000001b (INIT_ARRAYSZ) 24 (bytes)
+ 0x000000000000001a (FINI_ARRAY) 0x5aa0
+ 0x000000000000001c (FINI_ARRAYSZ) 16 (bytes)
+ 0x000000000000001e (FLAGS) BIND_NOW
+ 0x000000006ffffffb (FLAGS_1) Flags: NOW
+ 0x000000006ffffff0 (VERSYM) 0x104c
+ 0x000000006ffffffe (VERNEED) 0x10dc
+ 0x000000006fffffff (VERNEEDNUM) 2
+ 0x0000000000000000 (NULL) 0x0
+
+Relocation section '.rela.dyn' at offset 0x1130 contains 18 entries:
+ Offset Info Type Sym. Value Sym. Name + Addend
+000000005a90 000000000008 R_X86_64_RELATIVE 28e0
+000000005ac0 000000000008 R_X86_64_RELATIVE 2450
+000000005ac8 000000000008 R_X86_64_RELATIVE 24a0
+000000005ad0 000000000008 R_X86_64_RELATIVE 24f0
+000000005ad8 000000000008 R_X86_64_RELATIVE 2580
+000000005ae0 000000000008 R_X86_64_RELATIVE 2620
+000000005ae8 000000000008 R_X86_64_RELATIVE 2680
+000000005b00 000000000008 R_X86_64_RELATIVE 2430
+000000005b08 000000000008 R_X86_64_RELATIVE 2790
+000000005b10 000000000008 R_X86_64_RELATIVE 27c0
+000000005b18 000000000008 R_X86_64_RELATIVE 27f0
+000000005b20 000000000008 R_X86_64_RELATIVE 2820
+000000005b28 000000000008 R_X86_64_RELATIVE 2860
+000000005b30 000000000008 R_X86_64_RELATIVE 28a0
+000000005b38 000000000008 R_X86_64_RELATIVE 28c0
+000000005df0 000000000008 R_X86_64_RELATIVE 5a88
+000000005df8 000000000008 R_X86_64_RELATIVE 5a78
+000000005e00 001900000006 R_X86_64_GLOB_DAT 0000000000000000 stderr@LIBC + 0
+
+Relocation section '.rela.plt' at offset 0x12e0 contains 60 entries:
+ Offset Info Type Sym. Value Sym. Name + Addend
+000000005e20 000200000007 R_X86_64_JUMP_SLO 0000000000000000 __libc_init@LIBC + 0
+000000005e28 000300000007 R_X86_64_JUMP_SLO 0000000000000000 __register_atfork@LIBC + 0
+000000005e30 002000000007 R_X86_64_JUMP_SLO 0000000000000000 strlen@LIBC + 0
+000000005e38 001000000007 R_X86_64_JUMP_SLO 0000000000000000 _ZN7android14AndroidRu + 0
+000000005e40 002300000007 R_X86_64_JUMP_SLO 0000000000000000 _ZN7android7String8C1E + 0
+000000005e48 000600000007 R_X86_64_JUMP_SLO 0000000000000000 _ZN7android10VectorImp + 0
+000000005e50 001800000007 R_X86_64_JUMP_SLO 0000000000000000 strcmp@LIBC + 0
+000000005e58 002400000007 R_X86_64_JUMP_SLO 0000000000000000 strdup@LIBC + 0
+000000005e60 000f00000007 R_X86_64_JUMP_SLO 0000000000000000 _ZN7android14AndroidRu + 0
+000000005e68 001e00000007 R_X86_64_JUMP_SLO 0000000000000000 strncmp@LIBC + 0
+000000005e70 001a00000007 R_X86_64_JUMP_SLO 0000000000000000 _ZN7android7String85se + 0
+000000005e78 002c00000007 R_X86_64_JUMP_SLO 0000000000000000 _ZNK7android7String86l + 0
+000000005e80 001300000007 R_X86_64_JUMP_SLO 0000000000000000 getenv@LIBC + 0
+000000005e88 001c00000007 R_X86_64_JUMP_SLO 0000000000000000 mkdir@LIBC + 0
+000000005e90 003400000007 R_X86_64_JUMP_SLO 0000000000000000 __errno@LIBC + 0
+000000005e98 003a00000007 R_X86_64_JUMP_SLO 0000000000000000 chown@LIBC + 0
+000000005ea0 003800000007 R_X86_64_JUMP_SLO 0000000000000000 chmod@LIBC + 0
+000000005ea8 001f00000007 R_X86_64_JUMP_SLO 0000000000000000 _ZN7android7String8C1E + 0
+000000005eb0 000500000007 R_X86_64_JUMP_SLO 0000000000000000 _ZN7android10VectorImp + 0
+000000005eb8 002500000007 R_X86_64_JUMP_SLO 0000000000000000 _ZN7android7String8D1E + 0
+000000005ec0 003b00000007 R_X86_64_JUMP_SLO 0000000000000000 property_get + 0
+000000005ec8 001d00000007 R_X86_64_JUMP_SLO 0000000000000000 _ZN7android7String86ap + 0
+000000005ed0 001b00000007 R_X86_64_JUMP_SLO 0000000000000000 _ZN7android7String85se + 0
+000000005ed8 000e00000007 R_X86_64_JUMP_SLO 0000000000000000 _ZN7android14AndroidRu + 0
+000000005ee0 000c00000007 R_X86_64_JUMP_SLO 0000000000000000 _ZN7android14AndroidRu + 0
+000000005ee8 000400000007 R_X86_64_JUMP_SLO 0000000000000000 _ZN7android10VectorImp + 0
+000000005ef0 000700000007 R_X86_64_JUMP_SLO 0000000000000000 _ZN7android10VectorImp + 0
+000000005ef8 001200000007 R_X86_64_JUMP_SLO 0000000000000000 _ZN7android14AndroidRu + 0
+000000005f00 003500000007 R_X86_64_JUMP_SLO 0000000000000000 __stack_chk_fail@LIBC + 0
+000000005f08 001500000007 R_X86_64_JUMP_SLO 0000000000000000 fwrite@LIBC + 0
+000000005f10 003200000007 R_X86_64_JUMP_SLO 0000000000000000 __android_log_assert + 0
+000000005f18 002200000007 R_X86_64_JUMP_SLO 0000000000000000 strerror@LIBC + 0
+000000005f20 003000000007 R_X86_64_JUMP_SLO 0000000000000000 _ZdlPv + 0
+000000005f28 000b00000007 R_X86_64_JUMP_SLO 0000000000000000 _ZN7android14AndroidRu + 0
+000000005f30 003300000007 R_X86_64_JUMP_SLO 0000000000000000 __android_log_print + 0
+000000005f38 001700000007 R_X86_64_JUMP_SLO 0000000000000000 free@LIBC + 0
+000000005f40 000900000007 R_X86_64_JUMP_SLO 0000000000000000 _ZN7android12ProcessSt + 0
+000000005f48 000800000007 R_X86_64_JUMP_SLO 0000000000000000 _ZN7android12ProcessSt + 0
+000000005f50 000a00000007 R_X86_64_JUMP_SLO 0000000000000000 _ZN7android14AndroidRu + 0
+000000005f58 000d00000007 R_X86_64_JUMP_SLO 0000000000000000 _ZN7android14AndroidRu + 0
+000000005f60 001600000007 R_X86_64_JUMP_SLO 0000000000000000 _ZN7android14IPCThread + 0
+000000005f68 001400000007 R_X86_64_JUMP_SLO 0000000000000000 _ZN7android14IPCThread + 0
+000000005f70 002700000007 R_X86_64_JUMP_SLO 0000000000000000 _ZN7android8hardware14 + 0
+000000005f78 002600000007 R_X86_64_JUMP_SLO 0000000000000000 _ZN7android8hardware14 + 0
+000000005f80 002a00000007 R_X86_64_JUMP_SLO 0000000000000000 _ZNK7android7RefBase9d + 0
+000000005f88 003700000007 R_X86_64_JUMP_SLO 0000000000000000 __vsnprintf_chk@LIBC + 0
+000000005f90 002100000007 R_X86_64_JUMP_SLO 0000000000000000 _ZN7android7String8C1E + 0
+000000005f98 001100000007 R_X86_64_JUMP_SLO 0000000000000000 memmove@LIBC + 0
+000000005fa0 003c00000007 R_X86_64_JUMP_SLO 0000000000000000 _ZNSt3__111__call_once + 0
+000000005fa8 002d00000007 R_X86_64_JUMP_SLO 0000000000000000 pthread_getspecific@LIBC + 0
+000000005fb0 003900000007 R_X86_64_JUMP_SLO 0000000000000000 sigemptyset@LIBC + 0
+000000005fb8 003600000007 R_X86_64_JUMP_SLO 0000000000000000 sigismember@LIBC + 0
+000000005fc0 003100000007 R_X86_64_JUMP_SLO 0000000000000000 sigaddset@LIBC + 0
+000000005fc8 002900000007 R_X86_64_JUMP_SLO 0000000000000000 pthread_setspecific@LIBC + 0
+000000005fd0 002800000007 R_X86_64_JUMP_SLO 0000000000000000 abort@LIBC + 0
+000000005fd8 003d00000007 R_X86_64_JUMP_SLO 0000000000000000 __android_log_write + 0
+000000005fe0 002f00000007 R_X86_64_JUMP_SLO 0000000000000000 sigdelset@LIBC + 0
+000000005fe8 003e00000007 R_X86_64_JUMP_SLO 0000000000000000 sigfillset64@LIBC_P + 0
+000000005ff0 002b00000007 R_X86_64_JUMP_SLO 0000000000000000 pthread_key_create@LIBC + 0
+000000005ff8 002e00000007 R_X86_64_JUMP_SLO 0000000000000000 dlsym@LIBC + 0
+
+The decoding of unwind sections for machine type Advanced Micro Devices X86-64 is not currently supported.
+
+Symbol table '.dynsym' contains 71 entries:
+ Num: Value Size Type Bind Vis Ndx Name
+ 0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
+ 1: 0000000000000000 0 FUNC GLOBAL DEFAULT UND __cxa_atexit@LIBC (2)
+ 2: 0000000000000000 0 FUNC GLOBAL DEFAULT UND __libc_init@LIBC (2)
+ 3: 0000000000000000 0 FUNC GLOBAL DEFAULT UND __register_atfork@LIBC (2)
+ 4: 0000000000000000 0 FUNC GLOBAL DEFAULT UND _ZN7android10VectorImpl13
+ 5: 0000000000000000 0 FUNC GLOBAL DEFAULT UND _ZN7android10VectorImpl3a
+ 6: 0000000000000000 0 FUNC GLOBAL DEFAULT UND _ZN7android10VectorImplC2
+ 7: 0000000000000000 0 FUNC GLOBAL DEFAULT UND _ZN7android10VectorImplD2
+ 8: 0000000000000000 0 FUNC GLOBAL DEFAULT UND _ZN7android12ProcessState
+ 9: 0000000000000000 0 FUNC GLOBAL DEFAULT UND _ZN7android12ProcessState
+ 10: 0000000000000000 0 FUNC GLOBAL DEFAULT UND _ZN7android14AndroidRunti
+ 11: 0000000000000000 0 FUNC GLOBAL DEFAULT UND _ZN7android14AndroidRunti
+ 12: 0000000000000000 0 FUNC GLOBAL DEFAULT UND _ZN7android14AndroidRunti
+ 13: 0000000000000000 0 FUNC GLOBAL DEFAULT UND _ZN7android14AndroidRunti
+ 14: 0000000000000000 0 FUNC GLOBAL DEFAULT UND _ZN7android14AndroidRunti
+ 15: 0000000000000000 0 FUNC GLOBAL DEFAULT UND _ZN7android14AndroidRunti
+ 16: 0000000000000000 0 FUNC GLOBAL DEFAULT UND _ZN7android14AndroidRunti
+ 17: 0000000000000000 0 FUNC GLOBAL DEFAULT UND memmove@LIBC (2)
+ 18: 0000000000000000 0 FUNC GLOBAL DEFAULT UND _ZN7android14AndroidRunti
+ 19: 0000000000000000 0 FUNC GLOBAL DEFAULT UND getenv@LIBC (2)
+ 20: 0000000000000000 0 FUNC GLOBAL DEFAULT UND _ZN7android14IPCThreadSta
+ 21: 0000000000000000 0 FUNC GLOBAL DEFAULT UND fwrite@LIBC (2)
+ 22: 0000000000000000 0 FUNC GLOBAL DEFAULT UND _ZN7android14IPCThreadSta
+ 23: 0000000000000000 0 FUNC GLOBAL DEFAULT UND free@LIBC (2)
+ 24: 0000000000000000 0 FUNC GLOBAL DEFAULT UND strcmp@LIBC (2)
+ 25: 0000000000000000 0 OBJECT GLOBAL DEFAULT UND stderr@LIBC (2)
+ 26: 0000000000000000 0 FUNC GLOBAL DEFAULT UND _ZN7android7String85setTo
+ 27: 0000000000000000 0 FUNC GLOBAL DEFAULT UND _ZN7android7String85setTo
+ 28: 0000000000000000 0 FUNC GLOBAL DEFAULT UND mkdir@LIBC (2)
+ 29: 0000000000000000 0 FUNC GLOBAL DEFAULT UND _ZN7android7String86appen
+ 30: 0000000000000000 0 FUNC GLOBAL DEFAULT UND strncmp@LIBC (2)
+ 31: 0000000000000000 0 FUNC GLOBAL DEFAULT UND _ZN7android7String8C1EPKc
+ 32: 0000000000000000 0 FUNC GLOBAL DEFAULT UND strlen@LIBC (2)
+ 33: 0000000000000000 0 FUNC GLOBAL DEFAULT UND _ZN7android7String8C1ERKS
+ 34: 0000000000000000 0 FUNC GLOBAL DEFAULT UND strerror@LIBC (2)
+ 35: 0000000000000000 0 FUNC GLOBAL DEFAULT UND _ZN7android7String8C1Ev
+ 36: 0000000000000000 0 FUNC GLOBAL DEFAULT UND strdup@LIBC (2)
+ 37: 0000000000000000 0 FUNC GLOBAL DEFAULT UND _ZN7android7String8D1Ev
+ 38: 0000000000000000 0 FUNC GLOBAL DEFAULT UND _ZN7android8hardware14IPC
+ 39: 0000000000000000 0 FUNC GLOBAL DEFAULT UND _ZN7android8hardware14IPC
+ 40: 0000000000000000 0 FUNC GLOBAL DEFAULT UND abort@LIBC (2)
+ 41: 0000000000000000 0 FUNC GLOBAL DEFAULT UND pthread_setspecific@LIBC (2)
+ 42: 0000000000000000 0 FUNC GLOBAL DEFAULT UND _ZNK7android7RefBase9decS
+ 43: 0000000000000000 0 FUNC GLOBAL DEFAULT UND pthread_key_create@LIBC (2)
+ 44: 0000000000000000 0 FUNC GLOBAL DEFAULT UND _ZNK7android7String86leng
+ 45: 0000000000000000 0 FUNC GLOBAL DEFAULT UND pthread_getspecific@LIBC (2)
+ 46: 0000000000000000 0 FUNC GLOBAL DEFAULT UND dlsym@LIBC (4)
+ 47: 0000000000000000 0 FUNC GLOBAL DEFAULT UND sigdelset@LIBC (2)
+ 48: 0000000000000000 0 FUNC GLOBAL DEFAULT UND _ZdlPv
+ 49: 0000000000000000 0 FUNC GLOBAL DEFAULT UND sigaddset@LIBC (2)
+ 50: 0000000000000000 0 FUNC GLOBAL DEFAULT UND __android_log_assert
+ 51: 0000000000000000 0 FUNC GLOBAL DEFAULT UND __android_log_print
+ 52: 0000000000000000 0 FUNC GLOBAL DEFAULT UND __errno@LIBC (2)
+ 53: 0000000000000000 0 FUNC GLOBAL DEFAULT UND __stack_chk_fail@LIBC (2)
+ 54: 0000000000000000 0 FUNC GLOBAL DEFAULT UND sigismember@LIBC (2)
+ 55: 0000000000000000 0 FUNC GLOBAL DEFAULT UND __vsnprintf_chk@LIBC (2)
+ 56: 0000000000000000 0 FUNC GLOBAL DEFAULT UND chmod@LIBC (2)
+ 57: 0000000000000000 0 FUNC GLOBAL DEFAULT UND sigemptyset@LIBC (2)
+ 58: 0000000000000000 0 FUNC GLOBAL DEFAULT UND chown@LIBC (2)
+ 59: 0000000000000000 0 FUNC GLOBAL DEFAULT UND property_get
+ 60: 0000000000000000 0 FUNC GLOBAL DEFAULT UND _ZNSt3__111__call_onceERV
+ 61: 0000000000000000 0 FUNC GLOBAL DEFAULT UND __android_log_write
+ 62: 0000000000000000 0 FUNC GLOBAL DEFAULT UND sigfillset64@LIBC_P (3)
+ 63: 00000000000034d0 320 FUNC GLOBAL PROTECTED 12 AddSpecialSignalHandlerFn
+ 64: 0000000000002eb0 322 FUNC GLOBAL PROTECTED 12 sigaction
+ 65: 0000000000003000 287 FUNC GLOBAL PROTECTED 12 sigaction64
+ 66: 0000000000003290 135 FUNC GLOBAL PROTECTED 12 sigprocmask
+ 67: 0000000000003440 135 FUNC GLOBAL PROTECTED 12 sigprocmask64
+ 68: 0000000000003120 361 FUNC GLOBAL PROTECTED 12 signal
+ 69: 0000000000003610 254 FUNC GLOBAL PROTECTED 12 RemoveSpecialSignalHandle
+ 70: 0000000000003710 263 FUNC GLOBAL PROTECTED 12 EnsureFrontOfChain
+
+Histogram for `.gnu.hash' bucket list length (total of 3 buckets):
+ Length Number % of total Coverage
+ 0 0 ( 0.0%)
+ 1 1 ( 33.3%) 12.5%
+ 2 1 ( 33.3%) 37.5%
+ 3 0 ( 0.0%) 37.5%
+ 4 0 ( 0.0%) 37.5%
+ 5 1 ( 33.3%) 100.0%
+
+Version symbols section '.gnu.version' contains 71 entries:
+ Addr: 000000000000104c Offset: 0x00104c Link: 4 (.dynsym)
+ 000: 0 (*local*) 2 (LIBC) 2 (LIBC) 2 (LIBC)
+ 004: 0 (*local*) 0 (*local*) 0 (*local*) 0 (*local*)
+ 008: 0 (*local*) 0 (*local*) 0 (*local*) 0 (*local*)
+ 00c: 0 (*local*) 0 (*local*) 0 (*local*) 0 (*local*)
+ 010: 0 (*local*) 2 (LIBC) 0 (*local*) 2 (LIBC)
+ 014: 0 (*local*) 2 (LIBC) 0 (*local*) 2 (LIBC)
+ 018: 2 (LIBC) 2 (LIBC) 0 (*local*) 0 (*local*)
+ 01c: 2 (LIBC) 0 (*local*) 2 (LIBC) 0 (*local*)
+ 020: 2 (LIBC) 0 (*local*) 2 (LIBC) 0 (*local*)
+ 024: 2 (LIBC) 0 (*local*) 0 (*local*) 0 (*local*)
+ 028: 2 (LIBC) 2 (LIBC) 0 (*local*) 2 (LIBC)
+ 02c: 0 (*local*) 2 (LIBC) 4 (LIBC) 2 (LIBC)
+ 030: 0 (*local*) 2 (LIBC) 0 (*local*) 0 (*local*)
+ 034: 2 (LIBC) 2 (LIBC) 2 (LIBC) 2 (LIBC)
+ 038: 2 (LIBC) 2 (LIBC) 2 (LIBC) 0 (*local*)
+ 03c: 0 (*local*) 0 (*local*) 3 (LIBC_P) 1 (*global*)
+ 040: 1 (*global*) 1 (*global*) 1 (*global*) 1 (*global*)
+ 044: 1 (*global*) 1 (*global*) 1 (*global*)
+
+Version needs section '.gnu.version_r' contains 2 entries:
+ Addr: 0x00000000000010dc Offset: 0x0010dc Link: 5 (.dynstr)
+ 000000: Version: 1 File: libc.so Cnt: 2
+ 0x0010: Name: LIBC Flags: none Version: 2
+ 0x0020: Name: LIBC_P Flags: none Version: 3
+ 0x0030: Version: 1 File: libdl.so Cnt: 1
+ 0x0040: Name: LIBC Flags: none Version: 4
+
+String dump of section '.rodata':
+ [ 0] -cp
+ [ 4] -classpath
+ [ f] --zygote
+ [ 18] --start-system-server
+ [ 2e] --application
+ [ 3c] --nice-name=
+ [ 49] --
+ [ 4c] application
+ [ 58] tool
+ [ 5d] start-system-server
+ [ 71] appproc
+ [ 79] app_process: Unable to determine ABI list from property %s.
+ [ b5] --abi-list=
+ [ c1] com.android.internal.os.ZygoteInit
+ [ e4] com.android.internal.os.RuntimeInit
+ [ 108] Error: no class name or --zygote supplied.^J
+ [ 134] app_process: no class name or --zygote supplied.
+ [ 165] ERROR: could not find class '%s'^J
+ [ 187] ANDROID_DATA
+ [ 194] androidRoot == NULL
+ [ 1a8] ANDROID_DATA environment variable unset
+ [ 1d0] %s/dalvik-cache/%s
+ [ 1e3] (numChars >= PATH_MAX || numChars < 0)
+ [ 20a] Error constructing dalvik cache : %s
+ [ 22f] (result < 0 && errno != EEXIST)
+ [ 24f] Error creating cache dir %s : %s
+ [ 270] (result < 0)
+ [ 27d] Error changing dalvik-cache ownership : %s
+ [ 2a8] Error changing dalvik-cache permissions : %s
+ [ 2d5] Usage: app_process [java-options] cmd-dir start-class-name [options]^J
+ [ 31b] exiting due to SIG_DFL handler for signal %d
+ [ 348] Invalid signal %d
+ [ 35a] Warning: Unexpected sigaction action found %p^J
+ [ 389] failed to create sigchain pthread key: %s
+ [ 3b3] libsigchain
+ [ 3bf] too many special signal handlers
+ [ 3e0] failed to find special handler to remove
+ [ 409] sigaction
+ [ 413] sigprocmask
+ [ 41f] sigaction64
+ [ 42b] sigprocmask64
+ [ 439] Unable to find next %s in signal chain
+ [ 460] zygote64
+ [ 470] ro.product.cpu.abilist64
+ [ 489] x86_64
+
+
+Displaying notes found in: .note.android.ident
+ Owner Data size Description
+ Android 0x00000004 NT_VERSION (version)
+ description data: 1c 00 00 00
+
+Displaying notes found in: .note.gnu.build-id
+ Owner Data size Description
+ GNU 0x00000010 NT_GNU_BUILD_ID (unique build ID bitstring)
+ Build ID: 6c3eb89f506fa4c558af06eff220de26
+
+Displaying notes found in: .note.gnu.gold-version
+ Owner Data size Description
+ GNU 0x00000009 NT_GNU_GOLD_VERSION (gold version)
+ Version: gold 1.12
diff --git a/libraries/compatibility-common-util/tests/gen_elf_golden_files.sh b/libraries/compatibility-common-util/tests/gen_elf_golden_files.sh
new file mode 100755
index 000000000..4b9f29db0
--- /dev/null
+++ b/libraries/compatibility-common-util/tests/gen_elf_golden_files.sh
@@ -0,0 +1,14 @@
+#!/bin/bash
+# This script generats readelf output file for compatibility-common-util-tests.
+# A typical flow is as follows:
+# 1. add the file name in targetFile if to add a new object test file in ./assets
+# 2. run: ./gen_elf_golden_files.sh
+# 3. update ReadElfTest to use the new files
+# 4. build: m release-parser compatibility-common-util-tests -j8
+# 5. test: ./run_tests.sh
+echo Generating ELF golden sample file for test via readelf
+targetFile="arm32_libdl.so arm64_libdl.so x86app_process32 x86app_process64"
+for file in $targetFile; do
+ echo Processing $file
+ readelf -a -p .rodata ./assets/$file > ./assets/${file/.so/}.txt
+done \ No newline at end of file
diff --git a/libraries/compatibility-common-util/tests/src/com/android/compatibility/common/util/BackupUtilsTest.java b/libraries/compatibility-common-util/tests/src/com/android/compatibility/common/util/BackupUtilsTest.java
new file mode 100644
index 000000000..84c177acc
--- /dev/null
+++ b/libraries/compatibility-common-util/tests/src/com/android/compatibility/common/util/BackupUtilsTest.java
@@ -0,0 +1,533 @@
+/*
+ * 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.compatibility.common.util;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import com.android.tradefed.util.RunUtil;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * Unit tests for {@link BackupUtils}
+ */
+@RunWith(JUnit4.class)
+public class BackupUtilsTest {
+ private static final int BACKUP_SERVICE_INIT_TIMEOUT_SECS = 1;
+ private static final int TEST_USER_ID = 10;
+
+ private boolean mIsDumpsysCommandCalled;
+ private boolean mIsEnableCommandCalled;
+ private boolean mIsActivateCommandCalled;
+
+ @Before
+ public void setUp() {
+ mIsDumpsysCommandCalled = false;
+ mIsEnableCommandCalled = false;
+ }
+
+ @Test
+ public void testEnableBackup_whenEnableTrueAndEnabled_returnsTrue() throws Exception {
+ BackupUtils backupUtils = new BackupUtils() {
+ @Override
+ protected InputStream executeShellCommand(String command) throws IOException {
+ String output = "";
+ if (command.equals("bmgr enabled")) {
+ output = "Backup Manager currently enabled";
+ } else if (command.equals("bmgr enable true")) {
+ output = "Backup Manager now enabled";
+ mIsEnableCommandCalled = true;
+ }
+ return new ByteArrayInputStream(output.getBytes("UTF-8"));
+ }
+ };
+ assertTrue(backupUtils.enableBackup(true));
+ assertTrue(mIsEnableCommandCalled);
+ }
+
+ @Test
+ public void testEnableBackup_whenEnableTrueAndDisabled_returnsFalse() throws Exception {
+ BackupUtils backupUtils = new BackupUtils() {
+ @Override
+ protected InputStream executeShellCommand(String command) throws IOException {
+ String output = "";
+ if (command.equals("bmgr enabled")) {
+ output = "Backup Manager currently disabled";
+ } else if (command.equals("bmgr enable true")) {
+ output = "Backup Manager now enabled";
+ mIsEnableCommandCalled = true;
+ }
+ return new ByteArrayInputStream(output.getBytes("UTF-8"));
+ }
+ };
+ assertFalse(backupUtils.enableBackup(true));
+ assertTrue(mIsEnableCommandCalled);
+ }
+
+ @Test
+ public void testEnableBackup_whenEnableFalseAndEnabled_returnsTrue() throws Exception {
+ BackupUtils backupUtils = new BackupUtils() {
+ @Override
+ protected InputStream executeShellCommand(String command) throws IOException {
+ String output = "";
+ if (command.equals("bmgr enabled")) {
+ output = "Backup Manager currently enabled";
+ } else if (command.equals("bmgr enable false")) {
+ output = "Backup Manager now disabled";
+ mIsEnableCommandCalled = true;
+ }
+ return new ByteArrayInputStream(output.getBytes("UTF-8"));
+ }
+ };
+ assertTrue(backupUtils.enableBackup(false));
+ assertTrue(mIsEnableCommandCalled);
+ }
+
+ @Test
+ public void testEnableBackup_whenEnableFalseAndDisabled_returnsFalse() throws Exception {
+ BackupUtils backupUtils = new BackupUtils() {
+ @Override
+ protected InputStream executeShellCommand(String command) throws IOException {
+ String output = "";
+ if (command.equals("bmgr enabled")) {
+ output = "Backup Manager currently disabled";
+ } else if (command.equals("bmgr enable false")) {
+ output = "Backup Manager now disabled";
+ mIsEnableCommandCalled = true;
+ }
+ return new ByteArrayInputStream(output.getBytes("UTF-8"));
+ }
+ };
+ assertFalse(backupUtils.enableBackup(false));
+ assertTrue(mIsEnableCommandCalled);
+ }
+
+ @Test
+ public void testEnableBackup_whenEnableTrueAndEnabledAndCommandsReturnMultipleLines()
+ throws Exception {
+ BackupUtils backupUtils = new BackupUtils() {
+ @Override
+ protected InputStream executeShellCommand(String command) throws IOException {
+ String output = "";
+ if (command.equals("bmgr enabled")) {
+ output = "Backup Manager currently enabled" + "\n...";
+ } else if (command.equals("bmgr enable true")) {
+ output = "Backup Manager now enabled" + "\n...";
+ mIsEnableCommandCalled = true;
+ }
+ return new ByteArrayInputStream(output.getBytes("UTF-8"));
+ }
+ };
+ assertTrue(backupUtils.enableBackup(true));
+ assertTrue(mIsEnableCommandCalled);
+ }
+
+ @Test
+ public void testEnableBackup_whenQueryCommandThrows_propagatesException() throws Exception {
+ BackupUtils backupUtils = new BackupUtils() {
+ @Override
+ protected InputStream executeShellCommand(String command) throws IOException {
+ String output = "";
+ if (command.equals("bmgr enabled")) {
+ throw new IOException(String.format(
+ "enableBackup: Failed to run command: %s", command));
+ } else if (command.equals("bmgr enable true")) {
+ output = "Backup Manager now enabled";
+ mIsEnableCommandCalled = true;
+ }
+ return new ByteArrayInputStream(output.getBytes("UTF-8"));
+ }
+ };
+
+ boolean isExceptionHappened = false;
+ try {
+ backupUtils.enableBackup(true);
+ } catch (IOException e) {
+ // enableBackup: Failed to run command: bmgr enabled
+ isExceptionHappened = true;
+ }
+ assertTrue(isExceptionHappened);
+ assertFalse(mIsEnableCommandCalled);
+ }
+
+ @Test
+ public void testEnableBackup_whenSetCommandThrows_propagatesException() throws Exception {
+ BackupUtils backupUtils = new BackupUtils() {
+ @Override
+ protected InputStream executeShellCommand(String command) throws IOException {
+ String output = "";
+ if (command.equals("bmgr enabled")) {
+ output = "Backup Manager currently enabled";
+ } else if (command.equals("bmgr enable true")) {
+ mIsEnableCommandCalled = true;
+ throw new IOException(String.format(
+ "enableBackup: Failed to run command: %s", command));
+ }
+ return new ByteArrayInputStream(output.getBytes("UTF-8"));
+ }
+ };
+
+ boolean isExceptionHappened = false;
+ try {
+ backupUtils.enableBackup(true);
+ } catch (IOException e) {
+ // enableBackup: Failed to run command: bmgr enable true
+ isExceptionHappened = true;
+ }
+ assertTrue(isExceptionHappened);
+ assertTrue(mIsEnableCommandCalled);
+ }
+
+ @Test
+ public void testEnableBackup_whenQueryCommandReturnsInvalidString_throwsException()
+ throws Exception {
+ BackupUtils backupUtils = new BackupUtils() {
+ @Override
+ protected InputStream executeShellCommand(String command) throws IOException {
+ String output = "";
+ if (command.equals("bmgr enabled")) {
+ output = "Backup Manager ???";
+ } else if (command.equals("bmgr enable true")) {
+ output = "Backup Manager now enabled";
+ mIsEnableCommandCalled = true;
+ }
+ return new ByteArrayInputStream(output.getBytes("UTF-8"));
+ }
+ };
+
+ boolean isExceptionHappened = false;
+ try {
+ backupUtils.enableBackup(true);
+ } catch (RuntimeException e) {
+ // non-parsable output setting bmgr enabled: Backup Manager ???
+ isExceptionHappened = true;
+ }
+ assertTrue(isExceptionHappened);
+ assertFalse(mIsEnableCommandCalled);
+ }
+
+ @Test
+ public void testEnableBackup_whenQueryCommandReturnsEmptyString_throwsException()
+ throws Exception {
+ BackupUtils backupUtils = new BackupUtils() {
+ @Override
+ protected InputStream executeShellCommand(String command) throws IOException {
+ String output = "";
+ if (command.equals("bmgr enabled")) {
+ // output is empty already
+ } else if (command.equals("bmgr enable true")) {
+ output = "Backup Manager now enabled";
+ mIsEnableCommandCalled = true;
+ }
+ return new ByteArrayInputStream(output.getBytes("UTF-8"));
+ }
+ };
+
+ boolean isExceptionHappened = false;
+ try {
+ backupUtils.enableBackup(true);
+ } catch (NullPointerException e) {
+ // null output by running command, bmgr enabled
+ isExceptionHappened = true;
+ }
+ assertTrue(isExceptionHappened);
+ assertFalse(mIsEnableCommandCalled);
+ }
+
+ @Test
+ public void testWaitForBackupInitialization_whenEnabled() throws Exception {
+ BackupUtils backupUtils = new BackupUtils() {
+ @Override
+ protected InputStream executeShellCommand(String command) throws IOException {
+ String output = "";
+ if (command.equals("dumpsys backup")) {
+ output = "Backup Manager is enabled / provisioned / not pending init";
+ mIsDumpsysCommandCalled = true;
+ }
+ return new ByteArrayInputStream(output.getBytes("UTF-8"));
+ }
+ };
+ backupUtils.waitForBackupInitialization();
+ assertTrue(mIsDumpsysCommandCalled);
+ }
+
+ @Test
+ public void testWaitForBackupInitialization_whenDisabled() throws Exception {
+ BackupUtils backupUtils = new BackupUtils() {
+ @Override
+ protected InputStream executeShellCommand(String command) throws IOException {
+ String output = "";
+ if (command.equals("dumpsys backup")) {
+ output = "Backup Manager is disabled / provisioned / not pending init";
+ mIsDumpsysCommandCalled = true;
+ }
+ return new ByteArrayInputStream(output.getBytes("UTF-8"));
+ }
+ };
+ backupUtils.waitForBackupInitialization();
+ assertTrue(mIsDumpsysCommandCalled);
+ }
+
+ @Test
+ public void testWaitUntilBackupServiceIsRunning_whenRunning_doesntThrow() throws Exception {
+ BackupUtils backupUtils = constructDumpsysForBackupUsers(TEST_USER_ID);
+
+ try {
+ backupUtils.waitUntilBackupServiceIsRunning(
+ TEST_USER_ID, BACKUP_SERVICE_INIT_TIMEOUT_SECS);
+ } catch (AssertionError e) {
+ fail("BackupUtils#waitUntilBackupServiceIsRunning threw an exception");
+ }
+ assertTrue(mIsDumpsysCommandCalled);
+ }
+
+ @Test
+ public void testWaitUntilBackupServiceIsRunning_whenNotRunning_throws() throws Exception {
+ // Pass in a different userId to not have the current one among running ids.
+ BackupUtils backupUtils = constructDumpsysForBackupUsers(TEST_USER_ID + 1);
+
+ boolean wasExceptionThrown = false;
+ try {
+ backupUtils.waitUntilBackupServiceIsRunning(
+ TEST_USER_ID, BACKUP_SERVICE_INIT_TIMEOUT_SECS);
+ } catch (AssertionError e) {
+ wasExceptionThrown = true;
+ }
+
+ assertTrue(mIsDumpsysCommandCalled);
+ assertTrue(wasExceptionThrown);
+ }
+
+ private BackupUtils constructDumpsysForBackupUsers(int runningUserId) {
+ return new BackupUtils() {
+ @Override
+ protected InputStream executeShellCommand(String command) throws IOException {
+ String output = "";
+ if (command.equals("dumpsys backup users")) {
+ output = "Backup Manager is running for users: " + runningUserId;
+ mIsDumpsysCommandCalled = true;
+ }
+ return new ByteArrayInputStream(output.getBytes("UTF-8"));
+ }
+ };
+ }
+
+ @Test
+ public void testWaitForBackupInitialization_whenEnabledAndCommandReturnsMultipleLines()
+ throws Exception {
+ BackupUtils backupUtils = new BackupUtils() {
+ @Override
+ protected InputStream executeShellCommand(String command) throws IOException {
+ String output = "";
+ if (command.equals("dumpsys backup")) {
+ output = "Backup Manager is enabled / provisioned / not pending init" + "\n...";
+ mIsDumpsysCommandCalled = true;
+ }
+ return new ByteArrayInputStream(output.getBytes("UTF-8"));
+ }
+ };
+ backupUtils.waitForBackupInitialization();
+ assertTrue(mIsDumpsysCommandCalled);
+ }
+
+ @Test
+ public void testWaitForBackupInitialization_whenCommandThrows_propagatesException()
+ throws Exception {
+ BackupUtils backupUtils = new BackupUtils() {
+ @Override
+ protected InputStream executeShellCommand(String command) throws IOException {
+ String output = "";
+ if (command.equals("dumpsys backup")) {
+ mIsDumpsysCommandCalled = true;
+ throw new IOException(String.format(
+ "waitForBackupInitialization: Failed to run command: %s", command));
+ }
+ return new ByteArrayInputStream(output.getBytes("UTF-8"));
+ }
+ };
+
+ boolean isExceptionHappened = false;
+ try {
+ backupUtils.waitForBackupInitialization();
+ } catch (IOException e) {
+ // waitForBackupInitialization: Failed to run command: dumpsys backup
+ isExceptionHappened = true;
+ }
+ assertTrue(isExceptionHappened);
+ assertTrue(mIsDumpsysCommandCalled);
+ }
+
+ @Test
+ public void testWaitForBackupInitialization_whenCommandReturnsInvalidString()
+ throws Exception {
+ class TestRunnable implements Runnable {
+ @Override
+ public void run() {
+ try {
+ BackupUtils backupUtils = new BackupUtils() {
+ @Override
+ protected InputStream executeShellCommand(String command)
+ throws IOException {
+ String output = "";
+ if (command.equals("dumpsys backup")) {
+ output = "Backup Manager ???";
+ mIsDumpsysCommandCalled = true;
+ }
+ return new ByteArrayInputStream(output.getBytes("UTF-8"));
+ }
+ };
+ backupUtils.waitForBackupInitialization();
+ } catch (IOException e) {
+ // ignore
+ }
+ }
+ }
+
+ TestRunnable testRunnable = new TestRunnable();
+ Thread testThread = new Thread(testRunnable);
+
+ try {
+ testThread.start();
+ RunUtil.getDefault().sleep(100);
+ assertTrue(mIsDumpsysCommandCalled);
+ assertTrue(testThread.isAlive());
+ } catch (Exception e) {
+ // ignore
+ } finally {
+ testThread.interrupt();
+ }
+ }
+
+ @Test
+ public void testWaitForBackupInitialization_whenCommandReturnsEmptyString_throwsException()
+ throws Exception {
+ BackupUtils backupUtils = new BackupUtils() {
+ @Override
+ protected InputStream executeShellCommand(String command) throws IOException {
+ String output = "";
+ if (command.equals("dumpsys backup")) {
+ // output is empty already
+ mIsDumpsysCommandCalled = true;
+ }
+ return new ByteArrayInputStream(output.getBytes("UTF-8"));
+ }
+ };
+
+ boolean isExceptionHappened = false;
+ try {
+ backupUtils.waitForBackupInitialization();
+ } catch (NullPointerException e) {
+ // null output by running command, dumpsys backup
+ isExceptionHappened = true;
+ }
+ assertTrue(isExceptionHappened);
+ assertTrue(mIsDumpsysCommandCalled);
+ }
+
+ @Test
+ public void testActivateBackup_whenEnableTrueAndEnabled_returnsTrue() throws Exception {
+ BackupUtils backupUtils =
+ new BackupUtils() {
+ @Override
+ protected InputStream executeShellCommand(String command) throws IOException {
+ String output = "";
+ if (command.equals(getBmgrCommand("activated", TEST_USER_ID))) {
+ output = "Backup Manager currently activated";
+ } else if (command.equals(getBmgrCommand("activate true", TEST_USER_ID))) {
+ output = "Backup Manager now activated";
+ mIsActivateCommandCalled = true;
+ }
+ return new ByteArrayInputStream(output.getBytes("UTF-8"));
+ }
+ };
+ assertTrue(backupUtils.activateBackupForUser(true, TEST_USER_ID));
+ assertTrue(mIsActivateCommandCalled);
+ }
+
+ @Test
+ public void testActivateBackup_whenEnableTrueAndDisabled_returnsFalse() throws Exception {
+ BackupUtils backupUtils =
+ new BackupUtils() {
+ @Override
+ protected InputStream executeShellCommand(String command) throws IOException {
+ String output = "";
+ if (command.equals(getBmgrCommand("activated", TEST_USER_ID))) {
+ output = "Backup Manager currently deactivated";
+ } else if (command.equals(getBmgrCommand("activate true", TEST_USER_ID))) {
+ output = "Backup Manager now activated";
+ mIsActivateCommandCalled = true;
+ }
+ return new ByteArrayInputStream(output.getBytes("UTF-8"));
+ }
+ };
+ assertFalse(backupUtils.activateBackupForUser(true, TEST_USER_ID));
+ assertTrue(mIsActivateCommandCalled);
+ }
+
+ @Test
+ public void testActivateBackup_whenEnableFalseAndEnabled_returnsTrue() throws Exception {
+ BackupUtils backupUtils =
+ new BackupUtils() {
+ @Override
+ protected InputStream executeShellCommand(String command) throws IOException {
+ String output = "";
+ if (command.equals(getBmgrCommand("activated", TEST_USER_ID))) {
+ output = "Backup Manager currently activated";
+ } else if (command.equals(getBmgrCommand("activate false", TEST_USER_ID))) {
+ output = "Backup Manager now deactivated";
+ mIsActivateCommandCalled = true;
+ }
+ return new ByteArrayInputStream(output.getBytes("UTF-8"));
+ }
+ };
+ assertTrue(backupUtils.activateBackupForUser(false, TEST_USER_ID));
+ assertTrue(mIsActivateCommandCalled);
+ }
+
+ @Test
+ public void testActivateBackup_whenEnableFalseAndDisabled_returnsFalse() throws Exception {
+ BackupUtils backupUtils =
+ new BackupUtils() {
+ @Override
+ protected InputStream executeShellCommand(String command) throws IOException {
+ String output = "";
+ if (command.equals(getBmgrCommand("activated", TEST_USER_ID))) {
+ output = "Backup Manager currently deactivated";
+ } else if (command.equals(getBmgrCommand("activate false", TEST_USER_ID))) {
+ output = "Backup Manager now deactivated";
+ mIsActivateCommandCalled = true;
+ }
+ return new ByteArrayInputStream(output.getBytes("UTF-8"));
+ }
+ };
+ assertFalse(backupUtils.activateBackupForUser(false, TEST_USER_ID));
+ assertTrue(mIsActivateCommandCalled);
+ }
+
+ private String getBmgrCommand(String command, int userId) {
+ return "bmgr --user " + userId + " " + command;
+ }
+}
diff --git a/libraries/compatibility-common-util/tests/src/com/android/compatibility/common/util/BusinessLogicTest.java b/libraries/compatibility-common-util/tests/src/com/android/compatibility/common/util/BusinessLogicTest.java
new file mode 100644
index 000000000..fdb21506d
--- /dev/null
+++ b/libraries/compatibility-common-util/tests/src/com/android/compatibility/common/util/BusinessLogicTest.java
@@ -0,0 +1,252 @@
+/*
+ * 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.compatibility.common.util;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import com.android.compatibility.common.util.BusinessLogic.BusinessLogicRule;
+import com.android.compatibility.common.util.BusinessLogic.BusinessLogicRuleAction;
+import com.android.compatibility.common.util.BusinessLogic.BusinessLogicRuleCondition;
+import com.android.tradefed.util.FileUtil;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.util.List;
+
+/**
+ * Unit tests for {@link BusinessLogic}
+ */
+@RunWith(JUnit4.class)
+public class BusinessLogicTest {
+
+ private static final String CORRECT_LOGIC =
+ "{\n" +
+ " \"name\": \"businessLogic/suites/gts\",\n" +
+ " \"businessLogicRulesLists\": [\n" +
+ " {\n" +
+ " \"testName\": \"testCaseName1\",\n" +
+ " \"description\": \"first test\",\n" +
+ " \"businessLogicRules\": [\n" +
+ " {\n" +
+ " \"ruleConditions\": [\n" +
+ " {\n" +
+ " \"methodName\": \"conditionMethodName1\",\n" +
+ " \"methodArgs\": [\n" +
+ " \"arg1\"\n" +
+ " ]\n" +
+ " }\n" +
+ " ],\n" +
+ " \"ruleActions\": [\n" +
+ " {\n" +
+ " \"methodName\": \"actionMethodName1\",\n" +
+ " \"methodArgs\": [\n" +
+ " \"arg1\",\n" +
+ " \"arg2\"\n" +
+ " ]\n" +
+ " }\n" +
+ " ]\n" +
+ " }\n" +
+ " ]\n" +
+ " },\n" +
+ " {\n" +
+ " \"testName\": \"testCaseName2\",\n" +
+ " \"businessLogicRules\": [\n" +
+ " {\n" +
+ " \"ruleConditions\": [\n" +
+ " {\n" +
+ " \"methodName\": \"conditionMethodName1\",\n" +
+ " \"methodArgs\": [\n" +
+ " \"arg1\"\n" +
+ " ]\n" +
+ " }\n" +
+ " ],\n" +
+ " \"ruleActions\": [\n" +
+ " {\n" +
+ " \"methodName\": \"actionMethodName1\",\n" +
+ " \"methodArgs\": [\n" +
+ " \"arg1\",\n" +
+ " \"arg2\"\n" +
+ " ]\n" +
+ " }\n" +
+ " ]\n" +
+ " },\n" +
+ " {\n" +
+ " \"ruleConditions\": [\n" +
+ " {\n" +
+ " \"methodName\": \"conditionMethodName1\",\n" +
+ " \"methodArgs\": [\n" +
+ " \"arg1\"\n" +
+ " ]\n" +
+ " },\n" +
+ " {\n" +
+ " \"methodName\": \"!conditionMethodName2\",\n" + // use negation
+ " \"methodArgs\": [\n" +
+ " \"arg2\"\n" +
+ " ]\n" +
+ " }\n" +
+ " ],\n" +
+ " \"ruleActions\": [\n" +
+ " {\n" +
+ " \"methodName\": \"actionMethodName1\",\n" +
+ " \"methodArgs\": [\n" +
+ " \"arg1\",\n" +
+ " \"arg2\"\n" +
+ " ]\n" +
+ " },\n" +
+ " {\n" +
+ " \"methodName\": \"actionMethodName2\"\n" +
+ " }\n" +
+ " ]\n" +
+ " }\n" +
+ " ]\n" +
+ " },\n" +
+ " {\n" +
+ " \"testName\": \"testCaseName3\"\n" +
+ " }\n" +
+ " ]\n" +
+ "}";
+
+ @Test
+ public void testCorrectLogic() throws Exception {
+ File file = createFileFromStr(CORRECT_LOGIC);
+ try {
+ BusinessLogic bl = BusinessLogicFactory.createFromFile(file);
+ assertEquals("Wrong number of business logic rule lists", 3, bl.mRules.size());
+ String description = bl.mRules.get("testCaseName1").get(0).getDescription();
+ assertEquals("Wrong or missing rule list description", "first test", description);
+ List<BusinessLogicRule> rulesList1 = bl.mRules.get("testCaseName1").get(0).getRules();
+ assertEquals("Wrong number of rules in first rule list", 1, rulesList1.size());
+ BusinessLogicRule rule1 = rulesList1.get(0);
+ List<BusinessLogicRuleCondition> rule1Conditions = rule1.mConditions;
+ assertEquals("Wrong number of conditions", 1, rule1Conditions.size());
+ BusinessLogicRuleCondition rule1Condition = rule1Conditions.get(0);
+ assertEquals("Wrong method name for business logic rule condition",
+ "conditionMethodName1", rule1Condition.mMethodName);
+ assertFalse("Wrong negation value for business logic rule condition",
+ rule1Condition.mNegated);
+ assertEquals("Wrong arg string count for business logic rule condition", 1,
+ rule1Condition.mMethodArgs.size());
+ assertEquals("Wrong arg for business logic rule condition", "arg1",
+ rule1Condition.mMethodArgs.get(0));
+ List<BusinessLogicRuleAction> rule1Actions = rule1.mActions;
+ assertEquals("Wrong number of actions", 1, rule1Actions.size());
+ BusinessLogicRuleAction rule1Action = rule1Actions.get(0);
+ assertEquals("Wrong method name for business logic rule action",
+ "actionMethodName1", rule1Action.mMethodName);
+ assertEquals("Wrong arg string count for business logic rule action", 2,
+ rule1Action.mMethodArgs.size());
+ assertEquals("Wrong arg for business logic rule action", "arg1",
+ rule1Action.mMethodArgs.get(0));
+ assertEquals("Wrong arg for business logic rule action", "arg2",
+ rule1Action.mMethodArgs.get(1));
+
+ List<BusinessLogicRule> rulesList2 = bl.mRules.get("testCaseName2").get(0).getRules();
+ assertEquals("Wrong number of rules in second rule list", 2, rulesList2.size());
+ BusinessLogicRule rule2 = rulesList2.get(0);
+ List<BusinessLogicRuleCondition> rule2Conditions = rule2.mConditions;
+ assertEquals("Wrong number of conditions", 1, rule2Conditions.size());
+ BusinessLogicRuleCondition rule2Condition = rule2Conditions.get(0);
+ assertEquals("Wrong method name for business logic rule condition",
+ "conditionMethodName1", rule2Condition.mMethodName);
+ assertFalse("Wrong negation value for business logic rule condition",
+ rule2Condition.mNegated);
+ assertEquals("Wrong arg string count for business logic rule condition", 1,
+ rule2Condition.mMethodArgs.size());
+ assertEquals("Wrong arg for business logic rule condition", "arg1",
+ rule2Condition.mMethodArgs.get(0));
+ List<BusinessLogicRuleAction> rule2Actions = rule2.mActions;
+ assertEquals("Wrong number of actions", 1, rule2Actions.size());
+ BusinessLogicRuleAction rule2Action = rule2Actions.get(0);
+ assertEquals("Wrong method name for business logic rule action",
+ "actionMethodName1", rule2Action.mMethodName);
+ assertEquals("Wrong arg string count for business logic rule action", 2,
+ rule2Action.mMethodArgs.size());
+ assertEquals("Wrong arg for business logic rule action", "arg1",
+ rule2Action.mMethodArgs.get(0));
+ assertEquals("Wrong arg for business logic rule action", "arg2",
+ rule2Action.mMethodArgs.get(1));
+ BusinessLogicRule rule3 = rulesList2.get(1);
+ List<BusinessLogicRuleCondition> rule3Conditions = rule3.mConditions;
+ assertEquals("Wrong number of conditions", 2, rule3Conditions.size());
+ BusinessLogicRuleCondition rule3Condition1 = rule3Conditions.get(0);
+ assertEquals("Wrong method name for business logic rule condition",
+ "conditionMethodName1", rule3Condition1.mMethodName);
+ assertFalse("Wrong negation value for business logic rule condition",
+ rule3Condition1.mNegated);
+ assertEquals("Wrong arg string count for business logic rule condition", 1,
+ rule3Condition1.mMethodArgs.size());
+ assertEquals("Wrong arg for business logic rule condition", "arg1",
+ rule3Condition1.mMethodArgs.get(0));
+ BusinessLogicRuleCondition rule3Condition2 = rule3Conditions.get(1);
+ assertEquals("Wrong method name for business logic rule condition",
+ "conditionMethodName2", rule3Condition2.mMethodName);
+ assertTrue("Wrong negation value for business logic rule condition",
+ rule3Condition2.mNegated);
+ assertEquals("Wrong arg string count for business logic rule condition", 1,
+ rule3Condition2.mMethodArgs.size());
+ assertEquals("Wrong arg for business logic rule condition", "arg2",
+ rule3Condition2.mMethodArgs.get(0));
+ List<BusinessLogicRuleAction> rule3Actions = rule3.mActions;
+ assertEquals("Wrong number of actions", 2, rule3Actions.size());
+ BusinessLogicRuleAction rule3Action1 = rule3Actions.get(0);
+ assertEquals("Wrong method name for business logic rule action",
+ "actionMethodName1", rule3Action1.mMethodName);
+ assertEquals("Wrong arg string count for business logic rule action", 2,
+ rule3Action1.mMethodArgs.size());
+ assertEquals("Wrong arg for business logic rule action", "arg1",
+ rule3Action1.mMethodArgs.get(0));
+ assertEquals("Wrong arg for business logic rule action", "arg2",
+ rule3Action1.mMethodArgs.get(1));
+ BusinessLogicRuleAction rule3Action2 = rule3Actions.get(1);
+ assertEquals("Wrong method name for business logic rule action",
+ "actionMethodName2", rule3Action2.mMethodName);
+ assertEquals("Wrong arg string count for business logic rule action", 0,
+ rule3Action2.mMethodArgs.size());
+
+ List<BusinessLogicRule> rulesList3 = bl.mRules.get("testCaseName3").get(0).getRules();
+ assertEquals("Wrong number of rules in third rule list", 0, rulesList3.size());
+ } finally {
+ FileUtil.deleteFile(file);
+ }
+ }
+
+ @Test(expected = RuntimeException.class)
+ public void testLogicWithWrongNodeName() throws Exception {
+ File file = createFileFromStr(CORRECT_LOGIC.replace("testName", "testNam3"));
+ try {
+ BusinessLogicFactory.createFromFile(file);
+ } finally {
+ FileUtil.deleteFile(file);
+ }
+ }
+
+ private static File createFileFromStr(String blString) throws IOException {
+ File file = File.createTempFile("test", "bl");
+ FileOutputStream stream = new FileOutputStream(file);
+ stream.write(blString.getBytes());
+ stream.flush();
+ stream.close();
+ return file;
+ }
+}
diff --git a/libraries/compatibility-common-util/tests/src/com/android/compatibility/common/util/CaseResultTest.java b/libraries/compatibility-common-util/tests/src/com/android/compatibility/common/util/CaseResultTest.java
new file mode 100644
index 000000000..c8b74c056
--- /dev/null
+++ b/libraries/compatibility-common-util/tests/src/com/android/compatibility/common/util/CaseResultTest.java
@@ -0,0 +1,120 @@
+/*
+ * 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.compatibility.common.util;
+
+import junit.framework.TestCase;
+
+/**
+ * Unit tests for {@link CaseResult}
+ */
+public class CaseResultTest extends TestCase {
+
+ private static final String CLASS = "android.test.FoorBar";
+ private static final String METHOD_1 = "testBlah1";
+ private static final String METHOD_2 = "testBlah2";
+ private static final String METHOD_3 = "testBlah3";
+ private static final String MESSAGE = "Something small is not alright";
+ private static final String STACK_TRACE = "Something small is not alright\n " +
+ "at four.big.insects.Marley.sing(Marley.java:10)";
+ private CaseResult mResult;
+
+ @Override
+ public void setUp() throws Exception {
+ mResult = new CaseResult(CLASS);
+ }
+
+ @Override
+ public void tearDown() throws Exception {
+ mResult = null;
+ }
+
+ public void testAccessors() throws Exception {
+ assertEquals("Incorrect case name", CLASS, mResult.getName());
+ }
+
+ public void testResultCreation() throws Exception {
+ ITestResult testResult = mResult.getOrCreateResult(METHOD_1);
+ // Should create one
+ assertEquals("Expected one result", 1, mResult.getResults().size());
+ assertTrue("Expected test result", mResult.getResults().contains(testResult));
+ // Should not create another one
+ ITestResult testResult2 = mResult.getOrCreateResult(METHOD_1);
+ assertEquals("Expected the same result", testResult, testResult2);
+ assertEquals("Expected one result", 1, mResult.getResults().size());
+ }
+
+ public void testResultReporting() throws Exception {
+ ITestResult testResult = mResult.getOrCreateResult(METHOD_1);
+ testResult.failed(STACK_TRACE);
+ assertEquals("Expected status to be set", TestStatus.FAIL, testResult.getResultStatus());
+ assertEquals("Expected message to be set", MESSAGE, testResult.getMessage());
+ assertEquals("Expected stack to be set", STACK_TRACE, testResult.getStackTrace());
+ testResult = mResult.getOrCreateResult(METHOD_2);
+ testResult.passed(null);
+ assertEquals("Expected status to be set", TestStatus.PASS, testResult.getResultStatus());
+ assertEquals("Expected two results", 2, mResult.getResults().size());
+ }
+
+ public void testCountResults() throws Exception {
+ mResult.getOrCreateResult(METHOD_1).failed(STACK_TRACE);
+ mResult.getOrCreateResult(METHOD_2).failed(STACK_TRACE);
+ mResult.getOrCreateResult(METHOD_3).passed(null);
+ assertEquals("Expected two failures", 2, mResult.countResults(TestStatus.FAIL));
+ assertEquals("Expected one pass", 1, mResult.countResults(TestStatus.PASS));
+ }
+
+ public void testMergeCase() throws Exception {
+ mResult.getOrCreateResult(METHOD_1).failed(STACK_TRACE);
+ mResult.getOrCreateResult(METHOD_2).passed(null);
+
+ // Same case another test and passing results in method 2
+ CaseResult otherResult = new CaseResult(CLASS);
+ otherResult.getOrCreateResult(METHOD_1).passed(null);
+ otherResult.getOrCreateResult(METHOD_2).passed(null);
+ otherResult.getOrCreateResult(METHOD_3).failed(STACK_TRACE);
+
+ mResult.mergeFrom(otherResult);
+ assertEquals("Expected one result", 3, mResult.getResults().size());
+ assertEquals("Expected one failures", 1, mResult.countResults(TestStatus.FAIL));
+ assertEquals("Expected two pass", 2, mResult.countResults(TestStatus.PASS));
+ }
+
+ public void testMergeCase_passToFail() throws Exception {
+ mResult.getOrCreateResult(METHOD_1).passed(null);
+
+ // Same case another test and passing results in method 2
+ CaseResult otherResult = new CaseResult(CLASS);
+ otherResult.getOrCreateResult(METHOD_1).passed(null);
+ otherResult.getOrCreateResult(METHOD_2).passed(null);
+ otherResult.getOrCreateResult(METHOD_3).failed(STACK_TRACE);
+
+ mResult.mergeFrom(otherResult);
+
+ assertEquals("Expected one result", 3, mResult.getResults().size());
+ assertEquals("Expected one failures", 1, mResult.countResults(TestStatus.FAIL));
+ assertEquals("Expected two pass", 2, mResult.countResults(TestStatus.PASS));
+ }
+
+ public void testMergeCase_mismatchedModuleName() throws Exception {
+
+ CaseResult otherResult = new CaseResult(CLASS + "foo");
+ try {
+ mResult.mergeFrom(otherResult);
+ fail("Expected IlleglArgumentException");
+ } catch (IllegalArgumentException expected) {}
+ }
+}
diff --git a/libraries/compatibility-common-util/tests/src/com/android/compatibility/common/util/CrashUtilsTest.java b/libraries/compatibility-common-util/tests/src/com/android/compatibility/common/util/CrashUtilsTest.java
new file mode 100644
index 000000000..2d80509ca
--- /dev/null
+++ b/libraries/compatibility-common-util/tests/src/com/android/compatibility/common/util/CrashUtilsTest.java
@@ -0,0 +1,219 @@
+/*
+ * 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.compatibility.common.util;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import org.json.JSONArray;
+import org.json.JSONException;
+import org.json.JSONObject;
+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.regex.Pattern;
+
+/** Unit tests for {@link CrashUtils}. */
+@RunWith(JUnit4.class)
+public class CrashUtilsTest {
+
+ private JSONArray mCrashes;
+
+ @Before
+ public void setUp() throws IOException {
+ try (BufferedReader txtReader =
+ new BufferedReader(
+ new InputStreamReader(
+ getClass().getClassLoader().getResourceAsStream("logcat.txt")))) {
+ StringBuffer input = new StringBuffer();
+ String tmp;
+ while ((tmp = txtReader.readLine()) != null) {
+ input.append(tmp + "\n");
+ }
+ mCrashes = CrashUtils.addAllCrashes(input.toString(), new JSONArray());
+ }
+ }
+
+ @Test
+ public void testGetAllCrashes() throws Exception {
+ JSONArray expectedResults = new JSONArray();
+ expectedResults.put(createCrashJson(
+ 11071, 11189, "AudioOut_D", "/system/bin/audioserver", "e9380000", "SIGSEGV", null));
+ expectedResults.put(createCrashJson(
+ 12736, 12761, "Binder:12736_2", "/system/bin/audioserver", "0", "SIGSEGV", null));
+ expectedResults.put(createCrashJson(
+ 26201, 26227, "Binder:26201_3", "/system/bin/audioserver", "0", "SIGSEGV", null));
+ expectedResults.put(createCrashJson(
+ 26246, 26282, "Binder:26246_5", "/system/bin/audioserver", "0", "SIGSEGV", null));
+ expectedResults.put(createCrashJson(
+ 245, 245, "installd", "/system/bin/installd", null, "SIGABRT",
+ "'utils.cpp:67] Check failed: is_valid_package_name(package_name) == 0 '"));
+ expectedResults.put(createCrashJson(
+ 6371, 8072, "media.codec", "omx@1.0-service", "ed000000", "SIGSEGV", null));
+ expectedResults.put(createCrashJson(
+ 8373, 8414, "loo", "com.android.bluetooth", null, "SIGABRT",
+ "'[FATAL:allocation_tracker.cc(143)] Check failed: map_entry != allocations.end()."));
+ expectedResults.put(createCrashJson(
+ 8080, 11665, "generic", "/system/bin/mediaserver", null, "SIGABRT",
+ "'frameworks/av/media/libstagefright/MPEG4Extractor.cpp:6853 CHECK_EQ( (unsigned)ptr[0],1u) failed: 129 vs. 1'"));
+ expectedResults.put(createCrashJson(
+ 11071, 11189, "synthetic_thread", "synthetic_process_0", "e9380000", "SIGSEGV", null));
+ expectedResults.put(createCrashJson(
+ 12736, 12761, "synthetic_thread", "synthetic_process_1", "0", "SIGSEGV", null));
+
+ Assert.assertEquals(expectedResults.toString() + "\n" + mCrashes.toString() + "\n", expectedResults.toString(), mCrashes.toString());
+ }
+
+ public JSONObject createCrashJson(
+ int pid,
+ int tid,
+ String name,
+ String process,
+ String faultaddress,
+ String signal,
+ String abortMessage) {
+ JSONObject json = new JSONObject();
+ try {
+ json.put(CrashUtils.PID, pid);
+ json.put(CrashUtils.TID, tid);
+ json.put(CrashUtils.NAME, name);
+ json.put(CrashUtils.PROCESS, process);
+ json.put(CrashUtils.FAULT_ADDRESS, faultaddress);
+ json.put(CrashUtils.SIGNAL, signal);
+ json.put(CrashUtils.ABORT_MESSAGE, abortMessage);
+ } catch (JSONException e) {}
+ return json;
+ }
+
+ @Test
+ public void testValidCrash() throws Exception {
+ Assert.assertTrue(CrashUtils.securityCrashDetected(mCrashes, new CrashUtils.Config()
+ .checkMinAddress(true)
+ .setProcessPatterns(Pattern.compile("synthetic_process_0"))));
+ }
+
+ @Test
+ public void testMissingName() throws Exception {
+ Assert.assertFalse(CrashUtils.securityCrashDetected(mCrashes, new CrashUtils.Config()
+ .checkMinAddress(true)
+ .setProcessPatterns(Pattern.compile(""))));
+ }
+
+ @Test
+ public void testSIGABRT() throws Exception {
+ Assert.assertFalse(CrashUtils.securityCrashDetected(mCrashes, new CrashUtils.Config()
+ .checkMinAddress(true)
+ .setProcessPatterns(Pattern.compile("installd"))));
+ }
+
+ @Test
+ public void testFaultAddressBelowMin() throws Exception {
+ Assert.assertFalse(CrashUtils.securityCrashDetected(mCrashes, new CrashUtils.Config()
+ .checkMinAddress(true)
+ .setProcessPatterns(Pattern.compile("synthetic_process_1"))));
+ }
+
+ @Test
+ public void testIgnoreMinAddressCheck() throws Exception {
+ Assert.assertTrue(CrashUtils.securityCrashDetected(mCrashes, new CrashUtils.Config()
+ .checkMinAddress(false)
+ .setProcessPatterns(Pattern.compile("synthetic_process_1"))));
+ }
+
+ @Test
+ public void testBadAbortMessage() throws Exception {
+ Assert.assertFalse(CrashUtils.securityCrashDetected(mCrashes, new CrashUtils.Config()
+ .checkMinAddress(true)
+ .setProcessPatterns(Pattern.compile("generic"))));
+ }
+
+ @Test
+ public void testGoodAndBadCrashes() throws Exception {
+ Assert.assertTrue(CrashUtils.securityCrashDetected(mCrashes, new CrashUtils.Config()
+ .checkMinAddress(true)
+ .setProcessPatterns(
+ Pattern.compile("synthetic_process_0"),
+ Pattern.compile("generic"))));
+ }
+
+ @Test
+ public void testNullFaultAddress() throws Exception {
+ JSONArray crashes = new JSONArray();
+ crashes.put(createCrashJson(8373, 8414, "loo", "com.android.bluetooth", null, "SIGSEGV", ""));
+ Assert.assertTrue(CrashUtils.securityCrashDetected(crashes, new CrashUtils.Config()
+ .checkMinAddress(true)
+ .setProcessPatterns(Pattern.compile("com\\.android\\.bluetooth"))));
+ }
+
+ @Test
+ public void testAbortMessageInclude() throws Exception {
+ JSONArray crashes = new JSONArray();
+ crashes.put(createCrashJson(8373, 8414, "loo", "com.android.bluetooth", null, "SIGABRT",
+ "'[FATAL:allocation_tracker.cc(143)] Check failed: map_entry != allocations.end()."));
+ Assert.assertTrue(CrashUtils.securityCrashDetected(crashes, new CrashUtils.Config()
+ .appendSignals(CrashUtils.SIGABRT)
+ .appendAbortMessageIncludes("Check failed:")
+ .setProcessPatterns(Pattern.compile("com\\.android\\.bluetooth"))));
+
+ Assert.assertFalse(CrashUtils.securityCrashDetected(crashes, new CrashUtils.Config()
+ .appendSignals(CrashUtils.SIGABRT)
+ .appendAbortMessageIncludes("include not matches")
+ .setProcessPatterns(Pattern.compile("com\\.android\\.bluetooth"))));
+ }
+
+ @Test
+ public void testAbortMessageExclude() throws Exception {
+ JSONArray crashes = new JSONArray();
+ crashes.put(createCrashJson(8373, 8414, "loo", "com.android.bluetooth", null, "SIGABRT",
+ "'[FATAL:allocation_tracker.cc(143)] Check failed: map_entry != allocations.end()."));
+ Assert.assertFalse(CrashUtils.securityCrashDetected(crashes, new CrashUtils.Config()
+ .appendSignals(CrashUtils.SIGABRT)
+ .appendAbortMessageExcludes("Check failed:")
+ .setProcessPatterns(Pattern.compile("com\\.android\\.bluetooth"))));
+
+ Assert.assertTrue(CrashUtils.securityCrashDetected(crashes, new CrashUtils.Config()
+ .appendSignals(CrashUtils.SIGABRT)
+ .appendAbortMessageExcludes("exclude not matches")
+ .setProcessPatterns(Pattern.compile("com\\.android\\.bluetooth"))));
+ }
+
+ @Test
+ public void testAbortMessageExcludeCannotLink() throws Exception {
+ JSONArray crashes = new JSONArray();
+ crashes.put(createCrashJson(
+ 18959, 18959, "CVE-2020-0073", "/data/local/tmp/CVE-2020-0073", null, "SIGABRT",
+ "'CANNOT LINK EXECUTABLE \"/data/local/tmp/CVE-2020-0073\": library "
+ + "\"libnfc-nci.so\" (\"(default)\", \"/data/local/tmp/CVE-2020-0073\", \"\") "
+ + "not found'"));
+ Assert.assertFalse(CrashUtils.securityCrashDetected(crashes, new CrashUtils.Config()
+ .appendSignals(CrashUtils.SIGABRT)
+ .setProcessPatterns(Pattern.compile("CVE-2020-0073"))));
+
+ crashes.put(createCrashJson(
+ 5105, 5105, "CVE-2015-6616-2", "/data/local/tmp/CVE-2015-6616-2", null, "SIGABRT",
+ "'CANNOT LINK EXECUTABLE \"/data/local/tmp/CVE-2015-6616-2\": "
+ + "cannot locate symbol \""
+ + "_ZN7android14MediaExtractor17CreateFromServiceERKNS_2spINS_10DataSourceEEEPKc"
+ + "\" referenced by \"/data/local/tmp/CVE-2015-6616-2\"...'"));
+ Assert.assertFalse(CrashUtils.securityCrashDetected(crashes, new CrashUtils.Config()
+ .appendSignals(CrashUtils.SIGABRT)
+ .setProcessPatterns(Pattern.compile("CVE-2015-6616-2"))));
+
+ }
+}
diff --git a/libraries/compatibility-common-util/tests/src/com/android/compatibility/common/util/DynamicConfigTest.java b/libraries/compatibility-common-util/tests/src/com/android/compatibility/common/util/DynamicConfigTest.java
new file mode 100644
index 000000000..954c1ce26
--- /dev/null
+++ b/libraries/compatibility-common-util/tests/src/com/android/compatibility/common/util/DynamicConfigTest.java
@@ -0,0 +1,125 @@
+/*
+ * 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.compatibility.common.util;
+
+import com.android.tradefed.util.FileUtil;
+
+import junit.framework.TestCase;
+
+import org.xmlpull.v1.XmlPullParserException;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+
+/**
+ * Unit tests for {@link DynamicConfig}
+ */
+public class DynamicConfigTest extends TestCase {
+ private static final String CORRECT_CONFIG =
+ "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" +
+ "<dynamicConfig>\n" +
+ " <entry key=\"remote_config_required\">\n" +
+ " <value>false</value>\n" +
+ " </entry>\n" +
+ " <entry key=\"test-config-1\">\n" +
+ " <value>test config 1</value>\n" +
+ " </entry>\n" +
+ " <entry key=\"test-config-2\">\n" +
+ " <value>testconfig2</value>\n" +
+ " </entry>\n" +
+ " <entry key=\"config-list\">\n" +
+ " <value>config0</value>\n" +
+ " <value>config1</value>\n" +
+ " <value>config2</value>\n" +
+ " <value>config3</value>\n" +
+ " <value>config4</value>\n" +
+ " </entry>\n" +
+ " <entry key=\"config-list-2\">\n" +
+ " <value>A</value>\n" +
+ " <value>B</value>\n" +
+ " <value>C</value>\n" +
+ " <value>D</value>\n" +
+ " <value>E</value>\n" +
+ " </entry>\n" +
+ "</dynamicConfig>\n";
+
+ private static final String CONFIG_WRONG_NODE_NAME =
+ "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" +
+ "<dynamicCsonfig>\n" + //The node name dynamicConfig is intentionally mistyped
+ " <entry key=\"remote_config_required\">\n" +
+ " <value>false</value>\n" +
+ " </entry>\n" +
+ " <entry key=\"test-config-1\">\n" +
+ " <value>test config 1</value>\n" +
+ " </entry>\n" +
+ " <entry key=\"test-config-2\">\n" +
+ " <value>testconfig2</value>\n" +
+ " </entry>\n" +
+ " <entry key=\"config-list\">\n" +
+ " <value>Nevermore</value>\n" +
+ " <value>Puck</value>\n" +
+ " <value>Zeus</value>\n" +
+ " <value>Earth Shaker</value>\n" +
+ " <value>Vengeful Spirit</value>\n" +
+ " </entry>\n" +
+ " <entry key=\"config-list-2\">\n" +
+ " <value>A</value>\n" +
+ " <value>B</value>\n" +
+ " <value>C</value>\n" +
+ " <value>D</value>\n" +
+ " <value>E</value>\n" +
+ " </entry>\n" +
+ "</dynamicConfig>\n";
+
+ public void testCorrectConfig() throws Exception {
+ DynamicConfig config = new DynamicConfig();
+ File file = createFileFromStr(CORRECT_CONFIG);
+ try {
+ config.initializeConfig(file);
+ assertEquals("Wrong Config", config.getValue("test-config-1"), "test config 1");
+ assertEquals("Wrong Config", config.getValue("test-config-2"), "testconfig2");
+ assertEquals("Wrong Config List", config.getValues("config-list").get(0), "config0");
+ assertEquals("Wrong Config List", config.getValues("config-list").get(2), "config2");
+ assertEquals("Wrong Config List", config.getValues("config-list-2").get(2), "C");
+ } finally {
+ FileUtil.deleteFile(file);
+ }
+ }
+
+ public void testConfigWithWrongNodeName() throws Exception {
+ DynamicConfig config = new DynamicConfig();
+ File file = createFileFromStr(CONFIG_WRONG_NODE_NAME);
+ try {
+ config.initializeConfig(file);
+ fail("Cannot detect error when config file has wrong node name");
+ } catch (XmlPullParserException e) {
+ //expected
+ } finally {
+ FileUtil.deleteFile(file);
+ }
+ }
+
+ private File createFileFromStr(String configStr) throws IOException {
+ File file = File.createTempFile("test", "dynamic");
+ FileOutputStream stream = new FileOutputStream(file);
+ stream.write(configStr.getBytes());
+ stream.flush();
+ stream.close();
+ return file;
+ }
+}
diff --git a/libraries/compatibility-common-util/tests/src/com/android/compatibility/common/util/LightInvocationResultTest.java b/libraries/compatibility-common-util/tests/src/com/android/compatibility/common/util/LightInvocationResultTest.java
new file mode 100644
index 000000000..8a872773a
--- /dev/null
+++ b/libraries/compatibility-common-util/tests/src/com/android/compatibility/common/util/LightInvocationResultTest.java
@@ -0,0 +1,50 @@
+/*
+ * 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.compatibility.common.util;
+
+import com.android.tradefed.util.FileUtil;
+
+import junit.framework.TestCase;
+
+import java.io.File;
+
+/**
+ * Unit tests for {@link LightInvocationResult}
+ */
+public class LightInvocationResultTest extends TestCase {
+
+ private File resultsDir;
+
+ @Override
+ public void setUp() throws Exception {
+ resultsDir = FileUtil.createTempDir("results");
+ }
+
+ @Override
+ public void tearDown() throws Exception {
+ FileUtil.recursiveDelete(resultsDir);
+ }
+
+ public void testLightInvocationResultInstatiate() throws Exception {
+ File resultDir = ResultHandlerTest.writeResultDir(resultsDir, false);
+ IInvocationResult fullResult = ResultHandler.getResultFromDir(resultDir);
+ LightInvocationResult lightResult = new LightInvocationResult(fullResult);
+ // Ensure that light result implementation does not use a reference to the full result
+ fullResult = null;
+ ResultHandlerTest.checkLightResult(lightResult);
+ }
+}
diff --git a/libraries/compatibility-common-util/tests/src/com/android/compatibility/common/util/MetricsXmlSerializerTest.java b/libraries/compatibility-common-util/tests/src/com/android/compatibility/common/util/MetricsXmlSerializerTest.java
new file mode 100644
index 000000000..dbbb47999
--- /dev/null
+++ b/libraries/compatibility-common-util/tests/src/com/android/compatibility/common/util/MetricsXmlSerializerTest.java
@@ -0,0 +1,81 @@
+/*
+ * 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.compatibility.common.util;
+
+import junit.framework.TestCase;
+
+import org.xmlpull.v1.XmlPullParserFactory;
+import org.xmlpull.v1.XmlSerializer;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+
+//TODO(stuartscott): Delete file for v2, ReportLog can serialize itself.
+/**
+ * Unit tests for {@link MetricsXmlSerializer}
+ */
+public class MetricsXmlSerializerTest extends TestCase {
+
+ static class LocalReportLog extends ReportLog {}
+ private static final double[] VALUES = new double[] {1, 11, 21, 1211, 111221};
+ private static final String HEADER = "<?xml version='1.0' encoding='utf-8' standalone='yes' ?>";
+ private static final String EXPECTED_XML = HEADER
+ + "<Summary message=\"Sample\" scoreType=\"higher_better\" unit=\"byte\">1.0</Summary>";
+
+ private LocalReportLog mLocalReportLog;
+ private MetricsXmlSerializer mMetricsXmlSerializer;
+ private ByteArrayOutputStream mByteArrayOutputStream;
+ private XmlSerializer xmlSerializer;
+
+ @Override
+ public void setUp() throws Exception {
+ mLocalReportLog = new LocalReportLog();
+ mByteArrayOutputStream = new ByteArrayOutputStream();
+ XmlPullParserFactory factory = XmlPullParserFactory.newInstance(null, null);
+ xmlSerializer = factory.newSerializer();
+ xmlSerializer.setOutput(mByteArrayOutputStream, "utf-8");
+
+ this.mMetricsXmlSerializer = new MetricsXmlSerializer(xmlSerializer);
+ }
+
+ public void testSerialize_null() throws IOException {
+ xmlSerializer.startDocument("utf-8", true);
+ mMetricsXmlSerializer.serialize(null);
+ xmlSerializer.endDocument();
+
+ assertEquals(HEADER.length(), mByteArrayOutputStream.toByteArray().length);
+ }
+
+ public void testSerialize_noData() throws IOException {
+ xmlSerializer.startDocument("utf-8", true);
+ mMetricsXmlSerializer.serialize(mLocalReportLog);
+ xmlSerializer.endDocument();
+
+ assertEquals(HEADER.length(), mByteArrayOutputStream.toByteArray().length);
+ }
+
+ public void testSerialize() throws IOException {
+ mLocalReportLog.setSummary("Sample", 1.0, ResultType.HIGHER_BETTER, ResultUnit.BYTE);
+ mLocalReportLog.addValues("Details", VALUES, ResultType.NEUTRAL, ResultUnit.FPS);
+
+ xmlSerializer.startDocument("utf-8", true);
+ mMetricsXmlSerializer.serialize(mLocalReportLog);
+ xmlSerializer.endDocument();
+
+ assertEquals(EXPECTED_XML, mByteArrayOutputStream.toString("utf-8"));
+ }
+} \ No newline at end of file
diff --git a/libraries/compatibility-common-util/tests/src/com/android/compatibility/common/util/MultipartFormTest.java b/libraries/compatibility-common-util/tests/src/com/android/compatibility/common/util/MultipartFormTest.java
new file mode 100644
index 000000000..dd96308ea
--- /dev/null
+++ b/libraries/compatibility-common-util/tests/src/com/android/compatibility/common/util/MultipartFormTest.java
@@ -0,0 +1,58 @@
+/*
+ * 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.compatibility.common.util;
+
+import junit.framework.TestCase;
+
+import java.util.Arrays;
+
+/**
+ * Unit tests for {@link MultipartForm}
+ */
+public class MultipartFormTest extends TestCase {
+
+ private static final String SERVER_URL = "http://127.0.0.1:5555";
+ private static final byte[] ZIP_ARRAY = {
+ 0xa, 0x2d, 0x2d, 0x43, 0x37, 0x35, 0x49, 0x35, 0x35, 0x75, 0x33, 0x52, 0x33, 0x70, 0x30,
+ 0x72, 0x37, 0x33, 0x72, 0xa, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x44, 0x69,
+ 0x73, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x66, 0x6f, 0x72,
+ 0x6d, 0x2d, 0x64, 0x61, 0x74, 0x61, 0x3b, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x22,
+ 0x66, 0x6f, 0x6f, 0x22, 0xa, 0xa, 0x62, 0x61, 0x72, 0xa, 0x2d, 0x2d, 0x43, 0x37, 0x35,
+ 0x49, 0x35, 0x35, 0x75, 0x33, 0x52, 0x33, 0x70, 0x30, 0x72, 0x37, 0x33, 0x72, 0xa, 0x43,
+ 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x44, 0x69, 0x73, 0x70, 0x6f, 0x73, 0x69,
+ 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x66, 0x6f, 0x72, 0x6d, 0x2d, 0x64, 0x61, 0x74,
+ 0x61, 0x3b, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x22, 0x62, 0x6c, 0x61, 0x68, 0x22,
+ 0x3b, 0x20, 0x66, 0x69, 0x6c, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x22, 0x62, 0x6c,
+ 0x61, 0x68, 0x2e, 0x78, 0x6d, 0x6c, 0x2e, 0x67, 0x7a, 0x22, 0xa, 0x43, 0x6f, 0x6e, 0x74,
+ 0x65, 0x6e, 0x74, 0x2d, 0x54, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x61, 0x70, 0x70, 0x6c,
+ 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x78, 0x2d, 0x67, 0x7a, 0x69, 0x70, 0xa,
+ 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x66,
+ 0x65, 0x72, 0x2d, 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x69, 0x6e, 0x67, 0x3a, 0x20, 0x62,
+ 0x69, 0x6e, 0x61, 0x72, 0x79, 0xa, 0xa, 0x62, 0x6c, 0x61, 0x68, 0xa, 0x2d, 0x2d, 0x43,
+ 0x37, 0x35, 0x49, 0x35, 0x35, 0x75, 0x33, 0x52, 0x33, 0x70, 0x30, 0x72, 0x37, 0x33,
+ 0x72, 0x2d, 0x2d, 0xa,
+ };
+
+ public void testContentBody() throws Exception {
+ MultipartForm form = new MultipartForm(SERVER_URL);
+ form.addFormValue("foo", "bar");
+ form.addFormFile("blah", "blah.xml.gz", "blah".getBytes());
+ byte[] data = form.getContentBody();
+ assertTrue("No data", data.length > 0);
+ assertTrue("Wrong data", Arrays.equals(ZIP_ARRAY, data));
+ }
+}
diff --git a/libraries/compatibility-common-util/tests/src/com/android/compatibility/common/util/ReadElfTest.java b/libraries/compatibility-common-util/tests/src/com/android/compatibility/common/util/ReadElfTest.java
new file mode 100644
index 000000000..cd2e6817e
--- /dev/null
+++ b/libraries/compatibility-common-util/tests/src/com/android/compatibility/common/util/ReadElfTest.java
@@ -0,0 +1,302 @@
+/*
+ * 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.compatibility.common.util;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.FileReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.ArrayList;
+import java.util.List;
+
+import static org.junit.Assert.*;
+
+/**
+ * Tests if {@link ReadElf} parses Executable and Linkable Format files properly.
+ *
+ * <p>These tests validate content, parsed by {@link ReadElf} is the same with the golden sample
+ * files. The golden sample files are the outputs from Linux cmd: readelf -a elf-file
+ *
+ * <p>
+ */
+@RunWith(JUnit4.class)
+public class ReadElfTest {
+ private static final String THIS_CLASS = "com.android.compatibility.common.util.ReadElfTest";
+ private static final String TEST_SO_ARM32B = "arm32_libdl.so";
+ private static final String TEST_SO_ARM32B_READELF = "arm32_libdl.txt";
+ private static final String TEST_SO_ARM64B = "arm64_libdl.so";
+ private static final String TEST_SO_ARM64B_READELF = "arm64_libdl.txt";
+ private static final String TEST_EXE_X8664B = "x86app_process64";
+ private static final String TEST_EXE_X8664B_READELF = "x86app_process64.txt";
+ private static final String TEST_EXE_X8632B = "x86app_process32";
+ private static final String TEST_EXE_X8632B_READELF = "x86app_process32.txt";
+
+ /**
+ * Test {@link ReadElf} for an ARM 32-bit Shared Object
+ *
+ * @throws Exception
+ */
+ @Test
+ public void testReadElfArm32b() throws Exception {
+ checkReadElf(TEST_SO_ARM32B, TEST_SO_ARM32B_READELF, ReadElf.ARCH_ARM, 32, ReadElf.ET_DYN);
+ }
+
+ /**
+ * Test {@link ReadElf} for an ARM 64-bit Shared Object
+ *
+ * @throws Exception
+ */
+ @Test
+ public void testReadElfArm64b() throws Exception {
+ checkReadElf(TEST_SO_ARM64B, TEST_SO_ARM64B_READELF, ReadElf.ARCH_ARM, 64, ReadElf.ET_DYN);
+ }
+
+ /**
+ * Test {@link ReadElf} for an x86 32-bit Executable
+ *
+ * @throws Exception
+ */
+ @Test
+ public void testReadElfX8632b() throws Exception {
+ checkReadElf(
+ TEST_EXE_X8632B, TEST_EXE_X8632B_READELF, ReadElf.ARCH_X86, 32, ReadElf.ET_DYN);
+ }
+
+ /**
+ * Test {@link ReadElf} for an x86 64-bit Executable
+ *
+ * @throws Exception
+ */
+ @Test
+ public void testReadElfX8664b() throws Exception {
+ checkReadElf(
+ TEST_EXE_X8664B, TEST_EXE_X8664B_READELF, ReadElf.ARCH_X86, 64, ReadElf.ET_DYN);
+ }
+
+ /**
+ * Compares {@link ReadElf} returns same results with Linux readelf cmd on the same ELF file
+ *
+ * @param elfFileName the name of an ELF file in Resource to be checked
+ * @param elfOutputFileName the name of the golden sample file in Resource
+ * @param bits the expected bits of the ELF file
+ * @param arch the expected Instruction Set Architecture of the ELF file
+ * @param type the expected object file type of the ELF file
+ */
+ private void checkReadElf(
+ String elfFileName, String elfOutputFileName, String arch, int bits, int type)
+ throws Exception {
+ File targetFile = getResrouceFile(elfFileName);
+ assertEquals("ReadElf.isElf() " + elfFileName, true, ReadElf.isElf(targetFile));
+ ReadElf elf = ReadElf.read(targetFile);
+ assertEquals("getBits() ", bits, elf.getBits());
+ assertEquals("getArchitecture() ", arch, elf.getArchitecture());
+ assertEquals("isDynamic() ", true, elf.isDynamic());
+ assertEquals("getType() ", type, elf.getType());
+
+ File elfOutputFile = getResrouceFile(elfOutputFileName);
+ assertEquals("ReadElf.isElf() " + elfOutputFileName, false, ReadElf.isElf(elfOutputFile));
+
+ final ReadElf.Symbol[] dynSymbolArr = elf.getDynSymArr();
+ chkDynSymbol(elfOutputFile, dynSymbolArr);
+
+ assertEquals(
+ "ReadElf.getDynamicDependencies() " + elfFileName,
+ getDynamicDependencies(elfOutputFile),
+ elf.getDynamicDependencies());
+
+ assertEquals(
+ "ReadElf.getRoStrings() " + elfFileName,
+ getRoStrings(elfOutputFile),
+ elf.getRoStrings());
+ }
+
+ /**
+ * Gets a list of needed libraries from a Linux readelf cmd output file
+ *
+ * @param elfOutputFileName a {@link File} object of an golden sample file
+ * @return a name list of needed libraries
+ */
+ private List<String> getDynamicDependencies(File elfOutputFile) throws IOException {
+ List<String> result = new ArrayList<>();
+
+ FileReader fileReader = new FileReader(elfOutputFile);
+ BufferedReader buffReader = new BufferedReader(fileReader);
+
+ String line;
+ boolean keepGoing = true;
+ while ((line = buffReader.readLine()) != null && keepGoing) {
+ // readelf output as: Dynamic section at offset 0xfdf0 contains 17 entries:
+ if (line.startsWith("Dynamic section")) {
+ String dsLine;
+ while ((dsLine = buffReader.readLine()) != null) {
+ String trimLine = dsLine.trim();
+ if (trimLine.isEmpty()) {
+ // End of the block
+ keepGoing = false;
+ break;
+ }
+
+ // 0x0000000000000001 (NEEDED) Shared library: [ld-android.so]
+ if (trimLine.contains("1 (NEEDED)")) {
+ result.add(
+ trimLine.substring(
+ trimLine.indexOf("[") + 1, trimLine.indexOf("]")));
+ }
+ }
+ }
+ }
+ fileReader.close();
+ return result;
+ }
+
+ /**
+ * Checks if all Dynamic Symbols in a golden sample file are in the symbol array
+ *
+ * @param targetFile a {@link File} object of an golden sample file
+ * @param dynSymbolArr a Dynamic Symbol array to be validated
+ */
+ private void chkDynSymbol(File targetFile, ReadElf.Symbol[] dynSymbolArr) throws IOException {
+ FileReader fileReader = new FileReader(targetFile);
+ BufferedReader buffReader = new BufferedReader(fileReader);
+
+ String line;
+ boolean keepGoing = true;
+ while ((line = buffReader.readLine()) != null && keepGoing) {
+ // readelf output as: Symbol table '.dynsym' contains 44 entries:
+ if (line.startsWith("Symbol table '.dynsym'")) {
+ // Skip the header: Num: Value Size Type Bind Vis Ndx Name
+ buffReader.readLine();
+ // Skip the 1st line: 0: 00000000 0 NOTYPE LOCAL DEFAULT UND
+ buffReader.readLine();
+
+ int i = 1;
+
+ String dsLine;
+ while ((dsLine = buffReader.readLine()) != null) {
+ // readelf output as:
+ // 20: 0000000000000ff8 24 FUNC WEAK DEFAULT 9
+ // android_init_anonymous_na@@LIBC_PLATFORM
+ String trimLine = dsLine.trim();
+ if (trimLine.isEmpty()) {
+ // End of the block
+ keepGoing = false;
+ break;
+ }
+
+ // Removes tailing (x) for an executable
+ // 1: 00000000 0 FUNC GLOBAL DEFAULT UND __cxa_atexit@LIBC (2)
+ int idx = trimLine.indexOf("(");
+ if (idx > 0) {
+ trimLine = trimLine.substring(0, idx);
+ }
+
+ String phases[] = trimLine.split("\\s+");
+ String symName = dynSymbolArr[i].name;
+ String name = phases[phases.length - 1].split("@")[0];
+ // readelf may truncate a long name
+ assertTrue(
+ String.format("chkDynSymbol name %d: %s vs %s", i, symName, name),
+ symName.startsWith(name));
+ assertEquals("chkDynSymbol type :", dynSymbolArr[i].toType(), phases[3]);
+ assertEquals("chkDynSymbol bind :", dynSymbolArr[i].toBind(), phases[4]);
+ assertEquals("chkDynSymbol ndx :", dynSymbolArr[i].toShndx(), phases[6]);
+ i++;
+ }
+ }
+ }
+ fileReader.close();
+ }
+
+ /**
+ * Gets a list of Read Only Strings from a Linux readelf -p .rodata cmd output file
+ *
+ * @param elfOutputFileName a {@link File} object of an golden sample file
+ * @return a list of RO Strings
+ */
+ private List<String> getRoStrings(File elfOutputFile) throws IOException {
+ List<String> result = new ArrayList<>();
+
+ FileReader fileReader = new FileReader(elfOutputFile);
+ BufferedReader buffReader = new BufferedReader(fileReader);
+
+ String line;
+ boolean keepGoing = true;
+ while ((line = buffReader.readLine()) != null && keepGoing) {
+ // readelf output as: String dump of section '.rodata':
+ if (line.startsWith("String dump of section '.rodata':")) {
+ String dsLine;
+ while ((dsLine = buffReader.readLine()) != null) {
+ String trimLine = dsLine.trim();
+ if (trimLine.isEmpty()) {
+ // End of the block
+ keepGoing = false;
+ break;
+ }
+
+ // [ 108] Error: no class name or --zygote supplied.^J
+ if (trimLine.contains("[")) {
+ result.add(
+ trimLine.substring(trimLine.indexOf("]") + 1, trimLine.length())
+ .trim()
+ .replace("^J", "\n"));
+ }
+ }
+ }
+ }
+ fileReader.close();
+ return result;
+ }
+
+ /**
+ * Reads a file from Resource and write to a tmp file
+ *
+ * @param fileName the name of a file in Resource
+ * @return the File object of a tmp file
+ */
+ private File getResrouceFile(String fileName) throws IOException {
+ File tempFile = File.createTempFile(fileName, "tmp");
+ tempFile.deleteOnExit();
+ try (InputStream input = openResourceAsStream(fileName);
+ OutputStream output = new FileOutputStream(tempFile)) {
+ byte[] buffer = new byte[4096];
+ int length;
+ while ((length = input.read(buffer)) > 0) {
+ output.write(buffer, 0, length);
+ }
+ }
+ return tempFile;
+ }
+
+ /**
+ * Gets an InputStrem of a file from Resource
+ *
+ * @param fileName the name of a file in Resrouce
+ * @return the (@link InputStream} object of the file
+ */
+ private InputStream openResourceAsStream(String fileName) {
+ InputStream input = getClass().getResourceAsStream("/" + fileName);
+ assertNotNull(input);
+ return input;
+ }
+} \ No newline at end of file
diff --git a/libraries/compatibility-common-util/tests/src/com/android/compatibility/common/util/ReportLogTest.java b/libraries/compatibility-common-util/tests/src/com/android/compatibility/common/util/ReportLogTest.java
new file mode 100644
index 000000000..0da5f2d0d
--- /dev/null
+++ b/libraries/compatibility-common-util/tests/src/com/android/compatibility/common/util/ReportLogTest.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.compatibility.common.util;
+
+import com.android.compatibility.common.util.ReportLog.Metric;
+
+import junit.framework.TestCase;
+
+import java.util.Arrays;
+
+/**
+ * Unit tests for {@link ReportLog}
+ */
+public class ReportLogTest extends TestCase {
+
+ private static final String SOURCE = "Source";
+ private static final String MESSAGE = "Message";
+ private static final double[] VALUES = new double[] {.1, 124, 4736, 835.683, 98, 395};
+ private static final String HEADER_XML =
+ "<?xml version='1.0' encoding='UTF-8' standalone='yes' ?>";
+ private static final String SUMMARY_XML =
+ HEADER_XML + "\r\n" +
+ "<Summary>\r\n" +
+ " <Metric source=\"com.android.compatibility.common.util.ReportLogTest#%s\" "
+ + "message=\"Sample\" score_type=\"higher_better\" score_unit=\"byte\">\r\n" +
+ " <Value>1.0</Value>\r\n" +
+ " </Metric>\r\n" +
+ "</Summary>";
+ private static final String FULL_XML = SUMMARY_XML;
+
+ private ReportLog mReportLog;
+
+ @Override
+ protected void setUp() throws Exception {
+ mReportLog = new ReportLog();
+ }
+
+ public void testSerialize_null() throws Exception {
+ try {
+ ReportLog.serialize(null);
+ fail("Expected IllegalArgumentException when serializing an empty report");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+ }
+
+ public void testSerialize_noData() throws Exception {
+ ReportLog.serialize(mReportLog);
+ }
+
+ public void testSerialize_summaryOnly() throws Exception {
+ mReportLog.setSummary("Sample", 1.0, ResultType.HIGHER_BETTER, ResultUnit.BYTE);
+ assertEquals(String.format(SUMMARY_XML, "testSerialize_summaryOnly:66"),
+ ReportLog.serialize(mReportLog));
+ }
+
+ public void testSerialize_detailOnly() throws Exception {
+ mReportLog.addValues("Details", VALUES, ResultType.NEUTRAL, ResultUnit.FPS);
+ assertEquals(HEADER_XML, ReportLog.serialize(mReportLog));
+ }
+
+ public void testSerialize_full() throws Exception {
+ mReportLog.setSummary("Sample", 1.0, ResultType.HIGHER_BETTER, ResultUnit.BYTE);
+ mReportLog.addValues("Details", VALUES, ResultType.NEUTRAL, ResultUnit.FPS);
+ assertEquals(String.format(FULL_XML, "testSerialize_full:77"),
+ ReportLog.serialize(mReportLog));
+ }
+
+ public void testParse_null() throws Exception {
+ try {
+ ReportLog.parse((String) null);
+ fail("Expected IllegalArgumentException when passing a null report");
+ } catch(IllegalArgumentException e) {
+ // Expected
+ }
+ }
+
+ public void testParse_noData() throws Exception {
+ ReportLog report = ReportLog.parse(HEADER_XML);
+ assertNull(report.getSummary());
+ }
+
+ public void testParse_summaryOnly() throws Exception {
+ ReportLog report = ReportLog.parse(String.format(SUMMARY_XML, "testParse_summaryOnly:125"));
+ assertNotNull(report);
+ assertEquals("Sample", report.getSummary().getMessage());
+ }
+
+ public void testParse_full() throws Exception {
+ ReportLog report = ReportLog.parse(String.format(FULL_XML, "testParse_full:140"));
+ assertNotNull(report);
+ assertEquals("Sample", report.getSummary().getMessage());
+ }
+
+ public void testLimits_source() throws Exception {
+ // Should pass with a short source.
+ Metric metric = new Metric(SOURCE, MESSAGE, 1.0, ResultType.HIGHER_BETTER, ResultUnit.BYTE);
+ assertEquals("Expected message to be ok", SOURCE, metric.getSource());
+ // Make a long source.
+ StringBuilder sb = new StringBuilder();
+ // 40 x "Source" = 240 character string
+ for (int i = 0; i < 40; i++) sb.append(SOURCE);
+ String source = sb.toString();
+ // Should be trimmed because source is too long.
+ metric = new Metric(source, MESSAGE, 1.0, ResultType.HIGHER_BETTER, ResultUnit.BYTE);
+ assertEquals("Expected source to be trimmed", source.substring(source.length() - 200),
+ metric.getSource());
+ }
+
+ public void testLimits_message() throws Exception {
+ // Should pass with a short message.
+ Metric metric = new Metric(SOURCE, MESSAGE, 1.0, ResultType.HIGHER_BETTER, ResultUnit.BYTE);
+ assertEquals("Expected message to be ok", MESSAGE, metric.getMessage());
+ // Make a long message.
+ StringBuilder sb = new StringBuilder();
+ // 40 x "Message" = 280 character string
+ for (int i = 0; i < 40; i++) sb.append(MESSAGE);
+ String message = sb.toString();
+ // Should be trimmed because message is too long.
+ metric = new Metric(SOURCE, message, 1.0, ResultType.HIGHER_BETTER, ResultUnit.BYTE);
+ assertEquals("Expected message to be trimmed", message.substring(0, 200),
+ metric.getMessage());
+ }
+
+ public void testLimits_values() throws Exception {
+ // Should pass with a small array.
+ Metric metric = new Metric(SOURCE, MESSAGE, VALUES, ResultType.HIGHER_BETTER,
+ ResultUnit.BYTE);
+ assertTrue("Expected values to be ok", Arrays.equals(VALUES, metric.getValues()));
+ // Make a big array.
+ double[] values = new double[1001];
+ for (int i = 0; i < values.length; i++) values[i] = i;
+ // Should be trimmed because array is too big.
+ metric = new Metric(SOURCE, MESSAGE, values, ResultType.HIGHER_BETTER, ResultUnit.BYTE);
+ assertTrue("Expected values to be trimmed", Arrays.equals(Arrays.copyOf(values, 1000),
+ metric.getValues()));
+ }
+
+}
diff --git a/libraries/compatibility-common-util/tests/src/com/android/compatibility/common/util/ResultHandlerTest.java b/libraries/compatibility-common-util/tests/src/com/android/compatibility/common/util/ResultHandlerTest.java
new file mode 100644
index 000000000..581e2018e
--- /dev/null
+++ b/libraries/compatibility-common-util/tests/src/com/android/compatibility/common/util/ResultHandlerTest.java
@@ -0,0 +1,750 @@
+/*
+ * 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.compatibility.common.util;
+
+import com.android.tradefed.util.FileUtil;
+import com.android.tradefed.util.AbiUtils;
+
+import org.w3c.dom.Element;
+import org.w3c.dom.NodeList;
+import org.xml.sax.InputSource;
+
+import junit.framework.TestCase;
+
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.StringReader;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import javax.xml.xpath.XPath;
+import javax.xml.xpath.XPathConstants;
+import javax.xml.xpath.XPathExpressionException;
+import javax.xml.xpath.XPathFactory;
+
+/**
+ * Unit tests for {@link ResultHandler}
+ */
+public class ResultHandlerTest extends TestCase {
+
+ private static final String SUITE_NAME = "CTS";
+ private static final String SUITE_VERSION = "5.0";
+ private static final String SUITE_PLAN = "cts";
+ private static final String SUITE_BUILD = "12345";
+ private static final String REPORT_VERSION = "5.0";
+ private static final String OS_NAME = System.getProperty("os.name");
+ private static final String OS_VERSION = System.getProperty("os.version");
+ private static final String OS_ARCH = System.getProperty("os.arch");
+ private static final String JAVA_VENDOR = System.getProperty("java.vendor");
+ private static final String JAVA_VERSION = System.getProperty("java.version");
+ private static final String NAME_A = "ModuleA";
+ private static final String NAME_B = "ModuleB";
+ private static final String DONE_A = "false";
+ private static final String DONE_B = "true";
+ private static final String RUNTIME_A = "100";
+ private static final String RUNTIME_B = "200";
+ private static final String ABI = "mips64";
+ private static final String ID_A = AbiUtils.createId(ABI, NAME_A);
+ private static final String ID_B = AbiUtils.createId(ABI, NAME_B);
+
+ private static final String BUILD_FINGERPRINT = "build_fingerprint";
+ private static final String BUILD_FINGERPRINT_UNALTERED = "build_fingerprint_unaltered";
+ private static final String BUILD_ID = "build_id";
+ private static final String BUILD_PRODUCT = "build_product";
+ private static final String RUN_HISTORY = "run_history";
+ private static final String EXAMPLE_BUILD_ID = "XYZ";
+ private static final String EXAMPLE_BUILD_PRODUCT = "wolverine";
+ private static final String EXAMPLE_BUILD_FINGERPRINT = "example_build_fingerprint";
+ private static final String EXAMPLE_BUILD_FINGERPRINT_UNALTERED = "example_build_fingerprint_unaltered";
+ private static final String EXAMPLE_RUN_HISTORY =
+ "[{\"startTime\":10000000000000,\"endTime\":10000000000001},"
+ + "{\"startTime\":10000000000002,\"endTime\":10000000000003}]";
+
+ private static final String DEVICE_A = "device123";
+ private static final String DEVICE_B = "device456";
+ private static final String DEVICES = "device456,device123";
+ private static final String CLASS_A = "android.test.Foor";
+ private static final String CLASS_B = "android.test.Bar";
+ private static final String METHOD_1 = "testBlah1";
+ private static final String METHOD_2 = "testBlah2";
+ private static final String METHOD_3 = "testBlah3";
+ private static final String METHOD_4 = "testBlah4";
+ private static final String METHOD_5 = "testBlah5";
+ private static final String METHOD_6_BRACKETS = "testBlah6[suffix]";
+ private static final String SUB_METHOD_3 = "subTestBlah3";
+ private static final String SUB_METHOD_6_BRACKETS = "subTestBlah6[suffix]";
+ private static final String SUMMARY_SOURCE = String.format("%s#%s:20", CLASS_B, METHOD_4);
+ private static final String SUMMARY_MESSAGE = "Headline";
+ private static final double SUMMARY_VALUE = 9001;
+ private static final String MESSAGE = "Something small is not alright";
+ private static final String STACK_TRACE = "Something small is not alright\n " +
+ "at four.big.insects.Marley.sing(Marley.java:10)";
+ private static final String BUG_REPORT = "https://cnsviewer.corp.google.com/cns/bugreport.txt";
+ private static final String LOGCAT = "https://cnsviewer.corp.google.com/cns/logcat.gz";
+ private static final String SCREENSHOT = "https://cnsviewer.corp.google.com/screenshot.png";
+ private static final long START_MS = 1431586801000L;
+ private static final long END_MS = 1431673199000L;
+ private static final String START_DISPLAY = "Fri Aug 20 15:13:03 PDT 2010";
+ private static final String END_DISPLAY = "Fri Aug 20 15:13:04 PDT 2010";
+ private static final long TEST_START_MS = 1000000000011L;
+ private static final long TEST_END_MS = 1000000000012L;
+ private static final boolean TEST_IS_AUTOMATED = false;
+
+ private static final String REFERENCE_URL = "http://android.com";
+ private static final String LOG_URL = "file:///path/to/logs";
+ private static final String COMMAND_LINE_ARGS = "cts -m CtsMyModuleTestCases";
+ private static final String XML_BASE =
+ "<?xml version='1.0' encoding='UTF-8' standalone='no' ?>" +
+ "<?xml-stylesheet type=\"text/xsl\" href=\"compatibility_result.xsl\"?>\n" +
+ "<Result start=\"%d\" end=\"%d\" start_display=\"%s\"" +
+ "end_display=\"%s\" suite_name=\"%s\" suite_version=\"%s\" " +
+ "suite_plan=\"%s\" suite_build_number=\"%s\" report_version=\"%s\" " +
+ "devices=\"%s\" host_name=\"%s\"" +
+ "os_name=\"%s\" os_version=\"%s\" os_arch=\"%s\" java_vendor=\"%s\"" +
+ "java_version=\"%s\" reference_url=\"%s\" log_url=\"%s\"" +
+ "command_line_args=\"%s\">\n" +
+ "%s%s%s" +
+ "</Result>";
+ private static final String XML_BUILD_INFO =
+ " <Build " +
+ BUILD_FINGERPRINT + "=\"%s\" " +
+ BUILD_ID + "=\"%s\" " +
+ BUILD_PRODUCT + "=\"%s\" " +
+ " />\n";
+ private static final String XML_BUILD_INFO_WITH_UNALTERED_BUILD_FINGERPRINT =
+ " <Build " +
+ BUILD_FINGERPRINT + "=\"%s\" " +
+ BUILD_FINGERPRINT_UNALTERED + "=\"%s\" " +
+ BUILD_ID + "=\"%s\" " +
+ BUILD_PRODUCT + "=\"%s\" " +
+ " />\n";
+ private static final String XML_SUMMARY =
+ " <Summary pass=\"%d\" failed=\"%d\" " +
+ "modules_done=\"1\" modules_total=\"1\" />\n";
+ private static final String XML_MODULE =
+ " <Module name=\"%s\" abi=\"%s\" device=\"%s\" runtime=\"%s\" done=\"%s\">\n" +
+ "%s" +
+ " </Module>\n";
+ private static final String XML_CASE =
+ " <TestCase name=\"%s\">\n" +
+ "%s" +
+ " </TestCase>\n";
+ private static final String XML_TEST_PASS =
+ " <Test result=\"pass\" name=\"%s\"/>\n";
+ private static final String XML_TEST_SKIP =
+ " <Test result=\"pass\" name=\"%s\" skipped=\"true\"/>\n";
+ private static final String XML_TEST_FAIL =
+ " <Test result=\"fail\" name=\"%s\">\n" +
+ " <Failure message=\"%s\">\n" +
+ " <StackTrace>%s</StackTrace>\n" +
+ " </Failure>\n" +
+ " <BugReport>%s</BugReport>\n" +
+ " <Logcat>%s</Logcat>\n" +
+ " <Screenshot>%s</Screenshot>\n" +
+ " </Test>\n";
+ private static final String XML_TEST_RESULT =
+ " <Test result=\"pass\" name=\"%s\">\n" +
+ " <Summary>\n" +
+ " <Metric source=\"%s\" message=\"%s\" score_type=\"%s\" score_unit=\"%s\">\n" +
+ " <Value>%s</Value>\n" +
+ " </Metric>\n" +
+ " </Summary>\n" +
+ " </Test>\n";
+ private static final String NEW_XML_TEST_RESULT =
+ " <Test result=\"pass\" name=\"%s\">\n"
+ + " <Metric key=\"%s\">%s</Metric>\n"
+ + " </Test>\n";
+
+ private File resultsDir = null;
+ private File resultDir = null;
+
+ @Override
+ public void setUp() throws Exception {
+ resultsDir = FileUtil.createTempDir("results");
+ resultDir = FileUtil.createTempDir("12345", resultsDir);
+ }
+
+ @Override
+ public void tearDown() throws Exception {
+ FileUtil.recursiveDelete(resultsDir);
+ }
+
+ public void testSerialization() throws Exception {
+ IInvocationResult result = new InvocationResult();
+ result.setStartTime(START_MS);
+ result.setTestPlan(SUITE_PLAN);
+ result.addDeviceSerial(DEVICE_A);
+ result.addDeviceSerial(DEVICE_B);
+ result.addInvocationInfo(BUILD_FINGERPRINT, EXAMPLE_BUILD_FINGERPRINT);
+ result.addInvocationInfo(BUILD_ID, EXAMPLE_BUILD_ID);
+ result.addInvocationInfo(BUILD_PRODUCT, EXAMPLE_BUILD_PRODUCT);
+ result.addInvocationInfo(RUN_HISTORY, EXAMPLE_RUN_HISTORY);
+ Collection<InvocationResult.RunHistory> runHistories =
+ ((InvocationResult) result).getRunHistories();
+ InvocationResult.RunHistory runHistory1 = new InvocationResult.RunHistory();
+ runHistory1.startTime = 10000000000000L;
+ runHistory1.endTime = 10000000000001L;
+ runHistories.add(runHistory1);
+ InvocationResult.RunHistory runHistory2 = new InvocationResult.RunHistory();
+ runHistory2.startTime = 10000000000002L;
+ runHistory2.endTime = 10000000000003L;
+ runHistories.add(runHistory2);
+
+ // Module A: test1 passes, test2 not executed
+ IModuleResult moduleA = result.getOrCreateModule(ID_A);
+ moduleA.setDone(false);
+ moduleA.addRuntime(Integer.parseInt(RUNTIME_A));
+ ICaseResult moduleACase = moduleA.getOrCreateResult(CLASS_A);
+ ITestResult moduleATest1 = moduleACase.getOrCreateResult(METHOD_1);
+ moduleATest1.setResultStatus(TestStatus.PASS);
+ ITestResult moduleATest2 = moduleACase.getOrCreateResult(METHOD_2);
+ moduleATest2.setResultStatus(null); // not executed test
+ // Module B: test3 fails, test4 passes with report log, test5 passes with skip
+ IModuleResult moduleB = result.getOrCreateModule(ID_B);
+ moduleB.setDone(true);
+ moduleB.addRuntime(Integer.parseInt(RUNTIME_B));
+ ICaseResult moduleBCase = moduleB.getOrCreateResult(CLASS_B);
+ ITestResult moduleBTest3 = moduleBCase.getOrCreateResult(METHOD_3);
+ moduleBTest3.setResultStatus(TestStatus.FAIL);
+ moduleBTest3.setMessage(MESSAGE);
+ moduleBTest3.setStackTrace(STACK_TRACE);
+ moduleBTest3.setBugReport(BUG_REPORT);
+ moduleBTest3.setLog(LOGCAT);
+ moduleBTest3.setScreenshot(SCREENSHOT);
+ ITestResult moduleBTest4 = moduleBCase.getOrCreateResult(METHOD_4);
+ moduleBTest4.setResultStatus(TestStatus.PASS);
+ ReportLog report = new ReportLog();
+ ReportLog.Metric summary = new ReportLog.Metric(SUMMARY_SOURCE, SUMMARY_MESSAGE,
+ SUMMARY_VALUE, ResultType.HIGHER_BETTER, ResultUnit.SCORE);
+ report.setSummary(summary);
+ moduleBTest4.setReportLog(report);
+ ITestResult moduleBTest5 = moduleBCase.getOrCreateResult(METHOD_5);
+ moduleBTest5.skipped();
+
+ Map<String, String> testAttributes = new HashMap<String, String>();
+ testAttributes.put("foo1", "bar1");
+ testAttributes.put("foo2", "bar2");
+ // Serialize to file
+ File res =
+ ResultHandler.writeResults(
+ SUITE_NAME,
+ SUITE_VERSION,
+ SUITE_PLAN,
+ SUITE_BUILD,
+ result,
+ resultDir,
+ START_MS,
+ END_MS,
+ REFERENCE_URL,
+ LOG_URL,
+ COMMAND_LINE_ARGS,
+ testAttributes);
+ String content = FileUtil.readStringFromFile(res);
+ assertXmlContainsAttribute(content, "Result", "foo1", "bar1");
+ assertXmlContainsAttribute(content, "Result", "foo2", "bar2");
+ assertXmlContainsAttribute(content, "Result/Build", "run_history", EXAMPLE_RUN_HISTORY);
+ assertXmlContainsNode(content, "Result/RunHistory");
+ assertXmlContainsAttribute(content, "Result/RunHistory/Run", "start", "10000000000000");
+ assertXmlContainsAttribute(content, "Result/RunHistory/Run", "end", "10000000000001");
+ assertXmlContainsAttribute(content, "Result/RunHistory/Run", "start", "10000000000002");
+ assertXmlContainsAttribute(content, "Result/RunHistory/Run", "end", "10000000000003");
+
+ // Parse the results and assert correctness
+ result = ResultHandler.getResultFromDir(resultDir);
+ checkResult(result, false);
+ checkRunHistory(result);
+ }
+
+ /*
+ * Test serialization for CTS Verifier since test results with test result history is only in
+ * CTS Verifier and was not parsed by suite harness.
+ */
+ public void testSerialization_whenTestResultWithTestResultHistoryWithoutParsing()
+ throws Exception {
+ IInvocationResult result = new InvocationResult();
+ result.setStartTime(START_MS);
+ result.setTestPlan(SUITE_PLAN);
+ result.addDeviceSerial(DEVICE_A);
+ result.addDeviceSerial(DEVICE_B);
+ result.addInvocationInfo(BUILD_FINGERPRINT, EXAMPLE_BUILD_FINGERPRINT);
+ result.addInvocationInfo(BUILD_ID, EXAMPLE_BUILD_ID);
+ result.addInvocationInfo(BUILD_PRODUCT, EXAMPLE_BUILD_PRODUCT);
+
+ // Module A: test1 passes, test2 not executed
+ IModuleResult moduleA = result.getOrCreateModule(ID_A);
+ moduleA.setDone(false);
+ moduleA.addRuntime(Integer.parseInt(RUNTIME_A));
+ ICaseResult moduleACase = moduleA.getOrCreateResult(CLASS_A);
+ ITestResult moduleATest1 = moduleACase.getOrCreateResult(METHOD_1);
+ moduleATest1.setResultStatus(TestStatus.PASS);
+ // Module B: test3 fails with test result history, test4 passes with report log,
+ // test5 passes with skip
+ IModuleResult moduleB = result.getOrCreateModule(ID_B);
+ moduleB.setDone(true);
+ moduleB.addRuntime(Integer.parseInt(RUNTIME_B));
+ ICaseResult moduleBCase = moduleB.getOrCreateResult(CLASS_B);
+ Set<TestResultHistory.ExecutionRecord> executionRecords =
+ new HashSet<TestResultHistory.ExecutionRecord>();
+ executionRecords.add(
+ new TestResultHistory.ExecutionRecord(
+ TEST_START_MS, TEST_END_MS, TEST_IS_AUTOMATED));
+
+ ITestResult moduleBTest3 = moduleBCase.getOrCreateResult(METHOD_3);
+ moduleBTest3.setResultStatus(TestStatus.FAIL);
+ moduleBTest3.setMessage(MESSAGE);
+ moduleBTest3.setStackTrace(STACK_TRACE);
+ moduleBTest3.setBugReport(BUG_REPORT);
+ moduleBTest3.setLog(LOGCAT);
+ moduleBTest3.setScreenshot(SCREENSHOT);
+ List<TestResultHistory> resultHistories = new ArrayList<TestResultHistory>();
+ TestResultHistory resultHistory =
+ new TestResultHistory(METHOD_3 + ":" + SUB_METHOD_3, executionRecords);
+ resultHistories.add(resultHistory);
+ moduleBTest3.setTestResultHistories(resultHistories);
+ ITestResult moduleBTest4 = moduleBCase.getOrCreateResult(METHOD_4);
+ moduleBTest4.setResultStatus(TestStatus.PASS);
+ ReportLog report = new ReportLog();
+ ReportLog.Metric summary =
+ new ReportLog.Metric(
+ SUMMARY_SOURCE,
+ SUMMARY_MESSAGE,
+ SUMMARY_VALUE,
+ ResultType.HIGHER_BETTER,
+ ResultUnit.SCORE);
+ report.setSummary(summary);
+ moduleBTest4.setReportLog(report);
+ ITestResult moduleBTest5 = moduleBCase.getOrCreateResult(METHOD_5);
+ moduleBTest5.skipped();
+ // For test name with bracket as suffix in CTS Verifier.
+ ITestResult moduleBTest6 = moduleBCase.getOrCreateResult(METHOD_6_BRACKETS);
+ moduleBTest6.setResultStatus(TestStatus.FAIL);
+ List<TestResultHistory> resultHistories2 = new ArrayList<TestResultHistory>();
+ TestResultHistory resultHistory2 =
+ new TestResultHistory(
+ METHOD_6_BRACKETS + ":" + SUB_METHOD_6_BRACKETS, executionRecords);
+ resultHistories2.add(resultHistory2);
+ moduleBTest6.setTestResultHistories(resultHistories2);
+
+ // Serialize to file
+ File res =
+ ResultHandler.writeResults(
+ SUITE_NAME,
+ SUITE_VERSION,
+ SUITE_PLAN,
+ SUITE_BUILD,
+ result,
+ resultDir,
+ START_MS,
+ END_MS,
+ REFERENCE_URL,
+ LOG_URL,
+ COMMAND_LINE_ARGS,
+ null);
+ String content = FileUtil.readStringFromFile(res);
+ assertXmlContainsNode(content, "Result/Module/TestCase/Test/RunHistory");
+ assertXmlContainsAttribute(
+ content,
+ "Result/Module/TestCase/Test/RunHistory/Run",
+ "start",
+ Long.toString(TEST_START_MS));
+ assertXmlContainsAttribute(
+ content,
+ "Result/Module/TestCase/Test/RunHistory/Run",
+ "end",
+ Long.toString(TEST_END_MS));
+ assertXmlContainsAttribute(
+ content,
+ "Result/Module/TestCase/Test/RunHistory/Run",
+ "isAutomated",
+ Boolean.toString(TEST_IS_AUTOMATED));
+ checkResult(result, EXAMPLE_BUILD_FINGERPRINT, false, false);
+ }
+
+ public void testParsing() throws Exception {
+ File resultDir = writeResultDir(resultsDir, false);
+ // Parse the results and assert correctness
+ checkResult(ResultHandler.getResultFromDir(resultDir), false);
+ }
+
+ public void testParsing_newTestFormat() throws Exception {
+ File resultDir = writeResultDir(resultsDir, true);
+ // Parse the results and assert correctness
+ checkResult(ResultHandler.getResultFromDir(resultDir), true);
+ }
+
+ public void testParsing_usesUnalteredBuildFingerprintWhenPresent() throws Exception {
+ String buildInfo = String.format(XML_BUILD_INFO_WITH_UNALTERED_BUILD_FINGERPRINT,
+ EXAMPLE_BUILD_FINGERPRINT, EXAMPLE_BUILD_FINGERPRINT_UNALTERED,
+ EXAMPLE_BUILD_ID, EXAMPLE_BUILD_PRODUCT);
+ File resultDir = writeResultDir(resultsDir, buildInfo, false);
+ checkResult(
+ ResultHandler.getResultFromDir(resultDir),
+ EXAMPLE_BUILD_FINGERPRINT_UNALTERED,
+ false,
+ true);
+ }
+
+ public void testParsing_whenUnalteredBuildFingerprintIsEmpty_usesRegularBuildFingerprint() throws Exception {
+ String buildInfo = String.format(XML_BUILD_INFO_WITH_UNALTERED_BUILD_FINGERPRINT,
+ EXAMPLE_BUILD_FINGERPRINT, "", EXAMPLE_BUILD_ID, EXAMPLE_BUILD_PRODUCT);
+ File resultDir = writeResultDir(resultsDir, buildInfo, false);
+ checkResult(
+ ResultHandler.getResultFromDir(resultDir), EXAMPLE_BUILD_FINGERPRINT, false, true);
+ }
+
+ public void testGetLightResults() throws Exception {
+ File resultDir = writeResultDir(resultsDir, false);
+ List<IInvocationResult> lightResults = ResultHandler.getLightResults(resultsDir);
+ assertEquals("Expected one result", 1, lightResults.size());
+ IInvocationResult lightResult = lightResults.get(0);
+ checkLightResult(lightResult);
+ }
+
+ static File writeResultDir(File resultsDir, boolean newTestFormat) throws IOException {
+ String buildInfo = String.format(XML_BUILD_INFO, EXAMPLE_BUILD_FINGERPRINT,
+ EXAMPLE_BUILD_ID, EXAMPLE_BUILD_PRODUCT);
+ return writeResultDir(resultsDir, buildInfo, newTestFormat);
+ }
+
+ /*
+ * Helper to write a result to the results dir, for testing.
+ * @return the written resultDir
+ */
+ static File writeResultDir(File resultsDir, String buildInfo, boolean newTestFormat)
+ throws IOException {
+ File resultDir = null;
+ FileWriter writer = null;
+ try {
+ resultDir = FileUtil.createTempDir("12345", resultsDir);
+ // Create the result file
+ File resultFile = new File(resultDir, ResultHandler.TEST_RESULT_FILE_NAME);
+ writer = new FileWriter(resultFile);
+ String summary = String.format(XML_SUMMARY, 2, 1);
+ String moduleATest = String.format(XML_TEST_PASS, METHOD_1);
+ String moduleACases = String.format(XML_CASE, CLASS_A, moduleATest);
+ String moduleA = String.format(XML_MODULE, NAME_A, ABI, DEVICE_A, RUNTIME_A, DONE_A,
+ moduleACases);
+ String moduleBTest3 = String.format(XML_TEST_FAIL, METHOD_3, MESSAGE, STACK_TRACE,
+ BUG_REPORT, LOGCAT, SCREENSHOT);
+ String moduleBTest4 = "";
+ if (newTestFormat) {
+ moduleBTest4 =
+ String.format(
+ NEW_XML_TEST_RESULT,
+ METHOD_4,
+ SUMMARY_MESSAGE,
+ Double.toString(SUMMARY_VALUE));
+ } else {
+ moduleBTest4 =
+ String.format(
+ XML_TEST_RESULT,
+ METHOD_4,
+ SUMMARY_SOURCE,
+ SUMMARY_MESSAGE,
+ ResultType.HIGHER_BETTER.toReportString(),
+ ResultUnit.SCORE.toReportString(),
+ Double.toString(SUMMARY_VALUE));
+ }
+
+ String moduleBTest5 = String.format(XML_TEST_SKIP, METHOD_5);
+ String moduleBTests = String.join("", moduleBTest3, moduleBTest4, moduleBTest5);
+ String moduleBCases = String.format(XML_CASE, CLASS_B, moduleBTests);
+ String moduleB = String.format(XML_MODULE, NAME_B, ABI, DEVICE_B, RUNTIME_B, DONE_B,
+ moduleBCases);
+ String modules = String.join("", moduleA, moduleB);
+ String hostName = "";
+ try {
+ hostName = InetAddress.getLocalHost().getHostName();
+ } catch (UnknownHostException ignored) {}
+ String output = String.format(XML_BASE, START_MS, END_MS, START_DISPLAY, END_DISPLAY,
+ SUITE_NAME, SUITE_VERSION, SUITE_PLAN, SUITE_BUILD, REPORT_VERSION, DEVICES,
+ hostName, OS_NAME, OS_VERSION, OS_ARCH, JAVA_VENDOR,
+ JAVA_VERSION, REFERENCE_URL, LOG_URL, COMMAND_LINE_ARGS,
+ buildInfo, summary, modules);
+ writer.write(output);
+ writer.flush();
+ } finally {
+ if (writer != null) {
+ writer.close();
+ }
+ }
+ return resultDir;
+ }
+
+ static void checkLightResult(IInvocationResult lightResult) throws Exception {
+ assertEquals("Expected 3 passes", 3, lightResult.countResults(TestStatus.PASS));
+ assertEquals("Expected 1 failure", 1, lightResult.countResults(TestStatus.FAIL));
+
+ Map<String, String> buildInfo = lightResult.getInvocationInfo();
+ assertEquals("Incorrect Build ID", EXAMPLE_BUILD_ID, buildInfo.get(BUILD_ID));
+ assertEquals("Incorrect Build Product",
+ EXAMPLE_BUILD_PRODUCT, buildInfo.get(BUILD_PRODUCT));
+
+ Set<String> serials = lightResult.getDeviceSerials();
+ assertTrue("Missing device", serials.contains(DEVICE_A));
+ assertTrue("Missing device", serials.contains(DEVICE_B));
+ assertEquals("Expected 2 devices", 2, serials.size());
+ assertTrue("Incorrect devices", serials.contains(DEVICE_A) && serials.contains(DEVICE_B));
+ assertEquals("Incorrect start time", START_MS, lightResult.getStartTime());
+ assertEquals("Incorrect test plan", SUITE_PLAN, lightResult.getTestPlan());
+ List<IModuleResult> modules = lightResult.getModules();
+ assertEquals("Expected 1 completed module", 1, lightResult.getModuleCompleteCount());
+ assertEquals("Expected 2 total modules", 2, modules.size());
+ }
+
+ static void checkResult(IInvocationResult result, boolean newTestFormat) throws Exception {
+ checkResult(result, EXAMPLE_BUILD_FINGERPRINT, newTestFormat, true);
+ }
+
+ static void checkRunHistory(IInvocationResult result) {
+ Map<String, String> buildInfo = result.getInvocationInfo();
+ assertEquals("Incorrect run history", EXAMPLE_RUN_HISTORY, buildInfo.get(RUN_HISTORY));
+ }
+
+ static void checkResult(
+ IInvocationResult result, String expectedBuildFingerprint, boolean newTestFormat,
+ boolean checkResultHistories) throws Exception {
+ assertEquals("Expected 3 passes", 3, result.countResults(TestStatus.PASS));
+ if (checkResultHistories) {
+ assertEquals("Expected 1 failure", 1, result.countResults(TestStatus.FAIL));
+ } else {
+ // CTS Verifier needs to check the condition of the test name with bracket,
+ // so adds one more test with failure result.
+ assertEquals("Expected 2 failure", 2, result.countResults(TestStatus.FAIL));
+ }
+
+ Map<String, String> buildInfo = result.getInvocationInfo();
+ assertEquals("Incorrect Build Fingerprint", expectedBuildFingerprint, result.getBuildFingerprint());
+ assertEquals("Incorrect Build ID", EXAMPLE_BUILD_ID, buildInfo.get(BUILD_ID));
+ assertEquals("Incorrect Build Product",
+ EXAMPLE_BUILD_PRODUCT, buildInfo.get(BUILD_PRODUCT));
+
+ Set<String> serials = result.getDeviceSerials();
+ assertTrue("Missing device", serials.contains(DEVICE_A));
+ assertTrue("Missing device", serials.contains(DEVICE_B));
+ assertEquals("Expected 2 devices", 2, serials.size());
+ assertTrue("Incorrect devices", serials.contains(DEVICE_A) && serials.contains(DEVICE_B));
+ assertEquals("Incorrect start time", START_MS, result.getStartTime());
+ assertEquals("Incorrect test plan", SUITE_PLAN, result.getTestPlan());
+
+ List<IModuleResult> modules = result.getModules();
+ assertEquals("Expected 2 modules", 2, modules.size());
+
+ IModuleResult moduleA = modules.get(0);
+ assertEquals("Expected 1 pass", 1, moduleA.countResults(TestStatus.PASS));
+ assertEquals("Expected 0 failures", 0, moduleA.countResults(TestStatus.FAIL));
+ assertEquals("Incorrect ABI", ABI, moduleA.getAbi());
+ assertEquals("Incorrect name", NAME_A, moduleA.getName());
+ assertEquals("Incorrect ID", ID_A, moduleA.getId());
+ assertEquals("Incorrect runtime", Integer.parseInt(RUNTIME_A), moduleA.getRuntime());
+ List<ICaseResult> moduleACases = moduleA.getResults();
+ assertEquals("Expected 1 test case", 1, moduleACases.size());
+ ICaseResult moduleACase = moduleACases.get(0);
+ assertEquals("Incorrect name", CLASS_A, moduleACase.getName());
+ List<ITestResult> moduleAResults = moduleACase.getResults();
+ assertEquals("Expected 1 result", 1, moduleAResults.size());
+ ITestResult moduleATest1 = moduleAResults.get(0);
+ assertEquals("Incorrect name", METHOD_1, moduleATest1.getName());
+ assertEquals("Incorrect result", TestStatus.PASS, moduleATest1.getResultStatus());
+ assertNull("Unexpected bugreport", moduleATest1.getBugReport());
+ assertNull("Unexpected log", moduleATest1.getLog());
+ assertNull("Unexpected screenshot", moduleATest1.getScreenshot());
+ assertNull("Unexpected message", moduleATest1.getMessage());
+ assertNull("Unexpected stack trace", moduleATest1.getStackTrace());
+ assertNull("Unexpected report", moduleATest1.getReportLog());
+
+ IModuleResult moduleB = modules.get(1);
+ assertEquals("Expected 2 passes", 2, moduleB.countResults(TestStatus.PASS));
+ if (checkResultHistories) {
+ assertEquals("Expected 1 failure", 1, moduleB.countResults(TestStatus.FAIL));
+ } else {
+ // CTS Verifier needs to check the condition of the test name with bracket,
+ // so adds one more test with failure result.
+ assertEquals("Expected 2 failure", 2, moduleB.countResults(TestStatus.FAIL));
+ }
+ assertEquals("Incorrect ABI", ABI, moduleB.getAbi());
+ assertEquals("Incorrect name", NAME_B, moduleB.getName());
+ assertEquals("Incorrect ID", ID_B, moduleB.getId());
+ assertEquals("Incorrect runtime", Integer.parseInt(RUNTIME_B), moduleB.getRuntime());
+ List<ICaseResult> moduleBCases = moduleB.getResults();
+ assertEquals("Expected 1 test case", 1, moduleBCases.size());
+ ICaseResult moduleBCase = moduleBCases.get(0);
+ assertEquals("Incorrect name", CLASS_B, moduleBCase.getName());
+ List<ITestResult> moduleBResults = moduleBCase.getResults();
+ if (checkResultHistories) {
+ assertEquals("Expected 3 results", 3, moduleBResults.size());
+ } else {
+ // CTS Verifier needs to check the condition of the test name with bracket,
+ // so adds one more test with failure result.
+ assertEquals("Expected 4 results", 4, moduleBResults.size());
+ }
+ ITestResult moduleBTest3 = moduleBResults.get(0);
+ assertEquals("Incorrect name", METHOD_3, moduleBTest3.getName());
+ assertEquals("Incorrect result", TestStatus.FAIL, moduleBTest3.getResultStatus());
+ assertEquals("Incorrect bugreport", BUG_REPORT, moduleBTest3.getBugReport());
+ assertEquals("Incorrect log", LOGCAT, moduleBTest3.getLog());
+ assertEquals("Incorrect screenshot", SCREENSHOT, moduleBTest3.getScreenshot());
+ assertEquals("Incorrect message", MESSAGE, moduleBTest3.getMessage());
+ assertEquals("Incorrect stack trace", STACK_TRACE, moduleBTest3.getStackTrace());
+ assertNull("Unexpected report", moduleBTest3.getReportLog());
+ List<TestResultHistory> resultHistories = moduleBTest3.getTestResultHistories();
+ // Check if unit tests do parsing result, because tests for CTS Verifier do not parse it.
+ if (checkResultHistories) {
+ // For xTS except CTS Verifier.
+ assertNull("Unexpected test result history list", resultHistories);
+ } else {
+ // For CTS Verifier.
+ assertNotNull("Expected test result history list", resultHistories);
+ assertEquals("Expected 1 test result history", 1, resultHistories.size());
+ for (TestResultHistory resultHistory : resultHistories) {
+ assertNotNull("Expected test result history", resultHistory);
+ assertEquals(
+ "Incorrect test name",
+ SUB_METHOD_3,
+ resultHistory.getSubTestName(METHOD_3, resultHistory.getTestName()));
+ for (TestResultHistory.ExecutionRecord execRecord :
+ resultHistory.getExecutionRecords()) {
+ assertEquals(
+ "Incorrect test start time", TEST_START_MS, execRecord.getStartTime());
+ assertEquals("Incorrect test end time", TEST_END_MS, execRecord.getEndTime());
+ assertEquals(
+ "Incorrect test is automated",
+ TEST_IS_AUTOMATED,
+ execRecord.getIsAutomated());
+ }
+ }
+ }
+ ITestResult moduleBTest4 = moduleBResults.get(1);
+ assertEquals("Incorrect name", METHOD_4, moduleBTest4.getName());
+ assertEquals("Incorrect result", TestStatus.PASS, moduleBTest4.getResultStatus());
+ assertNull("Unexpected bugreport", moduleBTest4.getBugReport());
+ assertNull("Unexpected log", moduleBTest4.getLog());
+ assertNull("Unexpected screenshot", moduleBTest4.getScreenshot());
+ assertNull("Unexpected message", moduleBTest4.getMessage());
+ assertNull("Unexpected stack trace", moduleBTest4.getStackTrace());
+ if (!newTestFormat) {
+ ReportLog report = moduleBTest4.getReportLog();
+ assertNotNull("Expected report", report);
+ ReportLog.Metric summary = report.getSummary();
+ assertNotNull("Expected report summary", summary);
+ assertEquals("Incorrect source", SUMMARY_SOURCE, summary.getSource());
+ assertEquals("Incorrect message", SUMMARY_MESSAGE, summary.getMessage());
+ assertEquals("Incorrect type", ResultType.HIGHER_BETTER, summary.getType());
+ assertEquals("Incorrect unit", ResultUnit.SCORE, summary.getUnit());
+ assertTrue(
+ "Incorrect values",
+ Arrays.equals(new double[] {SUMMARY_VALUE}, summary.getValues()));
+ }
+ ITestResult moduleBTest5 = moduleBResults.get(2);
+ assertEquals("Incorrect name", METHOD_5, moduleBTest5.getName());
+ assertEquals("Incorrect result", TestStatus.PASS, moduleBTest5.getResultStatus());
+ assertTrue("Expected skipped", moduleBTest5.isSkipped());
+ assertNull("Unexpected bugreport", moduleBTest5.getBugReport());
+ assertNull("Unexpected log", moduleBTest5.getLog());
+ assertNull("Unexpected screenshot", moduleBTest5.getScreenshot());
+ assertNull("Unexpected message", moduleBTest5.getMessage());
+ assertNull("Unexpected stack trace", moduleBTest5.getStackTrace());
+ assertNull("Unexpected report", moduleBTest5.getReportLog());
+ if (!checkResultHistories) {
+ // CTS Verifier needs to check the condition of the test name with bracket,
+ // so adds one more test with failure result.
+ ITestResult moduleBTest6 = moduleBResults.get(3);
+ assertEquals("Incorrect name", METHOD_6_BRACKETS, moduleBTest6.getName());
+ assertEquals("Incorrect result", TestStatus.FAIL, moduleBTest6.getResultStatus());
+ List<TestResultHistory> resultHistories2 = moduleBTest6.getTestResultHistories();
+ assertNotNull("Expected test result history list", resultHistories2);
+ assertEquals("Expected 1 test result history", 1, resultHistories2.size());
+ for (TestResultHistory resultHistory : resultHistories2) {
+ assertNotNull("Expected test result history", resultHistory);
+ assertEquals(
+ "Incorrect test name",
+ SUB_METHOD_6_BRACKETS,
+ resultHistory.getSubTestName(
+ METHOD_6_BRACKETS, resultHistory.getTestName()));
+ for (TestResultHistory.ExecutionRecord execRecord :
+ resultHistory.getExecutionRecords()) {
+ assertEquals(
+ "Incorrect test start time", TEST_START_MS, execRecord.getStartTime());
+ assertEquals("Incorrect test end time", TEST_END_MS, execRecord.getEndTime());
+ assertEquals(
+ "Incorrect test is automated",
+ TEST_IS_AUTOMATED,
+ execRecord.getIsAutomated());
+ }
+ }
+ }
+ }
+
+ /** Return all XML nodes that match the given xPathExpression. */
+ private NodeList getXmlNodes(String xml, String xPathExpression)
+ throws XPathExpressionException {
+
+ InputSource inputSource = new InputSource(new StringReader(xml));
+ XPath xpath = XPathFactory.newInstance().newXPath();
+ return (NodeList) xpath.evaluate(xPathExpression, inputSource, XPathConstants.NODESET);
+ }
+
+ /** Assert that the XML contains a node matching the given xPathExpression. */
+ private NodeList assertXmlContainsNode(String xml, String xPathExpression)
+ throws XPathExpressionException {
+ NodeList nodes = getXmlNodes(xml, xPathExpression);
+ assertNotNull(
+ String.format("XML '%s' returned null for xpath '%s'.", xml, xPathExpression),
+ nodes);
+ assertTrue(
+ String.format(
+ "XML '%s' should have returned at least 1 node for xpath '%s', "
+ + "but returned %s nodes instead.",
+ xml, xPathExpression, nodes.getLength()),
+ nodes.getLength() >= 1);
+ return nodes;
+ }
+
+ /**
+ * Assert that the XML contains a node matching the given xPathExpression and that the node has
+ * a given value.
+ */
+ private void assertXmlContainsAttribute(
+ String xml, String xPathExpression, String attributeName, String attributeValue)
+ throws XPathExpressionException {
+ NodeList nodes = assertXmlContainsNode(xml, xPathExpression);
+ boolean found = false;
+
+ for (int i = 0; i < nodes.getLength(); i++) {
+ Element element = (Element) nodes.item(i);
+ String value = element.getAttribute(attributeName);
+ if (attributeValue.equals(value)) {
+ found = true;
+ break;
+ }
+ }
+
+ assertTrue(
+ String.format(
+ "xPath '%s' should contain attribute '%s' but does not. XML: '%s'",
+ xPathExpression, attributeName, xml),
+ found);
+ }
+}
diff --git a/libraries/compatibility-common-util/tests/src/com/android/compatibility/common/util/StatTest.java b/libraries/compatibility-common-util/tests/src/com/android/compatibility/common/util/StatTest.java
new file mode 100644
index 000000000..6e53d48f3
--- /dev/null
+++ b/libraries/compatibility-common-util/tests/src/com/android/compatibility/common/util/StatTest.java
@@ -0,0 +1,85 @@
+/*
+ * 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.compatibility.common.util;
+
+import com.android.compatibility.common.util.Stat;
+import junit.framework.TestCase;
+
+/**
+ * Unit tests for the {@link Stat} class.
+ */
+public class StatTest extends TestCase {
+
+ /**
+ * Test {@link Stat#get95PercentileValue(double[])}.
+ */
+ public void testGet95PercentileValue() {
+ double[] values = new double[100];
+ for (int i = 0; i < 100; i++) {
+ values[i] = i;
+ }
+ assertEquals(95, (int) Stat.get95PercentileValue(values));
+
+ values = new double[1000];
+ for (int i = 0; i < 1000; i++) {
+ values[i] = i;
+ }
+ assertEquals(950, (int) Stat.get95PercentileValue(values));
+
+ values = new double[100];
+ for (int i = 0; i < 100; i++) {
+ values[i] = i * i;
+ }
+ assertEquals(95 * 95, (int) Stat.get95PercentileValue(values));
+ }
+
+ /**
+ * Test {@link Stat#getAverage(double[])}.
+ */
+ public void testGetAverage() {
+ double[] values = new double[]{0, 1, 2, 3, 4};
+ double average = Stat.getAverage(values);
+ assertEquals(2.0, average, 0.00001);
+
+ values = new double[]{1, 2, 3, 4, 5};
+ average = Stat.getAverage(values);
+ assertEquals(3.0, average, 0.00001);
+
+ values = new double[]{0, 1, 4, 9, 16};
+ average = Stat.getAverage(values);
+ assertEquals(6.0, average, 0.00001);
+ }
+
+ /**
+ * Test standard deviation.
+ */
+ public void testGetStandardDeviation() {
+ double[] values = new double[]{0, 1, 2, 3, 4};
+ double stddev = Stat.getStat(values).mStddev;
+ assertEquals(Math.sqrt(2.5), stddev, 0.00001);
+
+ values = new double[]{1, 2, 3, 4, 5};
+ stddev = Stat.getStat(values).mStddev;
+ assertEquals(Math.sqrt(2.5), stddev, 0.00001);
+
+ values = new double[]{0, 2, 4, 6, 8};
+ stddev = Stat.getStat(values).mStddev;
+ assertEquals(Math.sqrt(10.0), stddev, 0.00001);
+ }
+
+
+}
diff --git a/libraries/compatibility-common-util/tests/src/com/android/compatibility/common/util/TestResultTest.java b/libraries/compatibility-common-util/tests/src/com/android/compatibility/common/util/TestResultTest.java
new file mode 100644
index 000000000..5e4431ea8
--- /dev/null
+++ b/libraries/compatibility-common-util/tests/src/com/android/compatibility/common/util/TestResultTest.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.compatibility.common.util;
+
+import junit.framework.TestCase;
+
+/**
+ * Unit tests for {@link TestResult}
+ */
+public class TestResultTest extends TestCase {
+
+ private static final String CLASS = "android.test.FoorBar";
+ private static final String METHOD_1 = "testBlah1";
+ private static final String TEST_1 = String.format("%s#%s", CLASS, METHOD_1);
+ private CaseResult mCase;
+ private TestResult mResult;
+
+ @Override
+ public void setUp() throws Exception {
+ mCase = new CaseResult(CLASS);
+ mResult = new TestResult(mCase, METHOD_1);
+ }
+
+ @Override
+ public void tearDown() throws Exception {
+ mResult = null;
+ }
+
+ public void testAccessors() throws Exception {
+ assertEquals("Incorrect test name", METHOD_1, mResult.getName());
+ assertEquals("Incorrect full name", TEST_1, mResult.getFullName());
+ }
+
+} \ No newline at end of file