mmap_classifier_unittest.py revision a1401311d1ab56c4ed0a474bd38c108f75cb0cd9
1# Copyright 2014 The Chromium Authors. All rights reserved.
2# Use of this source code is governed by a BSD-style license that can be
3# found in the LICENSE file.
4
5import unittest
6
7from memory_inspector.classification import mmap_classifier
8from memory_inspector.core import memory_map
9
10
11_TEST_RULES = """
12[
13{
14  'name': 'anon',
15  'mmap_file': r'^\[anon',
16  'children': [
17    {
18      'name': 'jit',
19      'mmap_prot': 'r-x',
20    },
21  ],
22},
23{
24  'name': 'dev',
25  'mmap_file': r'^/dev',
26  'children': [
27    {
28      'name': 'gpu',
29      'mmap_file': r'/gpu',
30    },
31  ],
32},
33{
34  'name': 'lib',
35  'mmap_file': r'.so$',
36  'children': [
37    {
38      'name': 'data',
39      'mmap_prot': 'rw',
40    },
41    {
42      'name': 'text',
43      'mmap_prot': 'r-x',
44    },
45  ],
46},
47]
48"""
49
50_TEST_MMAPS = [
51#    START    END      PROT    FILE          P.Dirt  P.Clean  S.Dirt  S.Clean
52    (0x00000, 0x03fff, 'rw--', '[anon]',     4096,   0,       4096,   0),
53    (0x04000, 0x07fff, 'rw--', '/lib/1.so',  8192,   0,       0,      0),
54    (0x08000, 0x0bfff, 'r-x-', '/lib/1.so',  4096,   8192,    0,      0),
55    (0x0c000, 0x0ffff, 'rw--', '/lib/2.so',  0,      0,       4096,   8192),
56    (0x10000, 0x13fff, 'r-x-', '/lib/2.so',  0,      12288,   0,      4096),
57    (0x14000, 0x17fff, 'rw--', '/dev/gpu/1', 4096,   0,       0,      0),
58    (0x18000, 0x1bfff, 'rw--', '/dev/gpu/2', 8192,   0,       4096,   0),
59    (0x1c000, 0x1ffff, 'rw--', '/dev/foo',   0,      4096,    0,      8192),
60    (0x20000, 0x23fff, 'r-x-', '[anon:jit]', 8192,   0,       4096,   0),
61    (0x24000, 0x27fff, 'r---', 'OTHER',      0,      0,       8192,   0),
62]
63
64_EXPECTED_RESULTS = {
65    'Total':                                [36864,  24576,  24576,  20480],
66    'Total::anon':                          [12288,  0,      8192,   0],
67    'Total::anon::jit':                     [8192,   0,      4096,   0],
68    'Total::anon::anon-other':              [4096,   0,      4096,   0],
69    'Total::dev':                           [12288,  4096,   4096,   8192],
70    'Total::dev::gpu':                      [12288,  0,      4096,   0],
71    'Total::dev::dev-other':                [0,      4096,   0,      8192],
72    'Total::lib':                           [12288,  20480,  4096,   12288],
73    'Total::lib::data':                     [8192,   0,      4096,   8192],
74    'Total::lib::text':                     [4096,   20480,  0,      4096],
75    'Total::lib::lib-other':                [0,      0,      0,      0],
76    'Total::Total-other':                   [0,      0,      8192,   0],
77}
78
79
80
81class MmapClassifierTest(unittest.TestCase):
82  def runTest(self):
83    rule_tree = mmap_classifier.LoadRules(_TEST_RULES)
84    mmap = memory_map.Map()
85    for m in _TEST_MMAPS:
86      mmap.Add(memory_map.MapEntry(
87          m[0], m[1], m[2], m[3], 0, m[4], m[5], m[6], m[7]))
88
89    res = mmap_classifier.Classify(mmap, rule_tree)
90
91    def CheckResult(node, prefix):
92      node_name = prefix + node.name
93      self.assertIn(node_name, _EXPECTED_RESULTS)
94      subtotal = node.values[0]
95      values = node.values[1:]
96
97      # First check that the subtotal matches clean + dirty + shared + priv.
98      self.assertEqual(subtotal, values[0] + values[1] + values[2] + values[3])
99
100      # Then check that the single values match the expectations.
101      self.assertEqual(values, _EXPECTED_RESULTS[node_name])
102
103      for child in node.children:
104        CheckResult(child, node_name + '::')
105
106    CheckResult(res.total, '')