Repository: etcd-io/etcd
File: tests/robustness/validate/patch_history.go (Go)

Code before:
	"github.com/anishathalye/porcupine"

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

func patchFailedRequestWithInfiniteReturnTime(reports []report.ClientReport) []report.ClientReport {
	ret := make([]report.ClientReport, 0, len(reports))
	for _, report := range reports {
		operations := make([]porcupine.Operation, 0, len(report.KeyValue))
		for _, operation := range report.KeyValue {
			// Failed writes can still be persisted, setting to infinite for now as we don't know when request has took effect.
			if operation.Output.(model.MaybeEtcdResponse).Error != "" {
				operation.Return = math.MaxInt64
			}
			operations = append(operations, operation)
		}
		report.KeyValue = operations
		ret = append(ret, report)
	}

	return ret
}

func patchLinearizableOperations(reports []report.ClientReport, persistedRequests []model.EtcdRequest) []porcupine.Operation {
	reports = patchFailedRequestWithInfiniteReturnTime(reports)
	allOperations := relevantOperations(reports)
	putRevision := putRevision(reports)
	persistedPutCount := countPersistedPuts(persistedRequests)
	clientPutCount := countClientPuts(reports)
	putReturnTime := uniquePutReturnTime(allOperations, reports, persistedRequests, clientPutCount)
	return patchOperations(allOperations, putRevision, putReturnTime, clientPutCount, persistedPutCount)
}

func relevantOperations(reports []report.ClientReport) []porcupine.Operation {
	var ops []porcupine.Operation
	for _, r := range reports {
		for _, op := range r.KeyValue {
			request := op.Input.(model.EtcdRequest)
			resp := op.Output.(model.MaybeEtcdResponse)
			// Remove failed read requests as they are not relevant for linearization.
			if resp.Error == "" || !request.IsRead() {
				ops = append(ops, op)
			}
		}
	}
	return ops
}

func putRevision(reports []report.ClientReport) map[keyValue]int64 {
	requestRevision := map[keyValue]int64{}

Review comment (suggestion):
Like mentioned before, please don't call the function patch, nor put it in `patchLinearizableOperations`

Code after:
	"github.com/anishathalye/porcupine"

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

func patchLinearizableOperations(operations []porcupine.Operation, reports []report.ClientReport, persistedRequests []model.EtcdRequest) []porcupine.Operation {
	putRevision := putRevision(reports)
	persistedPutCount := countPersistedPuts(persistedRequests)
	clientPutCount := countClientPuts(reports)
	putReturnTime := uniquePutReturnTime(operations, reports, persistedRequests, clientPutCount)
	return patchOperations(operations, putRevision, putReturnTime, clientPutCount, persistedPutCount)
}

func putRevision(reports []report.ClientReport) map[keyValue]int64 {
	requestRevision := map[keyValue]int64{}
	for _, client := range reports {
		for _, watch := range client.Watch {
			for _, resp := range watch.Responses {
				for _, event := range resp.Events {
					switch event.Type {
					case model.RangeOperation:
					case model.PutOperation:
						kv := keyValue{Key: event.Key, Value: event.Value}
						requestRevision[kv] = event.Revision
					case model.DeleteOperation:
					default:
						panic(fmt.Sprintf("unknown event type %q", event.Type))
					}
				}
			}
		}
	}
	return requestRevision
}

func patchOperations(operations []porcupine.Operation, watchRevision, putReturnTime, clientPutCount, persistedPutCount map[keyValue]int64) []porcupine.Operation {
	newOperations := make([]porcupine.Operation, 0, len(operations))

	for _, op := range operations {
		request := op.Input.(model.EtcdRequest)
		resp := op.Output.(model.MaybeEtcdResponse)
		if resp.Error == "" || request.Type != model.Txn {
			// Cannot patch those requests.
			newOperations = append(newOperations, op)
			continue
		}
		var txnRevision int64
		var persisted bool
		for _, etcdOp := range append(request.Txn.OperationsOnSuccess, request.Txn.OperationsOnFailure...) {
			switch etcdOp.Type {