summaryrefslogtreecommitdiffstats
path: root/third_party/libwebrtc/build/android/list_class_verification_failures_test.py
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/libwebrtc/build/android/list_class_verification_failures_test.py')
-rwxr-xr-xthird_party/libwebrtc/build/android/list_class_verification_failures_test.py237
1 files changed, 237 insertions, 0 deletions
diff --git a/third_party/libwebrtc/build/android/list_class_verification_failures_test.py b/third_party/libwebrtc/build/android/list_class_verification_failures_test.py
new file mode 100755
index 0000000000..c3522d651d
--- /dev/null
+++ b/third_party/libwebrtc/build/android/list_class_verification_failures_test.py
@@ -0,0 +1,237 @@
+#!/usr/bin/env vpython3
+# Copyright 2018 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+import unittest
+
+import list_class_verification_failures as list_verification
+
+import devil_chromium # pylint: disable=unused-import
+from devil.android import device_errors
+from devil.android import device_utils
+from devil.android.ndk import abis
+from devil.android.sdk import version_codes
+
+import mock # pylint: disable=import-error
+
+
+def _CreateOdexLine(java_class_name, type_idx, verification_status):
+ """Create a rough approximation of a line of oatdump output."""
+ return ('{type_idx}: L{java_class}; (offset=0xac) (type_idx={type_idx}) '
+ '({verification}) '
+ '(OatClassNoneCompiled)'.format(type_idx=type_idx,
+ java_class=java_class_name,
+ verification=verification_status))
+
+
+def _ClassForName(name, classes):
+ return next(c for c in classes if c.name == name)
+
+
+class _DetermineDeviceToUseTest(unittest.TestCase):
+
+ def testDetermineDeviceToUse_emptyListWithOneAttachedDevice(self):
+ fake_attached_devices = ['123']
+ user_specified_devices = []
+ device_utils.DeviceUtils.HealthyDevices = mock.MagicMock(
+ return_value=fake_attached_devices)
+ result = list_verification.DetermineDeviceToUse(user_specified_devices)
+ self.assertEqual(result, fake_attached_devices[0])
+ # pylint: disable=no-member
+ device_utils.DeviceUtils.HealthyDevices.assert_called_with(device_arg=None)
+ # pylint: enable=no-member
+
+ def testDetermineDeviceToUse_emptyListWithNoAttachedDevices(self):
+ user_specified_devices = []
+ device_utils.DeviceUtils.HealthyDevices = mock.MagicMock(
+ side_effect=device_errors.NoDevicesError())
+ with self.assertRaises(device_errors.NoDevicesError) as _:
+ list_verification.DetermineDeviceToUse(user_specified_devices)
+ # pylint: disable=no-member
+ device_utils.DeviceUtils.HealthyDevices.assert_called_with(device_arg=None)
+ # pylint: enable=no-member
+
+ def testDetermineDeviceToUse_oneElementListWithOneAttachedDevice(self):
+ user_specified_devices = ['123']
+ fake_attached_devices = ['123']
+ device_utils.DeviceUtils.HealthyDevices = mock.MagicMock(
+ return_value=fake_attached_devices)
+ result = list_verification.DetermineDeviceToUse(user_specified_devices)
+ self.assertEqual(result, fake_attached_devices[0])
+ # pylint: disable=no-member
+ device_utils.DeviceUtils.HealthyDevices.assert_called_with(
+ device_arg=user_specified_devices)
+ # pylint: enable=no-member
+
+
+class _ListClassVerificationFailuresTest(unittest.TestCase):
+
+ def testPathToDexForPlatformVersion_noPaths(self):
+ sdk_int = version_codes.LOLLIPOP
+ paths_to_apk = []
+ package_name = 'package.name'
+ arch = abis.ARM_64
+
+ device = mock.Mock(build_version_sdk=sdk_int, product_cpu_abi=arch)
+ device.GetApplicationPaths = mock.MagicMock(return_value=paths_to_apk)
+
+ with self.assertRaises(list_verification.DeviceOSError) as cm:
+ list_verification.PathToDexForPlatformVersion(device, package_name)
+ message = str(cm.exception)
+ self.assertIn('Could not find data directory', message)
+
+ def testPathToDexForPlatformVersion_multiplePaths(self):
+ sdk_int = version_codes.LOLLIPOP
+ paths_to_apk = ['/first/path', '/second/path']
+ package_name = 'package.name'
+ arch = abis.ARM_64
+
+ device = mock.Mock(build_version_sdk=sdk_int, product_cpu_abi=arch)
+ device.GetApplicationPaths = mock.MagicMock(return_value=paths_to_apk)
+
+ with self.assertRaises(list_verification.DeviceOSError) as cm:
+ list_verification.PathToDexForPlatformVersion(device, package_name)
+ message = str(cm.exception)
+ self.assertIn('Expected exactly one path for', message)
+
+ def testPathToDexForPlatformVersion_dalvikApiLevel(self):
+ sdk_int = version_codes.KITKAT
+ paths_to_apk = ['/some/path']
+ package_name = 'package.name'
+ arch = abis.ARM_64
+
+ device = mock.Mock(build_version_sdk=sdk_int, product_cpu_abi=arch)
+ device.GetApplicationPaths = mock.MagicMock(return_value=paths_to_apk)
+
+ with self.assertRaises(list_verification.UnsupportedDeviceError) as _:
+ list_verification.PathToDexForPlatformVersion(device, package_name)
+
+ def testPathToDexForPlatformVersion_lollipopArm(self):
+ sdk_int = version_codes.LOLLIPOP
+ package_name = 'package.name'
+ paths_to_apk = ['/some/path/{}-1/base.apk'.format(package_name)]
+ arch = 'arm'
+
+ device = mock.Mock(build_version_sdk=sdk_int, product_cpu_abi=arch)
+ device.GetApplicationPaths = mock.MagicMock(return_value=paths_to_apk)
+ device.FileExists = mock.MagicMock(return_value=True)
+
+ odex_file = list_verification.PathToDexForPlatformVersion(device,
+ package_name)
+ self.assertEqual(odex_file,
+ ('/data/dalvik-cache/arm/data@app'
+ '@package.name-1@base.apk@classes.dex'))
+
+ def testPathToDexForPlatformVersion_mashmallowArm(self):
+ sdk_int = version_codes.MARSHMALLOW
+ package_name = 'package.name'
+ paths_to_apk = ['/some/path/{}-1/base.apk'.format(package_name)]
+ arch = 'arm'
+
+ device = mock.Mock(build_version_sdk=sdk_int, product_cpu_abi=arch)
+ device.GetApplicationPaths = mock.MagicMock(return_value=paths_to_apk)
+ device.FileExists = mock.MagicMock(return_value=True)
+
+ odex_file = list_verification.PathToDexForPlatformVersion(device,
+ package_name)
+ self.assertEqual(odex_file,
+ '/some/path/package.name-1/oat/arm/base.odex')
+
+ def testPathToDexForPlatformVersion_mashmallowArm64(self):
+ sdk_int = version_codes.MARSHMALLOW
+ package_name = 'package.name'
+ paths_to_apk = ['/some/path/{}-1/base.apk'.format(package_name)]
+ arch = abis.ARM_64
+
+ device = mock.Mock(build_version_sdk=sdk_int, product_cpu_abi=arch)
+ device.GetApplicationPaths = mock.MagicMock(return_value=paths_to_apk)
+ device.FileExists = mock.MagicMock(return_value=True)
+
+ odex_file = list_verification.PathToDexForPlatformVersion(device,
+ package_name)
+ self.assertEqual(odex_file,
+ '/some/path/package.name-1/oat/arm64/base.odex')
+
+ def testPathToDexForPlatformVersion_pieNoOdexFile(self):
+ sdk_int = version_codes.PIE
+ package_name = 'package.name'
+ paths_to_apk = ['/some/path/{}-1/base.apk'.format(package_name)]
+ arch = abis.ARM_64
+
+ device = mock.Mock(build_version_sdk=sdk_int, product_cpu_abi=arch)
+ device.GetApplicationPaths = mock.MagicMock(return_value=paths_to_apk)
+ device.FileExists = mock.MagicMock(return_value=False)
+
+ with self.assertRaises(list_verification.DeviceOSError) as cm:
+ list_verification.PathToDexForPlatformVersion(device, package_name)
+ message = str(cm.exception)
+ self.assertIn('you must run dex2oat on debuggable apps on >= P', message)
+
+ def testPathToDexForPlatformVersion_lowerApiLevelNoOdexFile(self):
+ sdk_int = version_codes.MARSHMALLOW
+ package_name = 'package.name'
+ paths_to_apk = ['/some/path/{}-1/base.apk'.format(package_name)]
+ arch = abis.ARM_64
+
+ device = mock.Mock(build_version_sdk=sdk_int, product_cpu_abi=arch)
+ device.GetApplicationPaths = mock.MagicMock(return_value=paths_to_apk)
+ device.FileExists = mock.MagicMock(return_value=False)
+
+ with self.assertRaises(list_verification.DeviceOSError) as _:
+ list_verification.PathToDexForPlatformVersion(device, package_name)
+
+ def testListClasses_noProguardMap(self):
+ oatdump_output = [
+ _CreateOdexLine('a.b.JavaClass1', 6, 'StatusVerified'),
+ _CreateOdexLine('a.b.JavaClass2', 7,
+ 'StatusRetryVerificationAtRuntime'),
+ ]
+
+ classes = list_verification.ListClassesAndVerificationStatus(oatdump_output,
+ None)
+ self.assertEqual(2, len(classes))
+ java_class_1 = _ClassForName('a.b.JavaClass1', classes)
+ java_class_2 = _ClassForName('a.b.JavaClass2', classes)
+ self.assertEqual(java_class_1.verification_status, 'Verified')
+ self.assertEqual(java_class_2.verification_status,
+ 'RetryVerificationAtRuntime')
+
+ def testListClasses_proguardMap(self):
+ oatdump_output = [
+ _CreateOdexLine('a.b.ObfuscatedJavaClass1', 6, 'StatusVerified'),
+ _CreateOdexLine('a.b.ObfuscatedJavaClass2', 7,
+ 'StatusRetryVerificationAtRuntime'),
+ ]
+
+ mapping = {
+ 'a.b.ObfuscatedJavaClass1': 'a.b.JavaClass1',
+ 'a.b.ObfuscatedJavaClass2': 'a.b.JavaClass2',
+ }
+ classes = list_verification.ListClassesAndVerificationStatus(oatdump_output,
+ mapping)
+ self.assertEqual(2, len(classes))
+ java_class_1 = _ClassForName('a.b.JavaClass1', classes)
+ java_class_2 = _ClassForName('a.b.JavaClass2', classes)
+ self.assertEqual(java_class_1.verification_status, 'Verified')
+ self.assertEqual(java_class_2.verification_status,
+ 'RetryVerificationAtRuntime')
+
+ def testListClasses_noStatusPrefix(self):
+ oatdump_output = [
+ _CreateOdexLine('a.b.JavaClass1', 6, 'Verified'),
+ _CreateOdexLine('a.b.JavaClass2', 7, 'RetryVerificationAtRuntime'),
+ ]
+
+ classes = list_verification.ListClassesAndVerificationStatus(oatdump_output,
+ None)
+ self.assertEqual(2, len(classes))
+ java_class_1 = _ClassForName('a.b.JavaClass1', classes)
+ java_class_2 = _ClassForName('a.b.JavaClass2', classes)
+ self.assertEqual(java_class_1.verification_status, 'Verified')
+ self.assertEqual(java_class_2.verification_status,
+ 'RetryVerificationAtRuntime')
+
+if __name__ == '__main__':
+ # Suppress logging messages.
+ unittest.main(buffer=True)