Home | History | Annotate | Download | only in android
      1 #!/usr/bin/env python
      2 #
      3 # Copyright 2013 The Chromium Authors. All rights reserved.
      4 # Use of this source code is governed by a BSD-style license that can be
      5 # found in the LICENSE file.
      6 
      7 """Unittest for symbolize.py.
      8 
      9 This test uses test libraries generated by the Android g++ toolchain.
     10 
     11 Should things break you can recreate the libraries and get the updated
     12 addresses and demangled names by running the following:
     13   cd test/symbolize/
     14   make
     15   nm -gC *.so
     16 """
     17 
     18 import sys
     19 import StringIO
     20 import unittest
     21 
     22 import symbolize
     23 
     24 LIB_A_PATH = '/build/android/tests/symbolize/liba.so'
     25 LIB_B_PATH = '/build/android/tests/symbolize/libb.so'
     26 
     27 def RunSymbolizer(text):
     28   output = StringIO.StringIO()
     29   s = symbolize.Symbolizer(output)
     30   s.write(text)
     31   return output.getvalue()
     32 
     33 
     34 class SymbolizerUnittest(unittest.TestCase):
     35   def testSingleLineNoMatch(self):
     36     # Leading '#' is required.
     37     expected = '00 0x00000000 ' + LIB_A_PATH + '+0x00000254\n'
     38     self.assertEqual(expected, RunSymbolizer(expected))
     39 
     40     # Whitespace should be exactly one space.
     41     expected = '#00  0x00000000 ' + LIB_A_PATH + '+0x00000254\n'
     42     self.assertEqual(expected, RunSymbolizer(expected))
     43     expected = '#00 0x00000000  ' + LIB_A_PATH + '+0x00000254\n'
     44     self.assertEqual(expected, RunSymbolizer(expected))
     45 
     46     # Decimal stack frame numbers are required.
     47     expected = '#0a 0x00000000 ' + LIB_A_PATH + '+0x00000254\n'
     48     self.assertEqual(expected, RunSymbolizer(expected))
     49 
     50     # Hexadecimal addresses are required.
     51     expected = '#00 0xghijklmn ' + LIB_A_PATH + '+0x00000254\n'
     52     self.assertEqual(expected, RunSymbolizer(expected))
     53     expected = '#00 0x00000000 ' + LIB_A_PATH + '+0xghijklmn\n'
     54     self.assertEqual(expected, RunSymbolizer(expected))
     55 
     56     # Addresses must be exactly 8 characters.
     57     expected = '#00 0x0000000 ' + LIB_A_PATH + '+0x00000254\n'
     58     self.assertEqual(expected, RunSymbolizer(expected))
     59     expected = '#00 0x000000000 ' + LIB_A_PATH + '+0x00000254\n'
     60     self.assertEqual(expected, RunSymbolizer(expected))
     61 
     62     expected = '#00 0x0000000 ' + LIB_A_PATH + '+0x0000254\n'
     63     self.assertEqual(expected, RunSymbolizer(expected))
     64     expected = '#00 0x000000000 ' + LIB_A_PATH + '+0x000000254\n'
     65     self.assertEqual(expected, RunSymbolizer(expected))
     66 
     67     # Addresses must be prefixed with '0x'.
     68     expected = '#00 00000000 ' + LIB_A_PATH + '+0x00000254\n'
     69     self.assertEqual(expected, RunSymbolizer(expected))
     70     expected = '#00 0x00000000 ' + LIB_A_PATH + '+00000254\n'
     71     self.assertEqual(expected, RunSymbolizer(expected))
     72 
     73     # Library name is required.
     74     expected = '#00 0x00000000\n'
     75     self.assertEqual(expected, RunSymbolizer(expected))
     76     expected = '#00 0x00000000 +0x00000254\n'
     77     self.assertEqual(expected, RunSymbolizer(expected))
     78 
     79     # Library name must be followed by offset with no spaces around '+'.
     80     expected = '#00 0x00000000 ' + LIB_A_PATH + ' +0x00000254\n'
     81     self.assertEqual(expected, RunSymbolizer(expected))
     82     expected = '#00 0x00000000 ' + LIB_A_PATH + '+ 0x00000254\n'
     83     self.assertEqual(expected, RunSymbolizer(expected))
     84     expected = '#00 0x00000000 ' + LIB_A_PATH + ' 0x00000254\n'
     85     self.assertEqual(expected, RunSymbolizer(expected))
     86     expected = '#00 0x00000000 ' + LIB_A_PATH + '+\n'
     87     self.assertEqual(expected, RunSymbolizer(expected))
     88 
     89   def testSingleLine(self):
     90     text = '#00 0x00000000 ' + LIB_A_PATH + '+0x00000254\n'
     91     expected = '#00 0x00000000 A::Bar(char const*)\n'
     92     actual = RunSymbolizer(text)
     93     self.assertEqual(expected, actual)
     94 
     95   def testSingleLineWithSurroundingText(self):
     96     text = 'LEFT #00 0x00000000 ' + LIB_A_PATH + '+0x00000254 RIGHT\n'
     97     expected = 'LEFT #00 0x00000000 A::Bar(char const*) RIGHT\n'
     98     actual = RunSymbolizer(text)
     99     self.assertEqual(expected, actual)
    100 
    101   def testMultipleLinesSameLibrary(self):
    102     text = '#00 0x00000000 ' + LIB_A_PATH + '+0x00000254\n'
    103     text += '#01 0x00000000 ' + LIB_A_PATH + '+0x00000234\n'
    104     expected = '#00 0x00000000 A::Bar(char const*)\n'
    105     expected += '#01 0x00000000 A::Foo(int)\n'
    106     actual = RunSymbolizer(text)
    107     self.assertEqual(expected, actual)
    108 
    109   def testMultipleLinesDifferentLibrary(self):
    110     text = '#00 0x00000000 ' + LIB_A_PATH + '+0x00000254\n'
    111     text += '#01 0x00000000 ' + LIB_B_PATH + '+0x00000234\n'
    112     expected = '#00 0x00000000 A::Bar(char const*)\n'
    113     expected += '#01 0x00000000 B::Baz(float)\n'
    114     actual = RunSymbolizer(text)
    115     self.assertEqual(expected, actual)
    116 
    117   def testMultipleLinesWithSurroundingTextEverywhere(self):
    118     text = 'TOP\n'
    119     text += 'LEFT #00 0x00000000 ' + LIB_A_PATH + '+0x00000254 RIGHT\n'
    120     text += 'LEFT #01 0x00000000 ' + LIB_B_PATH + '+0x00000234 RIGHT\n'
    121     text += 'BOTTOM\n'
    122     expected = 'TOP\n'
    123     expected += 'LEFT #00 0x00000000 A::Bar(char const*) RIGHT\n'
    124     expected += 'LEFT #01 0x00000000 B::Baz(float) RIGHT\n'
    125     expected += 'BOTTOM\n'
    126     actual = RunSymbolizer(text)
    127     self.assertEqual(expected, actual)
    128 
    129 
    130 if __name__ == '__main__':
    131   unittest.main()
    132