1// Copyright 2015 The Go Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style 3// license that can be found in the LICENSE file. 4 5// +build linux 6 7package fsnotify 8 9import ( 10 "testing" 11 "time" 12 13 "golang.org/x/sys/unix" 14) 15 16type testFd [2]int 17 18func makeTestFd(t *testing.T) testFd { 19 var tfd testFd 20 errno := unix.Pipe(tfd[:]) 21 if errno != nil { 22 t.Fatalf("Failed to create pipe: %v", errno) 23 } 24 return tfd 25} 26 27func (tfd testFd) fd() int { 28 return tfd[0] 29} 30 31func (tfd testFd) closeWrite(t *testing.T) { 32 errno := unix.Close(tfd[1]) 33 if errno != nil { 34 t.Fatalf("Failed to close write end of pipe: %v", errno) 35 } 36} 37 38func (tfd testFd) put(t *testing.T) { 39 buf := make([]byte, 10) 40 _, errno := unix.Write(tfd[1], buf) 41 if errno != nil { 42 t.Fatalf("Failed to write to pipe: %v", errno) 43 } 44} 45 46func (tfd testFd) get(t *testing.T) { 47 buf := make([]byte, 10) 48 _, errno := unix.Read(tfd[0], buf) 49 if errno != nil { 50 t.Fatalf("Failed to read from pipe: %v", errno) 51 } 52} 53 54func (tfd testFd) close() { 55 unix.Close(tfd[1]) 56 unix.Close(tfd[0]) 57} 58 59func makePoller(t *testing.T) (testFd, *fdPoller) { 60 tfd := makeTestFd(t) 61 poller, err := newFdPoller(tfd.fd()) 62 if err != nil { 63 t.Fatalf("Failed to create poller: %v", err) 64 } 65 return tfd, poller 66} 67 68func TestPollerWithBadFd(t *testing.T) { 69 _, err := newFdPoller(-1) 70 if err != unix.EBADF { 71 t.Fatalf("Expected EBADF, got: %v", err) 72 } 73} 74 75func TestPollerWithData(t *testing.T) { 76 tfd, poller := makePoller(t) 77 defer tfd.close() 78 defer poller.close() 79 80 tfd.put(t) 81 ok, err := poller.wait() 82 if err != nil { 83 t.Fatalf("poller failed: %v", err) 84 } 85 if !ok { 86 t.Fatalf("expected poller to return true") 87 } 88 tfd.get(t) 89} 90 91func TestPollerWithWakeup(t *testing.T) { 92 tfd, poller := makePoller(t) 93 defer tfd.close() 94 defer poller.close() 95 96 err := poller.wake() 97 if err != nil { 98 t.Fatalf("wake failed: %v", err) 99 } 100 ok, err := poller.wait() 101 if err != nil { 102 t.Fatalf("poller failed: %v", err) 103 } 104 if ok { 105 t.Fatalf("expected poller to return false") 106 } 107} 108 109func TestPollerWithClose(t *testing.T) { 110 tfd, poller := makePoller(t) 111 defer tfd.close() 112 defer poller.close() 113 114 tfd.closeWrite(t) 115 ok, err := poller.wait() 116 if err != nil { 117 t.Fatalf("poller failed: %v", err) 118 } 119 if !ok { 120 t.Fatalf("expected poller to return true") 121 } 122} 123 124func TestPollerWithWakeupAndData(t *testing.T) { 125 tfd, poller := makePoller(t) 126 defer tfd.close() 127 defer poller.close() 128 129 tfd.put(t) 130 err := poller.wake() 131 if err != nil { 132 t.Fatalf("wake failed: %v", err) 133 } 134 135 // both data and wakeup 136 ok, err := poller.wait() 137 if err != nil { 138 t.Fatalf("poller failed: %v", err) 139 } 140 if !ok { 141 t.Fatalf("expected poller to return true") 142 } 143 144 // data is still in the buffer, wakeup is cleared 145 ok, err = poller.wait() 146 if err != nil { 147 t.Fatalf("poller failed: %v", err) 148 } 149 if !ok { 150 t.Fatalf("expected poller to return true") 151 } 152 153 tfd.get(t) 154 // data is gone, only wakeup now 155 err = poller.wake() 156 if err != nil { 157 t.Fatalf("wake failed: %v", err) 158 } 159 ok, err = poller.wait() 160 if err != nil { 161 t.Fatalf("poller failed: %v", err) 162 } 163 if ok { 164 t.Fatalf("expected poller to return false") 165 } 166} 167 168func TestPollerConcurrent(t *testing.T) { 169 tfd, poller := makePoller(t) 170 defer tfd.close() 171 defer poller.close() 172 173 oks := make(chan bool) 174 live := make(chan bool) 175 defer close(live) 176 go func() { 177 defer close(oks) 178 for { 179 ok, err := poller.wait() 180 if err != nil { 181 t.Fatalf("poller failed: %v", err) 182 } 183 oks <- ok 184 if !<-live { 185 return 186 } 187 } 188 }() 189 190 // Try a write 191 select { 192 case <-time.After(50 * time.Millisecond): 193 case <-oks: 194 t.Fatalf("poller did not wait") 195 } 196 tfd.put(t) 197 if !<-oks { 198 t.Fatalf("expected true") 199 } 200 tfd.get(t) 201 live <- true 202 203 // Try a wakeup 204 select { 205 case <-time.After(50 * time.Millisecond): 206 case <-oks: 207 t.Fatalf("poller did not wait") 208 } 209 err := poller.wake() 210 if err != nil { 211 t.Fatalf("wake failed: %v", err) 212 } 213 if <-oks { 214 t.Fatalf("expected false") 215 } 216 live <- true 217 218 // Try a close 219 select { 220 case <-time.After(50 * time.Millisecond): 221 case <-oks: 222 t.Fatalf("poller did not wait") 223 } 224 tfd.closeWrite(t) 225 if !<-oks { 226 t.Fatalf("expected true") 227 } 228 tfd.get(t) 229} 230