摘要:我在测试过程中遇到了竞争状况,我的服务器在向其发出客户端请求之前尚未可靠地准备好服务请求。如何仅在侦听器准备好之前进行阻止,并且仍然维护可组合的公共 API,而不要求用户 BYO net.Listener
?
client.Do(req)
我们看到以下错误,因为在我们调用测试函数之前,在后台启动(阻塞)服务器的 goroutine 没有监听TestRun
。
--- FAIL: TestRun/Server_accepts_HTTP_requests (0.00s) /home/matt/repos/admission-control/server_test.go:64: failed to make a request: Get https://127.0.0.1:37877: dial tcp 127.0.0.1:37877: connect: connection refused
我没有httptest.Server
直接使用,因为我正在尝试测试我自己的服务器组件的阻止和取消特性。
我创建一个,在使用 启动它后将httptest.NewUnstartedServer
其克隆*tls.Config
到一个新的中,然后在调用 之前将其关闭。这还有一个好处是为我提供了配置了匹配的 RootCA。http.Server
StartTLS()
*AdmissionServer.Run()
*http.Client
测试 TLS 在这里很重要,因为它公开的守护进程存在于仅 TLS 的环境中。
func newTestServer(ctx context.Context, t *testing.T) *httptest.Server {
testHandler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintln(w, "OK")
})
testSrv := httptest.NewUnstartedServer(testHandler)
admissionServer, err := NewServer(nil, &noopLogger{})
if err != nil {
t.Fatalf("admission server creation failed: %s", err)
return nil
}
// We start the test server, copy its config out, and close it down so we can
// start our own server. This is because httptest.Server only generates a
// self-signed TLS config after starting it.
testSrv.StartTLS()
admissionServer.srv = &http.Server{
Addr: testSrv.Listener.Addr().String(),
Handler: testHandler,
TLSConfig: testSrv.TLS.Clone(),
}
testSrv.Close()
// We need a better synchronization primitive here that doesn't block
// but allows the underlying listener to be ready before
// serving client requests.
go func() {
if err := admissionServer.Run(ctx); err != nil {
t.Fatalf("server returned unexpectedly: %s", err)
}
}()
return testSrv
}
青春有我
相关分类