12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#!/usr/bin/env python
2a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)# Copyright 2013 The Chromium Authors. All rights reserved.
32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)# Use of this source code is governed by a BSD-style license that can be
42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)# found in the LICENSE file.
52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)import cStringIO
72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)import logging
82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)import os
92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)import sys
102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)import unittest
112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ROOT_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)sys.path.insert(0, ROOT_DIR)
142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
15a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)from procfs import ProcMaps
162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class ProcMapsTest(unittest.TestCase):
192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  _TEST_PROCMAPS = '\n'.join([
202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      '00000000-00001000 r--p 00000000 fc:00 0',
212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      '0080b000-0080c000 r-xp 0020b000 fc:00 2231329'
222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          '                            /usr/bin/some',
232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      '0080c000-0080f000 ---p 0020c000 fc:00 2231329'
242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          '                            /usr/bin/some',
252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      '0100a000-0100c000 r-xp 0120a000 fc:00 22381'
262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          '                            /usr/bin/chrome',
272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      '0100c000-0100f000 ---p 0120c000 fc:00 22381'
282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          '                            /usr/bin/chrome',
292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      '0237d000-02a9b000 rw-p 00000000 00:00 0'
302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          '                                  [heap]',
312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      '7fb920e6d000-7fb920e85000 r-xp 00000000 fc:00 263482'
322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          '                     /lib/x86_64-linux-gnu/libpthread-2.15.so',
332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      '7fb920e85000-7fb921084000 ---p 00018000 fc:00 263482'
342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          '                     /lib/x86_64-linux-gnu/libpthread-2.15.so',
352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      '7fb9225f4000-7fb922654000 rw-s 00000000 00:04 19660808'
362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          '                   /SYSV00000000 (deleted)',
372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      'ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0'
382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          '                  [vsyscall]',
392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ])
402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  _EXPECTED = [
422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      (0x0, 0x1000, 'r', '-', '-', 'p', 0x0, 'fc', '00', 0, ''),
432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      (0x80b000, 0x80c000, 'r', '-', 'x', 'p', 0x20b000,
442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       'fc', '00', 2231329, '/usr/bin/some'),
452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      (0x80c000, 0x80f000, '-', '-', '-', 'p', 0x20c000,
462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       'fc', '00', 2231329, '/usr/bin/some'),
472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      (0x100a000, 0x100c000, 'r', '-', 'x', 'p', 0x120a000,
482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       'fc', '00', 22381, '/usr/bin/chrome'),
492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      (0x100c000, 0x100f000, '-', '-', '-', 'p', 0x120c000,
502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       'fc', '00', 22381, '/usr/bin/chrome'),
512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      (0x237d000, 0x2a9b000, 'r', 'w', '-', 'p', 0x0,
522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       '00', '00', 0, '[heap]'),
532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      (0x7fb920e6d000, 0x7fb920e85000, 'r', '-', 'x', 'p', 0x0,
542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       'fc', '00', 263482, '/lib/x86_64-linux-gnu/libpthread-2.15.so'),
552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      (0x7fb920e85000, 0x7fb921084000, '-', '-', '-', 'p', 0x18000,
562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       'fc', '00', 263482, '/lib/x86_64-linux-gnu/libpthread-2.15.so'),
572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      (0x7fb9225f4000, 0x7fb922654000, 'r', 'w', '-', 's', 0x0,
582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       '00', '04', 19660808, '/SYSV00000000 (deleted)'),
592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      (0xffffffffff600000, 0xffffffffff601000, 'r', '-', 'x', 'p', 0x0,
602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       '00', '00', 0, '[vsyscall]'),
612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ]
622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  @staticmethod
642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  def _expected_as_dict(index):
652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return {
662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        'begin': ProcMapsTest._EXPECTED[index][0],
672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        'end': ProcMapsTest._EXPECTED[index][1],
682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        'readable': ProcMapsTest._EXPECTED[index][2],
692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        'writable': ProcMapsTest._EXPECTED[index][3],
702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        'executable': ProcMapsTest._EXPECTED[index][4],
712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        'private': ProcMapsTest._EXPECTED[index][5],
722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        'offset': ProcMapsTest._EXPECTED[index][6],
732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        'major': ProcMapsTest._EXPECTED[index][7],
742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        'minor': ProcMapsTest._EXPECTED[index][8],
752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        'inode': ProcMapsTest._EXPECTED[index][9],
762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        'name': ProcMapsTest._EXPECTED[index][10],
772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        }
782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  def test_load(self):
80a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    maps = ProcMaps.load_file(cStringIO.StringIO(self._TEST_PROCMAPS))
812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    for index, entry in enumerate(maps):
822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      self.assertEqual(entry.as_dict(), self._expected_as_dict(index))
832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  def test_constants(self):
85a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    maps = ProcMaps.load_file(cStringIO.StringIO(self._TEST_PROCMAPS))
86cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    selected = [0, 2, 4, 7]
872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    for index, entry in enumerate(maps.iter(ProcMaps.constants)):
882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      self.assertEqual(entry.as_dict(),
892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                       self._expected_as_dict(selected[index]))
902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  def test_executable(self):
92a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    maps = ProcMaps.load_file(cStringIO.StringIO(self._TEST_PROCMAPS))
93cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    selected = [1, 3, 6, 9]
942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    for index, entry in enumerate(maps.iter(ProcMaps.executable)):
952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      self.assertEqual(entry.as_dict(),
962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                       self._expected_as_dict(selected[index]))
972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  def test_executable_and_constants(self):
99a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    maps = ProcMaps.load_file(cStringIO.StringIO(self._TEST_PROCMAPS))
100cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    selected = [0, 1, 2, 3, 4, 6, 7, 9]
1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    for index, entry in enumerate(maps.iter(ProcMaps.executable_and_constants)):
1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      self.assertEqual(entry.as_dict(),
1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                       self._expected_as_dict(selected[index]))
1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)if __name__ == '__main__':
1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  logging.basicConfig(
1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      level=logging.DEBUG if '-v' in sys.argv else logging.ERROR,
1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      format='%(levelname)5s %(filename)15s(%(lineno)3d): %(message)s')
1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  unittest.main()
111