linux_perf_report_test.py 5.25 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
# Copyright 2016 the V8 project authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

import linux_perf_report as ipr
import StringIO
import unittest


PERF_SCRIPT_OUTPUT = """
# This line is a comment
# This should be ignored too
#
#    cdefab01  aRandomSymbol::Name(to, be, ignored)

   00000000 firstSymbol
   00000123 secondSymbol

   01234567 foo
   abcdef76 BytecodeHandler:bar
   76543210 baz

# Indentation shouldn't matter (neither should this line)

    01234567 foo
      abcdef76 BytecodeHandler:bar
        76543210 baz

      01234567 beep
   abcdef76 BytecodeHandler:bar
    76543210 baz

   01234567 hello
   abcdef76 v8::internal::Compiler
   00000000 Stub:CEntryStub
   76543210 world
   11111111 BytecodeHandler:nope

   00000000 Lost
   11111111 Builtin:InterpreterEntryTrampoline
   22222222 bar

43 44 45
   00000000 hello
   11111111 LazyCompile:~Foo

46 47 48 49 50 51 52 53 54 55
   11111111 Builtin:InterpreterEntryTrampoline
   22222222 bar
"""


class LinuxPerfReportTest(unittest.TestCase):
  def test_collapsed_callchains_generator(self):
    perf_stream = StringIO.StringIO(PERF_SCRIPT_OUTPUT)
    callchains = list(ipr.collapsed_callchains_generator(perf_stream))
    self.assertListEqual(callchains, [
56 57 58 59 60 61 62
      ['firstSymbol', 'secondSymbol', '[other]'],
      ["foo", "BytecodeHandler:bar", "[interpreter]"],
      ["foo", "BytecodeHandler:bar", "[interpreter]"],
      ["beep", "BytecodeHandler:bar", "[interpreter]"],
      ["hello", "v8::internal::Compiler", "Stub:CEntryStub", "[compiler]"],
      ["Lost", "[misattributed]"],
      ["hello", "LazyCompile:~Foo", "[jit]"],
63 64 65
      ["[entry trampoline]"],
    ])

66
  def test_collapsed_callchains_generator_hide_other(self):
67 68
    perf_stream = StringIO.StringIO(PERF_SCRIPT_OUTPUT)
    callchains = list(ipr.collapsed_callchains_generator(perf_stream,
69 70 71
                                                         hide_other=True,
                                                         hide_compiler=True,
                                                         hide_jit=True))
72
    self.assertListEqual(callchains, [
73 74 75
      ["foo", "BytecodeHandler:bar", "[interpreter]"],
      ["foo", "BytecodeHandler:bar", "[interpreter]"],
      ["beep", "BytecodeHandler:bar", "[interpreter]"],
76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134
      ["Lost", "[misattributed]"],
      ["[entry trampoline]"],
    ])

  def test_calculate_samples_count_per_callchain(self):
    counters = ipr.calculate_samples_count_per_callchain([
      ["foo", "BytecodeHandler:bar"],
      ["foo", "BytecodeHandler:bar"],
      ["beep", "BytecodeHandler:bar"],
      ["hello", "v8::internal::Compiler", "[compiler]"],
    ])
    self.assertItemsEqual(counters, [
      ('BytecodeHandler:bar;foo', 2),
      ('BytecodeHandler:bar;beep', 1),
      ('[compiler];v8::internal::Compiler;hello', 1),
    ])

  def test_calculate_samples_count_per_callchain(self):
    counters = ipr.calculate_samples_count_per_callchain([
      ["foo", "BytecodeHandler:bar"],
      ["foo", "BytecodeHandler:bar"],
      ["beep", "BytecodeHandler:bar"],
    ])
    self.assertItemsEqual(counters, [
      ('BytecodeHandler:bar;foo', 2),
      ('BytecodeHandler:bar;beep', 1),
    ])

  def test_calculate_samples_count_per_handler_show_compile(self):
    counters = ipr.calculate_samples_count_per_handler([
      ["foo", "BytecodeHandler:bar"],
      ["foo", "BytecodeHandler:bar"],
      ["beep", "BytecodeHandler:bar"],
      ["hello", "v8::internal::Compiler", "[compiler]"],
    ])
    self.assertItemsEqual(counters, [
      ("bar", 3),
      ("[compiler]", 1)
    ])

  def test_calculate_samples_count_per_handler_(self):
    counters = ipr.calculate_samples_count_per_handler([
      ["foo", "BytecodeHandler:bar"],
      ["foo", "BytecodeHandler:bar"],
      ["beep", "BytecodeHandler:bar"],
    ])
    self.assertItemsEqual(counters, [("bar", 3)])

  def test_multiple_handlers(self):
    perf_stream = StringIO.StringIO("""
        0000 foo(bar)
        1234 BytecodeHandler:first
        5678 a::random::call<to>(something, else)
        9abc BytecodeHandler:second
        def0 otherIrrelevant(stuff)
        1111 entrypoint
    """)
    callchains = list(ipr.collapsed_callchains_generator(perf_stream, False))
    self.assertListEqual(callchains, [
135
      ["foo", "BytecodeHandler:first", "[interpreter]"],
136 137 138 139 140 141 142 143 144 145 146
    ])

  def test_compiler_symbols_regex(self):
    compiler_symbols = [
      "v8::internal::Parser",
      "v8::internal::(anonymous namespace)::Compile",
      "v8::internal::Compiler::foo",
    ]
    for compiler_symbol in compiler_symbols:
      self.assertTrue(ipr.COMPILER_SYMBOLS_RE.match(compiler_symbol))

147 148 149 150 151 152 153 154 155
  def test_jit_code_symbols_regex(self):
    jit_code_symbols = [
      "LazyCompile:~Foo blah.js",
      "Eval:*",
      "Script:*Bar tmp.js",
    ]
    for jit_code_symbol in jit_code_symbols:
      self.assertTrue(ipr.JIT_CODE_SYMBOLS_RE.match(jit_code_symbol))

156 157 158 159 160 161 162 163
  def test_strip_function_parameters(self):
    def should_match(signature, name):
      self.assertEqual(ipr.strip_function_parameters(signature), name)

    should_match("foo(bar)", "foo"),
    should_match("Foo(foomatic::(anonymous)::bar(baz))", "Foo"),
    should_match("v8::(anonymous ns)::bar<thing(with, parentheses)>(baz, poe)",
       "v8::(anonymous ns)::bar<thing(with, parentheses)>")
164 165 166

if __name__ == '__main__':
    unittest.main()