diff --git a/tests/e2e/utl_migrate_test.go b/tests/e2e/utl_migrate_test.go index 8325e4144..08772fbcd 100644 --- a/tests/e2e/utl_migrate_test.go +++ b/tests/e2e/utl_migrate_test.go @@ -17,6 +17,7 @@ package e2e import ( "context" "fmt" + "path/filepath" "strings" "testing" "time" @@ -148,7 +149,8 @@ func TestEtctlutlMigrate(t *testing.T) { } t.Log("etcdutl migrate...") - args := []string{e2e.BinPath.Etcdutl, "migrate", "--data-dir", dataDirPath, "--target-version", tc.targetVersion} + memberDataDir := epc.Procs[0].Config().DataDirPath + args := []string{e2e.BinPath.Etcdutl, "migrate", "--data-dir", memberDataDir, "--target-version", tc.targetVersion} if tc.force { args = append(args, "--force") } @@ -158,7 +160,7 @@ func TestEtctlutlMigrate(t *testing.T) { } t.Log("etcdutl migrate...") - be := backend.NewDefaultBackend(lg, dataDirPath+"/member/snap/db") + be := backend.NewDefaultBackend(lg, filepath.Join(memberDataDir, "member/snap/db")) defer be.Close() ver := schema.ReadStorageVersion(be.ReadTx()) diff --git a/tests/e2e/v2store_deprecation_test.go b/tests/e2e/v2store_deprecation_test.go index ee415cc14..b4c855cb1 100644 --- a/tests/e2e/v2store_deprecation_test.go +++ b/tests/e2e/v2store_deprecation_test.go @@ -32,12 +32,13 @@ import ( "go.uber.org/zap/zaptest" ) -func createV2store(t testing.TB, dataDirPath string) { +func createV2store(t testing.TB, dataDirPath string) string { t.Log("Creating not-yet v2-deprecated etcd") cfg := e2e.ConfigStandalone(e2e.EtcdProcessClusterConfig{Version: e2e.LastVersion, EnableV2: true, DataDirPath: dataDirPath, SnapshotCount: 5}) epc, err := e2e.NewEtcdProcessCluster(context.TODO(), t, cfg) assert.NoError(t, err) + memberDataDir := epc.Procs[0].Config().DataDirPath defer func() { assert.NoError(t, epc.Stop()) @@ -51,6 +52,7 @@ func createV2store(t testing.TB, dataDirPath string) { t.Fatalf("failed put with curl (%v)", err) } } + return memberDataDir } func assertVerifyCannotStartV2deprecationWriteOnly(t testing.TB, dataDirPath string) { @@ -79,16 +81,17 @@ func TestV2DeprecationFlags(t *testing.T) { t.Skipf("%q does not exist", e2e.BinPath.EtcdLastRelease) } + var memberDataDir string t.Run("create-storev2-data", func(t *testing.T) { - createV2store(t, dataDirPath) + memberDataDir = createV2store(t, dataDirPath) }) t.Run("--v2-deprecation=not-yet fails", func(t *testing.T) { - assertVerifyCannotStartV2deprecationNotYet(t, dataDirPath) + assertVerifyCannotStartV2deprecationNotYet(t, memberDataDir) }) t.Run("--v2-deprecation=write-only fails", func(t *testing.T) { - assertVerifyCannotStartV2deprecationWriteOnly(t, dataDirPath) + assertVerifyCannotStartV2deprecationWriteOnly(t, memberDataDir) }) } @@ -105,17 +108,19 @@ func TestV2DeprecationSnapshotMatches(t *testing.T) { } snapshotCount := 10 epc := runEtcdAndCreateSnapshot(t, e2e.LastVersion, lastReleaseData, snapshotCount) + oldMemberDataDir := epc.Procs[0].Config().DataDirPath cc1, err := e2e.NewEtcdctl(epc.Cfg, epc.EndpointsV3()) assert.NoError(t, err) members1 := addAndRemoveKeysAndMembers(ctx, t, cc1, snapshotCount) assert.NoError(t, epc.Close()) epc = runEtcdAndCreateSnapshot(t, e2e.CurrentVersion, currentReleaseData, snapshotCount) + newMemberDataDir := epc.Procs[0].Config().DataDirPath cc2, err := e2e.NewEtcdctl(epc.Cfg, epc.EndpointsV3()) assert.NoError(t, err) members2 := addAndRemoveKeysAndMembers(ctx, t, cc2, snapshotCount) assert.NoError(t, epc.Close()) - assertSnapshotsMatch(t, lastReleaseData, currentReleaseData, func(data []byte) []byte { + assertSnapshotsMatch(t, oldMemberDataDir, newMemberDataDir, func(data []byte) []byte { // Patch cluster version data = bytes.Replace(data, []byte("3.5.0"), []byte("X.X.X"), -1) data = bytes.Replace(data, []byte("3.6.0"), []byte("X.X.X"), -1) diff --git a/tests/framework/e2e/cluster.go b/tests/framework/e2e/cluster.go index be3e98b5c..446a10382 100644 --- a/tests/framework/e2e/cluster.go +++ b/tests/framework/e2e/cluster.go @@ -19,6 +19,7 @@ import ( "fmt" "net/url" "path" + "path/filepath" "regexp" "strings" "testing" @@ -121,8 +122,13 @@ type EtcdProcessCluster struct { } type EtcdProcessClusterConfig struct { - Logger *zap.Logger - Version ClusterVersion + Logger *zap.Logger + Version ClusterVersion + // DataDirPath specifies the data-dir for the members. If test cases + // do not specify `DataDirPath`, then e2e framework creates a + // temporary directory for each member; otherwise, it creates a + // subdirectory (e.g. member-0, member-1 and member-2) under the given + // `DataDirPath` for each member. DataDirPath string KeepDataDir bool EnvVars map[string]string @@ -423,9 +429,17 @@ func (cfg *EtcdProcessClusterConfig) EtcdServerProcessConfig(tb testing.TB, i in purl := url.URL{Scheme: cfg.PeerScheme(), Host: fmt.Sprintf("localhost:%d", port+1)} name := fmt.Sprintf("%s-test-%d", testNameCleanRegex.ReplaceAllString(tb.Name(), ""), i) + dataDirPath := cfg.DataDirPath if cfg.DataDirPath == "" { dataDirPath = tb.TempDir() + } else { + // When test cases specify the DataDirPath and there are more than + // one member in the cluster, we need to create a subdirectory for + // each member to avoid conflict. + // We also create a subdirectory for one-member cluster, because we + // support dynamically adding new member. + dataDirPath = filepath.Join(cfg.DataDirPath, fmt.Sprintf("member-%d", i)) } args := []string{