Skip to content
This repository was archived by the owner on Dec 9, 2024. It is now read-only.

Commit 9958038

Browse files
authored
case: txn list_append (#229)
Signed-off-by: mahjonp <junpeng.man@gmail.com>
1 parent 2ebe549 commit 9958038

File tree

14 files changed

+658
-314
lines changed

14 files changed

+658
-314
lines changed

cmd/append/main.go

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
package main
2+
3+
import (
4+
"context"
5+
"flag"
6+
7+
"github.com/pingcap/tipocket/cmd/util"
8+
"github.com/pingcap/tipocket/pkg/cluster"
9+
"github.com/pingcap/tipocket/pkg/control"
10+
test_infra "github.com/pingcap/tipocket/pkg/test-infra"
11+
"github.com/pingcap/tipocket/pkg/test-infra/fixture"
12+
"github.com/pingcap/tipocket/pkg/verify"
13+
listappend "github.com/pingcap/tipocket/tests/list_append"
14+
)
15+
16+
var (
17+
tableCount = flag.Int("table-count", 1, "table count")
18+
readLock = flag.String("readLock", "FOR UPDATE", "maybe empty or 'FOR UPDATE'")
19+
)
20+
21+
func main() {
22+
flag.Parse()
23+
24+
suit := util.Suit{
25+
Config: &control.Config{
26+
Mode: control.Mode(fixture.Context.Mode),
27+
ClientCount: fixture.Context.ClientCount,
28+
RequestCount: fixture.Context.RequestCount,
29+
RunRound: fixture.Context.RunRound,
30+
RunTime: fixture.Context.RunTime,
31+
History: fixture.Context.HistoryFile,
32+
},
33+
Provisioner: cluster.NewK8sProvisioner(),
34+
ClientCreator: listappend.NewClientCreator(*tableCount, *readLock),
35+
NemesisGens: util.ParseNemesisGenerators(fixture.Context.Nemesis),
36+
ClientRequestGen: util.OnClientLoop,
37+
VerifySuit: verify.Suit{
38+
Checker: listappend.AppendChecker{},
39+
Parser: listappend.AppendParser{},
40+
},
41+
ClusterDefs: test_infra.NewDefaultCluster(fixture.Context.Namespace, fixture.Context.Namespace,
42+
fixture.Context.TiDBClusterConfig),
43+
}
44+
suit.Run(context.Background())
45+
}

cmd/util/suit.go

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -82,15 +82,22 @@ func (suit *Suit) Run(ctx context.Context) {
8282
suit.Config.ClientNodes = append(suit.Config.ClientNodes,
8383
suit.Config.ClientNodes[rand.Intn(retClientCount)])
8484
}
85+
86+
// set loki client
87+
var lokiCli *loki.Client
88+
if fixture.Context.LokiAddress != "" {
89+
lokiCli = loki.NewClient(startTime, fixture.Context.LokiAddress,
90+
fixture.Context.LokiUsername, fixture.Context.LokiPassword)
91+
}
92+
8593
c := control.NewController(
8694
sctx,
8795
suit.Config,
8896
suit.ClientCreator,
8997
suit.NemesisGens,
9098
suit.ClientRequestGen,
9199
suit.VerifySuit,
92-
loki.NewClient(startTime, fixture.Context.LokiAddress,
93-
fixture.Context.LokiUsername, fixture.Context.LokiPassword),
100+
lokiCli,
94101
fixture.Context.LogPath,
95102
)
96103

pkg/control/control.go

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -88,13 +88,15 @@ func NewController(
8888
// init time stamp
8989
c.lastQueryTime = minTime
9090

91-
if _, err := os.Stat(c.logPath); err != nil {
92-
if os.IsNotExist(err) {
93-
if err := os.Mkdir(c.logPath, os.ModePerm); err != nil {
91+
if c.lokiClient != nil {
92+
if _, err := os.Stat(c.logPath); err != nil {
93+
if os.IsNotExist(err) {
94+
if err := os.Mkdir(c.logPath, os.ModePerm); err != nil {
95+
log.Fatalf("failed to create directory %s error is %v", c.logPath, err)
96+
}
97+
} else {
9498
log.Fatalf("failed to create directory %s error is %v", c.logPath, err)
9599
}
96-
} else {
97-
log.Fatalf("failed to create directory %s error is %v", c.logPath, err)
98100
}
99101
}
100102

pkg/elle/core/history.go

Lines changed: 76 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package core
22

33
import (
44
"fmt"
5+
"reflect"
56
"regexp"
67
"strconv"
78
"strings"
@@ -52,123 +53,103 @@ const (
5253
)
5354

5455
// Mop interface
55-
type Mop interface {
56-
fmt.Stringer
57-
58-
IsAppend() bool
59-
IsRead() bool
60-
GetMopType() MopType
61-
GetKey() string
62-
GetValue() MopValueType
63-
IsEqual(b Mop) bool
64-
}
65-
66-
// Append implements Mop
67-
type Append struct {
68-
Key string `json:"key"`
69-
Value MopValueType `json:"value"`
70-
}
71-
72-
func (a Append) String() string {
73-
return fmt.Sprintf("[:append %s %v]", a.Key, a.Value)
56+
type Mop struct {
57+
T MopType `json:"type"`
58+
M map[string]interface{} `json:"m"`
7459
}
7560

7661
// IsAppend ...
77-
func (Append) IsAppend() bool {
78-
return true
62+
func (m Mop) IsAppend() bool {
63+
return m.T == MopTypeAppend
7964
}
8065

8166
// IsRead ...
82-
func (Append) IsRead() bool {
83-
return false
67+
func (m Mop) IsRead() bool {
68+
return m.T == MopTypeRead
8469
}
8570

8671
// GetMopType ...
87-
func (Append) GetMopType() MopType {
88-
return MopTypeAppend
89-
}
90-
91-
// GetKey get append key
92-
func (a Append) GetKey() string {
93-
return a.Key
72+
func (m Mop) GetMopType() MopType {
73+
return m.T
9474
}
9575

96-
// GetValue get append value
97-
func (a Append) GetValue() MopValueType {
98-
return a.Value
76+
// GetKey ...
77+
func (m Mop) GetKey() string {
78+
return m.M["key"].(string)
9979
}
10080

101-
// IsEqual ...
102-
func (a Append) IsEqual(b Mop) bool {
103-
if a.GetMopType() != b.GetMopType() {
104-
return false
81+
// GetValue ...
82+
func (m Mop) GetValue() MopValueType {
83+
value := m.M["value"]
84+
if value == nil {
85+
return nil
10586
}
106-
return a == b
87+
return value.(MopValueType)
10788
}
10889

109-
// Read implements Mop
110-
type Read struct {
111-
Key string `json:"key"`
112-
Value MopValueType `json:"value"`
90+
// IsEqual ...
91+
func (m Mop) IsEqual(n Mop) bool {
92+
return reflect.DeepEqual(m, n)
11393
}
11494

115-
func (r Read) String() string {
116-
if r.Value == nil {
117-
return fmt.Sprintf("[:r %s nil]", r.Key)
95+
// String ...
96+
func (m Mop) String() string {
97+
switch m.T {
98+
case MopTypeRead:
99+
key := m.M["key"].(string)
100+
value := m.M["value"]
101+
if value == nil {
102+
return fmt.Sprintf("[:r %s nil]", key)
103+
}
104+
return fmt.Sprintf("[:r %s %v]", key, value)
105+
case MopTypeAppend:
106+
key := m.M["key"].(string)
107+
value := m.M["value"].(int)
108+
return fmt.Sprintf("[:append %s %v]", key, value)
109+
default:
110+
panic("unreachable")
118111
}
119-
return fmt.Sprintf("[:r %s %v]", r.Key, r.Value)
120-
}
121-
122-
// IsAppend ...
123-
func (Read) IsAppend() bool {
124-
return false
125-
}
126-
127-
// IsRead ...
128-
func (Read) IsRead() bool {
129-
return true
130-
}
131-
132-
// GetMopType ...
133-
func (Read) GetMopType() MopType {
134-
return MopTypeRead
135-
}
136-
137-
// GetKey get read key
138-
func (r Read) GetKey() string {
139-
return r.Key
140112
}
141113

142-
// GetValue get read value
143-
func (r Read) GetValue() MopValueType {
144-
return r.Value
114+
// Append implements Mop
115+
func Append(key string, value int) Mop {
116+
return Mop{
117+
T: MopTypeAppend,
118+
M: map[string]interface{}{
119+
"key": key,
120+
"value": value,
121+
},
122+
}
145123
}
146124

147-
// IsEqual return true if two Mop is deep equal
148-
func (r Read) IsEqual(b Mop) bool {
149-
if r.GetMopType() != b.GetMopType() {
150-
return false
151-
}
152-
aValue := r.GetValue().([]int)
153-
bValue := b.GetValue().([]int)
154-
if len(aValue) != len(bValue) {
155-
return false
156-
}
157-
for idx := range aValue {
158-
if aValue[idx] != bValue[idx] {
159-
return false
125+
// Read ...
126+
func Read(key string, values []int) Mop {
127+
if values == nil {
128+
return Mop{
129+
T: MopTypeRead,
130+
M: map[string]interface{}{
131+
"key": key,
132+
"value": nil,
133+
},
160134
}
161135
}
162-
return true
136+
return Mop{
137+
T: MopTypeRead,
138+
M: map[string]interface{}{
139+
"key": key,
140+
"value": values,
141+
},
142+
}
163143
}
164144

165145
// Op is operation
166146
type Op struct {
167-
Index IntOptional `json:"index"`
168-
Process IntOptional `json:"process"`
147+
Index IntOptional `json:"index,omitempty"`
148+
Process IntOptional `json:"process,omitempty"`
169149
Time time.Time `json:"time"`
170150
Type OpType `json:"type"`
171151
Value *[]Mop `json:"value"`
152+
Error string `json:"error,omitempty"`
172153
}
173154

174155
func (op Op) String() string {
@@ -191,7 +172,10 @@ func (op Op) String() string {
191172
parts = append(parts, fmt.Sprintf(":index %d", op.Index.MustGet()))
192173
}
193174

194-
return strings.Join(parts, " ")
175+
if op.Error != "" {
176+
parts = append(parts, fmt.Sprintf(":error [%s]", op.Error))
177+
}
178+
return strings.Join(parts, " ") + "}"
195179
}
196180

197181
// ValueLength ...
@@ -349,9 +333,13 @@ func ParseOp(opString string) (Op, error) {
349333
var mop Mop
350334
switch mopMatch[2] {
351335
case "append":
352-
mop = Append{Key: key, Value: value}
336+
mop = Append(key, value.(int))
353337
case "r":
354-
mop = Read{Key: key, Value: value}
338+
if value != nil {
339+
mop = Read(key, value.([]int))
340+
} else {
341+
mop = Read(key, nil)
342+
}
355343
default:
356344
panic("unreachable")
357345
}

0 commit comments

Comments
 (0)