Skip to content

Commit beb0f6e

Browse files
committed
e2e: add upgrade test for clusters set up by promoted members
Signed-off-by: Wei Fu <[email protected]>
1 parent 53b88df commit beb0f6e

File tree

1 file changed

+114
-0
lines changed

1 file changed

+114
-0
lines changed

tests/e2e/etcd_release_upgrade_test.go

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,17 +16,21 @@ package e2e
1616

1717
import (
1818
"fmt"
19+
"strings"
1920
"sync"
2021
"testing"
2122
"time"
2223

24+
"github.com/coreos/go-semver/semver"
2325
"github.com/stretchr/testify/assert"
2426
"github.com/stretchr/testify/require"
2527

2628
"go.etcd.io/etcd/api/v3/version"
2729
"go.etcd.io/etcd/client/pkg/v3/fileutil"
2830
"go.etcd.io/etcd/pkg/v3/expect"
31+
"go.etcd.io/etcd/tests/v3/framework/config"
2932
"go.etcd.io/etcd/tests/v3/framework/e2e"
33+
"go.etcd.io/etcd/tests/v3/framework/testutils"
3034
)
3135

3236
// TestReleaseUpgrade ensures that changes to master branch does not affect
@@ -165,3 +169,113 @@ func TestReleaseUpgradeWithRestart(t *testing.T) {
165169

166170
require.NoError(t, ctlV3Get(cx, []string{kvs[0].key}, []kv{kvs[0]}...))
167171
}
172+
173+
func TestClusterUpgradeAfterPromotingMembers(t *testing.T) {
174+
if !fileutil.Exist(e2e.BinPath.EtcdLastRelease) {
175+
t.Skipf("%q does not exist", e2e.BinPath.EtcdLastRelease)
176+
}
177+
178+
e2e.BeforeTest(t)
179+
180+
currentVersion, err := e2e.GetVersionFromBinary(e2e.BinPath.Etcd)
181+
require.NoErrorf(t, err, "failed to get version from binary")
182+
183+
lastClusterVersion, err := e2e.GetVersionFromBinary(e2e.BinPath.EtcdLastRelease)
184+
require.NoErrorf(t, err, "failed to get version from last release binary")
185+
186+
clusterSize := 3
187+
188+
epc := createNewClusterByPromotingMembers(t, e2e.LastVersion, clusterSize)
189+
defer func() {
190+
require.NoError(t, epc.Close())
191+
}()
192+
193+
err = e2e.DowngradeUpgradeMembers(t, nil, epc, 3, false, lastClusterVersion, currentVersion)
194+
require.NoError(t, err)
195+
196+
t.Log("Checking all member status after upgrading")
197+
mresp, merr := epc.Etcdctl().MemberList(t.Context(), true)
198+
require.NoError(t, merr)
199+
require.Len(t, mresp.Members, clusterSize)
200+
for _, m := range mresp.Members {
201+
require.Falsef(t, m.IsLearner, "%s should not be learner", m.Name)
202+
}
203+
}
204+
205+
func createNewClusterByPromotingMembers(t *testing.T, clusterVersion e2e.ClusterVersion, clusterSize int) *e2e.EtcdProcessCluster {
206+
require.Truef(t, clusterSize >= 1, "clusterSize >= 1")
207+
208+
var version *semver.Version
209+
var err error
210+
211+
switch clusterVersion {
212+
case e2e.CurrentVersion:
213+
version, err = e2e.GetVersionFromBinary(e2e.BinPath.Etcd)
214+
require.NoErrorf(t, err, "failed to get version from binary")
215+
case e2e.LastVersion:
216+
if !fileutil.Exist(e2e.BinPath.EtcdLastRelease) {
217+
t.Skipf("%q does not exist", e2e.BinPath.EtcdLastRelease)
218+
}
219+
220+
version, err = e2e.GetVersionFromBinary(e2e.BinPath.EtcdLastRelease)
221+
require.NoErrorf(t, err, "failed to get version from last release binary")
222+
default:
223+
t.Fatalf("unexpected cluster version: %v", clusterVersion)
224+
}
225+
226+
t.Logf("Creating new etcd cluster - version: %v, clusterSize: %v", version, clusterSize)
227+
228+
t.Log("Creating first node")
229+
epc, err := e2e.NewEtcdProcessCluster(t.Context(), t,
230+
e2e.WithVersion(clusterVersion),
231+
e2e.WithClusterSize(1),
232+
e2e.WithSnapshotCount(10),
233+
)
234+
require.NoErrorf(t, err, "failed to start first etcd process")
235+
defer func() {
236+
if t.Failed() {
237+
epc.Close()
238+
}
239+
}()
240+
241+
for i := 1; i < clusterSize; i++ {
242+
var nodeID uint64
243+
var aerr error
244+
245+
// NOTE: New promoted member needs time to get connected.
246+
t.Logf("[%d] Adding new node as learner", i)
247+
testutils.ExecuteWithTimeout(t, 1*time.Minute, func() {
248+
for {
249+
nodeID, aerr = epc.StartNewProc(t.Context(), nil, t, true)
250+
if aerr != nil {
251+
if strings.Contains(aerr.Error(), "etcdserver: unhealthy cluster") {
252+
time.Sleep(1 * time.Second)
253+
continue
254+
}
255+
}
256+
break
257+
}
258+
})
259+
require.NoError(t, aerr)
260+
261+
t.Logf("[%d] Promoting node(%d)", i, nodeID)
262+
etcdctl := epc.Procs[0].Etcdctl()
263+
_, err = etcdctl.MemberPromote(t.Context(), nodeID)
264+
require.NoError(t, err)
265+
}
266+
267+
t.Log("Checking all member status")
268+
mresp, merr := epc.Etcdctl().MemberList(t.Context(), true)
269+
require.NoError(t, merr)
270+
require.Len(t, mresp.Members, clusterSize)
271+
for _, m := range mresp.Members {
272+
require.Falsef(t, m.IsLearner, "%s should not be learner", m.Name)
273+
}
274+
275+
t.Logf("Adding 10 key/value to trigger snapshot")
276+
for i := 0; i < 10; i++ {
277+
err = epc.Etcdctl().Put(t.Context(), "foo", "bar", config.PutOptions{})
278+
require.NoError(t, err)
279+
}
280+
return epc
281+
}

0 commit comments

Comments
 (0)