From d8da98c49fbb6b61faf805419c5356a05f43793f Mon Sep 17 00:00:00 2001 From: Marek Siarkowicz Date: Mon, 5 Dec 2022 15:40:30 +0100 Subject: [PATCH] tests: Fix return time for failed requests globally Signed-off-by: Marek Siarkowicz --- tests/linearizability/client.go | 4 +- tests/linearizability/history.go | 51 +++++++++++++------ tests/linearizability/linearizability_test.go | 6 ++- 3 files changed, 41 insertions(+), 20 deletions(-) diff --git a/tests/linearizability/client.go b/tests/linearizability/client.go index 7189eb848..4a4e0c675 100644 --- a/tests/linearizability/client.go +++ b/tests/linearizability/client.go @@ -24,7 +24,7 @@ import ( type recordingClient struct { client clientv3.Client - history *history + history *appendableHistory } func NewClient(endpoints []string, ids idProvider) (*recordingClient, error) { @@ -39,7 +39,7 @@ func NewClient(endpoints []string, ids idProvider) (*recordingClient, error) { } return &recordingClient{ client: *cc, - history: NewHistory(ids), + history: newAppendableHistory(ids), }, nil } diff --git a/tests/linearizability/history.go b/tests/linearizability/history.go index 364ed950c..2b5017c6e 100644 --- a/tests/linearizability/history.go +++ b/tests/linearizability/history.go @@ -21,30 +21,31 @@ import ( clientv3 "go.etcd.io/etcd/client/v3" ) -type history struct { +type appendableHistory struct { // id of the next write operation. If needed a new id might be requested from idProvider. id int idProvider idProvider - operations []porcupine.Operation - failed []porcupine.Operation + history } -func NewHistory(ids idProvider) *history { - return &history{ +func newAppendableHistory(ids idProvider) *appendableHistory { + return &appendableHistory{ id: ids.ClientId(), idProvider: ids, - operations: []porcupine.Operation{}, - failed: []porcupine.Operation{}, + history: history{ + successful: []porcupine.Operation{}, + failed: []porcupine.Operation{}, + }, } } -func (h *history) AppendGet(key string, start, end time.Time, resp *clientv3.GetResponse) { +func (h *appendableHistory) AppendGet(key string, start, end time.Time, resp *clientv3.GetResponse) { var readData string if len(resp.Kvs) == 1 { readData = string(resp.Kvs[0].Value) } - h.operations = append(h.operations, porcupine.Operation{ + h.successful = append(h.successful, porcupine.Operation{ ClientId: h.id, Input: EtcdRequest{Op: Get, Key: key}, Call: start.UnixNano(), @@ -53,7 +54,7 @@ func (h *history) AppendGet(key string, start, end time.Time, resp *clientv3.Get }) } -func (h *history) AppendPut(key, value string, start, end time.Time, resp *clientv3.PutResponse, err error) { +func (h *appendableHistory) AppendPut(key, value string, start, end time.Time, resp *clientv3.PutResponse, err error) { if err != nil { h.failed = append(h.failed, porcupine.Operation{ ClientId: h.id, @@ -71,7 +72,7 @@ func (h *history) AppendPut(key, value string, start, end time.Time, resp *clien if resp != nil && resp.Header != nil { revision = resp.Header.Revision } - h.operations = append(h.operations, porcupine.Operation{ + h.successful = append(h.successful, porcupine.Operation{ ClientId: h.id, Input: EtcdRequest{Op: Put, Key: key, PutData: value}, Call: start.UnixNano(), @@ -80,7 +81,7 @@ func (h *history) AppendPut(key, value string, start, end time.Time, resp *clien }) } -func (h *history) AppendDelete(key string, start, end time.Time, resp *clientv3.DeleteResponse, err error) { +func (h *appendableHistory) AppendDelete(key string, start, end time.Time, resp *clientv3.DeleteResponse, err error) { if err != nil { h.failed = append(h.failed, porcupine.Operation{ ClientId: h.id, @@ -100,7 +101,7 @@ func (h *history) AppendDelete(key string, start, end time.Time, resp *clientv3. revision = resp.Header.Revision deleted = resp.Deleted } - h.operations = append(h.operations, porcupine.Operation{ + h.successful = append(h.successful, porcupine.Operation{ ClientId: h.id, Input: EtcdRequest{Op: Delete, Key: key}, Call: start.UnixNano(), @@ -109,10 +110,28 @@ func (h *history) AppendDelete(key string, start, end time.Time, resp *clientv3. }) } -func (h *history) Operations() []porcupine.Operation { - operations := make([]porcupine.Operation, 0, len(h.operations)+len(h.failed)) +type history struct { + successful []porcupine.Operation + // failed requests are kept separate as we don't know return time of failed operations. + failed []porcupine.Operation +} + +func (h history) Merge(h2 history) history { + result := history{ + successful: make([]porcupine.Operation, 0, len(h.successful)+len(h2.successful)), + failed: make([]porcupine.Operation, 0, len(h.failed)+len(h2.failed)), + } + result.successful = append(result.successful, h.successful...) + result.successful = append(result.successful, h2.successful...) + result.failed = append(result.failed, h.failed...) + result.failed = append(result.failed, h2.failed...) + return result +} + +func (h history) Operations() []porcupine.Operation { + operations := make([]porcupine.Operation, 0, len(h.successful)+len(h.failed)) var maxTime int64 - for _, op := range h.operations { + for _, op := range h.successful { operations = append(operations, op) if op.Return > maxTime { maxTime = op.Return diff --git a/tests/linearizability/linearizability_test.go b/tests/linearizability/linearizability_test.go index 0e74f4e49..78780e700 100644 --- a/tests/linearizability/linearizability_test.go +++ b/tests/linearizability/linearizability_test.go @@ -140,11 +140,12 @@ type FailpointConfig struct { waitBetweenTriggers time.Duration } -func simulateTraffic(ctx context.Context, t *testing.T, clus *e2e.EtcdProcessCluster, config trafficConfig) (operations []porcupine.Operation) { +func simulateTraffic(ctx context.Context, t *testing.T, clus *e2e.EtcdProcessCluster, config trafficConfig) []porcupine.Operation { mux := sync.Mutex{} endpoints := clus.EndpointsV3() ids := newIdProvider() + h := history{} limiter := rate.NewLimiter(rate.Limit(config.maximalQPS), 200) startTime := time.Now() @@ -162,12 +163,13 @@ func simulateTraffic(ctx context.Context, t *testing.T, clus *e2e.EtcdProcessClu config.traffic.Run(ctx, c, limiter, ids) mux.Lock() - operations = append(operations, c.history.Operations()...) + h = h.Merge(c.history.history) mux.Unlock() }(c) } wg.Wait() endTime := time.Now() + operations := h.Operations() t.Logf("Recorded %d operations", len(operations)) qps := float64(len(operations)) / float64(endTime.Sub(startTime)) * float64(time.Second)