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 StringIO
     19 import unittest
     20 
     21 import symbolize
     22 
     23 LIB_A_PATH = '/build/android/tests/symbolize/liba.so'
     24 LIB_B_PATH = '/build/android/tests/symbolize/libb.so'
     25 
     26 def RunSymbolizer(text):
     27   output = StringIO.StringIO()
     28   s = symbolize.Symbolizer(output)
     29   s.write(text)
     30   return output.getvalue()
     31 
     32 
     33 class SymbolizerUnittest(unittest.TestCase):
     34   def testSingleLineNoMatch(self):
     35     # Leading '#' is required.
     36     expected = '00 0x00000000 ' + LIB_A_PATH + '+0x00000254\n'
     37     self.assertEqual(expected, RunSymbolizer(expected))
     38 
     39     # Whitespace should be exactly one space.
     40     expected = '#00  0x00000000 ' + LIB_A_PATH + '+0x00000254\n'
     41     self.assertEqual(expected, RunSymbolizer(expected))
     42     expected = '#00 0x00000000  ' + LIB_A_PATH + '+0x00000254\n'
     43     self.assertEqual(expected, RunSymbolizer(expected))
     44 
     45     # Decimal stack frame numbers are required.
     46     expected = '#0a 0x00000000 ' + LIB_A_PATH + '+0x00000254\n'
     47     self.assertEqual(expected, RunSymbolizer(expected))
     48 
     49     # Hexadecimal addresses are required.
     50     expected = '#00 0xghijklmn ' + LIB_A_PATH + '+0x00000254\n'
     51     self.assertEqual(expected, RunSymbolizer(expected))
     52     expected = '#00 0x00000000 ' + LIB_A_PATH + '+0xghijklmn\n'
     53     self.assertEqual(expected, RunSymbolizer(expected))
     54 
     55     # Addresses must be exactly 8 characters.
     56     expected = '#00 0x0000000 ' + LIB_A_PATH + '+0x00000254\n'
     57     self.assertEqual(expected, RunSymbolizer(expected))
     58     expected = '#00 0x000000000 ' + LIB_A_PATH + '+0x00000254\n'
     59     self.assertEqual(expected, RunSymbolizer(expected))
     60 
     61     expected = '#00 0x0000000 ' + LIB_A_PATH + '+0x0000254\n'
     62     self.assertEqual(expected, RunSymbolizer(expected))
     63     expected = '#00 0x000000000 ' + LIB_A_PATH + '+0x000000254\n'
     64     self.assertEqual(expected, RunSymbolizer(expected))
     65 
     66     # Addresses must be prefixed with '0x'.
     67     expected = '#00 00000000 ' + LIB_A_PATH + '+0x00000254\n'
     68     self.assertEqual(expected, RunSymbolizer(expected))
     69     expected = '#00 0x00000000 ' + LIB_A_PATH + '+00000254\n'
     70     self.assertEqual(expected, RunSymbolizer(expected))
     71 
     72     # Library name is required.
     73     expected = '#00 0x00000000\n'
     74     self.assertEqual(expected, RunSymbolizer(expected))
     75     expected = '#00 0x00000000 +0x00000254\n'
     76     self.assertEqual(expected, RunSymbolizer(expected))
     77 
     78     # Library name must be followed by offset with no spaces around '+'.
     79     expected = '#00 0x00000000 ' + LIB_A_PATH + ' +0x00000254\n'
     80     self.assertEqual(expected, RunSymbolizer(expected))
     81     expected = '#00 0x00000000 ' + LIB_A_PATH + '+ 0x00000254\n'
     82     self.assertEqual(expected, RunSymbolizer(expected))
     83     expected = '#00 0x00000000 ' + LIB_A_PATH + ' 0x00000254\n'
     84     self.assertEqual(expected, RunSymbolizer(expected))
     85     expected = '#00 0x00000000 ' + LIB_A_PATH + '+\n'
     86     self.assertEqual(expected, RunSymbolizer(expected))
     87 
     88   def testSingleLine(self):
     89     text = '#00 0x00000000 ' + LIB_A_PATH + '+0x00000254\n'
     90     expected = '#00 0x00000000 A::Bar(char const*)\n'
     91     actual = RunSymbolizer(text)
     92     self.assertEqual(expected, actual)
     93 
     94   def testSingleLineWithSurroundingText(self):
     95     text = 'LEFT #00 0x00000000 ' + LIB_A_PATH + '+0x00000254 RIGHT\n'
     96     expected = 'LEFT #00 0x00000000 A::Bar(char const*) RIGHT\n'
     97     actual = RunSymbolizer(text)
     98     self.assertEqual(expected, actual)
     99 
    100   def testMultipleLinesSameLibrary(self):
    101     text = '#00 0x00000000 ' + LIB_A_PATH + '+0x00000254\n'
    102     text += '#01 0x00000000 ' + LIB_A_PATH + '+0x00000234\n'
    103     expected = '#00 0x00000000 A::Bar(char const*)\n'
    104     expected += '#01 0x00000000 A::Foo(int)\n'
    105     actual = RunSymbolizer(text)
    106     self.assertEqual(expected, actual)
    107 
    108   def testMultipleLinesDifferentLibrary(self):
    109     text = '#00 0x00000000 ' + LIB_A_PATH + '+0x00000254\n'
    110     text += '#01 0x00000000 ' + LIB_B_PATH + '+0x00000234\n'
    111     expected = '#00 0x00000000 A::Bar(char const*)\n'
    112     expected += '#01 0x00000000 B::Baz(float)\n'
    113     actual = RunSymbolizer(text)
    114     self.assertEqual(expected, actual)
    115 
    116   def testMultipleLinesWithSurroundingTextEverywhere(self):
    117     text = 'TOP\n'
    118     text += 'LEFT #00 0x00000000 ' + LIB_A_PATH + '+0x00000254 RIGHT\n'
    119     text += 'LEFT #01 0x00000000 ' + LIB_B_PATH + '+0x00000234 RIGHT\n'
    120     text += 'BOTTOM\n'
    121     expected = 'TOP\n'
    122     expected += 'LEFT #00 0x00000000 A::Bar(char const*) RIGHT\n'
    123     expected += 'LEFT #01 0x00000000 B::Baz(float) RIGHT\n'
    124     expected += 'BOTTOM\n'
    125     actual = RunSymbolizer(text)
    126     self.assertEqual(expected, actual)
    127 
    128 
    129 if __name__ == '__main__':
    130   unittest.main()
    131