-
Notifications
You must be signed in to change notification settings - Fork 17.8k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
cmd/go: fail if a test binary exits with no output
For example, if a test calls os.Exit(0), that could trick a 'go test' run into not running some of the other tests, and thinking that they all succeeded. This can easily go unnoticed and cause developers headaches. Add a simple sanity check as part of 'go test': if the test binary succeeds and doesn't print anything, we should error, as something clearly went very wrong. This is done by inspecting each of the stdout writes from the spawned process, since we don't want to read the entirety of the output into a buffer. We need to introduce a "buffered" bool var, as there's now an io.Writer layer between cmd.Stdout and &buf. A few TestMain funcs in the standard library needed fixing, as they returned without printing anything as a means to skip testing the entire package. For that purpose add testenv.MainMust, which prints a warning and prints SKIP, similar to when -run matches no tests. Finally, add tests for both os.Exit(0) and os.Exit(1), both as part of TestMain and as part of a single test, and test that the various stdout modes still do the right thing. Fixes #29062. Change-Id: Ic6f8ef3387dfc64e4cd3e8f903d7ca5f5f38d397 Reviewed-on: https://go-review.googlesource.com/c/go/+/184457 Run-TryBot: Daniel Martí <[email protected]> TryBot-Result: Gobot Gobot <[email protected]> Reviewed-by: Bryan C. Mills <[email protected]>
- Loading branch information
Showing
7 changed files
with
200 additions
and
12 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,152 @@ | ||
env GO111MODULE=on | ||
|
||
# If a test exits with a zero status code, 'go test' prints its own error | ||
# message and fails. | ||
! go test ./zero | ||
! stdout ^ok | ||
! stdout 'exit status' | ||
stdout 'did not print anything' | ||
stdout ^FAIL | ||
|
||
# If a test exits with a non-zero status code, 'go test' fails normally. | ||
! go test ./one | ||
! stdout ^ok | ||
stdout 'exit status' | ||
! stdout 'did not print anything' | ||
stdout ^FAIL | ||
|
||
# Ensure that other flags still do the right thing. | ||
go test -list=. ./zero | ||
stdout ExitZero | ||
|
||
! go test -bench=. ./zero | ||
stdout 'did not print anything' | ||
|
||
# 'go test' with no args streams output without buffering. Ensure that it still | ||
# catches a zero exit with missing output. | ||
cd zero | ||
! go test | ||
stdout 'did not print anything' | ||
cd ../normal | ||
go test | ||
stdout ^ok | ||
cd .. | ||
|
||
# If a TestMain prints something and exits with a zero status code, 'go test' | ||
# shouldn't complain about that. It's a common way to skip testing a package | ||
# entirely. | ||
go test ./main_zero_warning | ||
! stdout 'skipping all tests' | ||
stdout ^ok | ||
|
||
# With -v, we'll see the warning from TestMain. | ||
go test -v ./main_zero_warning | ||
stdout 'skipping all tests' | ||
stdout ^ok | ||
|
||
# Listing all tests won't actually give a result if TestMain exits. That's okay, | ||
# because this is how TestMain works. If we decide to support -list even when | ||
# TestMain is used to skip entire packages, we can change this test case. | ||
go test -list=. ./main_zero_warning | ||
stdout 'skipping all tests' | ||
! stdout TestNotListed | ||
|
||
# If a TestMain prints nothing and exits with a zero status code, 'go test' | ||
# should fail. | ||
! go test ./main_zero_nowarning | ||
stdout 'did not print anything' | ||
|
||
# A test that simply prints "PASS" and exits with a zero status code shouldn't | ||
# be OK, but we don't catch that at the moment. It's hard to tell if any test | ||
# started but didn't finish without using -test.v. | ||
go test ./fake_pass | ||
stdout ^ok | ||
|
||
-- go.mod -- | ||
module m | ||
|
||
-- ./normal/normal.go -- | ||
package normal | ||
-- ./normal/normal_test.go -- | ||
package normal | ||
|
||
import "testing" | ||
|
||
func TestExitZero(t *testing.T) { | ||
} | ||
|
||
-- ./zero/zero.go -- | ||
package zero | ||
-- ./zero/zero_test.go -- | ||
package zero | ||
|
||
import ( | ||
"os" | ||
"testing" | ||
) | ||
|
||
func TestExitZero(t *testing.T) { | ||
os.Exit(0) | ||
} | ||
|
||
-- ./one/one.go -- | ||
package one | ||
-- ./one/one_test.go -- | ||
package one | ||
|
||
import ( | ||
"os" | ||
"testing" | ||
) | ||
|
||
func TestExitOne(t *testing.T) { | ||
os.Exit(1) | ||
} | ||
|
||
-- ./main_zero_warning/zero.go -- | ||
package zero | ||
-- ./main_zero_warning/zero_test.go -- | ||
package zero | ||
|
||
import ( | ||
"fmt" | ||
"os" | ||
"testing" | ||
) | ||
|
||
func TestMain(m *testing.M) { | ||
fmt.Println("skipping all tests") | ||
os.Exit(0) | ||
} | ||
|
||
func TestNotListed(t *testing.T) {} | ||
|
||
-- ./main_zero_nowarning/zero.go -- | ||
package zero | ||
-- ./main_zero_nowarning/zero_test.go -- | ||
package zero | ||
|
||
import ( | ||
"os" | ||
"testing" | ||
) | ||
|
||
func TestMain(m *testing.M) { | ||
os.Exit(0) | ||
} | ||
|
||
-- ./fake_pass/fake.go -- | ||
package fake | ||
-- ./fake_pass/fake_test.go -- | ||
package fake | ||
|
||
import ( | ||
"fmt" | ||
"os" | ||
"testing" | ||
) | ||
|
||
func TestFakePass(t *testing.T) { | ||
fmt.Println("PASS") | ||
os.Exit(0) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters