forked from CodisLabs/codis
-
Notifications
You must be signed in to change notification settings - Fork 0
/
extra_incr.go
129 lines (120 loc) · 2.92 KB
/
extra_incr.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
// Copyright 2014 Wandoujia Inc. All Rights Reserved.
// Licensed under the MIT (MIT-LICENSE.txt) license.
package main
import (
"flag"
"fmt"
"time"
"github.com/garyburd/redigo/redis"
)
type ExtraIncrTestCase struct {
proxy string
master1 string
slave1 string
master2 string
slave2 string
group int
round int
nkeys int
ntags int
}
func init() {
testcase = &ExtraIncrTestCase{}
}
func (tc *ExtraIncrTestCase) init() {
flag.StringVar(&tc.proxy, "proxy", "", "redis host:port")
flag.StringVar(&tc.master1, "master1", "", "redis host:port")
flag.StringVar(&tc.slave1, "slave1", "", "redis host:port")
flag.StringVar(&tc.master2, "master2", "", "redis host:port")
flag.StringVar(&tc.slave2, "slave2", "", "redis host:port")
flag.IntVar(&tc.group, "group", 8, "# of test players")
flag.IntVar(&tc.round, "round", 100, "# of incr opts per key")
flag.IntVar(&tc.nkeys, "nkeys", 10000, "# of keys per test")
flag.IntVar(&tc.ntags, "ntags", 1000, "# tags")
}
func (tc *ExtraIncrTestCase) main() {
go func() {
c := NewConn(tc.proxy)
for {
time.Sleep(time.Second * 5)
c.Check()
}
}()
tg := &TestGroup{}
tg.Reset()
for g := 0; g < tc.group; g++ {
tg.AddPlayer()
go tc.player(g, tg)
}
tg.Start()
tg.Wait()
fmt.Println("done")
}
func (tc *ExtraIncrTestCase) player(gid int, tg *TestGroup) {
tg.PlayerWait()
defer tg.PlayerDone()
c := NewConn(tc.proxy)
defer c.Close()
us := UnitSlice(make([]*Unit, tc.nkeys))
for i := 0; i < len(us); i++ {
key := fmt.Sprintf("extra_incr_%d_{%d}_%d", gid, i%tc.ntags, i)
us[i] = NewUnit(key)
}
for _, u := range us {
u.Del(c, false)
ops.Incr()
}
for i := 0; i < tc.round; i++ {
for _, u := range us {
u.Incr(c)
ops.Incr()
}
}
time.Sleep(time.Second * 5)
c1s, c1m := NewConn(tc.slave1), NewConn(tc.master1)
c2s, c2m := NewConn(tc.slave2), NewConn(tc.master2)
defer c1s.Close()
defer c1m.Close()
defer c2s.Close()
defer c2m.Close()
for _, u := range us {
s := tc.groupfetch(c1s, c2s, u.key)
m := tc.groupfetch(c1m, c2m, u.key)
if s != m || s != u.val {
Panic("check failed, key = %s, val = %d, master = %d, slave = %d", u.key, u.val, s, m)
}
}
for _, u := range us {
u.Del(c, true)
ops.Incr()
}
c.Check()
}
func (tc *ExtraIncrTestCase) groupfetch(c1, c2 redis.Conn, key string) int {
r1, e1 := c1.Do("get", key)
r2, e2 := c2.Do("get", key)
if e1 != nil || e2 != nil {
Panic("groupfetch key = %s, e1 = %s, e2 = %s", key, e1, e2)
}
if r1 == nil && r2 == nil {
Panic("groupfetch key = %s, r1 == nil && r2 == nil", key)
}
if r1 != nil && r2 != nil {
Panic("groupfetch key = %s, r1 != nil && r2 != nil, %v %v", key, r1, r2)
}
if r1 != nil {
if v, err := redis.Int(r1, nil); err != nil {
Panic("groupfetch key = %s, error = %s", key, err)
} else {
return v
}
}
if r2 != nil {
if v, err := redis.Int(r2, nil); err != nil {
Panic("groupfetch key = %s, error = %s", key, err)
} else {
return v
}
}
return -1
}