github.com/cilium/ebpf@v0.15.1-0.20240517100537-8079b37aa138/link/tracepoint_test.go (about)

     1  package link
     2  
     3  import (
     4  	"errors"
     5  	"os"
     6  	"testing"
     7  
     8  	"github.com/cilium/ebpf"
     9  	"github.com/cilium/ebpf/internal/testutils"
    10  	"github.com/cilium/ebpf/internal/unix"
    11  
    12  	"github.com/go-quicktest/qt"
    13  )
    14  
    15  func TestTracepoint(t *testing.T) {
    16  	// Requires at least 4.7 (98b5c2c65c29 "perf, bpf: allow bpf programs attach to tracepoints")
    17  	testutils.SkipOnOldKernel(t, "4.7", "tracepoint support")
    18  
    19  	prog := mustLoadProgram(t, ebpf.TracePoint, 0, "")
    20  
    21  	// printk is guaranteed to be present.
    22  	// Kernels before 4.14 don't support attaching to syscall tracepoints.
    23  	tp, err := Tracepoint("printk", "console", prog, nil)
    24  	if err != nil {
    25  		t.Fatal(err)
    26  	}
    27  
    28  	if err := tp.Close(); err != nil {
    29  		t.Error("closing tracepoint:", err)
    30  	}
    31  }
    32  
    33  func TestTracepointMissing(t *testing.T) {
    34  	// Requires at least 4.7 (98b5c2c65c29 "perf, bpf: allow bpf programs attach to tracepoints")
    35  	testutils.SkipOnOldKernel(t, "4.7", "tracepoint support")
    36  
    37  	prog := mustLoadProgram(t, ebpf.TracePoint, 0, "")
    38  
    39  	_, err := Tracepoint("missing", "foobazbar", prog, nil)
    40  	if !errors.Is(err, os.ErrNotExist) {
    41  		t.Error("Expected os.ErrNotExist, got", err)
    42  	}
    43  }
    44  
    45  func TestTracepointErrors(t *testing.T) {
    46  	// Invalid Tracepoint incantations.
    47  	_, err := Tracepoint("", "", nil, nil) // empty names
    48  	qt.Assert(t, qt.ErrorIs(err, errInvalidInput))
    49  
    50  	_, err = Tracepoint("_", "_", nil, nil) // empty prog
    51  	qt.Assert(t, qt.ErrorIs(err, errInvalidInput))
    52  
    53  	_, err = Tracepoint(".", "+", &ebpf.Program{}, nil) // illegal chars in group/name
    54  	qt.Assert(t, qt.ErrorIs(err, errInvalidInput))
    55  
    56  	_, err = Tracepoint("foo", "bar", &ebpf.Program{}, nil) // wrong prog type
    57  	qt.Assert(t, qt.ErrorIs(err, errInvalidInput))
    58  }
    59  
    60  func TestTracepointProgramCall(t *testing.T) {
    61  	// Kernels before 4.14 don't support attaching to syscall tracepoints.
    62  	testutils.SkipOnOldKernel(t, "4.14", "syscalls tracepoint support")
    63  
    64  	m, p := newUpdaterMapProg(t, ebpf.TracePoint, 0)
    65  
    66  	// Open Tracepoint at /sys/kernel/tracing/events/syscalls/sys_enter_getpid
    67  	// and attach it to the ebpf program created above.
    68  	tp, err := Tracepoint("syscalls", "sys_enter_getpid", p, nil)
    69  	if err != nil {
    70  		t.Fatal(err)
    71  	}
    72  
    73  	// Trigger ebpf program call.
    74  	unix.Getpid()
    75  
    76  	// Assert that the value got incremented to at least 1, while allowing
    77  	// for bigger values, because we could race with other getpid callers.
    78  	assertMapValueGE(t, m, 0, 1)
    79  
    80  	// Detach the Tracepoint.
    81  	if err := tp.Close(); err != nil {
    82  		t.Fatal(err)
    83  	}
    84  
    85  	// Reset map value to 0 at index 0.
    86  	if err := m.Update(uint32(0), uint32(0), ebpf.UpdateExist); err != nil {
    87  		t.Fatal(err)
    88  	}
    89  
    90  	// Retrigger the ebpf program call.
    91  	unix.Getpid()
    92  
    93  	// Assert that this time the value has not been updated.
    94  	assertMapValue(t, m, 0, 0)
    95  }