github.com/bananabytelabs/wazero@v0.0.0-20240105073314-54b22a776da8/internal/sysfs/poll_test.go (about) 1 //go:build windows || linux || darwin 2 3 package sysfs 4 5 import ( 6 "os" 7 "runtime" 8 "testing" 9 "time" 10 11 "github.com/bananabytelabs/wazero/experimental/sys" 12 "github.com/bananabytelabs/wazero/internal/testing/require" 13 ) 14 15 func Test_poll(t *testing.T) { 16 t.Run("should return immediately with no fds and duration 0", func(t *testing.T) { 17 for { 18 n, err := _poll([]pollFd{}, 0) 19 if err == sys.EINTR { 20 t.Logf("Select interrupted") 21 continue 22 } 23 require.EqualErrno(t, 0, err) 24 require.Equal(t, 0, n) 25 return 26 } 27 }) 28 29 t.Run("should wait for the given duration", func(t *testing.T) { 30 dur := int32(250) 31 var took time.Duration 32 for { 33 34 // On some platforms (e.g. Linux), the passed-in timeval is 35 // updated by select(2). We are not accounting for this 36 // in our implementation. 37 start := time.Now() 38 n, err := _poll([]pollFd{}, dur) 39 took = time.Since(start) 40 if err == sys.EINTR { 41 t.Logf("Select interrupted after %v", took) 42 continue 43 } 44 require.EqualErrno(t, 0, err) 45 require.Equal(t, 0, n) 46 47 // On some platforms the actual timeout might be arbitrarily 48 // less than requested. 49 if took < time.Duration(dur)*time.Millisecond { 50 if runtime.GOOS == "linux" { 51 // Linux promises to only return early if a file descriptor 52 // becomes ready (not applicable here), or the call 53 // is interrupted by a signal handler (explicitly retried in the loop above), 54 // or the timeout expires. 55 t.Errorf("Select: slept for %v, expected %v", took, dur) 56 } else { 57 t.Logf("Select: slept for %v, requested %v", took, dur) 58 } 59 } 60 return 61 } 62 }) 63 64 t.Run("should return 1 if a given FD has data", func(t *testing.T) { 65 rr, ww, err := os.Pipe() 66 require.NoError(t, err) 67 defer rr.Close() 68 defer ww.Close() 69 70 _, err = ww.Write([]byte("TEST")) 71 require.NoError(t, err) 72 73 for { 74 fds := []pollFd{newPollFd(rr.Fd(), _POLLIN, 0)} 75 if err == sys.EINTR { 76 t.Log("Select interrupted") 77 continue 78 } 79 n, err := _poll(fds, 0) 80 require.EqualErrno(t, 0, err) 81 require.Equal(t, 1, n) 82 return 83 } 84 }) 85 }