github.com/pyroscope-io/pyroscope@v0.37.3-0.20230725203016-5f6947968bd0/pkg/convert/perf/script_test.go (about) 1 package perf 2 3 import ( 4 "bytes" 5 "testing" 6 ) 7 8 func TestParseEventStart(t *testing.T) { 9 test := func(s string, comm string, pid int, tid int, ok bool) { 10 t.Run(s, func(t *testing.T) { 11 rComm, rPid, rTid, err := parseEventStart([]byte(s)) 12 if ok { 13 if err != nil { 14 t.Errorf("expected no error") 15 } 16 if comm != string(rComm) { 17 t.Errorf("comm %v != %v", comm, rComm) 18 } 19 if rPid != pid { 20 t.Errorf("pid %v != %v", rPid, pid) 21 } 22 if rTid != tid { 23 t.Errorf("tid %v != %v", rTid, tid) 24 } 25 return 26 } 27 if err == nil { 28 t.Errorf("expected error ") 29 } 30 }) 31 } 32 33 test("java 12688 [002] 6544038.708352: cpu-clock:", "java", 12688, 0, true) 34 test("V8 WorkerThread 25607 4794564.109216: cycles:", "V8 WorkerThread", 25607, 0, true) 35 test("java 24636/25607 [000] 4794564.109216: cycles:", "java", 24636, 25607, true) 36 test("java 12688/12764 6544038.708352: cpu-clock:", "java", 12688, 12764, true) 37 test("V8 WorkerThread 24636/25607 [000] 94564.109216: cycles:", "V8 WorkerThread", 24636, 25607, true) 38 test("", "", 0, 0, false) 39 test("\n", "", 0, 0, false) 40 test("swapper;start_kernel;rest_init;cpu_idle;default_idle;native_safe_halt 1\n", "", 0, 0, false) 41 } 42 43 func TestParseStackFrame(t *testing.T) { 44 test := func(s string, addr, sym, mod string, ok bool) { 45 t.Run(s, func(t *testing.T) { 46 rAddr, rSym, rMod, err := parseStackFrame([]byte(s)) 47 if ok { 48 if err != nil { 49 t.Errorf("expected no error") 50 } 51 if string(rAddr) != addr { 52 t.Errorf("addr %v != %v", rAddr, addr) 53 } 54 if string(rSym) != sym { 55 t.Errorf("mod %v != %v", rSym, sym) 56 } 57 if string(rMod) != mod { 58 t.Errorf("mod %v != %v", rMod, mod) 59 } 60 return 61 } 62 if err == nil { 63 t.Errorf("expected error<") 64 } 65 }) 66 } 67 test(" ffffffffb37b3618 __cgroup_account_cputime+0x28 (/lib/modules/5.19.0/build/vmlinux)\n", 68 "ffffffffb37b3618", "__cgroup_account_cputime+0x28", "/lib/modules/5.19.0/build/vmlinux", true) 69 test(" ffffffffb37105ed update_curr+0x10d (/lib/modules/5.19.0/build/vmlinux)\n", "ffffffffb37105ed", 70 "update_curr+0x10d", "/lib/modules/5.19.0/build/vmlinux", true) 71 test(" ffffffffb3712293 dequeue_entity+0x23 (/lib/modules/5.19.0/build/vmlinux)\n", "ffffffffb3712293", 72 "dequeue_entity+0x23", "/lib/modules/5.19.0/build/vmlinux", true) 73 test(" ffffffffb3712773 dequeue_task_fair+0xb3 (/lib/modules/5.19.0/build/vmlinux)\n", "ffffffffb3712773", 74 "dequeue_task_fair+0xb3", "/lib/modules/5.19.0/build/vmlinux", true) 75 test(" ffffffffb36ff7e2 dequeue_task+0x42 (/lib/modules/5.19.0/build/vmlinux)\n", "ffffffffb36ff7e2", 76 "dequeue_task+0x42", "/lib/modules/5.19.0/build/vmlinux", true) 77 test(" ffffffffb4408753 __schedule+0x3e3 (/lib/modules/5.19.0/build/vmlinux)\n", "ffffffffb4408753", 78 "__schedule+0x3e3", "/lib/modules/5.19.0/build/vmlinux", true) 79 test(" ffffffffb440982c schedule+0x5c (/lib/modules/5.19.0/build/vmlinux)\n", "ffffffffb440982c", 80 "schedule+0x5c", "/lib/modules/5.19.0/build/vmlinux", true) 81 test(" ffffffffb379d3f8 futex_wait_queue+0x78 (/lib/modules/5.19.0/build/vmlinux)\n", "ffffffffb379d3f8", 82 "futex_wait_queue+0x78", "/lib/modules/5.19.0/build/vmlinux", true) 83 test(" ffffffffb379daba futex_wait+0x15a (/lib/modules/5.19.0/build/vmlinux)\n", "ffffffffb379daba", 84 "futex_wait+0x15a", "/lib/modules/5.19.0/build/vmlinux", true) 85 test(" ffffffffb379a2f8 do_futex+0x138 (/lib/modules/5.19.0/build/vmlinux)\n", "ffffffffb379a2f8", 86 "do_futex+0x138", "/lib/modules/5.19.0/build/vmlinux", true) 87 test(" ffffffffb379a7c8 __x64_sys_futex+0x78 (/lib/modules/5.19.0/build/vmlinux)\n", "ffffffffb379a7c8", 88 "__x64_sys_futex+0x78", "/lib/modules/5.19.0/build/vmlinux", true) 89 test(" ffffffffb43f916c do_syscall_64+0x5c (/lib/modules/5.19.0/build/vmlinux)\n", "ffffffffb43f916c", 90 "do_syscall_64+0x5c", "/lib/modules/5.19.0/build/vmlinux", true) 91 test(" ffffffffb460009b entry_SYSCALL_64_after_hwframe+0x63 (/lib/modules/5.19.0/build/vmlinux)\n", 92 "ffffffffb460009b", "entry_SYSCALL_64_after_hwframe+0x63", "/lib/modules/5.19.0/build/vmlinux", true) 93 test(" 91197 __GI___strncasecmp_l_sse2+0x1547 (/usr/lib/x86_64-linux-gnu/libc.so.6)\n", 94 "91197", "__GI___strncasecmp_l_sse2+0x1547", "/usr/lib/x86_64-linux-gnu/libc.so.6", true) 95 test(" 3fa48f [unknown] ([unknown])\n", "3fa48f", "[unknown]", "[unknown]", true) 96 test("java 12688 [002] 6544038.708352: cpu-clock:", "", "", "", false) 97 test("V8 WorkerThread 25607 4794564.109216: cycles:", "", "", "", false) 98 test("java 24636/25607 [000] 4794564.109216: cycles:", "", "", "", false) 99 test("java 12688/12764 6544038.708352: cpu-clock:", "", "", "", false) 100 test("V8 WorkerThread 24636/25607 [000] 94564.109216: cycles:", "", "", "", false) 101 test("", "", "", "", false) 102 test("\n", "", "", "", false) 103 } 104 105 func TestParseSingleEvent(t *testing.T) { 106 event := "perf 617960 [004] 116825.359144: 16 cycles: \n" + 107 " ffffffffb377256a exit_to_user_mode_prepare+0x6a (/lib/modules/5.19.0/build/vmlinux)\n" + 108 " ffffffffb43fe8a6 syscall_exit_to_user_mode+0x26 (/lib/modules/5.19.0/build/vmlinux)\n" + 109 " ffffffffb43f9179 do_syscall_64+0x69 (/lib/modules/5.19.0/build/vmlinux)\n" + 110 " ffffffffb460009b entry_SYSCALL_64_after_hwframe+0x63 (/lib/modules/5.19.0/build/vmlinux)\n" + 111 " 11aaff setsourcefilter+0x18f (/usr/lib/x86_64-linux-gnu/libc.so.6)\n" + 112 " 3364c7 __evlist__enable.constprop.0+0x97 (/home/korniltsev/github/jammy/tools/perf/perf)\n" + 113 " 296253 __cmd_record.constprop.0+0x2683 (/home/korniltsev/github/jammy/tools/perf/perf)\n" + 114 " 297db7 cmd_record+0xbb7 (/home/korniltsev/github/jammy/tools/perf/perf)\n" + 115 " 31ecd0 run_builtin+0x70 (/home/korniltsev/github/jammy/tools/perf/perf)\n" + 116 " 27ae79 main+0x6a9 (/home/korniltsev/github/jammy/tools/perf/perf)\n" + 117 " 29d90 __vstrfmon_l_internal+0x4e0 (/usr/lib/x86_64-linux-gnu/libc.so.6)\n" + 118 "\n" 119 p := NewScriptParser([]byte(event)) 120 events, err := p.ParseEvents() 121 if err != nil { 122 t.Fatalf("err %v", err) 123 } 124 if len(events) != 1 { 125 t.Fatalf("expected 1 event") 126 } 127 stack := events[0] 128 expected := [][]byte{ 129 []byte("perf"), 130 []byte("__vstrfmon_l_internal+0x4e0"), 131 []byte("main+0x6a9"), 132 []byte("run_builtin+0x70"), 133 []byte("cmd_record+0xbb7"), 134 []byte("__cmd_record.constprop.0+0x2683"), 135 []byte("__evlist__enable.constprop.0+0x97"), 136 []byte("setsourcefilter+0x18f"), 137 []byte("entry_SYSCALL_64_after_hwframe+0x63"), 138 []byte("do_syscall_64+0x69"), 139 []byte("syscall_exit_to_user_mode+0x26"), 140 []byte("exit_to_user_mode_prepare+0x6a"), 141 } 142 for i := 0; i < len(expected); i++ { 143 if !bytes.Equal(expected[i], stack[i]) { 144 t.Fatalf("expected %s got %s", string(expected[i]), string(stack[i])) 145 } 146 } 147 } 148 149 func TestMultipleEvents(t *testing.T) { 150 event := "perf 617960 [004] 116825.359144: 16 cycles: \n" + 151 " ffffffffb460009b entry_SYSCALL_64_after_hwframe+0x63 (/lib/modules/5.19.0/build/vmlinux)\n" + 152 " 27ae79 main+0x6a9 (/home/korniltsev/github/jammy/tools/perf/perf)\n" + 153 "\n" + 154 "perf 617960 [004] 116825.359144: 16 cycles: \n" + 155 " ffffffffb43f9179 do_syscall_64+0x69 (/lib/modules/5.19.0/build/vmlinux)\n" + 156 " 31ecd0 run_builtin+0x70 (/home/korniltsev/github/jammy/tools/perf/perf)\n" + 157 "\n" 158 p := NewScriptParser([]byte(event)) 159 events, err := p.ParseEvents() 160 if err != nil { 161 t.Fatalf("err %v", err) 162 } 163 if len(events) != 2 { 164 t.Fatalf("expected 2 events") 165 } 166 167 expect := func(expected [][]byte, actual [][]byte) { 168 for i := 0; i < len(expected); i++ { 169 if !bytes.Equal(expected[i], actual[i]) { 170 t.Fatalf("expected %s got %s", string(expected[i]), string(actual[i])) 171 } 172 } 173 } 174 expect([][]byte{ 175 []byte("perf"), 176 []byte("main+0x6a9"), 177 []byte("entry_SYSCALL_64_after_hwframe+0x63"), 178 }, events[0]) 179 expect([][]byte{ 180 []byte("perf"), 181 []byte("run_builtin+0x70"), 182 []byte("do_syscall_64+0x69"), 183 }, events[1]) 184 }