# 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)
