Skip to content

Commit 9276aeb

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 9276aeb

File tree

1 file changed

+103
-0
lines changed

1 file changed

+103
-0
lines changed

tests/e2e/etcd_release_upgrade_test.go

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

0 commit comments

Comments
 (0)