1 package perf
2
3 import (
4 "bytes"
5 "io"
6 "os"
7 "testing"
8
9 "github.com/cilium/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
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
77 if size < buffer {
78 t.Fatalf("ring size %d smaller than buffer %d", size, buffer)
79 }
80
81
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
92 _, err := newPerfEventRing(0, 8192, 8193)
93 if err == nil {
94 t.Fatal("watermark > buffer allowed")
95 }
96
97
98 _, err = newPerfEventRing(0, 8192, 8192)
99 if err == nil {
100 t.Fatal("watermark == buffer allowed")
101 }
102
103
104 check(8193, 8192)
105
106
107 check(65537, 8192)
108 }
109
View as plain text