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