`cmd/go`: 文档进程执行 `go test` 的退出代码

xytpbqjk  于 2个月前  发布在  Go
关注(0)|答案(7)|浏览(38)

请在提交问题之前回答以下问题。谢谢!

您正在使用的Go版本是什么( go version )?

1.10.3

这个问题是否在最新版本中重现?

是的。

您正在使用什么操作系统和处理器架构( go env )?

GOARCH="amd64"
GOBIN=""
GOCACHE="/home/user/.cache/go-build"
GOEXE=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOOS="linux"
GOPATH="/home/user/devel/go"
GORACE=""
GOROOT="/home/user/devel/golang1.10"
GOTMPDIR=""
GOTOOLDIR="/home/user/devel/golang1.10/pkg/tool/linux_amd64"
GCCGO="gccgo"
CC="gcc"
CXX="g++"
CGO_ENABLED="1"
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build141686204=/tmp/go-build -gno-record-gcc-switches"

您做了什么?

我运行了 go help test 并尝试在输出中搜索关键字 "return"、"exit" 和 "code"。

您期望看到什么?

我希望 go test 的退出代码有文档记录,以便在脚本中(以及从Makefiles中,通过CI系统等)做出合理的决策。

您实际看到了什么?

没有提到返回/退出代码。
我期望以下情况得到记录(如果实现的话):

  • 成功运行—所有测试编译并通过良好—退出代码为0。
  • 失败运行—至少一个包的编译失败或至少一个测试失败—非零退出代码。
  • 传递了无效参数并且/或者列出的其中一个包未找到—非零退出代码,与前一种情况不同。

我还认为缓存的结果应该有效地“记住”当前生成结果时使用的退出代码(并缓存)。
另请参阅 #23716

o2g1uqev

o2g1uqev1#

忽略我,我是个傻子。t.Error != t.Fail
我同意OP的观点,但是它应该有一个非零状态,1表示错误,2表示失败,对吗?

uyhoqukh

uyhoqukh2#

目前大多数失败的退出状态为1,如果构建被中断则为2。

wljmcqd8

wljmcqd83#

我们是否区分标志解析错误,输出不同的退出代码?例如,传入"-c=invalid"返回2,而传入"-covermode=invalid"返回1。

e5nqia27

e5nqia274#

@GTB3NW 注意,您的特定问题可能与这个问题的本质无关,这个问题是关于记录已实现的行为的。
在我的工作日子里,在我们的CI管道中,我们多次使用不同的命令行选项(例如,包括-race进行夜间测试,还包括-bench …等),而go test在出错时总是以非零退出代码退出,因为我认为至少从v1.6开始就是这样,我实在没有理由认为以前不是这样。
我只是为了参考目的创建了这个问题(例如,对于可能不太熟悉Go来实现CI管道的开发运维人员)。
请尝试找出可能导致您go test进程退出码被掩盖的原因。
请注意,所有默认在通用操作系统中发现的/bin/sh风格的shell都以一种模式运行,该模式忽略任何错误,这意味着,如果您有一个类似于

go test ...
echo Whatever

的脚本,如果go test失败,这段代码永远不会退出。
(这些shell自始至终都是这样做的;甚至这是POSIX规定的。)
您需要重新编写您的脚本,使它们能够在set -e -u下运行(这几乎总是一个好主意),或者像下面这样明确测试感兴趣的命令是否失败:

go test ...
rc=$?
if [ $rc -ne 0 ]; then
  echo "testing failed" >&2
  exit $rc
fi
  • 更新*@GTB3NW,啊,我看到您已经解决了这个问题 :-)

对不起给您带来了麻烦——应该重新阅读帖子而不是依赖于评论邮件(它会忽略编辑)。

mwkjh3gx

mwkjh3gx5#

好的,这里有一个问题需要解决。我已经阅读了文档,但可能遗漏了一些内容。以下应该失败并返回错误代码1,对吗?
blahtest/blah_test.go:

package blahtest

import "testing"

func TestBlah(t *testing.T) {
	t.Fatal("Blah")
}
go test <redacted>/blahtest -v

=== RUN   TestBlah
--- FAIL: TestBlah (0.00s)
        blah_test.go:6: Blah
FAIL
ok      <redacted>/blahtest      0.004s

在/blahtest上不应该也失败吗?
目标是运行:
go test -v -short $(go list ${PKG}./... | grep -v /vendor/)
测试所有包,如果其中一个失败,整个测试就会失败。这肯定是一个常见的需求。要么是我误解了测试设施/存在bug/go test缺少一些关键功能。
有人能帮我指明正确的方向吗?我非常感谢!

pxy2qtax

pxy2qtax6#

如果你看到一个0退出代码或ok的失败测试摘要,请按照以下步骤重新提交一个单独的问题。

jfgube3f

jfgube3f7#

在我们记录错误代码之前,我认为我们可能需要做一些工作来使它们保持一致。这是一个相当大的调查,可能应该作为更广泛的go test清理的一部分进行(我希望为Go 1.14或1.15完成,但没有具体的时间表)。

相关问题