# 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 00000000 hello 11111111 LazyCompile:~Foo 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, [ ['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]"], ["[entry trampoline]"], ]) def test_collapsed_callchains_generator_hide_other(self): perf_stream = StringIO.StringIO(PERF_SCRIPT_OUTPUT) callchains = list(ipr.collapsed_callchains_generator(perf_stream, hide_other=True, hide_compiler=True, hide_jit=True)) self.assertListEqual(callchains, [ ["foo", "BytecodeHandler:bar", "[interpreter]"], ["foo", "BytecodeHandler:bar", "[interpreter]"], ["beep", "BytecodeHandler:bar", "[interpreter]"], ["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(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", "[interpreter]"], ]) 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_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)) 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(baz, poe)", "v8::(anonymous ns)::bar") if __name__ == '__main__': unittest.main()