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

Code before:

import (
	"context"
	"testing"
	"time"

	"github.com/stretchr/testify/require"
	"go.uber.org/zap"

	clientv3 "go.etcd.io/etcd/client/v3"
	"go.etcd.io/etcd/tests/v3/framework/e2e"
	"go.etcd.io/etcd/tests/v3/robustness/identity"
)

func CheckHashKV(ctx context.Context, t *testing.T, clus *e2e.EtcdProcessCluster, rev int64, baseTime time.Time, ids identity.Provider) {
	HashKVs := make([]*clientv3.HashKVResponse, len(clus.Procs))
	maxRevision := int64(0)
	for i, member := range clus.Procs {
		c, err := clientv3.New(clientv3.Config{
			Endpoints:            member.EndpointsGRPC(),
			Logger:               zap.NewNop(),
			DialKeepAliveTime:    10 * time.Second,
			DialKeepAliveTimeout: 100 * time.Millisecond,
		})
		require.NoError(t, err)
		defer c.Close()

		var resp []*clientv3.HashKVResponse
		for _, ep := range c.Endpoints() {
			t.Logf("[CheckHashKV] calling endpoint %v with revision %v", c.Endpoints(), rev)
			hashKV, err := c.HashKV(ctx, ep, rev)
			require.NoError(t, err)
			resp = append(resp, hashKV)
		}
		require.Lenf(t, resp, 1, "We should only have 1 HashKVResponse per request")
		HashKVs[i] = resp[0]
		t.Logf("[CheckHashKV] member %v, resp[0] = Hash %v HashRevision %v CompactRevision %v Header.Revision %v", i, resp[0].Hash, resp[0].HashRevision, resp[0].CompactRevision, resp[0].Header.Revision)

		if maxRevision < resp[0].Header.Revision {
			maxRevision = resp[0].Header.Revision
		}
	}

	rev = maxRevision
	for i, member := range clus.Procs {
		c, err := clientv3.New(clientv3.Config{
			Endpoints:            member.EndpointsGRPC(),
			Logger:               zap.NewNop(),
			DialKeepAliveTime:    10 * time.Second,
			DialKeepAliveTimeout: 100 * time.Millisecond,
		})

Review comment (suggestion):
```suggestion
	c, err := clientv3.New(clientv3.Config{
		Endpoints:            clus.EndpointsGRPC(),
		Logger:               zap.NewNop(),
		DialKeepAliveTime:    10 * time.Second,
		DialKeepAliveTimeout: 100 * time.Millisecond,
	})
	if err != nil {
		t.Error(err)
		return
	}
	defer c.Close()
	for i, member := range clus.Procs {
```
Don't defer in for loop

Code after:

import (
	"context"
	"fmt"
	"time"

	"go.uber.org/zap"

	clientv3 "go.etcd.io/etcd/client/v3"
	"go.etcd.io/etcd/tests/v3/framework/e2e"
)

func CheckHashKV(ctx context.Context, clus *e2e.EtcdProcessCluster) error {
	c, err := clientv3.New(clientv3.Config{
		Endpoints:            clus.EndpointsGRPC(),
		Logger:               zap.NewNop(),
		DialKeepAliveTime:    10 * time.Second,
		DialKeepAliveTimeout: 100 * time.Millisecond,
	})
	if err != nil {
		return err
	}
	defer c.Close()

	hashKV, err := c.HashKV(ctx, clus.EndpointsGRPC()[0], 0)
	if err != nil {
		return err
	}
	rev := hashKV.Header.Revision

	hashKVs := make([]*clientv3.HashKVResponse, 0)
	hashKVs = append(hashKVs, hashKV)

	for _, member := range clus.Procs {
		hashKV, err := c.HashKV(ctx, member.EndpointsGRPC()[0], rev)
		if err != nil {
			return err
		}
		if hashKV.Header.Revision != rev {
			return fmt.Errorf("max revision between nodes should be the same. Want %v, get %v", rev, hashKV.Header.Revision)
		}
		hashKVs = append(hashKVs, hashKV)
	}

	for i := 1; i < len(hashKVs); i++ {
		if hashKVs[i-1].HashRevision != hashKVs[i].HashRevision {
			return fmt.Errorf("hashRevision mismatch, node %v has %+v, node %v has %+v", hashKVs[i-1].Header.MemberId, hashKVs[i-1], hashKVs[i].Header.MemberId, hashKVs[i])
		}
		if hashKVs[i-1].CompactRevision != hashKVs[i].CompactRevision {
			return fmt.Errorf("compactRevision mismatch, node %v has %+v, node %v has %+v", hashKVs[i-1].Header.MemberId, hashKVs[i-1], hashKVs[i].Header.MemberId, hashKVs[i])
		}