ronantakizawa/codereview-bench huggingface dataset:
Repository: etcd-io/etcd
File: tests/robustness/client/kvhash.go (Go)

Code before:
// See the License for the specific language governing permissions and
// limitations under the License.

package client

import (
	"context"
	"testing"
	"time"

	"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 getHashKV(ctx context.Context, t *testing.T, endpoints []string, rev int64) (int64, *clientv3.HashKVResponse) {
	c, err := clientv3.New(clientv3.Config{
		Endpoints:            endpoints,
		Logger:               zap.NewNop(),
		DialKeepAliveTime:    10 * time.Second,
		DialKeepAliveTimeout: 100 * time.Millisecond,
	})
	if err != nil {
		t.Error(err)
		return 0, nil
	}
	defer c.Close()

	hashKV, err := c.HashKV(ctx, c.Endpoints()[0], rev)
	if err != nil {
		t.Error(err)
		return 0, nil
	}

	return hashKV.Header.Revision, hashKV
}

func CheckHashKV(ctx context.Context, t *testing.T, clus *e2e.EtcdProcessCluster, rev int64, baseTime time.Time, ids identity.Provider) {
	hashKVs := make([]*clientv3.HashKVResponse, 0)
	if rev == 0 {
		maxRevision, hashKV := getHashKV(ctx, t, clus.EndpointsGRPC(), rev)
		rev = maxRevision
		hashKVs = append(hashKVs, hashKV)
	}

	for _, member := range clus.Procs {
		maxRevision, hashKV := getHashKV(ctx, t, member.EndpointsGRPC(), rev)
		if maxRevision != rev {
			t.Errorf("Max revision between nodes should be the same. Want %v, get %v", rev, maxRevision)

Review comment (suggestion):
Return error, not everything needs to be aware of `t`

Code after:
// See the License for the specific language governing permissions and
// limitations under the License.

package client

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])
Repository: etcd-io/etcd
File: tests/robustness/client/kvhash.go (Go)

Code before:
	c, err := clientv3.New(clientv3.Config{
		Endpoints:            endpoints,
		Logger:               zap.NewNop(),
		DialKeepAliveTime:    10 * time.Second,
		DialKeepAliveTimeout: 100 * time.Millisecond,
	})
	if err != nil {
		t.Error(err)
		return 0, nil
	}
	defer c.Close()

	hashKV, err := c.HashKV(ctx, c.Endpoints()[0], rev)
	if err != nil {
		t.Error(err)
		return 0, nil
	}

	return hashKV.Header.Revision, hashKV
}

func CheckHashKV(ctx context.Context, t *testing.T, clus *e2e.EtcdProcessCluster, rev int64, baseTime time.Time, ids identity.Provider) {
	hashKVs := make([]*clientv3.HashKVResponse, 0)
	if rev == 0 {
		maxRevision, hashKV := getHashKV(ctx, t, clus.EndpointsGRPC(), rev)
		rev = maxRevision
		hashKVs = append(hashKVs, hashKV)
	}

	for _, member := range clus.Procs {
		maxRevision, hashKV := getHashKV(ctx, t, member.EndpointsGRPC(), rev)
		if maxRevision != rev {
			t.Errorf("Max revision between nodes should be the same. Want %v, get %v", rev, maxRevision)
		}
		hashKVs = append(hashKVs, hashKV)
	}

	for i := 1; i < len(clus.Procs); i++ {
		if hashKVs[i-1].HashRevision != hashKVs[i].HashRevision {
			t.Error("HashRevision mismatch")
		}
		if hashKVs[i-1].CompactRevision != hashKVs[i].CompactRevision {
			t.Error("CompactRevision mismatch")
		}
		if hashKVs[i-1].Hash != hashKVs[i].Hash {
			t.Error("Hash mismatch")
		}
	}
}


Review comment (suggestion):
```suggestion
		_, resp := getHashKV(ctx, t, clus.EndpointsGRPC(), rev)
		rev = resp.Header.Revision
```

Code after:
		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])
		}
		if hashKVs[i-1].Hash != hashKVs[i].Hash {
			return fmt.Errorf("hash mismatch, node %v has %+v, node %v has %+v", hashKVs[i-1].Header.MemberId, hashKVs[i-1], hashKVs[i].Header.MemberId, hashKVs[i])
		}
	}
	return nil
}
Repository: etcd-io/etcd
File: tests/robustness/client/kvhash.go (Go)

Code before:
	}
	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")
		}
		if hashKVs[i-1].CompactRevision != hashKVs[i].CompactRevision {
			return fmt.Errorf("compactRevision mismatch")
		}
		if hashKVs[i-1].Hash != hashKVs[i].Hash {
			return fmt.Errorf("hash mismatch")
		}
	}
	return nil
}


Review comment (bug):
This doesn't provide enough debug information. Please provide member identification (should be within response header) and dump the responses

Code after:
	}
	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])
		}
		if hashKVs[i-1].Hash != hashKVs[i].Hash {
			return fmt.Errorf("hash mismatch, node %v has %+v, node %v has %+v", hashKVs[i-1].Header.MemberId, hashKVs[i-1], hashKVs[i].Header.MemberId, hashKVs[i])
		}
	}
	return nil
}
Repository: etcd-io/etcd
File: tests/e2e/etcd_config_test.go (Go)

Code before:
	expectedDeprecationLevelMsg := `"v2-deprecation":"write-only"`

	for _, optionLevel := range validV2DeprecationLevels {
		t.Run(optionLevel, func(t *testing.T) {
			proc, err := e2e.SpawnCmd(
				append(commonArgs, "--v2-deprecation", optionLevel), nil,
			)
			require.NoError(t, err)
			require.NoError(t, e2e.WaitReadyExpectProc(t.Context(), proc, []string{expectedDeprecationLevelMsg}))
			require.NoError(t, proc.Stop())

			proc.Wait() // ensure the port has been released
			proc.Close()
		})
	}
}

func TestEtcdAdvertiseClientUnix(t *testing.T) {
	e2e.SkipInShortMode(t)

	// Create a temporary directory for the data directory
	dataDir := t.TempDir()
	unixSocket := "unix:///tmp/etcd-client.sock"

	// Clean up the socket file after test
	defer os.Remove("/tmp/etcd-client.sock")

	// Start etcd with AdvertiseClientUrls set to a unix socket
	proc, err := e2e.SpawnCmd(
		[]string{
			e2e.BinPath.Etcd,
			"--data-dir", dataDir,
			"--name", "etcd1",
			"--listen-client-urls", unixSocket,
			"--advertise-client-urls", unixSocket,
		}, nil,
	)
	require.NoError(t, err)
	defer func() {
		_ = proc.Stop()
		_ = proc.Close()
	}()

	// Wait for the process to be ready
	require.NoError(t, e2e.WaitReadyExpectProc(t.Context(), proc, e2e.EtcdServerReadyLines))

	// Write a key/value pair using etcdctl with unix socket
	putArgs := []string{
		e2e.BinPath.Etcdctl,
		"--endpoints", unixSocket,
		"put", "foo", "bar",

Review comment (suggestion):
Could we change this to use a `t.TempDir()`, so we don't need to clean it up and ensure it's unique?

```suggestion
	socketDir := t.TempDir()
	unixSocket := fmt.Sprintf("unix://%s/etcd-client.sock", socketDir)
```

Code after:
	expectedDeprecationLevelMsg := `"v2-deprecation":"write-only"`

	for _, optionLevel := range validV2DeprecationLevels {
		t.Run(optionLevel, func(t *testing.T) {
			proc, err := e2e.SpawnCmd(
				append(commonArgs, "--v2-deprecation", optionLevel), nil,
			)
			require.NoError(t, err)
			require.NoError(t, e2e.WaitReadyExpectProc(t.Context(), proc, []string{expectedDeprecationLevelMsg}))
			require.NoError(t, proc.Stop())

			proc.Wait() // ensure the port has been released
			proc.Close()
		})
	}
}

func TestEtcdAdvertiseClientUnix(t *testing.T) {
	e2e.SkipInShortMode(t)

	// Create a temporary directory for the data directory
	dataDir := t.TempDir()
	socketDir := t.TempDir()
	unixSocket := fmt.Sprintf("unix://%s/etcd-client.sock", socketDir)

	// Start etcd with AdvertiseClientUrls set to a unix socket
	proc, err := e2e.SpawnCmd(
		[]string{
			e2e.BinPath.Etcd,
			"--data-dir", dataDir,
			"--name", "etcd1",
			"--listen-client-urls", unixSocket,
			"--advertise-client-urls", unixSocket,
		}, nil,
	)
	require.NoError(t, err)
	defer func() {
		_ = proc.Stop()
		_ = proc.Close()
	}()

	// Wait for the process to be ready
	require.NoError(t, e2e.WaitReadyExpectProc(t.Context(), proc, e2e.EtcdServerReadyLines))

	// Write a key/value pair using etcdctl with unix socket
	putArgs := []string{
		e2e.BinPath.Etcdctl,
		"--endpoints", unixSocket,
		"put", "foo", "bar",
	}
	putProc, err := e2e.SpawnCmd(putArgs, nil)
Repository: etcd-io/etcd
File: pkg/adt/interval_tree.go (Go)

Code before:
	return ret
}

// Find gets the IntervalValue for the node matching the given interval
func (ivt *intervalTree) Find(ivl Interval) (ret *IntervalValue) {
	n := ivt.find(ivl)
	if n == ivt.sentinel {
		return nil
	}
	return &n.iv
}

// Intersects returns true if there is some tree node intersecting the given interval.
func (ivt *intervalTree) Intersects(iv Interval) bool {
	x := ivt.root
	for x != ivt.sentinel && iv.Compare(&x.iv.Ivl) != 0 {
		if x.left != ivt.sentinel && x.left.max.Compare(iv.Begin) > 0 {
			x = x.left
		} else {
			x = x.right
		}
	}
	return x != ivt.sentinel
}

// Contains returns true if the interval tree's keys cover the entire given interval.
func (ivt *intervalTree) Contains(ivl Interval) bool {
	var maxEnd, minBegin Comparable

	isContiguous := true
	ivt.Visit(ivl, func(n *IntervalValue) bool {
		if minBegin == nil {
			minBegin = n.Ivl.Begin
			maxEnd = n.Ivl.End
			return true
		}
		if maxEnd.Compare(n.Ivl.Begin) < 0 {
			isContiguous = false
			return false
		}
		if n.Ivl.End.Compare(maxEnd) > 0 {
			maxEnd = n.Ivl.End
		}
		return true
	})

	return isContiguous && minBegin != nil && maxEnd.Compare(ivl.End) >= 0 && minBegin.Compare(ivl.Begin) <= 0
}

// Stab returns a slice with all elements in the tree intersecting the interval.
func (ivt *intervalTree) Stab(iv Interval) (ivs []*IntervalValue) {

Review comment (suggestion):
Pls revert the change to the `Insert` method
```suggestion
		if beginCompare < 0 {
			x = x.left
		} else {
			x = x.right
```

Code after:
func (ivt *intervalTree) Visit(ivl Interval, ivv IntervalVisitor) {
	ivt.root.visit(&ivl, ivt.sentinel, func(n *intervalNode) bool { return ivv(&n.iv) })
}

// find the exact node for a given interval
func (ivt *intervalTree) find(ivl Interval) *intervalNode {
	x := ivt.root
	// Search until hit sentinel or exact match.
	for x != ivt.sentinel {
		beginCompare := ivl.Begin.Compare(x.iv.Ivl.Begin)
		endCompare := ivl.End.Compare(x.iv.Ivl.End)
		if beginCompare == 0 && endCompare == 0 {
			return x
		}
		// Split on left endpoint. If left endpoints match,
		// instead split on right endpoints.
		if beginCompare < 0 {
			x = x.left
		} else if beginCompare == 0 {
			if endCompare < 0 {
				x = x.left
			} else {
				x = x.right
			}
		} else {
			x = x.right
		}
	}
	return x
}

// Find gets the IntervalValue for the node matching the given interval
func (ivt *intervalTree) Find(ivl Interval) (ret *IntervalValue) {
	n := ivt.find(ivl)
	if n == ivt.sentinel {
		return nil
	}
	return &n.iv
}

// Intersects returns true if there is some tree node intersecting the given interval.
func (ivt *intervalTree) Intersects(iv Interval) bool {
	x := ivt.root
	for x != ivt.sentinel && iv.Compare(&x.iv.Ivl) != 0 {
		if x.left != ivt.sentinel && x.left.max.Compare(iv.Begin) > 0 {
			x = x.left
		} else {
			x = x.right
		}
	}
	return x != ivt.sentinel
Repository: etcd-io/etcd
File: pkg/adt/interval_tree.go (Go)

Code before:
//	 else
//	 	y.right = z
//
//	 z.left = T.nil
//	 z.right = T.nil
//	 z.color = RED
//
//	 RB-INSERT-FIXUP(T, z)

// Insert adds a node with the given interval into the tree.
func (ivt *intervalTree) Insert(ivl Interval, val any) {
	y := ivt.sentinel
	z := ivt.createIntervalNode(ivl, val)
	x := ivt.root
	for x != ivt.sentinel {
		y = x
		if z.iv.Ivl.Begin.Compare(x.iv.Ivl.Begin) < 0 {
			x = x.left
		} else {
			x = x.right
		}
	}

	z.parent = y
	if y == ivt.sentinel {
		ivt.root = z
	} else {
		if z.iv.Ivl.Begin.Compare(y.iv.Ivl.Begin) < 0 {
			y.left = z
		} else {
			y.right = z
		}
		y.updateMax(ivt.sentinel)
	}
	z.c = red

	ivt.insertFixup(z)
	ivt.count++
}

// "Introduction to Algorithms" (Cormen et al, 3rd ed.), chapter 13.3, p316
//
//	RB-INSERT-FIXUP(T, z)
//
//	while z.p.color == RED
//		if z.p == z.p.p.left
//			y = z.p.p.right
//			if y.color == RED
//				z.p.color = BLACK
//				y.color = BLACK
//				z.p.p.color = RED

Review comment (performance):
**You changed the behaviour, so it's a breaking change.**

Previously it only checks the interval's `Begin`; an intervalTree inserts a new node to the left if` newNode.Ivl.Begin < x.Ivl.Begin`, otherwise inserts it to the right.

Now you not only checks the `Begin`, but also checks the `End`, and inserts the new node to the left if Begin matches and newNode's End is less.

This PR's purpose is to optimize the exact search (find), I don't see a reason why update the Insert. So please consider to revert the change. Pls also see comment for the `find` method.

Code after:
//	 else
//	 	y.right = z
//
//	 z.left = T.nil
//	 z.right = T.nil
//	 z.color = RED
//
//	 RB-INSERT-FIXUP(T, z)

// Insert adds a node with the given interval into the tree.
func (ivt *intervalTree) Insert(ivl Interval, val any) {
	y := ivt.sentinel
	z := ivt.createIntervalNode(ivl, val)
	x := ivt.root
	for x != ivt.sentinel {
		y = x
		// Split on left endpoint. If left endpoints match, instead split on right endpoint.
		beginCompare := z.iv.Ivl.Begin.Compare(x.iv.Ivl.Begin)
		if beginCompare < 0 {
			x = x.left
		} else if beginCompare == 0 {
			if z.iv.Ivl.End.Compare(x.iv.Ivl.End) < 0 {
				x = x.left
			} else {
				x = x.right
			}
		} else {
			x = x.right
		}
	}

	z.parent = y
	if y == ivt.sentinel {
		ivt.root = z
	} else {
		beginCompare := z.iv.Ivl.Begin.Compare(y.iv.Ivl.Begin)
		if beginCompare < 0 {
			y.left = z
		} else if beginCompare == 0 {
			if z.iv.Ivl.End.Compare(y.iv.Ivl.End) < 0 {
				y.left = z
			} else {
				y.right = z
			}
		} else {
			y.right = z
		}
		y.updateMax(ivt.sentinel)
	}
	z.c = red
Repository: etcd-io/etcd
File: scripts/test.sh (Shell)

Code before:
      ;;
  esac

  tar xzvf "/tmp/$file" -C /tmp/ --strip-components=1
  mkdir -p ./bin
  mv /tmp/etcd ./bin/etcd-last-release
}

function release_tests_pass {
  git config user.email "prow@etcd.io"
  git config user.name "Prow"

  gpg --batch --gen-key <<EOF
%no-protection
Key-Type: 1
Key-Length: 2048
Subkey-Type: 1
Subkey-Length: 2048
Name-Real: Prow
Name-Email: prow@etcd.io
Expire-Date: 0
EOF

  git remote add origin https://github.com/etcd-io/etcd.git
  DRY_RUN=true run "${ETCD_ROOT_DIR}/scripts/release.sh" --no-upload --no-docker-push --no-gh-release --in-place 3.6.99
  VERSION=3.6.99 run "${ETCD_ROOT_DIR}/scripts/test_images.sh"
}

function mod_tidy_for_module {
  run go mod tidy -diff
}

function mod_tidy_pass {
  run_for_modules generic_checker mod_tidy_for_module
}

function proto_annotations_pass {
  "${ETCD_ROOT_DIR}/scripts/verify_proto_annotations.sh"
}

function genproto_pass {
  "${ETCD_ROOT_DIR}/scripts/verify_genproto.sh"
}

########### MAIN ###############################################################

function run_pass {
  local pass="${1}"
  shift 1
  log_callout -e "\\n'${pass}' started at $(date)"
  if "${pass}_pass" "$@" ; then

Review comment (bug):
Can we read the current minor from `./api/version/version.go` and set the patch to 99? That way, they can cleanly backport to 3.6 and 3.5 [3.4 has a different file structure, so maybe it makes sense to fix it to 3.4.99]).

It may sound like an overkill, but tests will fail once we release 3.6 and start working on 3.7 on the main branch.

Code after:
      ;;
  esac

  tar xzvf "/tmp/$file" -C /tmp/ --strip-components=1
  mkdir -p ./bin
  mv /tmp/etcd ./bin/etcd-last-release
}

function release_tests_pass {
  VERSION=$(go list -m go.etcd.io/etcd/api/v3 2>/dev/null | awk '{split(substr($2,2), a, "."); print a[1]"."a[2]".99"}')

  if [ -n "${CI:-}" ]; then
    git config user.email "prow@etcd.io"
    git config user.name "Prow"

    gpg --batch --gen-key <<EOF
%no-protection
Key-Type: 1
Key-Length: 2048
Subkey-Type: 1
Subkey-Length: 2048
Name-Real: Prow
Name-Email: prow@etcd.io
Expire-Date: 0
EOF

    git remote add origin https://github.com/etcd-io/etcd.git
  fi

  DRY_RUN=true run "${ETCD_ROOT_DIR}/scripts/release.sh" --no-upload --no-docker-push --no-gh-release --in-place "${VERSION}"
  VERSION="${VERSION}" run "${ETCD_ROOT_DIR}/scripts/test_images.sh"
}

function mod_tidy_for_module {
  run go mod tidy -diff
}

function mod_tidy_pass {
  run_for_modules generic_checker mod_tidy_for_module
}

function proto_annotations_pass {
  "${ETCD_ROOT_DIR}/scripts/verify_proto_annotations.sh"
}

function genproto_pass {
  "${ETCD_ROOT_DIR}/scripts/verify_genproto.sh"
}

########### MAIN ###############################################################
Repository: etcd-io/etcd
File: scripts/test.sh (Shell)

Code before:
  fi

  log_callout "Downloading $file"

  set +e
  curl --fail -L "https://github.com/etcd-io/etcd/releases/download/$UPGRADE_VER/$file" -o "/tmp/$file"
  local result=$?
  set -e
  case $result in
    0)  ;;
    *)  log_error "--- FAIL:" ${result}
      return $result
      ;;
  esac

  tar xzvf "/tmp/$file" -C /tmp/ --strip-components=1
  mkdir -p ./bin
  mv /tmp/etcd ./bin/etcd-last-release
}

function release_tests_pass {
  VERSION=3.4.99

  if [ "${1-}" ]; then
    VERSION=$1
  fi

  if [ "${CI}" ]; then
    git config user.email "prow@etcd.io"
    git config user.name "Prow"

    gpg --batch --gen-key <<EOF
%no-protection
Key-Type: 1
Key-Length: 2048
Subkey-Type: 1
Subkey-Length: 2048
Name-Real: Prow
Name-Email: prow@etcd.io
Expire-Date: 0
EOF

    git remote add origin https://github.com/etcd-io/etcd.git
  fi

  DRY_RUN=true run "${ETCD_ROOT_DIR}/scripts/release.sh" --no-upload --no-docker-push --no-gh-release --in-place "${VERSION}"
  VERSION="${VERSION}" run "${ETCD_ROOT_DIR}/scripts/test_images.sh"
}

function mod_tidy_for_module {
  run go mod tidy -diff

Review comment (suggestion):
We do not practice passing arguments in other test passes. Could we use an environment variable instead? (i.e., use `$VERSION` as input).

Code after:
  fi

  log_callout "Downloading $file"

  set +e
  curl --fail -L "https://github.com/etcd-io/etcd/releases/download/$UPGRADE_VER/$file" -o "/tmp/$file"
  local result=$?
  set -e
  case $result in
    0)  ;;
    *)  log_error "--- FAIL:" ${result}
      return $result
      ;;
  esac

  tar xzvf "/tmp/$file" -C /tmp/ --strip-components=1
  mkdir -p ./bin
  mv /tmp/etcd ./bin/etcd-last-release
}

function release_tests_pass {
  VERSION=$(go list -m go.etcd.io/etcd/api/v3 2>/dev/null | awk '{split(substr($2,2), a, "."); print a[1]"."a[2]".99"}')

  if [ -n "${CI:-}" ]; then
    git config user.email "prow@etcd.io"
    git config user.name "Prow"

    gpg --batch --gen-key <<EOF
%no-protection
Key-Type: 1
Key-Length: 2048
Subkey-Type: 1
Subkey-Length: 2048
Name-Real: Prow
Name-Email: prow@etcd.io
Expire-Date: 0
EOF

    git remote add origin https://github.com/etcd-io/etcd.git
  fi

  DRY_RUN=true run "${ETCD_ROOT_DIR}/scripts/release.sh" --no-upload --no-docker-push --no-gh-release --in-place "${VERSION}"
  VERSION="${VERSION}" run "${ETCD_ROOT_DIR}/scripts/test_images.sh"
}

function mod_tidy_for_module {
  run go mod tidy -diff
}

function mod_tidy_pass {
  run_for_modules generic_checker mod_tidy_for_module