Skip to content

Commit f85f42d

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 f85f42d

File tree

1 file changed

+102
-0
lines changed

1 file changed

+102
-0
lines changed

tests/e2e/etcd_release_upgrade_test.go

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

0 commit comments

Comments
 (0)