Repository: etcd-io/etcd
File: tests/integration/v3_lease_test.go (Go)

Code before:
		prevUnavailableCount := getLeaseKeepAliveMetric(t, follower, "Unavailable")
		leader.Stop(t)
		anotherFollower.Stop(t)

		keepAliveClient, err := followerClient.LeaseKeepAlive(clientv3.WithRequireLeader(t.Context()))
		require.NoError(t, err)

		_, err = keepAliveClient.Recv()
		require.Equal(t, rpctypes.ErrGRPCNoLeader, err)
		require.Equal(t, prevUnavailableCount+1, getLeaseKeepAliveMetric(t, follower, "Unavailable"))
	})
}

func setupLeaseForwardingCluster(t *testing.T) (*integration.Member, *integration.Member, *integration.Member) {
	t.Helper()
	cluster := integration.NewCluster(t, &integration.ClusterConfig{Size: 3})
	t.Cleanup(func() { cluster.Terminate(t) })

	leaderIdx := cluster.WaitLeader(t)
	var followersIdx []int
	for _, idx := range []int{0, 1, 2} {
		if idx != leaderIdx {
			followersIdx = append(followersIdx, idx)
		}
	}
	return cluster.Members[leaderIdx], cluster.Members[followersIdx[0]], cluster.Members[followersIdx[1]]
}

func getLeaseKeepAliveMetric(t *testing.T, member *integration.Member, grpcCode string) int64 {
	t.Helper()
	metricVal, err := member.Metric(
		"grpc_server_handled_total",
		`grpc_method="LeaseKeepAlive"`,
		fmt.Sprintf(`grpc_code="%v"`, grpcCode),
	)
	require.NoError(t, err)
	count, err := strconv.ParseInt(metricVal, 10, 32)
	require.NoError(t, err)
	return count
}

func sleepBeforeServingLeaseRenew(t *testing.T, duration time.Duration) {
	t.Helper()
	failpointName := "beforeServeHTTPLeaseRenew"
	require.NoError(t, gofail.Enable(failpointName, fmt.Sprintf(`sleep("%s")`, duration)))
	t.Cleanup(func() {
		terr := gofail.Disable(failpointName)
		if terr != nil && !errors.Is(terr, gofail.ErrDisabled) {
			t.Fatalf("Failed to disable failpoint %v, got error: %v", failpointName, terr)
		}
	})

Review comment (suggestion):
```suggestion
	return cluster.Members[leaderIdx], cluster.Members[(leaderIdx+1)%3], cluster.Members[(leaderIdx+2)%3]
```

Code after:
		prevUnavailableCount := getLeaseKeepAliveMetric(t, follower, "Unavailable")
		leader.Stop(t)
		anotherFollower.Stop(t)

		keepAliveClient, err := followerClient.LeaseKeepAlive(clientv3.WithRequireLeader(t.Context()))
		require.NoError(t, err)

		_, err = keepAliveClient.Recv()
		require.Equal(t, rpctypes.ErrGRPCNoLeader, err)
		require.Equal(t, prevUnavailableCount+1, getLeaseKeepAliveMetric(t, follower, "Unavailable"))
	})
}

func setupLeaseForwardingCluster(t *testing.T) (*integration.Member, *integration.Member, *integration.Member) {
	t.Helper()
	cluster := integration.NewCluster(t, &integration.ClusterConfig{Size: 3})
	t.Cleanup(func() { cluster.Terminate(t) })

	leaderIdx := cluster.WaitLeader(t)
	return cluster.Members[leaderIdx], cluster.Members[(leaderIdx+1)%3], cluster.Members[(leaderIdx+2)%3]
}

func getLeaseKeepAliveMetric(t *testing.T, member *integration.Member, grpcCode string) int64 {
	t.Helper()
	metricVal, err := member.Metric(
		"grpc_server_handled_total",
		`grpc_method="LeaseKeepAlive"`,
		fmt.Sprintf(`grpc_code="%v"`, grpcCode),
	)
	require.NoError(t, err)
	count, err := strconv.ParseInt(metricVal, 10, 32)
	require.NoError(t, err)
	return count
}

func sleepBeforeServingLeaseRenew(t *testing.T, duration time.Duration) {
	t.Helper()
	failpointName := "beforeServeHTTPLeaseRenew"
	require.NoError(t, gofail.Enable(failpointName, fmt.Sprintf(`sleep("%s")`, duration)))
	t.Cleanup(func() {
		terr := gofail.Disable(failpointName)
		if terr != nil && !errors.Is(terr, gofail.ErrDisabled) {
			t.Fatalf("Failed to disable failpoint %v, got error: %v", failpointName, terr)
		}
	})
}

// TestV3LeaseCheckpoint ensures a lease checkpoint results in a remaining TTL being persisted
// across leader elections.
func TestV3LeaseCheckpoint(t *testing.T) {
	tcs := []struct {