...
1 package epoll
2
3 import (
4 "errors"
5 "os"
6 "testing"
7 "time"
8
9 "github.com/cilium/ebpf/internal/unix"
10 )
11
12 func TestPoller(t *testing.T) {
13 event, err := newEventFd()
14 if err != nil {
15 t.Fatal(err)
16 }
17 defer event.close()
18
19 poller, err := New()
20 if err != nil {
21 t.Fatal(err)
22 }
23 defer poller.Close()
24
25 if err := poller.Add(event.raw, 42); err != nil {
26 t.Fatal("Can't add fd:", err)
27 }
28
29 done := make(chan struct{}, 1)
30 read := func() {
31 defer func() {
32 done <- struct{}{}
33 }()
34
35 events := make([]unix.EpollEvent, 1)
36
37 n, err := poller.Wait(events)
38 if errors.Is(err, os.ErrClosed) {
39 return
40 }
41
42 if err != nil {
43 t.Error("Error from wait:", err)
44 return
45 }
46
47 if n != 1 {
48 t.Errorf("Got %d instead of 1 events", n)
49 }
50
51 if e := events[0]; e.Pad != 42 {
52 t.Errorf("Incorrect value in EpollEvent.Pad: %d != 42", e.Pad)
53 }
54 }
55
56 if err := event.add(1); err != nil {
57 t.Fatal(err)
58 }
59
60 go read()
61 select {
62 case <-done:
63 case <-time.After(time.Second):
64 t.Fatal("Timed out")
65 }
66
67 if _, err := event.read(); err != nil {
68 t.Fatal(err)
69 }
70
71 go read()
72 select {
73 case <-done:
74 t.Fatal("Wait doesn't block")
75 case <-time.After(time.Second):
76 }
77
78 if err := poller.Close(); err != nil {
79 t.Fatal("Close returns an error:", err)
80 }
81
82 select {
83 case <-done:
84 case <-time.After(time.Second):
85 t.Fatal("Close doesn't unblock Wait")
86 }
87
88 if err := poller.Close(); !errors.Is(err, os.ErrClosed) {
89 t.Fatal("Closing a second time doesn't return ErrClosed:", err)
90 }
91 }
92
View as plain text