mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-06-19 13:21:37 +00:00
rpc: fix flaky TestTracingHTTPTimeout (#35172)
`TestTracingHTTPTimeout` still flakes in CI after #35101, failing at the POST: --- FAIL: TestTracingHTTPTimeout (0.26s) tracing_test.go:633: request: Post "http://127.0.0.1:43497": EOF The test sets a short server `WriteTimeout` and posts a blocking call. `ContextRequestTimeout` leaves a fixed 100ms for the server to write its timeout response before the HTTP write deadline cuts the connection. I can't repro it locally, but my theory is that under load that write can miss the window, so the connection is dropped and the client POST returns `EOF`, failing the test before it inspects the span. This is the only test exposed to it because it is the only one that configures a `WriteTimeout`. The EOF is benign: the server sets the timeout error on the SERVER span before attempting the write, independent of whether the client receives the response. Since that span status is all the test asserts, `tryPostJSONRPC` tolerates the transport error instead of failing on it.
This commit is contained in:
parent
7d74166d3d
commit
a326298f51
1 changed files with 18 additions and 3 deletions
|
|
@ -346,17 +346,27 @@ func TestTracingSubscribeUnsubscribe(t *testing.T) {
|
|||
// like notifications (no "id" field).
|
||||
func postJSONRPC(t *testing.T, url, body string) {
|
||||
t.Helper()
|
||||
if err := tryPostJSONRPC(url, body); err != nil {
|
||||
t.Fatalf("request: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
// tryPostJSONRPC is like postJSONRPC but returns the transport error instead of
|
||||
// failing the test. The write-timeout test uses this because the HTTP
|
||||
// WriteTimeout can drop the connection before the response is flushed.
|
||||
func tryPostJSONRPC(url, body string) error {
|
||||
req, err := http.NewRequest(http.MethodPost, url, strings.NewReader(body))
|
||||
if err != nil {
|
||||
t.Fatalf("new request: %v", err)
|
||||
return err
|
||||
}
|
||||
req.Header.Set("Content-Type", "application/json")
|
||||
resp, err := http.DefaultClient.Do(req)
|
||||
if err != nil {
|
||||
t.Fatalf("request: %v", err)
|
||||
return err
|
||||
}
|
||||
_, _ = io.Copy(io.Discard, resp.Body)
|
||||
resp.Body.Close()
|
||||
return nil
|
||||
}
|
||||
|
||||
// TestTracingHTTPNotification verifies that a JSON-RPC notification emits the
|
||||
|
|
@ -630,7 +640,12 @@ func TestTracingHTTPTimeout(t *testing.T) {
|
|||
// test_block waits on ctx.Done() and returns an error. The internal
|
||||
// timer cancels ctx, so test_block unblocks shortly after the timeout
|
||||
// response goes out.
|
||||
postJSONRPC(t, httpsrv.URL, `{"jsonrpc":"2.0","id":1,"method":"test_block"}`)
|
||||
//
|
||||
// Ignore the client-side result. Under load the HTTP WriteTimeout can
|
||||
// drop the connection before the timeout response is flushed, which the
|
||||
// client sees as EOF. The server still records the timeout on its span,
|
||||
// which is what we assert below.
|
||||
_ = tryPostJSONRPC(httpsrv.URL, `{"jsonrpc":"2.0","id":1,"method":"test_block"}`)
|
||||
|
||||
// Wait for the in-flight request to finish so the deferred spanEnd fires
|
||||
// before GetSpans is called.
|
||||
|
|
|
|||
Loading…
Reference in a new issue