tests: Fix return time for failed requests globally

Signed-off-by: Marek Siarkowicz <siarkowicz@google.com>
This commit is contained in:
Marek Siarkowicz 2022-12-05 15:40:30 +01:00
parent 45fdc2bbac
commit d8da98c49f
3 changed files with 41 additions and 20 deletions

View File

@ -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
}

View File

@ -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

View File

@ -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)