mirror of
https://github.com/etcd-io/etcd.git
synced 2024-09-27 06:25:44 +00:00
linearizability tests - Add support for delete api
Signed-off-by: Geeta Gharpure <geetagh@amazon.com>
This commit is contained in:
parent
6a156bd555
commit
de991a9f2d
@ -89,3 +89,26 @@ func (c *recordingClient) Put(ctx context.Context, key, value string) error {
|
|||||||
})
|
})
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *recordingClient) Delete(ctx context.Context, key string) error {
|
||||||
|
callTime := time.Now()
|
||||||
|
resp, err := c.client.Delete(ctx, key)
|
||||||
|
returnTime := time.Now()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
var revision int64
|
||||||
|
var deleted int64
|
||||||
|
if resp != nil && resp.Header != nil {
|
||||||
|
revision = resp.Header.Revision
|
||||||
|
deleted = resp.Deleted
|
||||||
|
}
|
||||||
|
c.operations = append(c.operations, porcupine.Operation{
|
||||||
|
ClientId: c.id,
|
||||||
|
Input: etcdRequest{op: Delete, key: key},
|
||||||
|
Call: callTime.UnixNano(),
|
||||||
|
Output: etcdResponse{revision: revision, deleted: deleted},
|
||||||
|
Return: returnTime.UnixNano(),
|
||||||
|
})
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
@ -24,8 +24,9 @@ import (
|
|||||||
type Operation string
|
type Operation string
|
||||||
|
|
||||||
const (
|
const (
|
||||||
Get Operation = "get"
|
Get Operation = "get"
|
||||||
Put Operation = "put"
|
Put Operation = "put"
|
||||||
|
Delete Operation = "delete"
|
||||||
)
|
)
|
||||||
|
|
||||||
type etcdRequest struct {
|
type etcdRequest struct {
|
||||||
@ -37,6 +38,7 @@ type etcdRequest struct {
|
|||||||
type etcdResponse struct {
|
type etcdResponse struct {
|
||||||
getData string
|
getData string
|
||||||
revision int64
|
revision int64
|
||||||
|
deleted int64
|
||||||
err error
|
err error
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -78,6 +80,12 @@ var etcdModel = porcupine.Model{
|
|||||||
} else {
|
} else {
|
||||||
return fmt.Sprintf("put(%q, %q) -> ok, rev: %d", request.key, request.putData, response.revision)
|
return fmt.Sprintf("put(%q, %q) -> ok, rev: %d", request.key, request.putData, response.revision)
|
||||||
}
|
}
|
||||||
|
case Delete:
|
||||||
|
if response.err != nil {
|
||||||
|
return fmt.Sprintf("delete(%q) -> %s", request.key, response.err)
|
||||||
|
} else {
|
||||||
|
return fmt.Sprintf("delete(%q) -> ok, rev: %d deleted:%d", request.key, response.revision, response.deleted)
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
return "<invalid>"
|
return "<invalid>"
|
||||||
}
|
}
|
||||||
@ -99,6 +107,8 @@ func step(state EtcdState, request etcdRequest, response etcdResponse) (bool, Et
|
|||||||
return stepGet(state, request, response)
|
return stepGet(state, request, response)
|
||||||
case Put:
|
case Put:
|
||||||
return stepPut(state, request, response)
|
return stepPut(state, request, response)
|
||||||
|
case Delete:
|
||||||
|
return stepDelete(state, request, response)
|
||||||
default:
|
default:
|
||||||
panic("Unknown operation")
|
panic("Unknown operation")
|
||||||
}
|
}
|
||||||
@ -119,6 +129,9 @@ func initState(request etcdRequest, response etcdResponse) EtcdState {
|
|||||||
} else {
|
} else {
|
||||||
state.FailedWrites[request.putData] = struct{}{}
|
state.FailedWrites[request.putData] = struct{}{}
|
||||||
}
|
}
|
||||||
|
case Delete:
|
||||||
|
//TODO should state have 'deleted' field?
|
||||||
|
state.Value = ""
|
||||||
default:
|
default:
|
||||||
panic("Unknown operation")
|
panic("Unknown operation")
|
||||||
}
|
}
|
||||||
@ -151,3 +164,15 @@ func stepPut(state EtcdState, request etcdRequest, response etcdResponse) (bool,
|
|||||||
state.LastRevision = response.revision
|
state.LastRevision = response.revision
|
||||||
return true, state
|
return true, state
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func stepDelete(state EtcdState, request etcdRequest, response etcdResponse) (bool, EtcdState) {
|
||||||
|
if response.err != nil {
|
||||||
|
state.FailedWrites[request.putData] = struct{}{}
|
||||||
|
return true, state
|
||||||
|
}
|
||||||
|
if response.deleted == 1 && state.LastRevision >= response.revision {
|
||||||
|
return false, state
|
||||||
|
}
|
||||||
|
state.LastRevision = response.revision
|
||||||
|
return true, state
|
||||||
|
}
|
||||||
|
@ -104,6 +104,18 @@ func TestModel(t *testing.T) {
|
|||||||
{req: etcdRequest{op: Put, key: "key", putData: "3"}, resp: etcdResponse{revision: 4}},
|
{req: etcdRequest{op: Put, key: "key", putData: "3"}, resp: etcdResponse{revision: 4}},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "Deleting non existent key does not change revision",
|
||||||
|
operations: []testOperation{
|
||||||
|
{req: etcdRequest{op: Delete, key: "NotThere"}, resp: etcdResponse{deleted: 0, revision: 4}},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Deleting existent key bumps up revision",
|
||||||
|
operations: []testOperation{
|
||||||
|
{req: etcdRequest{op: Delete, key: "key"}, resp: etcdResponse{deleted: 1, revision: 5}},
|
||||||
|
},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
for _, tc := range tcs {
|
for _, tc := range tcs {
|
||||||
var ok bool
|
var ok bool
|
||||||
|
Loading…
x
Reference in New Issue
Block a user