On Fri, 5 Nov 2021, 11:08 pm Axel Wagner, <axel.wagner...@googlemail.com>
wrote:

> First, to point out the obvious: It is a bad idea to have a test read from
> stdin. You should pass a separate io.Reader and use that.
>
> Next: exec.Cmd.{Stdin,Stdout,Stderr} are all set to os.DevNull by default,
> meaning you don't get any input or output. I assume
>
> - `go test` does not modify Cmd.Stdin (leaving it at os.DevNull) of the
> sub-process it launches and redirects Cmd.{Stdout,Stderr} to buffers.
> - Your test (if you use `exec.Command(…).Run()`) also does not modify any
> of them, so they stay at os.DevNull
> - Other languages have them default to stdin/stdout/stderr of the parent
> process, so they try to read from stdin, which is a line-buffered terminal,
> so it blocks until you input a line.
>
> Again, the solution here should be to not rely on os.Stdin at all, but
> instead test a function which uses a general io.Reader.
>

Great thank you for clarifying that.

I ran into this as I was writing a test for an interactive input function
and I expected the test to hang but it didn't. So bit of an accidental find
and glad I found this.



> On Fri, Nov 5, 2021 at 12:48 PM Amit Saha <amitsaha...@gmail.com> wrote:
>
>>
>>
>> > On 5 Nov 2021, at 10:27 pm, Amit Saha <amitsaha...@gmail.com> wrote:
>> >
>> > I have this test function:
>> >
>> > package main
>> >
>> > import (
>> >         "bufio"
>> >         "fmt"
>> >         "os"
>> >         "testing"
>> > )
>> >
>> > func TestInput(t *testing.T) {
>> >         scanner := bufio.NewScanner(os.Stdin)
>> >         msg := "Your name please? Press the Enter key when done"
>> >         fmt.Fprintln(os.Stdout, msg)
>> >
>> >         scanner.Scan()
>> >         if err := scanner.Err(); err != nil {
>> >                 t.Fatal(err)
>> >         }
>> >         name := scanner.Text()
>> >         if len(name) == 0 {
>> >                 t.Log("empty input")
>> >         }
>> >         t.Log(name)
>> >
>> > }
>> >
>> > When i run it via go test -v, this is what i get (TLDR; terminates
>> without waiting for the interactive input):
>> >
>> > % go test -v
>> >
>> > === RUN   TestInput
>> >
>> > Your name please? Press the Enter key when done
>> >
>> >     stdin_test.go:21: empty input
>> >
>> >     stdin_test.go:23:
>> >
>> > --- PASS: TestInput (0.00s)
>> >
>> > PASS
>> >
>> > ok  test 0.370s
>> >
>> >
>> >
>> > However, when i compile the test and then run the binary, it waits for
>> me to enter the input:
>> >
>> >
>> >
>> > % go test -c
>> >
>> > % ./test.test
>> >
>> > Your name please? Press the Enter key when done
>> >
>> >
>> >
>> >
>> > The latter behavior is more inline with what i was expecting in the
>> first case as well.
>> >
>> > I thought may be it has something to do with the fact that go test is
>> executing the binary (i think) after compiling, and started looking at:
>> https://github.com/golang/go/blob/c7f2f51fed15b410dea5f608420858b401887d0a/src/cmd/go/internal/test/test.go
>> , but can't see anything obvious.
>> >
>> > Wondering if anyone of you folks have an answer?
>> >
>>
>> Did a bit more of experimentation, and it seems like, that’s just how
>> exec.Command(“mycmd").Run() works.
>>
>> I tried with exec.Command("wc").Run() and it returns immediately as well.
>> (Running the Unix “word count” program).
>>
>> I suppose I am surprised since in another language I am familiar with
>> (Python), a command waiting for an interactive input when executed via
>> os/exec would “hang”, for example:
>>
>> % python3
>> Python 3.8.2 (default, Apr  8 2021, 23:19:18)
>> [Clang 12.0.5 (clang-1205.0.22.9)] on darwin
>> Type "help", "copyright", "credits" or "license" for more information.
>> >>> import subprocess
>> >>> subprocess.check_output(["wc”])
>>
>> This will hang
>>
>> >
>> >
>> > Thanks,
>> >
>> > Amit.
>> >
>> >
>> >
>> >
>> >
>> > --
>> > You received this message because you are subscribed to a topic in the
>> Google Groups "golang-nuts" group.
>> > To unsubscribe from this topic, visit
>> https://groups.google.com/d/topic/golang-nuts/24pL7iQbx64/unsubscribe.
>> > To unsubscribe from this group and all its topics, send an email to
>> golang-nuts+unsubscr...@googlegroups.com.
>> > To view this discussion on the web visit
>> https://groups.google.com/d/msgid/golang-nuts/0f48fc8d-7e21-46a6-b736-90ea2f0bcbe6n%40googlegroups.com
>> .
>>
>> --
>> You received this message because you are subscribed to the Google Groups
>> "golang-nuts" group.
>> To unsubscribe from this group and stop receiving emails from it, send an
>> email to golang-nuts+unsubscr...@googlegroups.com.
>> To view this discussion on the web visit
>> https://groups.google.com/d/msgid/golang-nuts/25A4D3EA-F228-447C-A19E-8BE062840E20%40gmail.com
>> .
>>
>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/CANODV3kq1sgTuvYDd%3DWPM00zen%2BuMQOrSrc0gcixS_-L%3DK8gjQ%40mail.gmail.com.

Reply via email to