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  }