github.com/kubeshark/ebpf@v0.9.2/perf/ring_test.go (about) 1 package perf 2 3 import ( 4 "bytes" 5 "io" 6 "os" 7 "testing" 8 9 "github.com/kubeshark/ebpf/internal/unix" 10 ) 11 12 func TestRingBufferReader(t *testing.T) { 13 buf := make([]byte, 2) 14 15 ring := makeRing(2, 0) 16 n, err := ring.Read(buf) 17 if err != io.EOF { 18 t.Error("Expected io.EOF, got", err) 19 } 20 if n != 2 { 21 t.Errorf("Expected to read 2 bytes, got %d", n) 22 } 23 if !bytes.Equal(buf, []byte{0, 1}) { 24 t.Error("Expected [0, 1], got", buf) 25 } 26 n, err = ring.Read(buf) 27 if err != io.EOF { 28 t.Error("Expected io.EOF, got", err) 29 } 30 if n != 0 { 31 t.Error("Expected to read 0 bytes, got", n) 32 } 33 34 // Wrapping read 35 ring = makeRing(2, 1) 36 n, err = io.ReadFull(ring, buf) 37 if err != nil { 38 t.Error("Error while reading:", err) 39 } 40 if n != 2 { 41 t.Errorf("Expected to read 2 byte, got %d", n) 42 } 43 if !bytes.Equal(buf, []byte{1, 0}) { 44 t.Error("Expected [1, 0], got", buf) 45 } 46 } 47 48 func makeRing(size, offset int) *ringReader { 49 if size != 0 && (size&(size-1)) != 0 { 50 panic("size must be power of two") 51 } 52 53 ring := make([]byte, size) 54 for i := range ring { 55 ring[i] = byte(i) 56 } 57 58 meta := unix.PerfEventMmapPage{ 59 Data_head: uint64(len(ring) + offset), 60 Data_tail: uint64(offset), 61 Data_size: uint64(len(ring)), 62 } 63 64 return newRingReader(&meta, ring) 65 } 66 67 func TestPerfEventRing(t *testing.T) { 68 check := func(buffer, watermark int) { 69 ring, err := newPerfEventRing(0, buffer, watermark) 70 if err != nil { 71 t.Fatal(err) 72 } 73 74 size := len(ring.ringReader.ring) 75 76 // Ring size should be at least as big as buffer 77 if size < buffer { 78 t.Fatalf("ring size %d smaller than buffer %d", size, buffer) 79 } 80 81 // Ring size should be of the form 2^n pages (meta page has already been removed) 82 if size%os.Getpagesize() != 0 { 83 t.Fatalf("ring size %d not whole number of pages (pageSize %d)", size, os.Getpagesize()) 84 } 85 nPages := size / os.Getpagesize() 86 if nPages&(nPages-1) != 0 { 87 t.Fatalf("ring size %d (%d pages) not a power of two pages (pageSize %d)", size, nPages, os.Getpagesize()) 88 } 89 } 90 91 // watermark > buffer 92 _, err := newPerfEventRing(0, 8192, 8193) 93 if err == nil { 94 t.Fatal("watermark > buffer allowed") 95 } 96 97 // watermark == buffer 98 _, err = newPerfEventRing(0, 8192, 8192) 99 if err == nil { 100 t.Fatal("watermark == buffer allowed") 101 } 102 103 // buffer not a power of two, watermark < buffer 104 check(8193, 8192) 105 106 // large buffer not a multiple of page size at all (prime) 107 check(65537, 8192) 108 }