A lightweight mechanism to provide an *instant kickstart* to a Go web server instance upon changing any Go source files under the project directory (and its subdirectories).

inotify_poller_test.go 4.1KB

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