Skip to content

Commit 249c0d7

Browse files
authored
Merge pull request #15827 from serathius/robustness-k8s-2
tests/robustness: Implement delete request for kubernetes scenario
2 parents 79eabc1 + 40f71ef commit 249c0d7

File tree

7 files changed

+251
-158
lines changed

7 files changed

+251
-158
lines changed

tests/robustness/client.go

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -96,23 +96,35 @@ func (c *recordingClient) Delete(ctx context.Context, key string) error {
9696
return nil
9797
}
9898

99-
func (c *recordingClient) CompareAndSet(ctx context.Context, key, value string, expectedRevision int64) error {
99+
func (c *recordingClient) CompareRevisionAndDelete(ctx context.Context, key string, expectedRevision int64) error {
100100
callTime := time.Since(c.baseTime)
101+
resp, err := c.compareRevisionTxn(ctx, key, expectedRevision, clientv3.OpDelete(key)).Commit()
102+
returnTime := time.Since(c.baseTime)
103+
c.history.AppendCompareRevisionAndDelete(key, expectedRevision, callTime, returnTime, resp, err)
104+
return err
105+
}
106+
107+
func (c *recordingClient) CompareRevisionAndPut(ctx context.Context, key, value string, expectedRevision int64) error {
108+
callTime := time.Since(c.baseTime)
109+
resp, err := c.compareRevisionTxn(ctx, key, expectedRevision, clientv3.OpPut(key, value)).Commit()
110+
returnTime := time.Since(c.baseTime)
111+
c.history.AppendCompareRevisionAndPut(key, expectedRevision, value, callTime, returnTime, resp, err)
112+
return err
113+
}
114+
115+
func (c *recordingClient) compareRevisionTxn(ctx context.Context, key string, expectedRevision int64, op clientv3.Op) clientv3.Txn {
101116
txn := c.client.Txn(ctx)
102117
var cmp clientv3.Cmp
103118
if expectedRevision == 0 {
104119
cmp = clientv3.Compare(clientv3.CreateRevision(key), "=", 0)
105120
} else {
106121
cmp = clientv3.Compare(clientv3.ModRevision(key), "=", expectedRevision)
107122
}
108-
resp, err := txn.If(
123+
return txn.If(
109124
cmp,
110125
).Then(
111-
clientv3.OpPut(key, value),
112-
).Commit()
113-
returnTime := time.Since(c.baseTime)
114-
c.history.AppendCompareAndSet(key, expectedRevision, value, callTime, returnTime, resp, err)
115-
return err
126+
op,
127+
)
116128
}
117129

118130
func (c *recordingClient) Txn(ctx context.Context, cmp []clientv3.Cmp, ops []clientv3.Op) error {

tests/robustness/linearizability_test.go

Lines changed: 26 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -41,18 +41,18 @@ var (
4141
maximalQPS: 200,
4242
clientCount: 8,
4343
requestProgress: false,
44-
traffic: traffic{
44+
traffic: etcdTraffic{
4545
keyCount: 10,
4646
leaseTTL: DefaultLeaseTTL,
4747
largePutSize: 32769,
48-
writes: []requestChance{
49-
{operation: Put, chance: 45},
50-
{operation: LargePut, chance: 5},
51-
{operation: Delete, chance: 10},
52-
{operation: MultiOpTxn, chance: 10},
53-
{operation: PutWithLease, chance: 10},
54-
{operation: LeaseRevoke, chance: 10},
55-
{operation: CompareAndSet, chance: 10},
48+
writeChoices: []choiceWeight{
49+
{choice: string(Put), weight: 45},
50+
{choice: string(LargePut), weight: 5},
51+
{choice: string(Delete), weight: 10},
52+
{choice: string(MultiOpTxn), weight: 10},
53+
{choice: string(PutWithLease), weight: 10},
54+
{choice: string(LeaseRevoke), weight: 10},
55+
{choice: string(CompareAndSet), weight: 10},
5656
},
5757
},
5858
}
@@ -62,14 +62,14 @@ var (
6262
maximalQPS: 1000,
6363
clientCount: 12,
6464
requestProgress: false,
65-
traffic: traffic{
65+
traffic: etcdTraffic{
6666
keyCount: 10,
6767
largePutSize: 32769,
6868
leaseTTL: DefaultLeaseTTL,
69-
writes: []requestChance{
70-
{operation: Put, chance: 85},
71-
{operation: MultiOpTxn, chance: 10},
72-
{operation: LargePut, chance: 5},
69+
writeChoices: []choiceWeight{
70+
{choice: string(Put), weight: 85},
71+
{choice: string(MultiOpTxn), weight: 10},
72+
{choice: string(LargePut), weight: 5},
7373
},
7474
},
7575
}
@@ -79,7 +79,14 @@ var (
7979
maximalQPS: 1000,
8080
clientCount: 12,
8181
traffic: kubernetesTraffic{
82-
keyCount: 5,
82+
averageKeyCount: 5,
83+
resource: "pods",
84+
namespace: "default",
85+
writeChoices: []choiceWeight{
86+
{choice: string(KubernetesUpdate), weight: 75},
87+
{choice: string(KubernetesDelete), weight: 15},
88+
{choice: string(KubernetesCreate), weight: 10},
89+
},
8390
},
8491
}
8592
ReqProgTraffic = trafficConfig{
@@ -88,13 +95,13 @@ var (
8895
maximalQPS: 1000,
8996
clientCount: 12,
9097
requestProgress: true,
91-
traffic: traffic{
98+
traffic: etcdTraffic{
9299
keyCount: 10,
93100
largePutSize: 8196,
94101
leaseTTL: DefaultLeaseTTL,
95-
writes: []requestChance{
96-
{operation: Put, chance: 95},
97-
{operation: LargePut, chance: 5},
102+
writeChoices: []choiceWeight{
103+
{choice: string(Put), weight: 95},
104+
{choice: string(LargePut), weight: 5},
98105
},
99106
},
100107
}

tests/robustness/model/describe_test.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -80,17 +80,17 @@ func TestModelDescribe(t *testing.T) {
8080
expectDescribe: `delete("key6") -> err: "failed"`,
8181
},
8282
{
83-
req: compareAndSetRequest("key7", 7, "77"),
84-
resp: compareAndSetResponse(false, 7),
83+
req: compareRevisionAndPutRequest("key7", 7, "77"),
84+
resp: compareRevisionAndPutResponse(false, 7),
8585
expectDescribe: `if(mod_rev(key7)==7).then(put("key7", "77")) -> txn failed, rev: 7`,
8686
},
8787
{
88-
req: compareAndSetRequest("key8", 8, "88"),
89-
resp: compareAndSetResponse(true, 8),
88+
req: compareRevisionAndPutRequest("key8", 8, "88"),
89+
resp: compareRevisionAndPutResponse(true, 8),
9090
expectDescribe: `if(mod_rev(key8)==8).then(put("key8", "88")) -> ok, rev: 8`,
9191
},
9292
{
93-
req: compareAndSetRequest("key9", 9, "99"),
93+
req: compareRevisionAndPutRequest("key9", 9, "99"),
9494
resp: failedResponse(errors.New("failed")),
9595
expectDescribe: `if(mod_rev(key9)==9).then(put("key9", "99")) -> err: "failed"`,
9696
},

tests/robustness/model/deterministic_test.go

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ func TestModelBase(t *testing.T) {
6666
{
6767
name: "First Txn can start from non-zero revision",
6868
operations: []testOperation{
69-
{req: compareAndSetRequest("key", 0, "42"), resp: compareAndSetResponse(false, 42).EtcdResponse},
69+
{req: compareRevisionAndPutRequest("key", 0, "42"), resp: compareRevisionAndPutResponse(false, 42).EtcdResponse},
7070
},
7171
},
7272
{
@@ -157,10 +157,10 @@ func TestModelBase(t *testing.T) {
157157
name: "Txn sets new value if value matches expected",
158158
operations: []testOperation{
159159
{req: getRequest("key"), resp: getResponse("key", "1", 1, 1).EtcdResponse},
160-
{req: compareAndSetRequest("key", 1, "2"), resp: compareAndSetResponse(true, 1).EtcdResponse, failure: true},
161-
{req: compareAndSetRequest("key", 1, "2"), resp: compareAndSetResponse(false, 2).EtcdResponse, failure: true},
162-
{req: compareAndSetRequest("key", 1, "2"), resp: compareAndSetResponse(false, 1).EtcdResponse, failure: true},
163-
{req: compareAndSetRequest("key", 1, "2"), resp: compareAndSetResponse(true, 2).EtcdResponse},
160+
{req: compareRevisionAndPutRequest("key", 1, "2"), resp: compareRevisionAndPutResponse(true, 1).EtcdResponse, failure: true},
161+
{req: compareRevisionAndPutRequest("key", 1, "2"), resp: compareRevisionAndPutResponse(false, 2).EtcdResponse, failure: true},
162+
{req: compareRevisionAndPutRequest("key", 1, "2"), resp: compareRevisionAndPutResponse(false, 1).EtcdResponse, failure: true},
163+
{req: compareRevisionAndPutRequest("key", 1, "2"), resp: compareRevisionAndPutResponse(true, 2).EtcdResponse},
164164
{req: getRequest("key"), resp: getResponse("key", "1", 1, 1).EtcdResponse, failure: true},
165165
{req: getRequest("key"), resp: getResponse("key", "1", 1, 2).EtcdResponse, failure: true},
166166
{req: getRequest("key"), resp: getResponse("key", "1", 2, 2).EtcdResponse, failure: true},
@@ -172,19 +172,19 @@ func TestModelBase(t *testing.T) {
172172
name: "Txn can expect on empty key",
173173
operations: []testOperation{
174174
{req: getRequest("key1"), resp: emptyGetResponse(1).EtcdResponse},
175-
{req: compareAndSetRequest("key1", 0, "2"), resp: compareAndSetResponse(true, 2).EtcdResponse},
176-
{req: compareAndSetRequest("key2", 0, "3"), resp: compareAndSetResponse(true, 3).EtcdResponse},
177-
{req: compareAndSetRequest("key3", 4, "4"), resp: compareAndSetResponse(false, 4).EtcdResponse, failure: true},
175+
{req: compareRevisionAndPutRequest("key1", 0, "2"), resp: compareRevisionAndPutResponse(true, 2).EtcdResponse},
176+
{req: compareRevisionAndPutRequest("key2", 0, "3"), resp: compareRevisionAndPutResponse(true, 3).EtcdResponse},
177+
{req: compareRevisionAndPutRequest("key3", 4, "4"), resp: compareRevisionAndPutResponse(false, 4).EtcdResponse, failure: true},
178178
},
179179
},
180180
{
181181
name: "Txn doesn't do anything if value doesn't match expected",
182182
operations: []testOperation{
183183
{req: getRequest("key"), resp: getResponse("key", "1", 1, 1).EtcdResponse},
184-
{req: compareAndSetRequest("key", 2, "3"), resp: compareAndSetResponse(true, 2).EtcdResponse, failure: true},
185-
{req: compareAndSetRequest("key", 2, "3"), resp: compareAndSetResponse(true, 1).EtcdResponse, failure: true},
186-
{req: compareAndSetRequest("key", 2, "3"), resp: compareAndSetResponse(false, 2).EtcdResponse, failure: true},
187-
{req: compareAndSetRequest("key", 2, "3"), resp: compareAndSetResponse(false, 1).EtcdResponse},
184+
{req: compareRevisionAndPutRequest("key", 2, "3"), resp: compareRevisionAndPutResponse(true, 2).EtcdResponse, failure: true},
185+
{req: compareRevisionAndPutRequest("key", 2, "3"), resp: compareRevisionAndPutResponse(true, 1).EtcdResponse, failure: true},
186+
{req: compareRevisionAndPutRequest("key", 2, "3"), resp: compareRevisionAndPutResponse(false, 2).EtcdResponse, failure: true},
187+
{req: compareRevisionAndPutRequest("key", 2, "3"), resp: compareRevisionAndPutResponse(false, 1).EtcdResponse},
188188
{req: getRequest("key"), resp: getResponse("key", "2", 1, 1).EtcdResponse, failure: true},
189189
{req: getRequest("key"), resp: getResponse("key", "2", 2, 2).EtcdResponse, failure: true},
190190
{req: getRequest("key"), resp: getResponse("key", "3", 1, 1).EtcdResponse, failure: true},
@@ -317,7 +317,7 @@ func TestModelBase(t *testing.T) {
317317
{req: leaseRevokeRequest(1), resp: leaseRevokeResponse(3).EtcdResponse},
318318
{req: putRequest("key", "4"), resp: putResponse(4).EtcdResponse},
319319
{req: getRequest("key"), resp: getResponse("key", "4", 4, 4).EtcdResponse},
320-
{req: compareAndSetRequest("key", 4, "5"), resp: compareAndSetResponse(true, 5).EtcdResponse},
320+
{req: compareRevisionAndPutRequest("key", 4, "5"), resp: compareRevisionAndPutResponse(true, 5).EtcdResponse},
321321
{req: deleteRequest("key"), resp: deleteResponse(1, 6).EtcdResponse},
322322
{req: defragmentRequest(), resp: defragmentResponse(6).EtcdResponse},
323323
},
@@ -336,7 +336,7 @@ func TestModelBase(t *testing.T) {
336336
{req: defragmentRequest(), resp: defragmentResponse(4).EtcdResponse},
337337
{req: getRequest("key"), resp: getResponse("key", "4", 4, 4).EtcdResponse},
338338
{req: defragmentRequest(), resp: defragmentResponse(4).EtcdResponse},
339-
{req: compareAndSetRequest("key", 4, "5"), resp: compareAndSetResponse(true, 5).EtcdResponse},
339+
{req: compareRevisionAndPutRequest("key", 4, "5"), resp: compareRevisionAndPutResponse(true, 5).EtcdResponse},
340340
{req: defragmentRequest(), resp: defragmentResponse(5).EtcdResponse},
341341
{req: deleteRequest("key"), resp: deleteResponse(1, 6).EtcdResponse},
342342
{req: defragmentRequest(), resp: defragmentResponse(6).EtcdResponse},

tests/robustness/model/history.go

Lines changed: 40 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -180,8 +180,31 @@ func (h *AppendableHistory) AppendDelete(key string, start, end time.Duration, r
180180
})
181181
}
182182

183-
func (h *AppendableHistory) AppendCompareAndSet(key string, expectedRevision int64, value string, start, end time.Duration, resp *clientv3.TxnResponse, err error) {
184-
request := compareAndSetRequest(key, expectedRevision, value)
183+
func (h *AppendableHistory) AppendCompareRevisionAndDelete(key string, expectedRevision int64, start, end time.Duration, resp *clientv3.TxnResponse, err error) {
184+
request := compareRevisionAndDeleteRequest(key, expectedRevision)
185+
if err != nil {
186+
h.appendFailed(request, start, err)
187+
return
188+
}
189+
var revision int64
190+
if resp != nil && resp.Header != nil {
191+
revision = resp.Header.Revision
192+
}
193+
var deleted int64
194+
if resp != nil && len(resp.Responses) > 0 {
195+
deleted = resp.Responses[0].GetResponseDeleteRange().Deleted
196+
}
197+
h.successful = append(h.successful, porcupine.Operation{
198+
ClientId: h.id,
199+
Input: request,
200+
Call: start.Nanoseconds(),
201+
Output: compareRevisionAndDeleteResponse(resp.Succeeded, deleted, revision),
202+
Return: end.Nanoseconds(),
203+
})
204+
205+
}
206+
func (h *AppendableHistory) AppendCompareRevisionAndPut(key string, expectedRevision int64, value string, start, end time.Duration, resp *clientv3.TxnResponse, err error) {
207+
request := compareRevisionAndPutRequest(key, expectedRevision, value)
185208
if err != nil {
186209
h.appendFailed(request, start, err)
187210
return
@@ -194,7 +217,7 @@ func (h *AppendableHistory) AppendCompareAndSet(key string, expectedRevision int
194217
ClientId: h.id,
195218
Input: request,
196219
Call: start.Nanoseconds(),
197-
Output: compareAndSetResponse(resp.Succeeded, revision),
220+
Output: compareRevisionAndPutResponse(resp.Succeeded, revision),
198221
Return: end.Nanoseconds(),
199222
})
200223
}
@@ -376,18 +399,30 @@ func deleteResponse(deleted int64, revision int64) EtcdNonDeterministicResponse
376399
return EtcdNonDeterministicResponse{EtcdResponse: EtcdResponse{Txn: &TxnResponse{OpsResult: []EtcdOperationResult{{Deleted: deleted}}}, Revision: revision}}
377400
}
378401

379-
func compareAndSetRequest(key string, expectedRevision int64, value string) EtcdRequest {
402+
func compareRevisionAndDeleteRequest(key string, expectedRevision int64) EtcdRequest {
403+
return txnRequest([]EtcdCondition{{Key: key, ExpectedRevision: expectedRevision}}, []EtcdOperation{{Type: Delete, Key: key}})
404+
}
405+
406+
func compareRevisionAndPutRequest(key string, expectedRevision int64, value string) EtcdRequest {
380407
return txnRequest([]EtcdCondition{{Key: key, ExpectedRevision: expectedRevision}}, []EtcdOperation{{Type: Put, Key: key, Value: ToValueOrHash(value)}})
381408
}
382409

383-
func compareAndSetResponse(succeeded bool, revision int64) EtcdNonDeterministicResponse {
410+
func compareRevisionAndPutResponse(succeeded bool, revision int64) EtcdNonDeterministicResponse {
384411
var result []EtcdOperationResult
385412
if succeeded {
386413
result = []EtcdOperationResult{{}}
387414
}
388415
return txnResponse(result, succeeded, revision)
389416
}
390417

418+
func compareRevisionAndDeleteResponse(succeeded bool, deleted, revision int64) EtcdNonDeterministicResponse {
419+
var result []EtcdOperationResult
420+
if succeeded {
421+
result = []EtcdOperationResult{{Deleted: deleted}}
422+
}
423+
return txnResponse(result, succeeded, revision)
424+
}
425+
391426
func txnRequest(conds []EtcdCondition, onSuccess []EtcdOperation) EtcdRequest {
392427
return EtcdRequest{Type: Txn, Txn: &TxnRequest{Conds: conds, Ops: onSuccess}}
393428
}

0 commit comments

Comments
 (0)