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.