Skip to content

Commit f47fb47

Browse files
committed
Extract race tests to separate file. Add more race tests.
1 parent 9d394cc commit f47fb47

19 files changed

+411
-330
lines changed

Makefile

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
all: testdeps
2-
go test ./... -test.cpu=1,2,4
3-
go test ./... -test.short -test.race
2+
go test ./...
3+
go test ./... -short -race
44

55
testdeps: testdata/redis/src/redis-server
66

cluster_test.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,10 @@ func startCluster(scenario *clusterScenario) error {
6666
return err
6767
}
6868

69-
client := redis.NewClient(&redis.Options{Addr: "127.0.0.1:" + port})
69+
client := redis.NewClient(&redis.Options{
70+
Addr: ":" + port,
71+
})
72+
7073
info, err := client.ClusterNodes().Result()
7174
if err != nil {
7275
return err

command_test.go

Lines changed: 2 additions & 196 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,21 @@
11
package redis_test
22

33
import (
4-
"bytes"
5-
"strconv"
6-
"sync"
7-
"testing"
8-
"time"
9-
104
. "github.com/onsi/ginkgo"
115
. "github.com/onsi/gomega"
126

137
"gopkg.in/redis.v3"
14-
"gopkg.in/redis.v3/internal/pool"
158
)
169

1710
var _ = Describe("Command", func() {
1811
var client *redis.Client
1912

20-
connect := func() *redis.Client {
21-
return redis.NewClient(&redis.Options{
22-
Addr: redisAddr,
23-
PoolTimeout: time.Minute,
24-
})
25-
}
26-
2713
BeforeEach(func() {
28-
client = connect()
14+
client = redis.NewClient(redisOptions())
15+
Expect(client.FlushDb().Err()).NotTo(HaveOccurred())
2916
})
3017

3118
AfterEach(func() {
32-
Expect(client.FlushDb().Err()).NotTo(HaveOccurred())
3319
Expect(client.Close()).NotTo(HaveOccurred())
3420
})
3521

@@ -54,64 +40,6 @@ var _ = Describe("Command", func() {
5440
Expect(set.Val()).To(Equal("OK"))
5541
})
5642

57-
It("should escape special chars", func() {
58-
set := client.Set("key", "hello1\r\nhello2\r\n", 0)
59-
Expect(set.Err()).NotTo(HaveOccurred())
60-
Expect(set.Val()).To(Equal("OK"))
61-
62-
get := client.Get("key")
63-
Expect(get.Err()).NotTo(HaveOccurred())
64-
Expect(get.Val()).To(Equal("hello1\r\nhello2\r\n"))
65-
})
66-
67-
It("should handle big vals", func() {
68-
bigVal := string(bytes.Repeat([]byte{'*'}, 1<<16))
69-
70-
err := client.Set("key", bigVal, 0).Err()
71-
Expect(err).NotTo(HaveOccurred())
72-
73-
// Reconnect to get new connection.
74-
Expect(client.Close()).To(BeNil())
75-
client = connect()
76-
77-
got, err := client.Get("key").Result()
78-
Expect(err).NotTo(HaveOccurred())
79-
Expect(len(got)).To(Equal(len(bigVal)))
80-
Expect(got).To(Equal(bigVal))
81-
})
82-
83-
It("should handle many keys #1", func() {
84-
const n = 100000
85-
for i := 0; i < n; i++ {
86-
client.Set("keys.key"+strconv.Itoa(i), "hello"+strconv.Itoa(i), 0)
87-
}
88-
keys := client.Keys("keys.*")
89-
Expect(keys.Err()).NotTo(HaveOccurred())
90-
Expect(len(keys.Val())).To(Equal(n))
91-
})
92-
93-
It("should handle many keys #2", func() {
94-
const n = 100000
95-
96-
keys := []string{"non-existent-key"}
97-
for i := 0; i < n; i++ {
98-
key := "keys.key" + strconv.Itoa(i)
99-
client.Set(key, "hello"+strconv.Itoa(i), 0)
100-
keys = append(keys, key)
101-
}
102-
keys = append(keys, "non-existent-key")
103-
104-
mget := client.MGet(keys...)
105-
Expect(mget.Err()).NotTo(HaveOccurred())
106-
Expect(len(mget.Val())).To(Equal(n + 2))
107-
vals := mget.Val()
108-
for i := 0; i < n; i++ {
109-
Expect(vals[i+1]).To(Equal("hello" + strconv.Itoa(i)))
110-
}
111-
Expect(vals[0]).To(BeNil())
112-
Expect(vals[n+1]).To(BeNil())
113-
})
114-
11543
It("should convert strings via helpers", func() {
11644
set := client.Set("key", "10", 0)
11745
Expect(set.Err()).NotTo(HaveOccurred())
@@ -129,126 +57,4 @@ var _ = Describe("Command", func() {
12957
Expect(f).To(Equal(float64(10)))
13058
})
13159

132-
It("Cmd should return string", func() {
133-
cmd := redis.NewCmd("PING")
134-
client.Process(cmd)
135-
Expect(cmd.Err()).NotTo(HaveOccurred())
136-
Expect(cmd.Val()).To(Equal("PONG"))
137-
})
138-
139-
Describe("races", func() {
140-
var C, N = 10, 1000
141-
if testing.Short() {
142-
C = 3
143-
N = 100
144-
}
145-
146-
It("should echo", func() {
147-
perform(C, func() {
148-
for i := 0; i < N; i++ {
149-
msg := "echo" + strconv.Itoa(i)
150-
echo, err := client.Echo(msg).Result()
151-
Expect(err).NotTo(HaveOccurred())
152-
Expect(echo).To(Equal(msg))
153-
}
154-
})
155-
})
156-
157-
It("should incr", func() {
158-
key := "TestIncrFromGoroutines"
159-
160-
perform(C, func() {
161-
for i := 0; i < N; i++ {
162-
err := client.Incr(key).Err()
163-
Expect(err).NotTo(HaveOccurred())
164-
}
165-
})
166-
167-
val, err := client.Get(key).Int64()
168-
Expect(err).NotTo(HaveOccurred())
169-
Expect(val).To(Equal(int64(C * N)))
170-
})
171-
172-
It("should handle big vals", func() {
173-
client2 := connect()
174-
defer client2.Close()
175-
176-
bigVal := string(bytes.Repeat([]byte{'*'}, 1<<16))
177-
178-
var wg sync.WaitGroup
179-
wg.Add(2)
180-
181-
go func() {
182-
defer wg.Done()
183-
perform(C, func() {
184-
for i := 0; i < N; i++ {
185-
got, err := client.Get("key").Result()
186-
if err == redis.Nil {
187-
continue
188-
}
189-
Expect(got).To(Equal(bigVal))
190-
}
191-
})
192-
}()
193-
194-
go func() {
195-
defer wg.Done()
196-
perform(C, func() {
197-
for i := 0; i < N; i++ {
198-
err := client2.Set("key", bigVal, 0).Err()
199-
Expect(err).NotTo(HaveOccurred())
200-
}
201-
})
202-
}()
203-
204-
wg.Wait()
205-
})
206-
207-
It("should PubSub", func() {
208-
connPool := client.Pool()
209-
connPool.(*pool.ConnPool).DialLimiter = nil
210-
211-
var wg sync.WaitGroup
212-
wg.Add(2)
213-
214-
go func() {
215-
defer wg.Done()
216-
perform(C, func() {
217-
for i := 0; i < N; i++ {
218-
pubsub, err := client.Subscribe("mychannel")
219-
Expect(err).NotTo(HaveOccurred())
220-
221-
go func() {
222-
defer GinkgoRecover()
223-
224-
time.Sleep(time.Millisecond)
225-
err := pubsub.Close()
226-
Expect(err).NotTo(HaveOccurred())
227-
}()
228-
229-
_, err = pubsub.ReceiveMessage()
230-
Expect(err.Error()).To(ContainSubstring("closed"))
231-
}
232-
})
233-
}()
234-
235-
go func() {
236-
defer wg.Done()
237-
perform(C, func() {
238-
for i := 0; i < N; i++ {
239-
val := "echo" + strconv.Itoa(i)
240-
echo, err := client.Echo(val).Result()
241-
Expect(err).NotTo(HaveOccurred())
242-
Expect(echo).To(Equal(val))
243-
}
244-
})
245-
}()
246-
247-
wg.Wait()
248-
249-
Expect(connPool.Len()).To(Equal(connPool.FreeLen()))
250-
Expect(connPool.Len()).To(BeNumerically("<=", 10))
251-
})
252-
})
253-
25460
})

commands_test.go

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -19,14 +19,11 @@ var _ = Describe("Commands", func() {
1919
var client *redis.Client
2020

2121
BeforeEach(func() {
22-
client = redis.NewClient(&redis.Options{
23-
Addr: redisAddr,
24-
PoolTimeout: 30 * time.Second,
25-
})
22+
client = redis.NewClient(redisOptions())
23+
Expect(client.FlushDb().Err()).NotTo(HaveOccurred())
2624
})
2725

2826
AfterEach(func() {
29-
Expect(client.FlushDb().Err()).NotTo(HaveOccurred())
3027
Expect(client.Close()).NotTo(HaveOccurred())
3128
})
3229

@@ -299,31 +296,31 @@ var _ = Describe("Commands", func() {
299296
})
300297

301298
It("should Move", func() {
302-
move := client.Move("key", 1)
299+
move := client.Move("key", 2)
303300
Expect(move.Err()).NotTo(HaveOccurred())
304301
Expect(move.Val()).To(Equal(false))
305302

306303
set := client.Set("key", "hello", 0)
307304
Expect(set.Err()).NotTo(HaveOccurred())
308305
Expect(set.Val()).To(Equal("OK"))
309306

310-
move = client.Move("key", 1)
307+
move = client.Move("key", 2)
311308
Expect(move.Err()).NotTo(HaveOccurred())
312309
Expect(move.Val()).To(Equal(true))
313310

314311
get := client.Get("key")
315312
Expect(get.Err()).To(Equal(redis.Nil))
316313
Expect(get.Val()).To(Equal(""))
317314

318-
sel := client.Select(1)
315+
sel := client.Select(2)
319316
Expect(sel.Err()).NotTo(HaveOccurred())
320317
Expect(sel.Val()).To(Equal("OK"))
321318

322319
get = client.Get("key")
323320
Expect(get.Err()).NotTo(HaveOccurred())
324321
Expect(get.Val()).To(Equal("hello"))
325322
Expect(client.FlushDb().Err()).NotTo(HaveOccurred())
326-
Expect(client.Select(0).Err()).NotTo(HaveOccurred())
323+
Expect(client.Select(1).Err()).NotTo(HaveOccurred())
327324
})
328325

329326
It("should Object", func() {

example_test.go

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,9 @@ import (
1212
var client *redis.Client
1313

1414
func init() {
15-
client = redis.NewClient(&redis.Options{
16-
Addr: ":6379",
17-
DialTimeout: 10 * time.Second,
18-
})
15+
opt := redisOptions()
16+
opt.Addr = ":6379"
17+
client = redis.NewClient(opt)
1918
client.FlushDb()
2019
}
2120

internal/pool/conn.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package pool
22

33
import (
44
"bufio"
5+
"io"
56
"net"
67
"sync/atomic"
78
"time"
@@ -78,6 +79,17 @@ func (cn *Conn) RemoteAddr() net.Addr {
7879
return cn.NetConn.RemoteAddr()
7980
}
8081

82+
func (cn *Conn) ReadN(n int) ([]byte, error) {
83+
if d := n - cap(cn.Buf); d > 0 {
84+
cn.Buf = cn.Buf[:cap(cn.Buf)]
85+
cn.Buf = append(cn.Buf, make([]byte, d)...)
86+
} else {
87+
cn.Buf = cn.Buf[:n]
88+
}
89+
_, err := io.ReadFull(cn.Rd, cn.Buf)
90+
return cn.Buf, err
91+
}
92+
8193
func (cn *Conn) Close() error {
8294
return cn.NetConn.Close()
8395
}

internal/pool/conn_list.go

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ func (l *connList) Add(cn *Conn) {
4343
l.mu.Lock()
4444
for i, c := range l.cns {
4545
if c == nil {
46-
cn.idx = int32(i)
46+
cn.SetIndex(i)
4747
l.cns[i] = cn
4848
l.mu.Unlock()
4949
return
@@ -65,22 +65,25 @@ func (l *connList) Remove(idx int) {
6565
l.mu.Lock()
6666
if l.cns != nil {
6767
l.cns[idx] = nil
68-
l.len -= 1
68+
atomic.AddInt32(&l.len, -1)
6969
}
7070
l.mu.Unlock()
7171
}
7272

73-
func (l *connList) Close() error {
73+
func (l *connList) Reset() []*Conn {
7474
l.mu.Lock()
75-
for _, c := range l.cns {
76-
if c == nil {
75+
76+
for _, cn := range l.cns {
77+
if cn == nil {
7778
continue
7879
}
79-
c.idx = -1
80-
c.Close()
80+
cn.SetIndex(-1)
8181
}
82+
83+
cns := l.cns
8284
l.cns = nil
8385
l.len = 0
86+
8487
l.mu.Unlock()
85-
return nil
88+
return cns
8689
}

0 commit comments

Comments
 (0)