Skip to content

Commit

Permalink
interp: skip cancellable reader test on Windows
Browse files Browse the repository at this point in the history
And document StdIO and the test a bit better now that I've read up
on the topic a bit.
  • Loading branch information
mvdan committed Dec 17, 2024
1 parent a51b0f6 commit 71f43b4
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 4 deletions.
7 changes: 6 additions & 1 deletion interp/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -454,10 +454,15 @@ func stdinFile(r io.Reader) (*os.File, error) {
// standard error. If out or err are nil, they default to a writer that discards
// the output.
//
// Note that providing a non-nil standard input other than [os.File] will require
// Note that providing a non-nil standard input other than [*os.File] will require
// an [os.Pipe] and spawning a goroutine to copy into it,
// as an [os.File] is the only way to share a reader with subprocesses.
// This may cause the interpreter to consume the entire reader.
// See [os/exec.Cmd.Stdin].
//
// When providing an [*os.File] as standard input, consider using an [os.Pipe]
// as it has the best chance to support cancellable reads via [os.File.SetReadDeadline],
// so that cancelling the runner's context can stop a blocked standard input read.
func StdIO(in io.Reader, out, err io.Writer) RunnerOption {
return func(r *Runner) error {
stdin, _err := stdinFile(in)
Expand Down
13 changes: 10 additions & 3 deletions interp/interp_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4029,14 +4029,21 @@ func TestRunnerContext(t *testing.T) {
}
}

func TestCancelreader(t *testing.T) {
func TestCancelBlockedStdinRead(t *testing.T) {
if runtime.GOOS == "windows" {
// TODO: Why is this? The [os.File.SetReadDeadline] docs seem to imply that it should work
// across all major platforms, and the file polling implementation seems to be
// for all posix platforms including Windows.
// Our previous logic and tests with muesli/cancelreader did not test an os.Pipe
// on Windows either, so skipping here is not any worse.
t.Skip("os.Pipe on windows appears to not support cancellable reads")
}
t.Parallel()

p := syntax.NewParser()
file := parse(t, p, "read x")
ctx, cancel := context.WithTimeout(context.Background(), 100*time.Millisecond)
// Make the linter happy, even though we deliberately wait for the
// timeout.
// Make the linter happy, even though we deliberately wait for the timeout.
defer cancel()

stdinRead, stdinWrite, err := os.Pipe()
Expand Down

0 comments on commit 71f43b4

Please sign in to comment.