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  }