Skip to content

Commit

Permalink
Merge pull request etcd-io#16153 from serathius/robustness-report-load
Browse files Browse the repository at this point in the history
tests/robustness: Implement loading client reports
  • Loading branch information
serathius committed Jul 2, 2023
2 parents 833aabe + 11da84a commit 57a583d
Show file tree
Hide file tree
Showing 47 changed files with 1,780 additions and 248 deletions.
40 changes: 23 additions & 17 deletions tests/robustness/linearizability_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,14 @@ import (
"testing"
"time"

"go.etcd.io/etcd/tests/v3/robustness/model"

"go.uber.org/zap"
"go.uber.org/zap/zaptest"
"golang.org/x/sync/errgroup"

"go.etcd.io/etcd/tests/v3/robustness/report"

"go.etcd.io/etcd/api/v3/version"
"go.etcd.io/etcd/tests/v3/framework/e2e"
"go.etcd.io/etcd/tests/v3/robustness/identity"
Expand Down Expand Up @@ -136,18 +140,18 @@ type testScenario struct {
}

func testRobustness(ctx context.Context, t *testing.T, lg *zap.Logger, s testScenario) {
r := report{lg: lg}
report := report.TestReport{Logger: lg}
var err error
r.clus, err = e2e.NewEtcdProcessCluster(ctx, t, e2e.WithConfig(&s.cluster))
report.Cluster, err = e2e.NewEtcdProcessCluster(ctx, t, e2e.WithConfig(&s.cluster))
if err != nil {
t.Fatal(err)
}
defer r.clus.Close()
defer report.Cluster.Close()

if s.failpoint == nil {
s.failpoint = pickRandomFailpoint(t, r.clus)
s.failpoint = pickRandomFailpoint(t, report.Cluster)
} else {
err = validateFailpoint(r.clus, s.failpoint)
err = validateFailpoint(report.Cluster, s.failpoint)
if err != nil {
t.Fatal(err)
}
Expand All @@ -158,22 +162,22 @@ func testRobustness(ctx context.Context, t *testing.T, lg *zap.Logger, s testSce
// Refer to: https://github.com/golang/go/issues/49929
panicked := true
defer func() {
r.Report(t, panicked)
report.Report(t, panicked)
}()
r.clientReports = s.run(ctx, t, lg, r.clus)
forcestopCluster(r.clus)
report.Client = s.run(ctx, t, lg, report.Cluster)
forcestopCluster(report.Cluster)

watchProgressNotifyEnabled := r.clus.Cfg.WatchProcessNotifyInterval != 0
validateGotAtLeastOneProgressNotify(t, r.clientReports, s.watch.requestProgress || watchProgressNotifyEnabled)
watchProgressNotifyEnabled := report.Cluster.Cfg.WatchProcessNotifyInterval != 0
validateGotAtLeastOneProgressNotify(t, report.Client, s.watch.requestProgress || watchProgressNotifyEnabled)
validateConfig := validate.Config{ExpectRevisionUnique: s.traffic.Traffic.ExpectUniqueRevision()}
r.visualizeHistory = validate.ValidateAndReturnVisualize(t, lg, validateConfig, r.clientReports)
report.Visualize = validate.ValidateAndReturnVisualize(t, lg, validateConfig, report.Client)

panicked = false
}

func (s testScenario) run(ctx context.Context, t *testing.T, lg *zap.Logger, clus *e2e.EtcdProcessCluster) (reports []traffic.ClientReport) {
func (s testScenario) run(ctx context.Context, t *testing.T, lg *zap.Logger, clus *e2e.EtcdProcessCluster) (reports []report.ClientReport) {
g := errgroup.Group{}
var operationReport, watchReport []traffic.ClientReport
var operationReport, watchReport []report.ClientReport
finishTraffic := make(chan struct{})

// using baseTime time-measuring operation to get monotonic clock reading
Expand Down Expand Up @@ -201,12 +205,14 @@ func (s testScenario) run(ctx context.Context, t *testing.T, lg *zap.Logger, clu
return append(operationReport, watchReport...)
}

func operationsMaxRevision(reports []traffic.ClientReport) int64 {
func operationsMaxRevision(reports []report.ClientReport) int64 {
var maxRevision int64
for _, r := range reports {
revision := r.KeyValue.MaxRevision()
if revision > maxRevision {
maxRevision = revision
for _, op := range r.KeyValue {
resp := op.Output.(model.MaybeEtcdResponse)
if resp.Revision > maxRevision {
maxRevision = resp.Revision
}
}
}
return maxRevision
Expand Down
4 changes: 2 additions & 2 deletions tests/robustness/model/describe.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ import (
)

func describeEtcdResponse(request EtcdRequest, response MaybeEtcdResponse) string {
if response.Err != nil {
return fmt.Sprintf("err: %q", response.Err)
if response.Error != "" {
return fmt.Sprintf("err: %q", response.Error)
}
if response.PartialResponse {
return fmt.Sprintf("unknown, rev: %d", response.Revision)
Expand Down
4 changes: 2 additions & 2 deletions tests/robustness/model/deterministic.go
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ func (s EtcdState) Step(request EtcdRequest) (EtcdState, MaybeEtcdResponse) {
return s, MaybeEtcdResponse{EtcdResponse: EtcdResponse{Range: &resp, Revision: s.Revision}}
} else {
if request.Range.Revision > s.Revision {
return s, MaybeEtcdResponse{Err: EtcdFutureRevErr}
return s, MaybeEtcdResponse{Error: EtcdFutureRevErr.Error()}
}
return s, MaybeEtcdResponse{PartialResponse: true, EtcdResponse: EtcdResponse{Revision: s.Revision}}
}
Expand Down Expand Up @@ -312,7 +312,7 @@ type DefragmentRequest struct{}
type MaybeEtcdResponse struct {
EtcdResponse
PartialResponse bool
Err error
Error string
}

var EtcdFutureRevErr = errors.New("future rev")
Expand Down
2 changes: 1 addition & 1 deletion tests/robustness/model/history.go
Original file line number Diff line number Diff line change
Expand Up @@ -390,7 +390,7 @@ func rangeResponse(kvs []*mvccpb.KeyValue, count int64, revision int64) MaybeEtc
}

func failedResponse(err error) MaybeEtcdResponse {
return MaybeEtcdResponse{Err: err}
return MaybeEtcdResponse{Error: err.Error()}
}

func partialResponse(revision int64) MaybeEtcdResponse {
Expand Down
2 changes: 1 addition & 1 deletion tests/robustness/model/non_deterministic.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ type nonDeterministicState []EtcdState
func (states nonDeterministicState) apply(request EtcdRequest, response MaybeEtcdResponse) (bool, nonDeterministicState) {
var newStates nonDeterministicState
switch {
case response.Err != nil:
case response.Error != "":
newStates = states.stepFailedResponse(request)
case response.PartialResponse:
newStates = states.applyResponseRevision(request, response.EtcdResponse.Revision)
Expand Down
29 changes: 29 additions & 0 deletions tests/robustness/model/watch.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// Copyright 2023 The etcd Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package model

import "time"

type WatchOperation struct {
Request WatchRequest
Responses []WatchResponse
}

type WatchResponse struct {
Events []WatchEvent
IsProgressNotify bool
Revision int64
Time time.Duration
}
156 changes: 0 additions & 156 deletions tests/robustness/report.go

This file was deleted.

Loading

0 comments on commit 57a583d

Please sign in to comment.