mirror of
https://github.com/etcd-io/etcd.git
synced 2024-09-27 06:25:44 +00:00
Merge f7c6c33b19eb4dca60599e9a01e95ab833c57bb0 into c86c93ca2951338115159dcdd20711603044e1f1
This commit is contained in:
commit
25273b43fe
@ -316,6 +316,7 @@ func ToWatchResponse(r clientv3.WatchResponse, baseTime time.Time) model.WatchRe
|
|||||||
}
|
}
|
||||||
resp.IsProgressNotify = r.IsProgressNotify()
|
resp.IsProgressNotify = r.IsProgressNotify()
|
||||||
resp.Revision = r.Header.Revision
|
resp.Revision = r.Header.Revision
|
||||||
|
resp.MemberId = r.Header.MemberId
|
||||||
err := r.Err()
|
err := r.Err()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
resp.Error = r.Err().Error()
|
resp.Error = r.Err().Error()
|
||||||
|
|||||||
@ -101,6 +101,7 @@ func testRobustness(ctx context.Context, t *testing.T, lg *zap.Logger, s testSce
|
|||||||
watchProgressNotifyEnabled := c.Cfg.ServerConfig.ExperimentalWatchProgressNotifyInterval != 0
|
watchProgressNotifyEnabled := c.Cfg.ServerConfig.ExperimentalWatchProgressNotifyInterval != 0
|
||||||
validateGotAtLeastOneProgressNotify(t, r.Client, s.watch.requestProgress || watchProgressNotifyEnabled)
|
validateGotAtLeastOneProgressNotify(t, r.Client, s.watch.requestProgress || watchProgressNotifyEnabled)
|
||||||
}
|
}
|
||||||
|
validateWatchSequential(t, r.Client)
|
||||||
validateConfig := validate.Config{ExpectRevisionUnique: s.traffic.ExpectUniqueRevision()}
|
validateConfig := validate.Config{ExpectRevisionUnique: s.traffic.ExpectUniqueRevision()}
|
||||||
r.Visualize = validate.ValidateAndReturnVisualize(t, lg, validateConfig, r.Client, persistedRequests, 5*time.Minute)
|
r.Visualize = validate.ValidateAndReturnVisualize(t, lg, validateConfig, r.Client, persistedRequests, 5*time.Minute)
|
||||||
|
|
||||||
|
|||||||
@ -26,5 +26,6 @@ type WatchResponse struct {
|
|||||||
IsProgressNotify bool
|
IsProgressNotify bool
|
||||||
Revision int64
|
Revision int64
|
||||||
Time time.Duration
|
Time time.Duration
|
||||||
|
MemberId uint64
|
||||||
Error string
|
Error string
|
||||||
}
|
}
|
||||||
|
|||||||
@ -16,6 +16,7 @@ package robustness
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"sort"
|
||||||
"sync"
|
"sync"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
@ -141,3 +142,58 @@ external:
|
|||||||
t.Errorf("Progress notify does not match, expect: %v, got: %v", expectProgressNotify, gotProgressNotify)
|
t.Errorf("Progress notify does not match, expect: %v, got: %v", expectProgressNotify, gotProgressNotify)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type timeLastRevision struct {
|
||||||
|
time time.Duration
|
||||||
|
lastRevision int64
|
||||||
|
}
|
||||||
|
|
||||||
|
func combineWatchResponses(reports []report.ClientReport) map[uint64][]timeLastRevision {
|
||||||
|
result := make(map[uint64][]timeLastRevision)
|
||||||
|
for _, r := range reports {
|
||||||
|
for _, op := range r.Watch {
|
||||||
|
for _, resp := range op.Responses {
|
||||||
|
if len(resp.Events) == 0 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
result[resp.MemberId] = append(result[resp.MemberId], timeLastRevision{time: resp.Time, lastRevision: resp.Events[len(resp.Events)-1].Revision})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for memberId, structs := range result {
|
||||||
|
sort.Slice(structs, func(i, j int) bool {
|
||||||
|
return structs[i].time < structs[j].time
|
||||||
|
})
|
||||||
|
result[memberId] = structs
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
func validateWatchSequential(t *testing.T, reports []report.ClientReport) {
|
||||||
|
combinedWatchResponses := combineWatchResponses(reports)
|
||||||
|
for _, r := range reports {
|
||||||
|
for _, op := range r.Watch {
|
||||||
|
if op.Request.Revision != 0 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
for _, resp := range op.Responses {
|
||||||
|
if len(resp.Events) == 0 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
var lastMemberWatchRevision int64
|
||||||
|
for i, c := range combinedWatchResponses[resp.MemberId] {
|
||||||
|
// Reports are sorted by time, find first greater or equal and use previous one.
|
||||||
|
if resp.Time >= c.time {
|
||||||
|
if i == 0 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
lastMemberWatchRevision = combinedWatchResponses[resp.MemberId][i-1].lastRevision
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if resp.Events[0].Revision < lastMemberWatchRevision {
|
||||||
|
t.Errorf("Error watch is not sequential, expect: %v or higher, got: %v, member id: %v", lastMemberWatchRevision, resp.Events[0].Revision, resp.MemberId)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user