如何解决在单个 Go 目录文件上运行测试时出错
我正在学习关于 Go 的教程,我有实际的文件树:
.
├── arrays
├── concurrency
├── di
├── hello-world
├── integers
├── iteration
├── maps
├── mocking
├── pointers
├── racer
└── structs
如果我在所有文件夹文件中运行测试,它们都可以工作,除了名为 racer 的文件夹, 运行测试给我以下错误:
# runtime/cgo
cgo: exec /missing-cc: fork/exec /missing-cc: no such file or directory
FAIL github.com/Gabriel2233/go-with-tests/racer [build failed]
是否与我在文件中所做的事情有关?这是测试文件
package racer
import (
"net/http"
"net/http/httptest"
"testing"
"time"
)
func TestRacer(t *testing.T) {
slowServer := makeDelayedServer(20 * time.Millisecond)
fastServer := makeDelayedServer(0 * time.Millisecond)
defer slowServer.Close()
defer fastServer.Close()
slowURL := slowServer.URL
fastURL := fastServer.URL
want := fastURL
got := Racer(slowURL,fastURL)
if got != want {
t.Errorf("got %q,want %q",got,want)
}
t.Run("returns error if race takes more than 10s",func(t *testing.T) {
serverA := makeDelayedServer(time.Second * 11)
serverB := makeDelayedServer(time.Second * 12)
defer serverA.Close()
defer serverB.Close()
_,err := Racer(serverA.URL,serverB.URL)
if err == nil {
t.Error("expected an error but didn't get one")
}
})
}
func makeDelayedServer(delay time.Duration) *httptest.Server {
handler := http.HandlerFunc(func(w http.ResponseWriter,r *http.Request) {
time.Sleep(delay * time.Millisecond)
w.WriteHeader(http.StatusOK)
})
server := httptest.NewServer(handler)
return server
}
这是 Racer.go 文件
package racer
import (
"net/http"
"time"
)
func Racer(a,b string) (winner string) {
select {
case <-ping(a):
return a
case <-ping(b):
return b
}
}
func ping(url string) chan struct{} {
ch := make(chan struct{})
go func() {
http.Get(url)
close(ch)
}()
return ch
}
func measureResponseTime(url string) time.Duration {
start := time.Now()
http.Get(url)
return time.Since(start)
}
我在我的树中创建了第二个目录,我意识到使用 go 包 httptest 的两个文件夹都给了我上面在问题中提到的相同错误
解决方法
我认为,从 test 目录的名称来看,它使用了竞态检测器,而竞态检测器依赖于 cgo。我刚刚为自己验证了这一点,如果你制作一个小程序(我称之为 ra.go
),看起来像:
import (
"fmt"
)
var x string
//go:noinline
func check() {
if x != "Hello world!" {
fmt.Printf("FAIL,wanted 'Hello world!' but got '%s'\n",x)
}
}
func main() {
x = "Not Hello World,haha"
check()
}
如果您构建它 go build ra.go
应该可以正常工作,但是如果您打开竞争检测器,go build -race ra.go
我怀疑您会看到相同的错误消息。具体如何修复取决于您的操作系统;在 macOS 上(我正在测试所有这些),您需要安装 Xcode 及其命令行工具。 Linux 有一个更复杂的答案,而 Windows 我只是不知道(我应该,但我不知道)。
要了解幕后发生的事情(这可能是 TMI),请尝试以下操作:
go clean -cache
go build -x -race ra.go >& race.log
go build -x ra.go >& plain.log
然后检查这两个日志文件。在 macOS race.log
上将包含类似
clang -fno-caret-diagnostics -c -x c - -o /dev/null || true
以后(如果成功)
TERM='dumb' clang -I /Users/drchase/work/go-1.15/src/runtime/cgo -fPIC -m64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=$WORK/b034=/tmp/go-build -gno-record-gcc-switches -fno-common -I ./ -g -O2 -Wno-nullability-completeness -Wall -Werror -o ./_x001.o -c _cgo_export.c
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。