@@ -43,47 +43,34 @@ func TestLinearizability(t *testing.T) {
43
43
tcs := []struct {
44
44
name string
45
45
failpoint Failpoint
46
+ traffic Traffic
46
47
config e2e.EtcdProcessClusterConfig
47
48
}{
48
49
{
49
- name : "ClusterOfSize1" ,
50
- failpoint : RandomFailpoint ,
50
+ name : "Issue14890" ,
51
+ traffic : AppendOnly ,
52
+ failpoint : KillFailpoint ,
51
53
config : * e2e .NewConfig (
52
- e2e .WithClusterSize (1 ),
53
- e2e .WithGoFailEnabled (true ),
54
- e2e .WithCompactionBatchLimit (100 ), // required for compactBeforeCommitBatch and compactAfterCommitBatch failpoints
55
- ),
56
- },
57
- {
58
- name : "ClusterOfSize3" ,
59
- failpoint : RandomFailpoint ,
60
- config : * e2e .NewConfig (
61
- e2e .WithGoFailEnabled (true ),
62
- e2e .WithCompactionBatchLimit (100 ), // required for compactBeforeCommitBatch and compactAfterCommitBatch failpoints
63
- ),
64
- },
65
- {
66
- name : "Issue14370" ,
67
- failpoint : RaftBeforeSavePanic ,
68
- config : * e2e .NewConfig (
69
- e2e .WithClusterSize (1 ),
70
- e2e .WithGoFailEnabled (true ),
54
+ e2e .WithClusterSize (5 ),
71
55
),
72
56
},
73
57
}
74
58
for _ , tc := range tcs {
75
59
t .Run (tc .name , func (t * testing.T ) {
76
60
failpoint := FailpointConfig {
77
61
failpoint : tc .failpoint ,
78
- count : 1 ,
62
+ count : 60 ,
79
63
retries : 3 ,
80
64
waitBetweenTriggers : waitBetweenFailpointTriggers ,
81
65
}
82
66
traffic := trafficConfig {
83
- minimalQPS : minimalQPS ,
84
- maximalQPS : maximalQPS ,
85
- clientCount : 8 ,
86
- traffic : DefaultTraffic ,
67
+ minimalQPS : 100 ,
68
+ maximalQPS : 1000 ,
69
+ traffic : tc .traffic ,
70
+ clientCount : 10 ,
71
+ }
72
+ if tc .traffic == nil {
73
+ tc .traffic = DefaultTraffic
87
74
}
88
75
testLinearizability (context .Background (), t , tc .config , failpoint , traffic )
89
76
})
@@ -193,18 +180,63 @@ func checkOperationsAndPersistResults(t *testing.T, operations []porcupine.Opera
193
180
t .Error (err )
194
181
}
195
182
196
- linearizable , info := porcupine .CheckOperationsVerbose (etcdModel , operations , 0 )
197
- if linearizable != porcupine .Ok {
198
- t .Error ("Model is not linearizable" )
199
- persistMemberDataDir (t , clus , path )
183
+ appendOperations := []porcupine.Operation {}
184
+ isAppendOnly := true
185
+ appendCheck:
186
+ for _ , op := range operations {
187
+ req := op .Input .(EtcdRequest )
188
+ resp := op .Output .(EtcdResponse )
189
+ switch req .Op {
190
+ case Get :
191
+ appendOperations = append (appendOperations , porcupine.Operation {
192
+ ClientId : op .ClientId ,
193
+ Input : AppendRequest {Op : Get , Key : req .Key },
194
+ Call : op .Call ,
195
+ Output : AppendResponse {GetData : resp .GetData },
196
+ Return : op .Return ,
197
+ })
198
+ case Txn :
199
+ if resp .Err != nil || ! resp .TxnSucceeded {
200
+ continue
201
+ }
202
+ elements := strings .Split (req .TxnNewData , "," )
203
+ appendOperations = append (appendOperations , porcupine.Operation {
204
+ ClientId : op .ClientId ,
205
+ Input : AppendRequest {Op : Append , Key : req .Key , AppendData : elements [len (elements )- 1 ]},
206
+ Call : op .Call ,
207
+ Output : AppendResponse {GetData : resp .GetData },
208
+ Return : op .Return ,
209
+ })
210
+ default :
211
+ isAppendOnly = false
212
+ break appendCheck
213
+ }
200
214
}
201
-
202
215
visualizationPath := filepath .Join (path , "history.html" )
203
- t .Logf ("saving visualization to %q" , visualizationPath )
204
- err = porcupine .VisualizePath (etcdModel , info , visualizationPath )
205
- if err != nil {
206
- t .Errorf ("Failed to visualize, err: %v" , err )
216
+ if isAppendOnly {
217
+ t .Log ("Using append model" )
218
+ linearizable , info := porcupine .CheckOperationsVerbose (appendModel , appendOperations , 0 )
219
+ if linearizable != porcupine .Ok {
220
+ t .Error ("Model is not linearizable" )
221
+ persistMemberDataDir (t , clus , path )
222
+ }
223
+ err = porcupine .VisualizePath (appendModel , info , visualizationPath )
224
+ if err != nil {
225
+ t .Errorf ("Failed to visualize, err: %v" , err )
226
+ }
227
+ } else {
228
+ t .Error ("Using etcd model" )
229
+ linearizable , info := porcupine .CheckOperationsVerbose (etcdModel , operations , 0 )
230
+ if linearizable != porcupine .Ok {
231
+ t .Error ("Model is not linearizable" )
232
+ persistMemberDataDir (t , clus , path )
233
+ }
234
+ err = porcupine .VisualizePath (etcdModel , info , visualizationPath )
235
+ if err != nil {
236
+ t .Errorf ("Failed to visualize, err: %v" , err )
237
+ }
207
238
}
239
+ t .Logf ("saving visualization to %q" , visualizationPath )
208
240
}
209
241
210
242
func persistMemberDataDir (t * testing.T , clus * e2e.EtcdProcessCluster , path string ) {
0 commit comments