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

Code before:
	if results.Linearizable != porcupine.Ok {
		t.Error("Failed linearization, skipping further validation")
		return results
	}

	// TODO: Use requests from linearization for replay.
	replay := model.NewReplay(persistedRequests)

	err = validateWatch(lg, cfg, reports, replay)
	if err != nil {
		t.Errorf("Failed validating watch history, err: %s", err)
	}
	err = validateSerializableOperations(lg, serializableOperations, replay)
	if err != nil {
		t.Errorf("Failed validating serializable operations, err: %s", err)
	}
	return results
}

type Config struct {
	ExpectRevisionUnique bool
}

func prepareAndCategorizeOperations(reports []report.ClientReport, persistedRequests []model.EtcdRequest) ([]report.ClientReport, []porcupine.Operation, []porcupine.Operation) {
	patchedReport := patchFailedRequestWithInfiniteReturnTime(reports)
	return patchedReport, patchLinearizableOperations(patchedReport, persistedRequests), filterSerializableOperations(patchedReport)

}

func checkValidationAssumptions(reports []report.ClientReport, persistedRequests []model.EtcdRequest) error {
	err := validateEmptyDatabaseAtStart(reports)
	if err != nil {
		return err
	}

	err = validatePersistedRequestMatchClientRequests(reports, persistedRequests)
	if err != nil {
		return err
	}
	err = validateNonConcurrentClientRequests(reports)
	if err != nil {
		return err
	}
	return nil
}

func validateEmptyDatabaseAtStart(reports []report.ClientReport) error {
	for _, r := range reports {
		for _, op := range r.KeyValue {
			request := op.Input.(model.EtcdRequest)
			response := op.Output.(model.MaybeEtcdResponse)

Review comment (suggestion):
This should not be `patchLinearizableOperations` but `relevantOperations`

Code after:
	// The reason is that linearizableOperations are those dedicated for linearization, which requires them to have returnTime set to infinity as required by pourcupine.
	// As for the report, the original report is used so the consumer doesn't need to track what patching was done or not.
	patchedLinearizableOperations := patchLinearizableOperations(linearizableOperations, reports, persistedRequests)

	results := validateLinearizableOperationsAndVisualize(lg, patchedLinearizableOperations, timeout)
	if results.Linearizable != porcupine.Ok {
		t.Error("Failed linearization, skipping further validation")
		return results
	}

	// TODO: Use requests from linearization for replay.
	replay := model.NewReplay(persistedRequests)

	err = validateWatch(lg, cfg, reports, replay)
	if err != nil {
		t.Errorf("Failed validating watch history, err: %s", err)
	}
	err = validateSerializableOperations(lg, serializableOperations, replay)
	if err != nil {
		t.Errorf("Failed validating serializable operations, err: %s", err)
	}
	return results
}

type Config struct {
	ExpectRevisionUnique bool
}

func prepareAndCategorizeOperations(reports []report.ClientReport) ([]porcupine.Operation, []porcupine.Operation) {
	patchedOperations := patchFailedRequestWithInfiniteReturnTime(reports)
	return relevantOperations(patchedOperations), filterSerializableOperations(patchedOperations)
}

func relevantOperations(operations []porcupine.Operation) []porcupine.Operation {
	var ops []porcupine.Operation
	for _, op := range operations {
		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 filterSerializableOperations(operations []porcupine.Operation) []porcupine.Operation {
	resp := []porcupine.Operation{}
	for _, op := range operations {
		request := op.Input.(model.EtcdRequest)
		if request.Type == model.Range && request.Range.Revision != 0 {