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