Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

os/exec: example test setting Command.Stdout does not terminate #17768

Closed
stapelberg opened this issue Nov 3, 2016 · 5 comments
Closed

os/exec: example test setting Command.Stdout does not terminate #17768

stapelberg opened this issue Nov 3, 2016 · 5 comments
Labels
FrozenDueToAge NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. WaitingForInfo Issue is not actionable because of missing required information, which needs to be provided.

Comments

@stapelberg
Copy link
Contributor

What version of Go are you using (go version)?

go version go1.7.3 linux/amd64

What operating system and processor architecture are you using (go env)?

GOARCH="amd64"
GOBIN=""
GOEXE=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOOS="linux"
GOPATH="/usr/local/google/home/stapelberg/gocode"
GORACE=""
GOROOT="/usr/lib/google-golang"
GOTOOLDIR="/usr/lib/google-golang/pkg/tool/linux_amd64"
CC="gcc"
GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build817336530=/tmp/go-build -gno-record-gcc-switches"
CXX="g++"
CGO_ENABLED="1"

What did you do?

The following example test does not terminate:

package example_test

import (
    "os"
    "os/exec"
)

func ExampleFoo() {
    cmd := exec.Command("/bin/sh", "-c", "sleep 999d")
    cmd.Stdout = os.Stdout
    cmd.Start()

    // OUTPUT:
    // foo
}

Removing the cmd.Stdout = os.Stdout line makes it terminate.

In case it matters, I’m running go test -v example/..., the above example is stored in gocode/src/example/example_test.go

What did you expect to see?

I expected the test to fail.

What did you see instead?

The test does not terminate.

@josharian josharian changed the title Example test setting exec.Command.Stdout does not terminate os/exec: example test setting Command.Stdout does not terminate Nov 3, 2016
@quentinmit
Copy link
Contributor

@stapelberg Why did you expect the test to fail? The command is still running, so the test is still waiting for the output.

@quentinmit quentinmit added WaitingForInfo Issue is not actionable because of missing required information, which needs to be provided. NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. labels Nov 4, 2016
@stapelberg
Copy link
Contributor Author

How is testing determining that stdout might still be written to? Can the condition be documented, so that the behavior is at least not a surprise?

@freeformz
Copy link

I'm pretty sure this is related to the use of an Example and how it captures os.Stdout. When cmd.Stdout == nil it's effectively set to /dev/null and then closed during Start().

Also the use of exec.Start() isn't exactly correct as Start() doesn't wait for the program to complete, to do so you need to call cmd.Wait().

@stapelberg
Copy link
Contributor Author

How is testing determining that stdout might still be written to? Can the condition be documented, so that the behavior is at least not a surprise?

It seems like runExample is redirecting os.Stdout to a pipe and reads until EOF.

I think adjusting the documentation to mention that all uses of os.Stdout in an example test must close os.Stdout in order to have the example test terminate is sufficient to close this issue.

@bradfitz
Copy link
Contributor

I'm not sure where we'd document this, or even that we'd want to. Examples are supposed to be simple. If you're doing these sorts of shenanigans, I think this sort of pain is exactly the sort of feedback you need to stop writing complicated examples.

This works fine for me:

func ExampleFoo() {
        cmd := exec.Command("/bin/sh", "-c", "echo hello")
        cmd.Stdout = os.Stdout
        if err := cmd.Run(); err != nil {
                log.Fatal(err)
        }

        // OUTPUT:                                                                                                         
        // hello                                                                                                           
}

So I don't think there's anything to do here.

@golang golang locked and limited conversation to collaborators Nov 22, 2017
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
FrozenDueToAge NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. WaitingForInfo Issue is not actionable because of missing required information, which needs to be provided.
Projects
None yet
Development

No branches or pull requests

5 participants