Skip to content

Commit 2626dc1

Browse files
committed
add configurable buffer sizes tests
1 parent 14685b9 commit 2626dc1

File tree

1 file changed

+183
-0
lines changed

1 file changed

+183
-0
lines changed

internal/pool/buffer_size_test.go

Lines changed: 183 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,183 @@
1+
package pool_test
2+
3+
import (
4+
"bufio"
5+
"context"
6+
"net"
7+
"unsafe"
8+
9+
. "github.com/bsm/ginkgo/v2"
10+
. "github.com/bsm/gomega"
11+
12+
"github.com/redis/go-redis/v9/internal/pool"
13+
"github.com/redis/go-redis/v9/internal/proto"
14+
)
15+
16+
var _ = Describe("Buffer Size Configuration", func() {
17+
var connPool *pool.ConnPool
18+
ctx := context.Background()
19+
20+
AfterEach(func() {
21+
if connPool != nil {
22+
connPool.Close()
23+
}
24+
})
25+
26+
It("should use default buffer sizes when not specified", func() {
27+
connPool = pool.NewConnPool(&pool.Options{
28+
Dialer: dummyDialer,
29+
PoolSize: 1,
30+
PoolTimeout: 1000,
31+
})
32+
33+
cn, err := connPool.NewConn(ctx)
34+
Expect(err).NotTo(HaveOccurred())
35+
defer connPool.CloseConn(cn)
36+
37+
// Check that default buffer sizes are used (0.5MiB)
38+
writerBufSize := getWriterBufSizeUnsafe(cn)
39+
readerBufSize := getReaderBufSizeUnsafe(cn)
40+
41+
Expect(writerBufSize).To(Equal(proto.DefaultBufferSize)) // Default 0.5MiB buffer size
42+
Expect(readerBufSize).To(Equal(proto.DefaultBufferSize)) // Default 0.5MiB buffer size
43+
})
44+
45+
It("should use custom buffer sizes when specified", func() {
46+
customReadSize := 32 * 1024 // 32KB
47+
customWriteSize := 64 * 1024 // 64KB
48+
49+
connPool = pool.NewConnPool(&pool.Options{
50+
Dialer: dummyDialer,
51+
PoolSize: 1,
52+
PoolTimeout: 1000,
53+
ReadBufferSize: customReadSize,
54+
WriteBufferSize: customWriteSize,
55+
})
56+
57+
cn, err := connPool.NewConn(ctx)
58+
Expect(err).NotTo(HaveOccurred())
59+
defer connPool.CloseConn(cn)
60+
61+
// Check that custom buffer sizes are used
62+
writerBufSize := getWriterBufSizeUnsafe(cn)
63+
readerBufSize := getReaderBufSizeUnsafe(cn)
64+
65+
Expect(writerBufSize).To(Equal(customWriteSize))
66+
Expect(readerBufSize).To(Equal(customReadSize))
67+
})
68+
69+
It("should handle zero buffer sizes by using defaults", func() {
70+
connPool = pool.NewConnPool(&pool.Options{
71+
Dialer: dummyDialer,
72+
PoolSize: 1,
73+
PoolTimeout: 1000,
74+
ReadBufferSize: 0, // Should use default
75+
WriteBufferSize: 0, // Should use default
76+
})
77+
78+
cn, err := connPool.NewConn(ctx)
79+
Expect(err).NotTo(HaveOccurred())
80+
defer connPool.CloseConn(cn)
81+
82+
// Check that default buffer sizes are used (0.5MiB)
83+
writerBufSize := getWriterBufSizeUnsafe(cn)
84+
readerBufSize := getReaderBufSizeUnsafe(cn)
85+
86+
Expect(writerBufSize).To(Equal(proto.DefaultBufferSize)) // Default 0.5MiB buffer size
87+
Expect(readerBufSize).To(Equal(proto.DefaultBufferSize)) // Default 0.5MiB buffer size
88+
})
89+
90+
It("should use 0.5MiB default buffer sizes for standalone NewConn", func() {
91+
// Test that NewConn (without pool) also uses 0.5MiB defaults
92+
netConn := newDummyConn()
93+
cn := pool.NewConn(netConn)
94+
defer cn.Close()
95+
96+
writerBufSize := getWriterBufSizeUnsafe(cn)
97+
readerBufSize := getReaderBufSizeUnsafe(cn)
98+
99+
Expect(writerBufSize).To(Equal(proto.DefaultBufferSize)) // Default 0.5MiB buffer size
100+
Expect(readerBufSize).To(Equal(proto.DefaultBufferSize)) // Default 0.5MiB buffer size
101+
})
102+
103+
It("should use 0.5MiB defaults even when pool is created directly without buffer sizes", func() {
104+
// Test the scenario where someone creates a pool directly (like in tests)
105+
// without setting ReadBufferSize and WriteBufferSize
106+
connPool = pool.NewConnPool(&pool.Options{
107+
Dialer: dummyDialer,
108+
PoolSize: 1,
109+
PoolTimeout: 1000,
110+
// ReadBufferSize and WriteBufferSize are not set (will be 0)
111+
})
112+
113+
cn, err := connPool.NewConn(ctx)
114+
Expect(err).NotTo(HaveOccurred())
115+
defer connPool.CloseConn(cn)
116+
117+
// Should still get 0.5MiB defaults because NewConnPool sets them
118+
writerBufSize := getWriterBufSizeUnsafe(cn)
119+
readerBufSize := getReaderBufSizeUnsafe(cn)
120+
121+
Expect(writerBufSize).To(Equal(proto.DefaultBufferSize)) // Default 0.5MiB buffer size
122+
Expect(readerBufSize).To(Equal(proto.DefaultBufferSize)) // Default 0.5MiB buffer size
123+
})
124+
})
125+
126+
// Helper functions to extract buffer sizes using unsafe pointers
127+
func getWriterBufSizeUnsafe(cn *pool.Conn) int {
128+
cnPtr := (*struct {
129+
usedAt int64
130+
netConn net.Conn
131+
rd *proto.Reader
132+
bw *bufio.Writer
133+
wr *proto.Writer
134+
// ... other fields
135+
})(unsafe.Pointer(cn))
136+
137+
if cnPtr.bw == nil {
138+
return -1
139+
}
140+
141+
bwPtr := (*struct {
142+
err error
143+
buf []byte
144+
n int
145+
wr interface{}
146+
})(unsafe.Pointer(cnPtr.bw))
147+
148+
return len(bwPtr.buf)
149+
}
150+
151+
func getReaderBufSizeUnsafe(cn *pool.Conn) int {
152+
cnPtr := (*struct {
153+
usedAt int64
154+
netConn net.Conn
155+
rd *proto.Reader
156+
bw *bufio.Writer
157+
wr *proto.Writer
158+
// ... other fields
159+
})(unsafe.Pointer(cn))
160+
161+
if cnPtr.rd == nil {
162+
return -1
163+
}
164+
165+
rdPtr := (*struct {
166+
rd *bufio.Reader
167+
})(unsafe.Pointer(cnPtr.rd))
168+
169+
if rdPtr.rd == nil {
170+
return -1
171+
}
172+
173+
bufReaderPtr := (*struct {
174+
buf []byte
175+
rd interface{}
176+
r, w int
177+
err error
178+
lastByte int
179+
lastRuneSize int
180+
})(unsafe.Pointer(rdPtr.rd))
181+
182+
return len(bufReaderPtr.buf)
183+
}

0 commit comments

Comments
 (0)