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  }