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

"""Tests for convert_dex_profile.

Can be run from build/android/:
  $ cd build/android
  $ python convert_dex_profile_tests.py
"""

import os
import sys
import tempfile
import unittest

import convert_dex_profile as cp

sys.path.insert(1, os.path.join(os.path.dirname(__file__), 'gyp'))
from util import build_utils

cp.logging.disable(cp.logging.CRITICAL)

# There are two obfuscations used in the tests below, each with the same
# unobfuscated profile. The first, corresponding to DEX_DUMP, PROGUARD_MAPPING,
# and OBFUSCATED_PROFILE, has an ambiguous method a() which is mapped to both
# getInstance and initialize. The second, corresponding to DEX_DUMP_2,
# PROGUARD_MAPPING_2 and OBFUSCATED_PROFILE_2, removes the ambiguity.

DEX_DUMP = """

Class descriptor  : 'La;'
  Direct methods    -
      #0              : (in La;)
        name          : '<clinit>'
        type          : '(Ljava/lang/String;)V'
        code          -
        catches       : 1
                0x000f - 0x001e
                  <any> -> 0x0093
        positions     :
                0x0001 line=310
                0x0057 line=313
        locals        : 
      #1              : (in La;)
        name          : '<init>'
        type          : '()V'
        positions     :
        locals        : 
  Virtual methods   -
      #0              : (in La;)
        name          : 'a'
        type          : '(Ljava/lang/String;)I'
        positions     : 
          0x0000 line=2
          0x0003 line=3
          0x001b line=8
        locals        : 
          0x0000 - 0x0021 reg=3 this La; 
      #1              : (in La;)
        name          : 'a'
        type          : '(Ljava/lang/Object;)I'
        positions     : 
          0x0000 line=8
          0x0003 line=9
        locals        : 
          0x0000 - 0x0021 reg=3 this La; 
      #2              : (in La;)
        name          : 'b'
        type          : '()La;'
        positions     : 
          0x0000 line=1
        locals        : 
"""

# pylint: disable=line-too-long
PROGUARD_MAPPING = \
"""org.chromium.Original -> a:
    org.chromium.Original sDisplayAndroidManager -> e
    org.chromium.Original another() -> b
    4:4:void inlined():237:237 -> a
    4:4:org.chromium.Original getInstance():203 -> a
    5:5:void org.chromium.Original$Subclass.<init>(org.chromium.Original,byte):130:130 -> a
    5:5:void initialize():237 -> a
    5:5:org.chromium.Original getInstance():203 -> a
    6:6:void initialize():237:237 -> a
    9:9:android.content.Context org.chromium.base.ContextUtils.getApplicationContext():49:49 -> a
    9:9:android.content.Context getContext():219 -> a
    9:9:void initialize():245 -> a
    9:9:org.chromium.Original getInstance():203 -> a"""

OBFUSCATED_PROFILE = \
"""La;
PLa;->b()La;
SLa;->a(Ljava/lang/Object;)I
HPLa;->a(Ljava/lang/String;)I"""

DEX_DUMP_2 = """

Class descriptor  : 'La;'
  Direct methods    -
      #0              : (in La;)
        name          : '<clinit>'
        type          : '(Ljava/lang/String;)V'
        code          -
        catches       : 1
                0x000f - 0x001e
                  <any> -> 0x0093
        positions     :
                0x0001 line=310
                0x0057 line=313
        locals        : 
      #1              : (in La;)
        name          : '<init>'
        type          : '()V'
        positions     :
        locals        : 
  Virtual methods   -
      #0              : (in La;)
        name          : 'a'
        type          : '(Ljava/lang/String;)I'
        positions     : 
          0x0000 line=2
          0x0003 line=3
          0x001b line=8
        locals        : 
          0x0000 - 0x0021 reg=3 this La; 
      #1              : (in La;)
        name          : 'c'
        type          : '(Ljava/lang/Object;)I'
        positions     : 
          0x0000 line=8
          0x0003 line=9
        locals        : 
          0x0000 - 0x0021 reg=3 this La; 
      #2              : (in La;)
        name          : 'b'
        type          : '()La;'
        positions     : 
          0x0000 line=1
        locals        : 
"""

# pylint: disable=line-too-long
PROGUARD_MAPPING_2 = \
"""org.chromium.Original -> a:
    org.chromium.Original sDisplayAndroidManager -> e
    org.chromium.Original another() -> b
    void initialize() -> c
    org.chromium.Original getInstance():203 -> a
    4:4:void inlined():237:237 -> a"""

OBFUSCATED_PROFILE_2 = \
"""La;
PLa;->b()La;
HPSLa;->a()La;
HPLa;->c()V"""

UNOBFUSCATED_PROFILE = \
"""Lorg/chromium/Original;
PLorg/chromium/Original;->another()Lorg/chromium/Original;
HPSLorg/chromium/Original;->getInstance()Lorg/chromium/Original;
HPLorg/chromium/Original;->initialize()V"""

class GenerateProfileTests(unittest.TestCase):
  def testProcessDex(self):
    dex = cp.ProcessDex(DEX_DUMP.splitlines())
    self.assertIsNotNone(dex['a'])

    self.assertEquals(len(dex['a'].FindMethodsAtLine('<clinit>', 311, 313)), 1)
    self.assertEquals(len(dex['a'].FindMethodsAtLine('<clinit>', 309, 315)), 1)
    clinit = dex['a'].FindMethodsAtLine('<clinit>', 311, 313)[0]
    self.assertEquals(clinit.name, '<clinit>')
    self.assertEquals(clinit.return_type, 'V')
    self.assertEquals(clinit.param_types, 'Ljava/lang/String;')

    self.assertEquals(len(dex['a'].FindMethodsAtLine('a', 8, None)), 2)
    self.assertIsNone(dex['a'].FindMethodsAtLine('a', 100, None))

# pylint: disable=protected-access
  def testProcessProguardMapping(self):
    dex = cp.ProcessDex(DEX_DUMP.splitlines())
    mapping, reverse = cp.ProcessProguardMapping(
        PROGUARD_MAPPING.splitlines(), dex)

    self.assertEquals('La;', reverse.GetClassMapping('Lorg/chromium/Original;'))

    getInstance = cp.Method(
        'getInstance', 'Lorg/chromium/Original;', '', 'Lorg/chromium/Original;')
    initialize = cp.Method('initialize', 'Lorg/chromium/Original;', '', 'V')
    another = cp.Method(
        'another', 'Lorg/chromium/Original;', '', 'Lorg/chromium/Original;')
    subclassInit = cp.Method(
        '<init>', 'Lorg/chromium/Original$Subclass;',
        'Lorg/chromium/Original;B', 'V')

    mapped = mapping.GetMethodMapping(
        cp.Method('a', 'La;', 'Ljava/lang/String;', 'I'))
    self.assertEquals(len(mapped), 2)
    self.assertIn(getInstance, mapped)
    self.assertNotIn(subclassInit, mapped)
    self.assertNotIn(
        cp.Method('inlined', 'Lorg/chromium/Original;', '', 'V'), mapped)
    self.assertIn(initialize, mapped)

    mapped = mapping.GetMethodMapping(
        cp.Method('a', 'La;', 'Ljava/lang/Object;', 'I'))
    self.assertEquals(len(mapped), 1)
    self.assertIn(getInstance, mapped)

    mapped = mapping.GetMethodMapping(cp.Method('b', 'La;', '', 'La;'))
    self.assertEquals(len(mapped), 1)
    self.assertIn(another, mapped)

    for from_method, to_methods in mapping._method_mapping.iteritems():
      for to_method in to_methods:
        self.assertIn(from_method, reverse.GetMethodMapping(to_method))
    for from_class, to_class in mapping._class_mapping.iteritems():
      self.assertEquals(from_class, reverse.GetClassMapping(to_class))

  def testProcessProfile(self):
    dex = cp.ProcessDex(DEX_DUMP.splitlines())
    mapping, _ = cp.ProcessProguardMapping(PROGUARD_MAPPING.splitlines(), dex)
    profile = cp.ProcessProfile(OBFUSCATED_PROFILE.splitlines(), mapping)

    getInstance = cp.Method(
        'getInstance', 'Lorg/chromium/Original;', '', 'Lorg/chromium/Original;')
    initialize = cp.Method('initialize', 'Lorg/chromium/Original;', '', 'V')
    another = cp.Method(
        'another', 'Lorg/chromium/Original;', '', 'Lorg/chromium/Original;')

    self.assertIn('Lorg/chromium/Original;', profile._classes)
    self.assertIn(getInstance, profile._methods)
    self.assertIn(initialize, profile._methods)
    self.assertIn(another, profile._methods)

    self.assertEquals(profile._methods[getInstance], set(['H', 'S', 'P']))
    self.assertEquals(profile._methods[initialize], set(['H', 'P']))
    self.assertEquals(profile._methods[another], set(['P']))

  def testEndToEnd(self):
    dex = cp.ProcessDex(DEX_DUMP.splitlines())
    mapping, _ = cp.ProcessProguardMapping(PROGUARD_MAPPING.splitlines(), dex)

    profile = cp.ProcessProfile(OBFUSCATED_PROFILE.splitlines(), mapping)
    with tempfile.NamedTemporaryFile() as temp:
      profile.WriteToFile(temp.name)
      with open(temp.name, 'r') as f:
        for a, b in zip(sorted(f), sorted(UNOBFUSCATED_PROFILE.splitlines())):
          self.assertEquals(a.strip(), b.strip())

  def testObfuscateProfile(self):
    with build_utils.TempDir() as temp_dir:
      # The dex dump is used as the dexfile, by passing /bin/cat as the dexdump
      # program.
      dex_path = os.path.join(temp_dir, 'dexdump')
      with open(dex_path, 'w') as dex_file:
        dex_file.write(DEX_DUMP_2)
      mapping_path = os.path.join(temp_dir, 'mapping')
      with open(mapping_path, 'w') as mapping_file:
        mapping_file.write(PROGUARD_MAPPING_2)
      unobfuscated_path = os.path.join(temp_dir, 'unobfuscated')
      with open(unobfuscated_path, 'w') as unobfuscated_file:
        unobfuscated_file.write(UNOBFUSCATED_PROFILE)
      obfuscated_path = os.path.join(temp_dir, 'obfuscated')
      cp.ObfuscateProfile(unobfuscated_path, dex_path, mapping_path, '/bin/cat',
                          obfuscated_path)
      with open(obfuscated_path) as obfuscated_file:
        obfuscated_profile = sorted(obfuscated_file.readlines())
      for a, b in zip(
          sorted(OBFUSCATED_PROFILE_2.splitlines()), obfuscated_profile):
        self.assertEquals(a.strip(), b.strip())


if __name__ == '__main__':
  unittest.main()
