...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package redisx_test
16
17 import (
18 "net/textproto"
19 "sync"
20 "testing"
21
22 "github.com/gomodule/redigo/internal/redistest"
23 "github.com/gomodule/redigo/redis"
24 "github.com/gomodule/redigo/redisx"
25 )
26
27 func TestConnMux(t *testing.T) {
28 c, err := redistest.Dial()
29 if err != nil {
30 t.Fatalf("error connection to database, %v", err)
31 }
32 m := redisx.NewConnMux(c)
33 defer m.Close()
34
35 c1 := m.Get()
36 c2 := m.Get()
37 c1.Send("ECHO", "hello")
38 c2.Send("ECHO", "world")
39 c1.Flush()
40 c2.Flush()
41 s, err := redis.String(c1.Receive())
42 if err != nil {
43 t.Fatal(err)
44 }
45 if s != "hello" {
46 t.Fatalf("echo returned %q, want %q", s, "hello")
47 }
48 s, err = redis.String(c2.Receive())
49 if err != nil {
50 t.Fatal(err)
51 }
52 if s != "world" {
53 t.Fatalf("echo returned %q, want %q", s, "world")
54 }
55 c1.Close()
56 c2.Close()
57 }
58
59 func TestConnMuxClose(t *testing.T) {
60 c, err := redistest.Dial()
61 if err != nil {
62 t.Fatalf("error connection to database, %v", err)
63 }
64 m := redisx.NewConnMux(c)
65 defer m.Close()
66
67 c1 := m.Get()
68 c2 := m.Get()
69
70 if err := c1.Send("ECHO", "hello"); err != nil {
71 t.Fatal(err)
72 }
73 if err := c1.Close(); err != nil {
74 t.Fatal(err)
75 }
76
77 if err := c2.Send("ECHO", "world"); err != nil {
78 t.Fatal(err)
79 }
80 if err := c2.Flush(); err != nil {
81 t.Fatal(err)
82 }
83
84 s, err := redis.String(c2.Receive())
85 if err != nil {
86 t.Fatal(err)
87 }
88 if s != "world" {
89 t.Fatalf("echo returned %q, want %q", s, "world")
90 }
91 c2.Close()
92 }
93
94 func BenchmarkConn(b *testing.B) {
95 b.StopTimer()
96 c, err := redistest.Dial()
97 if err != nil {
98 b.Fatalf("error connection to database, %v", err)
99 }
100 defer c.Close()
101 b.StartTimer()
102
103 for i := 0; i < b.N; i++ {
104 if _, err := c.Do("PING"); err != nil {
105 b.Fatal(err)
106 }
107 }
108 }
109
110 func BenchmarkConnMux(b *testing.B) {
111 b.StopTimer()
112 c, err := redistest.Dial()
113 if err != nil {
114 b.Fatalf("error connection to database, %v", err)
115 }
116 m := redisx.NewConnMux(c)
117 defer m.Close()
118
119 b.StartTimer()
120
121 for i := 0; i < b.N; i++ {
122 c := m.Get()
123 if _, err := c.Do("PING"); err != nil {
124 b.Fatal(err)
125 }
126 c.Close()
127 }
128 }
129
130 func BenchmarkPool(b *testing.B) {
131 b.StopTimer()
132
133 p := redis.Pool{Dial: redistest.Dial, MaxIdle: 1}
134 defer p.Close()
135
136
137 c := p.Get()
138 if err := c.Err(); err != nil {
139 b.Fatal(err)
140 }
141 c.Close()
142
143 b.StartTimer()
144
145 for i := 0; i < b.N; i++ {
146 c := p.Get()
147 if _, err := c.Do("PING"); err != nil {
148 b.Fatal(err)
149 }
150 c.Close()
151 }
152 }
153
154 const numConcurrent = 10
155
156 func BenchmarkConnMuxConcurrent(b *testing.B) {
157 b.StopTimer()
158 c, err := redistest.Dial()
159 if err != nil {
160 b.Fatalf("error connection to database, %v", err)
161 }
162 defer c.Close()
163
164 m := redisx.NewConnMux(c)
165
166 var wg sync.WaitGroup
167 wg.Add(numConcurrent)
168
169 b.StartTimer()
170
171 for i := 0; i < numConcurrent; i++ {
172 go func() {
173 defer wg.Done()
174 for i := 0; i < b.N; i++ {
175 c := m.Get()
176 if _, err := c.Do("PING"); err != nil {
177 b.Fatal(err)
178 }
179 c.Close()
180 }
181 }()
182 }
183 wg.Wait()
184 }
185
186 func BenchmarkPoolConcurrent(b *testing.B) {
187 b.StopTimer()
188
189 p := redis.Pool{Dial: redistest.Dial, MaxIdle: numConcurrent}
190 defer p.Close()
191
192
193 conns := make([]redis.Conn, numConcurrent)
194 for i := range conns {
195 c := p.Get()
196 if err := c.Err(); err != nil {
197 b.Fatal(err)
198 }
199 conns[i] = c
200 }
201 for _, c := range conns {
202 c.Close()
203 }
204
205 var wg sync.WaitGroup
206 wg.Add(numConcurrent)
207
208 b.StartTimer()
209
210 for i := 0; i < numConcurrent; i++ {
211 go func() {
212 defer wg.Done()
213 for i := 0; i < b.N; i++ {
214 c := p.Get()
215 if _, err := c.Do("PING"); err != nil {
216 b.Fatal(err)
217 }
218 c.Close()
219 }
220 }()
221 }
222 wg.Wait()
223 }
224
225 func BenchmarkPipelineConcurrency(b *testing.B) {
226 b.StopTimer()
227 c, err := redistest.Dial()
228 if err != nil {
229 b.Fatalf("error connection to database, %v", err)
230 }
231 defer c.Close()
232
233 var wg sync.WaitGroup
234 wg.Add(numConcurrent)
235
236 var pipeline textproto.Pipeline
237
238 b.StartTimer()
239
240 for i := 0; i < numConcurrent; i++ {
241 go func() {
242 defer wg.Done()
243 for i := 0; i < b.N; i++ {
244 id := pipeline.Next()
245 pipeline.StartRequest(id)
246 c.Send("PING")
247 c.Flush()
248 pipeline.EndRequest(id)
249 pipeline.StartResponse(id)
250 _, err := c.Receive()
251 if err != nil {
252 b.Fatal(err)
253 }
254 pipeline.EndResponse(id)
255 }
256 }()
257 }
258 wg.Wait()
259 }
260
View as plain text