Repository: etcd-io/etcd
File: tests/e2e/etcd_release_upgrade_test.go (Go)

Code before:
	epc := createNewClusterByPromotingMembers(t, e2e.LastVersion, clusterSize)
	defer func() {
		require.NoError(t, epc.Close())
	}()

	err = e2e.DowngradeUpgradeMembers(t, nil, epc, 3, false, lastClusterVersion, currentVersion)
	require.NoError(t, err)

	t.Log("Checking all member status after upgrading")
	mresp, merr := epc.Etcdctl().MemberList(t.Context(), true)
	require.NoError(t, merr)
	require.Len(t, mresp.Members, clusterSize)
	for _, m := range mresp.Members {
		require.Falsef(t, m.IsLearner, "%s should not be learner", m.Name)
	}
}

func createNewClusterByPromotingMembers(t *testing.T, clusterVersion e2e.ClusterVersion, clusterSize int) *e2e.EtcdProcessCluster {
	require.GreaterOrEqualf(t, clusterSize, 1, "clusterSize >= 1")

	var version *semver.Version
	var err error

	switch clusterVersion {
	case e2e.CurrentVersion:
		version, err = e2e.GetVersionFromBinary(e2e.BinPath.Etcd)
		require.NoErrorf(t, err, "failed to get version from binary")
	case e2e.LastVersion:
		if !fileutil.Exist(e2e.BinPath.EtcdLastRelease) {
			t.Skipf("%q does not exist", e2e.BinPath.EtcdLastRelease)
		}

		version, err = e2e.GetVersionFromBinary(e2e.BinPath.EtcdLastRelease)
		require.NoErrorf(t, err, "failed to get version from last release binary")
	default:
		t.Fatalf("unexpected cluster version: %v", clusterVersion)
	}

	t.Logf("Creating new etcd cluster - version: %v, clusterSize: %v", version, clusterSize)

	t.Log("Creating first node")
	epc, err := e2e.NewEtcdProcessCluster(t.Context(), t,
		e2e.WithVersion(clusterVersion),
		e2e.WithClusterSize(1),
		e2e.WithSnapshotCount(10),
	)
	require.NoErrorf(t, err, "failed to start first etcd process")
	defer func() {
		if t.Failed() {
			epc.Close()
		}

Review comment (refactor):
It seems that we can remove this code block to simplify the case. It's just getting the `version` and print it in log message.

Code after:

	for _, tc := range []struct {
		name     string
		snapshot int
	}{
		{
			name:     "create snapshot after promoted",
			snapshot: 10,
		},
		{
			name: "no snapshot after promoted",
		},
	} {
		t.Run(tc.name, func(t *testing.T) {
			ctx := context.Background()

			epc, _ := mustCreateNewClusterByPromotingMembers(t, e2e.LastVersion, clusterSize,
				e2e.WithSnapshotCount(uint64(tc.snapshot)))
			defer func() {
				require.NoError(t, epc.Close())
			}()

			for i := 0; i < tc.snapshot; i++ {
				err = epc.Etcdctl().Put(ctx, "foo", "bar", config.PutOptions{})
				require.NoError(t, err)
			}

			err = e2e.DowngradeUpgradeMembers(t, nil, epc, clusterSize, false, lastClusterVersion, currentVersion)
			require.NoError(t, err)

			t.Logf("Checking all members' status after upgrading")
			ensureAllMembersAreVotingMembers(t, epc)

			t.Logf("Checking all members are ready to serve client requests")
			for i := 0; i < clusterSize; i++ {
				err = epc.Procs[i].Etcdctl().Put(context.Background(), "foo", "bar", config.PutOptions{})
				require.NoError(t, err)
			}
		})
	}
}

func mustCreateNewClusterByPromotingMembers(t *testing.T, clusterVersion e2e.ClusterVersion, clusterSize int, opts ...e2e.EPClusterOption) (*e2e.EtcdProcessCluster, []*etcdserverpb.Member) {
	require.GreaterOrEqualf(t, clusterSize, 1, "clusterSize must be at least 1")

	ctx := context.Background()

	t.Logf("Creating new etcd cluster - version: %s, clusterSize: %v", clusterVersion, clusterSize)
	opts = append(opts, e2e.WithVersion(clusterVersion), e2e.WithClusterSize(1))
	epc, err := e2e.NewEtcdProcessCluster(ctx, t, opts...)
	require.NoErrorf(t, err, "failed to start first etcd process")