rpc: refactor read limit test #32494 (#1412)

closes #32240 #32232

The main cause for the time out is the slow json encoding of large data.
In #32240 they tried to resolve the issue by reducing the size of the
test. However as Felix pointed out, the test is still kind of confusing.

I've refactored the test so it is more understandable and have reduced
the amount of data needed to be json encoded. I think it is still
important to ensure that the default read limit is not active, so I have
retained one large (~32 MB) test case, but it's at least smaller than
the existing ~64 MB test case.

Co-authored-by: lightclient <14004106+lightclient@users.noreply.github.com>
This commit is contained in:
Daniel Liu 2025-09-03 15:44:04 +08:00 committed by GitHub
parent a6762110b5
commit ce26c34c7b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -121,56 +121,49 @@ func TestWebsocketLargeRead(t *testing.T) {
srv = newTestServer() srv = newTestServer()
httpsrv = httptest.NewServer(srv.WebsocketHandler([]string{"*"})) httpsrv = httptest.NewServer(srv.WebsocketHandler([]string{"*"}))
wsURL = "ws:" + strings.TrimPrefix(httpsrv.URL, "http:") wsURL = "ws:" + strings.TrimPrefix(httpsrv.URL, "http:")
buffer = 64
) )
defer srv.Stop() defer srv.Stop()
defer httpsrv.Close() defer httpsrv.Close()
testLimit := func(limit *int64) { for _, tt := range []struct {
opts := []ClientOption{} size int
expLimit := int64(wsDefaultReadLimit) limit int
if limit != nil && *limit >= 0 { err bool
opts = append(opts, WithWebsocketMessageSizeLimit(*limit)) }{
if *limit > 0 { {200, 200, false}, // Small, successful request and limit
expLimit = *limit // 0 means infinite {2048, 1024, true}, // Normal, failed request
{wsDefaultReadLimit + buffer, 0, false}, // Large, successful request, infinite limit
} {
func() {
if tt.limit != 0 {
// Some buffer is added to the limit to account for JSON encoding. It's
// skipped when the limit is zero since the intention is for the limit
// to be infinite.
tt.limit += buffer
} }
} opts := []ClientOption{WithWebsocketMessageSizeLimit(int64(tt.limit))}
client, err := DialOptions(context.Background(), wsURL, opts...) client, err := DialOptions(context.Background(), wsURL, opts...)
if err != nil { if err != nil {
t.Fatalf("can't dial: %v", err) t.Fatalf("failed to dial test server: %v", err)
}
defer client.Close()
// Remove some bytes for json encoding overhead.
underLimit := int(expLimit - 128)
overLimit := expLimit + 1
if expLimit == wsDefaultReadLimit {
// No point trying the full 32MB in tests. Just sanity-check that
// it's not obviously limited.
underLimit = 1024
overLimit = -1
}
var res string
// Check under limit
if err = client.Call(&res, "test_repeat", "A", underLimit); err != nil {
t.Fatalf("unexpected error with limit %d: %v", expLimit, err)
}
if len(res) != underLimit || strings.Count(res, "A") != underLimit {
t.Fatal("incorrect data")
}
// Check over limit
if overLimit > 0 {
err = client.Call(&res, "test_repeat", "A", expLimit+1)
if err == nil || err != websocket.ErrReadLimit {
t.Fatalf("wrong error with limit %d: %v expecting %v", expLimit, err, websocket.ErrReadLimit)
} }
} defer client.Close()
}
ptr := func(v int64) *int64 { return &v }
testLimit(ptr(-1)) // Should be ignored (use default) var res string
testLimit(ptr(0)) // Should be ignored (use default) err = client.Call(&res, "test_repeat", "A", tt.size)
testLimit(nil) // Should be ignored (use default) if tt.err && err == nil {
testLimit(ptr(200)) t.Fatalf("expected error, got none")
testLimit(ptr(wsDefaultReadLimit * 2)) }
if !tt.err {
if err != nil {
t.Fatalf("unexpected error with limit %d: %v", tt.limit, err)
}
if strings.Count(res, "A") != tt.size {
t.Fatal("incorrect data")
}
}
}()
}
} }
func TestWebsocketPeerInfo(t *testing.T) { func TestWebsocketPeerInfo(t *testing.T) {