integration: put,txn with 'ignore_lease' flag
This commit is contained in:
@ -395,7 +395,7 @@ func TestV3PutIgnoreValue(t *testing.T) {
|
|||||||
_, err := kvc.Put(context.TODO(), &preq)
|
_, err := kvc.Put(context.TODO(), &preq)
|
||||||
return err
|
return err
|
||||||
},
|
},
|
||||||
rpctypes.ErrGRPCValue,
|
rpctypes.ErrGRPCValueProvided,
|
||||||
0,
|
0,
|
||||||
},
|
},
|
||||||
{ // overwrite with previous value, ensure no prev-kv is returned and lease is detached
|
{ // overwrite with previous value, ensure no prev-kv is returned and lease is detached
|
||||||
@ -448,6 +448,146 @@ func TestV3PutIgnoreValue(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TestV3PutIgnoreLease ensures that writes with ignore_lease uses previous lease for the key overwrites.
|
||||||
|
func TestV3PutIgnoreLease(t *testing.T) {
|
||||||
|
defer testutil.AfterTest(t)
|
||||||
|
|
||||||
|
clus := NewClusterV3(t, &ClusterConfig{Size: 1})
|
||||||
|
defer clus.Terminate(t)
|
||||||
|
|
||||||
|
kvc := toGRPC(clus.RandClient()).KV
|
||||||
|
|
||||||
|
// create lease
|
||||||
|
lc := toGRPC(clus.RandClient()).Lease
|
||||||
|
lresp, err := lc.LeaseGrant(context.TODO(), &pb.LeaseGrantRequest{TTL: 30})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if lresp.Error != "" {
|
||||||
|
t.Fatal(lresp.Error)
|
||||||
|
}
|
||||||
|
|
||||||
|
key, val, val1 := []byte("zoo"), []byte("bar"), []byte("bar1")
|
||||||
|
putReq := pb.PutRequest{Key: key, Value: val}
|
||||||
|
|
||||||
|
tests := []struct {
|
||||||
|
putFunc func() error
|
||||||
|
putErr error
|
||||||
|
wleaseID int64
|
||||||
|
wvalue []byte
|
||||||
|
}{
|
||||||
|
{ // put failure for non-existent key
|
||||||
|
func() error {
|
||||||
|
preq := putReq
|
||||||
|
preq.IgnoreLease = true
|
||||||
|
_, err := kvc.Put(context.TODO(), &preq)
|
||||||
|
return err
|
||||||
|
},
|
||||||
|
rpctypes.ErrGRPCKeyNotFound,
|
||||||
|
0,
|
||||||
|
nil,
|
||||||
|
},
|
||||||
|
{ // txn failure for non-existent key
|
||||||
|
func() error {
|
||||||
|
preq := putReq
|
||||||
|
preq.IgnoreLease = true
|
||||||
|
txn := &pb.TxnRequest{}
|
||||||
|
txn.Success = append(txn.Success, &pb.RequestOp{
|
||||||
|
Request: &pb.RequestOp_RequestPut{RequestPut: &preq}})
|
||||||
|
_, err := kvc.Txn(context.TODO(), txn)
|
||||||
|
return err
|
||||||
|
},
|
||||||
|
rpctypes.ErrGRPCKeyNotFound,
|
||||||
|
0,
|
||||||
|
nil,
|
||||||
|
},
|
||||||
|
{ // put success
|
||||||
|
func() error {
|
||||||
|
preq := putReq
|
||||||
|
preq.Lease = lresp.ID
|
||||||
|
_, err := kvc.Put(context.TODO(), &preq)
|
||||||
|
return err
|
||||||
|
},
|
||||||
|
nil,
|
||||||
|
lresp.ID,
|
||||||
|
val,
|
||||||
|
},
|
||||||
|
{ // txn success, modify value using 'ignore_lease' and ensure lease is not detached
|
||||||
|
func() error {
|
||||||
|
preq := putReq
|
||||||
|
preq.Value = val1
|
||||||
|
preq.IgnoreLease = true
|
||||||
|
txn := &pb.TxnRequest{}
|
||||||
|
txn.Success = append(txn.Success, &pb.RequestOp{
|
||||||
|
Request: &pb.RequestOp_RequestPut{RequestPut: &preq}})
|
||||||
|
_, err := kvc.Txn(context.TODO(), txn)
|
||||||
|
return err
|
||||||
|
},
|
||||||
|
nil,
|
||||||
|
lresp.ID,
|
||||||
|
val1,
|
||||||
|
},
|
||||||
|
{ // non-empty lease with ignore_lease should error
|
||||||
|
func() error {
|
||||||
|
preq := putReq
|
||||||
|
preq.Lease = lresp.ID
|
||||||
|
preq.IgnoreLease = true
|
||||||
|
_, err := kvc.Put(context.TODO(), &preq)
|
||||||
|
return err
|
||||||
|
},
|
||||||
|
rpctypes.ErrGRPCLeaseProvided,
|
||||||
|
0,
|
||||||
|
nil,
|
||||||
|
},
|
||||||
|
{ // overwrite with previous value, ensure no prev-kv is returned and lease is detached
|
||||||
|
func() error {
|
||||||
|
presp, err := kvc.Put(context.TODO(), &putReq)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if presp.PrevKv != nil && len(presp.PrevKv.Key) != 0 {
|
||||||
|
return fmt.Errorf("unexexpected previous key-value %v", presp.PrevKv)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
nil,
|
||||||
|
0,
|
||||||
|
val,
|
||||||
|
},
|
||||||
|
{ // revoke lease, ensure detached key doesn't get deleted
|
||||||
|
func() error {
|
||||||
|
_, err := lc.LeaseRevoke(context.TODO(), &pb.LeaseRevokeRequest{ID: lresp.ID})
|
||||||
|
return err
|
||||||
|
},
|
||||||
|
nil,
|
||||||
|
0,
|
||||||
|
val,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for i, tt := range tests {
|
||||||
|
if err := tt.putFunc(); !eqErrGRPC(err, tt.putErr) {
|
||||||
|
t.Fatalf("#%d: err expected %v, got %v", i, tt.putErr, err)
|
||||||
|
}
|
||||||
|
if tt.putErr != nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
rr, err := kvc.Range(context.TODO(), &pb.RangeRequest{Key: key})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("#%d: %v", i, err)
|
||||||
|
}
|
||||||
|
if len(rr.Kvs) != 1 {
|
||||||
|
t.Fatalf("#%d: len(rr.KVs) expected 1, got %d", i, len(rr.Kvs))
|
||||||
|
}
|
||||||
|
if !bytes.Equal(rr.Kvs[0].Value, tt.wvalue) {
|
||||||
|
t.Fatalf("#%d: value expected %q, got %q", i, val, rr.Kvs[0].Value)
|
||||||
|
}
|
||||||
|
if rr.Kvs[0].Lease != tt.wleaseID {
|
||||||
|
t.Fatalf("#%d: lease ID expected %d, got %d", i, tt.wleaseID, rr.Kvs[0].Lease)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// TestV3PutMissingLease ensures that a Put on a key with a bogus lease fails.
|
// TestV3PutMissingLease ensures that a Put on a key with a bogus lease fails.
|
||||||
func TestV3PutMissingLease(t *testing.T) {
|
func TestV3PutMissingLease(t *testing.T) {
|
||||||
defer testutil.AfterTest(t)
|
defer testutil.AfterTest(t)
|
||||||
|
Reference in New Issue
Block a user