Ben Murdoch | c561043 | 2016-08-08 18:44:38 +0100 | [diff] [blame^] | 1 | # Copyright 2016 the V8 project 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 | |
| 5 | import linux_perf_report as ipr |
| 6 | import StringIO |
| 7 | import unittest |
| 8 | |
| 9 | |
| 10 | PERF_SCRIPT_OUTPUT = """ |
| 11 | # This line is a comment |
| 12 | # This should be ignored too |
| 13 | # |
| 14 | # cdefab01 aRandomSymbol::Name(to, be, ignored) |
| 15 | |
| 16 | 00000000 firstSymbol |
| 17 | 00000123 secondSymbol |
| 18 | |
| 19 | 01234567 foo |
| 20 | abcdef76 BytecodeHandler:bar |
| 21 | 76543210 baz |
| 22 | |
| 23 | # Indentation shouldn't matter (neither should this line) |
| 24 | |
| 25 | 01234567 foo |
| 26 | abcdef76 BytecodeHandler:bar |
| 27 | 76543210 baz |
| 28 | |
| 29 | 01234567 beep |
| 30 | abcdef76 BytecodeHandler:bar |
| 31 | 76543210 baz |
| 32 | |
| 33 | 01234567 hello |
| 34 | abcdef76 v8::internal::Compiler |
| 35 | 00000000 Stub:CEntryStub |
| 36 | 76543210 world |
| 37 | 11111111 BytecodeHandler:nope |
| 38 | |
| 39 | 00000000 Lost |
| 40 | 11111111 Builtin:InterpreterEntryTrampoline |
| 41 | 22222222 bar |
| 42 | |
| 43 | 11111111 Builtin:InterpreterEntryTrampoline |
| 44 | 22222222 bar |
| 45 | """ |
| 46 | |
| 47 | |
| 48 | class LinuxPerfReportTest(unittest.TestCase): |
| 49 | def test_collapsed_callchains_generator(self): |
| 50 | perf_stream = StringIO.StringIO(PERF_SCRIPT_OUTPUT) |
| 51 | callchains = list(ipr.collapsed_callchains_generator(perf_stream)) |
| 52 | self.assertListEqual(callchains, [ |
| 53 | ["foo", "BytecodeHandler:bar"], |
| 54 | ["foo", "BytecodeHandler:bar"], |
| 55 | ["beep", "BytecodeHandler:bar"], |
| 56 | ["[entry trampoline]"], |
| 57 | ]) |
| 58 | |
| 59 | def test_collapsed_callchains_generator_show_other(self): |
| 60 | perf_stream = StringIO.StringIO(PERF_SCRIPT_OUTPUT) |
| 61 | callchains = list(ipr.collapsed_callchains_generator(perf_stream, |
| 62 | show_all=True)) |
| 63 | self.assertListEqual(callchains, [ |
| 64 | ['firstSymbol', 'secondSymbol', '[other]'], |
| 65 | ["foo", "BytecodeHandler:bar"], |
| 66 | ["foo", "BytecodeHandler:bar"], |
| 67 | ["beep", "BytecodeHandler:bar"], |
| 68 | ["hello", "v8::internal::Compiler", "[compiler]"], |
| 69 | ["Lost", "[misattributed]"], |
| 70 | ["[entry trampoline]"], |
| 71 | ]) |
| 72 | |
| 73 | def test_calculate_samples_count_per_callchain(self): |
| 74 | counters = ipr.calculate_samples_count_per_callchain([ |
| 75 | ["foo", "BytecodeHandler:bar"], |
| 76 | ["foo", "BytecodeHandler:bar"], |
| 77 | ["beep", "BytecodeHandler:bar"], |
| 78 | ["hello", "v8::internal::Compiler", "[compiler]"], |
| 79 | ]) |
| 80 | self.assertItemsEqual(counters, [ |
| 81 | ('BytecodeHandler:bar;foo', 2), |
| 82 | ('BytecodeHandler:bar;beep', 1), |
| 83 | ('[compiler];v8::internal::Compiler;hello', 1), |
| 84 | ]) |
| 85 | |
| 86 | def test_calculate_samples_count_per_callchain(self): |
| 87 | counters = ipr.calculate_samples_count_per_callchain([ |
| 88 | ["foo", "BytecodeHandler:bar"], |
| 89 | ["foo", "BytecodeHandler:bar"], |
| 90 | ["beep", "BytecodeHandler:bar"], |
| 91 | ]) |
| 92 | self.assertItemsEqual(counters, [ |
| 93 | ('BytecodeHandler:bar;foo', 2), |
| 94 | ('BytecodeHandler:bar;beep', 1), |
| 95 | ]) |
| 96 | |
| 97 | def test_calculate_samples_count_per_handler_show_compile(self): |
| 98 | counters = ipr.calculate_samples_count_per_handler([ |
| 99 | ["foo", "BytecodeHandler:bar"], |
| 100 | ["foo", "BytecodeHandler:bar"], |
| 101 | ["beep", "BytecodeHandler:bar"], |
| 102 | ["hello", "v8::internal::Compiler", "[compiler]"], |
| 103 | ]) |
| 104 | self.assertItemsEqual(counters, [ |
| 105 | ("bar", 3), |
| 106 | ("[compiler]", 1) |
| 107 | ]) |
| 108 | |
| 109 | def test_calculate_samples_count_per_handler_(self): |
| 110 | counters = ipr.calculate_samples_count_per_handler([ |
| 111 | ["foo", "BytecodeHandler:bar"], |
| 112 | ["foo", "BytecodeHandler:bar"], |
| 113 | ["beep", "BytecodeHandler:bar"], |
| 114 | ]) |
| 115 | self.assertItemsEqual(counters, [("bar", 3)]) |
| 116 | |
| 117 | def test_multiple_handlers(self): |
| 118 | perf_stream = StringIO.StringIO(""" |
| 119 | 0000 foo(bar) |
| 120 | 1234 BytecodeHandler:first |
| 121 | 5678 a::random::call<to>(something, else) |
| 122 | 9abc BytecodeHandler:second |
| 123 | def0 otherIrrelevant(stuff) |
| 124 | 1111 entrypoint |
| 125 | """) |
| 126 | callchains = list(ipr.collapsed_callchains_generator(perf_stream, False)) |
| 127 | self.assertListEqual(callchains, [ |
| 128 | ["foo", "BytecodeHandler:first"], |
| 129 | ]) |
| 130 | |
| 131 | def test_compiler_symbols_regex(self): |
| 132 | compiler_symbols = [ |
| 133 | "v8::internal::Parser", |
| 134 | "v8::internal::(anonymous namespace)::Compile", |
| 135 | "v8::internal::Compiler::foo", |
| 136 | ] |
| 137 | for compiler_symbol in compiler_symbols: |
| 138 | self.assertTrue(ipr.COMPILER_SYMBOLS_RE.match(compiler_symbol)) |
| 139 | |
| 140 | def test_strip_function_parameters(self): |
| 141 | def should_match(signature, name): |
| 142 | self.assertEqual(ipr.strip_function_parameters(signature), name) |
| 143 | |
| 144 | should_match("foo(bar)", "foo"), |
| 145 | should_match("Foo(foomatic::(anonymous)::bar(baz))", "Foo"), |
| 146 | should_match("v8::(anonymous ns)::bar<thing(with, parentheses)>(baz, poe)", |
| 147 | "v8::(anonymous ns)::bar<thing(with, parentheses)>") |