1
2
3
4
5
6
7 package unix_test
8
9
10
11 import (
12 "os"
13 "testing"
14
15 "golang.org/x/sys/unix"
16 )
17
18 func TestEpollIn(t *testing.T) {
19 efd, err := unix.EpollCreate1(0)
20 if err != nil {
21 t.Fatalf("EpollCreate1: %v", err)
22 }
23
24
25 r, w, err := os.Pipe()
26 if err != nil {
27 t.Fatal(err)
28 }
29 defer r.Close()
30 defer w.Close()
31
32 fd := int(r.Fd())
33 ev := unix.EpollEvent{Events: unix.EPOLLIN, Fd: int32(fd)}
34
35 err = unix.EpollCtl(efd, unix.EPOLL_CTL_ADD, fd, &ev)
36 if err != nil {
37 t.Fatalf("EpollCtl: %v", err)
38 }
39
40 if _, err := w.Write([]byte("HELLO GOPHER")); err != nil {
41 t.Fatal(err)
42 }
43
44 events := make([]unix.EpollEvent, 128)
45 n, err := unix.EpollWait(efd, events, 1)
46 if err != nil {
47 t.Fatalf("EpollWait: %v", err)
48 }
49
50 if n != 1 {
51 t.Errorf("EpollWait: wrong number of events: got %v, expected 1", n)
52 }
53
54 got := int(events[0].Fd)
55 if got != fd {
56 t.Errorf("EpollWait: wrong Fd in event: got %v, expected %v", got, fd)
57 }
58
59 if events[0].Events&unix.EPOLLIN == 0 {
60 t.Errorf("Expected EPOLLIN flag to be set, got %b", events[0].Events)
61 }
62 }
63
64 func TestEpollHup(t *testing.T) {
65 efd, err := unix.EpollCreate1(0)
66 if err != nil {
67 t.Fatalf("EpollCreate1: %v", err)
68 }
69
70
71 r, w, err := os.Pipe()
72 if err != nil {
73 t.Fatal(err)
74 }
75 defer r.Close()
76
77 fd := int(r.Fd())
78
79 ev := unix.EpollEvent{Events: unix.EPOLLIN, Fd: int32(fd)}
80
81 err = unix.EpollCtl(efd, unix.EPOLL_CTL_ADD, fd, &ev)
82 if err != nil {
83 t.Fatalf("EpollCtl: %v", err)
84 }
85
86 events := make([]unix.EpollEvent, 128)
87 n, err := unix.EpollWait(efd, events, 1)
88 if err != nil {
89 t.Fatalf("EpollWait: %v", err)
90 }
91
92 if events[0].Events&unix.EPOLLHUP != 0 {
93 t.Errorf("EPOLLHUP flag aset without hangup event; got n=%d, flags=%b", n, events[0].Events)
94 }
95
96 w.Close()
97
98 events = make([]unix.EpollEvent, 128)
99 n, err = unix.EpollWait(efd, events, 1)
100 if err != nil {
101 t.Fatalf("EpollWait: %v", err)
102 }
103
104 if n < 1 || events[0].Events&unix.EPOLLHUP == 0 {
105 t.Errorf("Expected EPOLLHUP flag to be set, got n=%d, flags=%b", n, events[0].Events)
106 }
107
108 }
109
110 func TestEpollInManyFds(t *testing.T) {
111 efd, err := unix.EpollCreate1(4)
112 if err != nil {
113 t.Fatalf("EpollCreate: %v", err)
114 }
115
116
117 rFds := make([]int, 10)
118 wPipes := make([]*os.File, 10)
119
120 for i := 0; i < 10; i++ {
121 r, w, err := os.Pipe()
122 if err != nil {
123 t.Fatal(err)
124 }
125 defer r.Close()
126 defer w.Close()
127
128 rFds[i] = int(r.Fd())
129 wPipes[i] = w
130 }
131
132
133 for _, fd := range rFds {
134 ev := unix.EpollEvent{Events: unix.EPOLLIN, Fd: int32(fd)}
135 err = unix.EpollCtl(efd, unix.EPOLL_CTL_ADD, fd, &ev)
136 if err != nil {
137 t.Fatalf("EpollCtl: %v", err)
138 }
139 }
140
141
142 for i, w := range wPipes {
143 if i%2 == 0 {
144 continue
145 }
146 if _, err := w.Write([]byte("HELLO")); err != nil {
147 t.Fatal(err)
148 }
149 }
150
151 events := make([]unix.EpollEvent, 128)
152 n, err := unix.EpollWait(efd, events, 1)
153 if err != nil {
154 t.Fatalf("EpollWait: %v", err)
155 }
156
157 if n != 5 {
158 t.Errorf("EpollWait: wrong number of events: got %v, expected 5", n)
159 }
160
161
162 if _, err := wPipes[0].Write([]byte("HELLO")); err != nil {
163 t.Fatal(err)
164 }
165
166
167 events = make([]unix.EpollEvent, 128)
168 n, err = unix.EpollWait(efd, events, 1)
169 if err != nil {
170 t.Fatalf("EpollWait: %v", err)
171 }
172
173 if n != 6 {
174 t.Errorf("EpollWait: wrong number of events: got %v, expected 6", n)
175 }
176
177 }
178
179 func TestMultipleEpolls(t *testing.T) {
180 efd1, err := unix.EpollCreate1(4)
181 if err != nil {
182 t.Fatalf("EpollCreate: %v", err)
183 }
184
185
186 efd2, err := unix.EpollCreate1(4)
187 if err != nil {
188 t.Fatalf("EpollCreate: %v", err)
189 }
190
191
192 rFds := make([]int, 10)
193 wPipes := make([]*os.File, 10)
194
195 for i := 0; i < 10; i++ {
196 r, w, err := os.Pipe()
197 if err != nil {
198 t.Fatal(err)
199 }
200 defer r.Close()
201 defer w.Close()
202
203 rFds[i] = int(r.Fd())
204 wPipes[i] = w
205 }
206
207
208 for i, fd := range rFds {
209 var efd int
210 if i < 7 {
211 efd = efd1
212 } else {
213 efd = efd2
214 }
215 ev := unix.EpollEvent{Events: unix.EPOLLIN, Fd: int32(fd)}
216 err = unix.EpollCtl(efd, unix.EPOLL_CTL_ADD, fd, &ev)
217 if err != nil {
218 t.Fatalf("EpollCtl: %v", err)
219 }
220 }
221
222
223 for _, w := range wPipes {
224 if _, err := w.Write([]byte("HELLO")); err != nil {
225 t.Fatal(err)
226 }
227 }
228
229 events := make([]unix.EpollEvent, 128)
230 n, err := unix.EpollWait(efd1, events, 1)
231 if err != nil {
232 t.Fatalf("EpollWait: %v", err)
233 }
234 if n != 7 {
235 t.Errorf("EpollWait: wrong number of events on ep1: got %v, expected 7", n)
236 }
237
238 events = make([]unix.EpollEvent, 128)
239 n, err = unix.EpollWait(efd2, events, 1)
240 if err != nil {
241 t.Fatalf("EpollWait: %v", err)
242 }
243 if n != 3 {
244 t.Errorf("EpollWait: wrong number of events on ep2: got %v, expected 3", n)
245 }
246 }
247
248 func TestEpollErrors(t *testing.T) {
249 efd, err := unix.EpollCreate1(4)
250 if err != nil {
251 t.Fatalf("EpollCreate: %v", err)
252 }
253
254
255 r, w, err := os.Pipe()
256 if err != nil {
257 t.Fatal(err)
258 }
259 defer r.Close()
260 defer w.Close()
261
262 fd := int(r.Fd())
263
264 ev := unix.EpollEvent{Events: unix.EPOLLIN, Fd: int32(fd)}
265 if err = unix.EpollCtl(efd+1, unix.EPOLL_CTL_ADD, fd, &ev); err != unix.EBADF {
266 t.Errorf("EpollCtl: got %v when EpollCtl ADD called with invalid epfd, expected EBADF", err)
267 }
268
269 if err = unix.EpollCtl(efd, unix.EPOLL_CTL_ADD, fd, &ev); err != nil {
270 t.Fatalf("EpollCtl: %v", err)
271 }
272
273 if err = unix.EpollCtl(efd, unix.EPOLL_CTL_MOD, -2, &ev); err != unix.ENOENT {
274 t.Errorf("EpollCtl: got %v when EpollCtl MOD called with invalid fd, expected ENOENT", err)
275 }
276 }
277
View as plain text