diff options
Diffstat (limited to 'third_party/libwebrtc/build/android/stacktrace/java_deobfuscate_test.py')
-rwxr-xr-x | third_party/libwebrtc/build/android/stacktrace/java_deobfuscate_test.py | 172 |
1 files changed, 172 insertions, 0 deletions
diff --git a/third_party/libwebrtc/build/android/stacktrace/java_deobfuscate_test.py b/third_party/libwebrtc/build/android/stacktrace/java_deobfuscate_test.py new file mode 100755 index 0000000000..d68323f129 --- /dev/null +++ b/third_party/libwebrtc/build/android/stacktrace/java_deobfuscate_test.py @@ -0,0 +1,172 @@ +#!/usr/bin/env vpython3 +# +# Copyright 2017 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 java_deobfuscate.""" + +import argparse +import os +import subprocess +import sys +import tempfile +import unittest + +# Set by command-line argument. +_JAVA_DEOBFUSCATE_PATH = None + +LINE_PREFIXES = [ + '', + # logcat -v threadtime + '09-08 14:38:35.535 18029 18084 E qcom_sensors_hal: ', + # logcat + 'W/GCM (15158): ', + 'W/GCM ( 158): ', +] + +TEST_MAP = """\ +this.was.Deobfuscated -> FOO: + int[] mFontFamily -> a + 1:3:void someMethod(int,android.os.Bundle):65:67 -> bar +never.Deobfuscated -> NOTFOO: + int[] mFontFamily -> a + 1:3:void someMethod(int,android.os.Bundle):65:67 -> bar +""" + +TEST_DATA = [ + '', + 'FOO', + 'FOO.bar', + 'Here is a FOO', + 'Here is a class FOO', + 'Here is a class FOO baz', + 'Here is a "FOO" baz', + 'Here is a type "FOO" baz', + 'Here is a "FOO.bar" baz', + 'SomeError: SomeFrameworkClass in isTestClass for FOO', + 'Here is a FOO.bar', + 'Here is a FOO.bar baz', + 'END FOO#bar', + 'new-instance 3810 (LSome/Framework/Class;) in LFOO;', + 'FOO: Error message', + 'Caused by: FOO: Error message', + '\tat FOO.bar(PG:1)', + '\t at\t FOO.bar\t (\t PG:\t 1\t )', + ('Unable to start activity ComponentInfo{garbage.in/here.test}:' + ' java.lang.NullPointerException: Attempt to invoke interface method' + ' \'void FOO.bar(int,android.os.Bundle)\' on a null object reference'), + ('Caused by: java.lang.NullPointerException: Attempt to read from field' + ' \'int[] FOO.a\' on a null object reference'), + 'java.lang.VerifyError: FOO', + ('java.lang.NoSuchFieldError: No instance field a of type ' + 'Ljava/lang/Class; in class LFOO;'), + 'NOTFOO: Object of type FOO was not destroyed...', +] + +EXPECTED_OUTPUT = [ + '', + 'this.was.Deobfuscated', + 'this.was.Deobfuscated.someMethod', + 'Here is a FOO', + 'Here is a class this.was.Deobfuscated', + 'Here is a class FOO baz', + 'Here is a "FOO" baz', + 'Here is a type "this.was.Deobfuscated" baz', + 'Here is a "this.was.Deobfuscated.someMethod" baz', + 'SomeError: SomeFrameworkClass in isTestClass for this.was.Deobfuscated', + 'Here is a this.was.Deobfuscated.someMethod', + 'Here is a FOO.bar baz', + 'END this.was.Deobfuscated#someMethod', + 'new-instance 3810 (LSome/Framework/Class;) in Lthis/was/Deobfuscated;', + 'this.was.Deobfuscated: Error message', + 'Caused by: this.was.Deobfuscated: Error message', + '\tat this.was.Deobfuscated.someMethod(Deobfuscated.java:65)', + ('\t at\t this.was.Deobfuscated.someMethod\t ' + '(\t Deobfuscated.java:\t 65\t )'), + ('Unable to start activity ComponentInfo{garbage.in/here.test}:' + ' java.lang.NullPointerException: Attempt to invoke interface method' + ' \'void this.was.Deobfuscated.someMethod(int,android.os.Bundle)\' on a' + ' null object reference'), + ('Caused by: java.lang.NullPointerException: Attempt to read from field' + ' \'int[] this.was.Deobfuscated.mFontFamily\' on a null object reference'), + 'java.lang.VerifyError: this.was.Deobfuscated', + ('java.lang.NoSuchFieldError: No instance field mFontFamily of type ' + 'Ljava/lang/Class; in class Lthis/was/Deobfuscated;'), + 'NOTFOO: Object of type this.was.Deobfuscated was not destroyed...', +] +TEST_DATA = [s + '\n' for s in TEST_DATA] +EXPECTED_OUTPUT = [s + '\n' for s in EXPECTED_OUTPUT] + + +class JavaDeobfuscateTest(unittest.TestCase): + + def __init__(self, *args, **kwargs): + super(JavaDeobfuscateTest, self).__init__(*args, **kwargs) + self._map_file = None + + def setUp(self): + self._map_file = tempfile.NamedTemporaryFile() + self._map_file.write(TEST_MAP) + self._map_file.flush() + + def tearDown(self): + if self._map_file: + self._map_file.close() + + def _testImpl(self, input_lines=None, expected_output_lines=None, + prefix=''): + self.assertTrue(bool(input_lines) == bool(expected_output_lines)) + + if not input_lines: + input_lines = [prefix + x for x in TEST_DATA] + if not expected_output_lines: + expected_output_lines = [prefix + x for x in EXPECTED_OUTPUT] + + cmd = [_JAVA_DEOBFUSCATE_PATH, self._map_file.name] + proc = subprocess.Popen(cmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE) + proc_output, _ = proc.communicate(''.join(input_lines)) + actual_output_lines = proc_output.splitlines(True) + for actual, expected in zip(actual_output_lines, expected_output_lines): + self.assertTrue( + actual == expected or actual.replace('bar', 'someMethod') == expected, + msg=''.join([ + 'Deobfuscation failed.\n', + ' actual: %s' % actual, + ' expected: %s' % expected])) + + def testNoPrefix(self): + self._testImpl(prefix='') + + def testThreadtimePrefix(self): + self._testImpl(prefix='09-08 14:38:35.535 18029 18084 E qcom_sensors_hal: ') + + def testStandardPrefix(self): + self._testImpl(prefix='W/GCM (15158): ') + + def testStandardPrefixWithPadding(self): + self._testImpl(prefix='W/GCM ( 158): ') + + @unittest.skip('causes java_deobfuscate to hang, see crbug.com/876539') + def testIndefiniteHang(self): + # Test for crbug.com/876539. + self._testImpl( + input_lines=[ + 'VFY: unable to resolve virtual method 2: LFOO;' + + '.onDescendantInvalidated ' + + '(Landroid/view/View;Landroid/view/View;)V', + ], + expected_output_lines=[ + 'VFY: unable to resolve virtual method 2: Lthis.was.Deobfuscated;' + + '.onDescendantInvalidated ' + + '(Landroid/view/View;Landroid/view/View;)V', + ]) + + +if __name__ == '__main__': + parser = argparse.ArgumentParser() + parser.add_argument('--java-deobfuscate-path', type=os.path.realpath, + required=True) + known_args, unittest_args = parser.parse_known_args() + _JAVA_DEOBFUSCATE_PATH = known_args.java_deobfuscate_path + unittest_args = [sys.argv[0]] + unittest_args + unittest.main(argv=unittest_args) |