Skip to content

Commit

Permalink
Add downgrade cancellation e2e tests
Browse files Browse the repository at this point in the history
Signed-off-by: Chun-Hung Tseng <[email protected]>
  • Loading branch information
henrybear327 authored and Chun-Hung Tseng committed Jan 21, 2025
1 parent 7c56ef2 commit f1ff53e
Show file tree
Hide file tree
Showing 4 changed files with 81 additions and 6 deletions.
2 changes: 1 addition & 1 deletion etcdctl/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -1119,7 +1119,7 @@ DOWNGRADE ENABLE starts a downgrade action to cluster.
Downgrade enable success, cluster version 3.6
```

### DOWNGRADE CANCEL \<TARGET_VERSION\>
### DOWNGRADE CANCEL

DOWNGRADE CANCEL cancels the ongoing downgrade action to cluster.

Expand Down
60 changes: 55 additions & 5 deletions tests/e2e/cluster_downgrade_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,23 +37,47 @@ import (
"go.etcd.io/etcd/tests/v3/framework/e2e"
)

type CancellationState int

const (
NoCancellation CancellationState = iota
CancelRightBeforeEnable
CancelRightAfterEnable
)

func TestDowngradeUpgradeClusterOf1(t *testing.T) {
testDowngradeUpgrade(t, 1, false)
testDowngradeUpgrade(t, 1, false, NoCancellation)
}

func TestDowngradeUpgradeClusterOf3(t *testing.T) {
testDowngradeUpgrade(t, 3, false)
testDowngradeUpgrade(t, 3, false, NoCancellation)
}

func TestDowngradeUpgradeClusterOf1WithSnapshot(t *testing.T) {
testDowngradeUpgrade(t, 1, true)
testDowngradeUpgrade(t, 1, true, NoCancellation)
}

func TestDowngradeUpgradeClusterOf3WithSnapshot(t *testing.T) {
testDowngradeUpgrade(t, 3, true)
testDowngradeUpgrade(t, 3, true, NoCancellation)
}

func TestDowngradeCancellationWithoutEnablingClusterOf1(t *testing.T) {
testDowngradeUpgrade(t, 1, false, CancelRightBeforeEnable)
}

func TestDowngradeCancellationRightAfterEnablingClusterOf1(t *testing.T) {
testDowngradeUpgrade(t, 1, false, CancelRightAfterEnable)
}

func TestDowngradeCancellationWithoutEnablingClusterOf3(t *testing.T) {
testDowngradeUpgrade(t, 3, false, CancelRightBeforeEnable)
}

func TestDowngradeCancellationRightAfterEnablingClusterOf3(t *testing.T) {
testDowngradeUpgrade(t, 3, false, CancelRightAfterEnable)
}

func testDowngradeUpgrade(t *testing.T, clusterSize int, triggerSnapshot bool) {
func testDowngradeUpgrade(t *testing.T, clusterSize int, triggerSnapshot bool, triggerCancellation CancellationState) {
currentEtcdBinary := e2e.BinPath.Etcd
lastReleaseBinary := e2e.BinPath.EtcdLastRelease
if !fileutil.Exist(lastReleaseBinary) {
Expand Down Expand Up @@ -107,7 +131,18 @@ func testDowngradeUpgrade(t *testing.T, clusterSize int, triggerSnapshot bool) {
require.NoError(t, err)
beforeMembers, beforeKV := getMembersAndKeys(t, cc)

if triggerCancellation == CancelRightBeforeEnable {
t.Logf("Cancelling downgrade before enabling")
e2e.DowngradeCancel(t, epc, generateIdenticalVersions(clusterSize, currentVersionStr))
return // No need to perform downgrading, end the test here
}
e2e.DowngradeEnable(t, epc, lastVersion)
if triggerCancellation == CancelRightAfterEnable {
t.Logf("Cancelling downgrade right after enabling (no node is downgraded yet)")
e2e.DowngradeCancel(t, epc, generateIdenticalVersions(clusterSize, currentVersionStr))
return // No need to perform downgrading, end the test here
}

t.Logf("Starting downgrade process to %q", lastVersionStr)
e2e.DowngradeUpgradeMembers(t, nil, epc, len(epc.Procs), currentVersion, lastClusterVersion)
e2e.AssertProcessLogs(t, leader(t, epc), "the cluster has been downgraded")
Expand Down Expand Up @@ -233,3 +268,18 @@ func getMembersAndKeys(t *testing.T, cc *e2e.EtcdctlV3) (*clientv3.MemberListRes

return members, kvs
}

func generateIdenticalVersions(clusterSize int, currentVersion string) []*version.Versions {
ret := make([]*version.Versions, clusterSize)

for i := range clusterSize {
ret[i] = &version.Versions{
Cluster: currentVersion,
Server: currentVersion,
Storage: currentVersion,
}

}

return ret
}
20 changes: 20 additions & 0 deletions tests/framework/e2e/downgrade.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,26 @@ func DowngradeEnable(t *testing.T, epc *EtcdProcessCluster, ver *semver.Version)
t.Log("Cluster is ready for downgrade")
}

func DowngradeCancel(t *testing.T, epc *EtcdProcessCluster, versions []*version.Versions) {
t.Logf("etcdctl downgrade cancel")
c := epc.Etcdctl()
testutils.ExecuteWithTimeout(t, 20*time.Second, func() {
err := c.DowngradeCancel(context.TODO())
require.NoError(t, err)
})

t.Log("Downgrade cancelled, validating if cluster is in the right state")
for i := 0; i < len(epc.Procs); i++ {
ValidateVersion(t, epc.Cfg, epc.Procs[i], version.Versions{
Cluster: versions[i].Cluster,
Server: versions[i].Server,
Storage: versions[i].Storage,
})
}

t.Log("Cluster downgrade cancellation is completed")
}

func DowngradeUpgradeMembers(t *testing.T, lg *zap.Logger, clus *EtcdProcessCluster, numberOfMembersToChange int, currentVersion, targetVersion *semver.Version) error {
if lg == nil {
lg = clus.lg
Expand Down
5 changes: 5 additions & 0 deletions tests/framework/e2e/etcdctl.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,11 @@ func (ctl *EtcdctlV3) DowngradeEnable(ctx context.Context, version string) error
return err
}

func (ctl *EtcdctlV3) DowngradeCancel(ctx context.Context) error {
_, err := SpawnWithExpectLines(ctx, ctl.cmdArgs("downgrade", "cancel"), nil, expect.ExpectedResponse{Value: "Downgrade cancel success"})
return err
}

func (ctl *EtcdctlV3) Get(ctx context.Context, key string, o config.GetOptions) (*clientv3.GetResponse, error) {
resp := clientv3.GetResponse{}
var args []string
Expand Down

0 comments on commit f1ff53e

Please sign in to comment.