148 lines
4.5 KiB
Python
148 lines
4.5 KiB
Python
|
# 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
|
||
|
|
||
|
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, [
|
||
|
["foo", "BytecodeHandler:bar"],
|
||
|
["foo", "BytecodeHandler:bar"],
|
||
|
["beep", "BytecodeHandler:bar"],
|
||
|
["[entry trampoline]"],
|
||
|
])
|
||
|
|
||
|
def test_collapsed_callchains_generator_show_other(self):
|
||
|
perf_stream = StringIO.StringIO(PERF_SCRIPT_OUTPUT)
|
||
|
callchains = list(ipr.collapsed_callchains_generator(perf_stream,
|
||
|
show_all=True))
|
||
|
self.assertListEqual(callchains, [
|
||
|
['firstSymbol', 'secondSymbol', '[other]'],
|
||
|
["foo", "BytecodeHandler:bar"],
|
||
|
["foo", "BytecodeHandler:bar"],
|
||
|
["beep", "BytecodeHandler:bar"],
|
||
|
["hello", "v8::internal::Compiler", "[compiler]"],
|
||
|
["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, [
|
||
|
["foo", "BytecodeHandler:first"],
|
||
|
])
|
||
|
|
||
|
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))
|
||
|
|
||
|
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)>")
|