sysfs: restore check for EINTR in poll test, fix Windows tests (#1604)

Signed-off-by: Edoardo Vacchi <evacchi@users.noreply.github.com>
This commit is contained in:
Edoardo Vacchi
2023-07-31 00:47:47 +02:00
committed by GitHub
parent 66070781b1
commit d88286ba63
2 changed files with 50 additions and 31 deletions

View File

@@ -8,40 +8,56 @@ import (
"testing" "testing"
"time" "time"
"github.com/tetratelabs/wazero/experimental/sys"
"github.com/tetratelabs/wazero/internal/testing/require" "github.com/tetratelabs/wazero/internal/testing/require"
) )
func Test_poll(t *testing.T) { func Test_poll(t *testing.T) {
t.Run("should return immediately with no fds and duration 0", func(t *testing.T) { t.Run("should return immediately with no fds and duration 0", func(t *testing.T) {
n, err := _poll([]pollFd{}, 0) for {
require.EqualErrno(t, 0, err) n, err := _poll([]pollFd{}, 0)
require.Equal(t, 0, n) if err == sys.EINTR {
t.Logf("Select interrupted")
continue
}
require.EqualErrno(t, 0, err)
require.Equal(t, 0, n)
return
}
}) })
t.Run("should wait for the given duration", func(t *testing.T) { t.Run("should wait for the given duration", func(t *testing.T) {
dur := int32(250) dur := int32(250)
var took time.Duration var took time.Duration
// On some platforms (e.g. Linux), the passed-in timeval is for {
// updated by select(2). We are not accounting for this
// in our implementation.
start := time.Now()
n, err := _poll([]pollFd{}, dur)
took = time.Since(start)
require.EqualErrno(t, 0, err)
require.Equal(t, 0, n)
// On some platforms the actual timeout might be arbitrarily // On some platforms (e.g. Linux), the passed-in timeval is
// less than requested. // updated by select(2). We are not accounting for this
if took < time.Duration(dur)*time.Millisecond { // in our implementation.
if runtime.GOOS == "linux" { start := time.Now()
// Linux promises to only return early if a file descriptor n, err := _poll([]pollFd{}, dur)
// becomes ready (not applicable here), or the call took = time.Since(start)
// is interrupted by a signal handler (explicitly retried in the loop above), if err == sys.EINTR {
// or the timeout expires. t.Logf("Select interrupted after %v", took)
t.Errorf("Select: slept for %v, expected %v", took, dur) continue
} else {
t.Logf("Select: slept for %v, requested %v", took, dur)
} }
require.EqualErrno(t, 0, err)
require.Equal(t, 0, n)
// On some platforms the actual timeout might be arbitrarily
// less than requested.
if took < time.Duration(dur)*time.Millisecond {
if runtime.GOOS == "linux" {
// Linux promises to only return early if a file descriptor
// becomes ready (not applicable here), or the call
// is interrupted by a signal handler (explicitly retried in the loop above),
// or the timeout expires.
t.Errorf("Select: slept for %v, expected %v", took, dur)
} else {
t.Logf("Select: slept for %v, requested %v", took, dur)
}
}
return
} }
}) })
@@ -54,9 +70,16 @@ func Test_poll(t *testing.T) {
_, err = ww.Write([]byte("TEST")) _, err = ww.Write([]byte("TEST"))
require.NoError(t, err) require.NoError(t, err)
fds := []pollFd{newPollFd(rr.Fd(), _POLLIN, 0)} for {
n, err := _poll(fds, 0) fds := []pollFd{newPollFd(rr.Fd(), _POLLIN, 0)}
require.EqualErrno(t, 0, err) if err == sys.EINTR {
require.Equal(t, 1, n) t.Log("Select interrupted")
continue
}
n, err := _poll(fds, 0)
require.EqualErrno(t, 0, err)
require.Equal(t, 1, n)
return
}
}) })
} }

View File

@@ -233,10 +233,6 @@ func TestPoll_Windows(t *testing.T) {
ch := make(chan result, 1) ch := make(chan result, 1)
go pollToChannel(r.Fd(), 200, ch) go pollToChannel(r.Fd(), 200, ch)
// Wait a little, then ensure a message has been written to the channel.
<-time.After(300 * time.Millisecond)
require.Equal(t, 1, len(ch))
// Ensure that the timer has expired. // Ensure that the timer has expired.
res := <-ch res := <-ch
require.Zero(t, res.err) require.Zero(t, res.err)
@@ -249,7 +245,7 @@ func TestPoll_Windows(t *testing.T) {
wh := syscall.Handle(w.Fd()) wh := syscall.Handle(w.Fd())
ch := make(chan result, 1) ch := make(chan result, 1)
go pollToChannel(r.Fd(), 600, ch) go pollToChannel(r.Fd(), 800, ch)
<-time.After(300 * time.Millisecond) <-time.After(300 * time.Millisecond)
require.Equal(t, 0, len(ch)) require.Equal(t, 0, len(ch))