diff --git a/e2e/ctl_v2_test.go b/e2e/ctl_v2_test.go index f986eb1f311..60d9ce74cea 100644 --- a/e2e/ctl_v2_test.go +++ b/e2e/ctl_v2_test.go @@ -226,7 +226,13 @@ func TestCtlV2RoleList(t *testing.T) { } } -func TestCtlV2Backup(t *testing.T) { // For https://github.com/coreos/etcd/issues/5360 +func TestCtlV2Backup(t *testing.T) { testCtlV2Backup(t, 0, false) } +func TestCtlV2BackupSnapshot(t *testing.T) { testCtlV2Backup(t, 1, false) } + +func TestCtlV2BackupV3(t *testing.T) { testCtlV2Backup(t, 0, true) } +func TestCtlV2BackupV3Snapshot(t *testing.T) { testCtlV2Backup(t, 1, true) } + +func testCtlV2Backup(t *testing.T, snapCount int, v3 bool) { defer testutil.AfterTest(t) backupDir, err := ioutil.TempDir("", "testbackup0.etcd") @@ -235,15 +241,29 @@ func TestCtlV2Backup(t *testing.T) { // For https://github.com/coreos/etcd/issue } defer os.RemoveAll(backupDir) - epc1 := setupEtcdctlTest(t, &configNoTLS, false) - if err := etcdctlSet(epc1, "foo1", "bar"); err != nil { + etcdCfg := configNoTLS + etcdCfg.snapCount = snapCount + epc1 := setupEtcdctlTest(t, &etcdCfg, false) + + // v3 put before v2 set so snapshot happens after v3 operations to confirm + // v3 data is preserved after snapshot. + if err := ctlV3Put(ctlCtx{t: t, epc: epc1}, "v3key", "123", ""); err != nil { t.Fatal(err) } - if err := etcdctlBackup(epc1, epc1.procs[0].Config().dataDirPath, backupDir); err != nil { + if err := etcdctlSet(epc1, "foo1", "bar"); err != nil { t.Fatal(err) } + if v3 { + // v3 must lock the db to backup, so stop process + if err := epc1.Stop(); err != nil { + t.Fatal(err) + } + } + if err := etcdctlBackup(epc1, epc1.procs[0].Config().dataDirPath, backupDir, v3); err != nil { + t.Fatal(err) + } if err := epc1.Close(); err != nil { t.Fatalf("error closing etcd processes (%v)", err) } @@ -260,6 +280,17 @@ func TestCtlV2Backup(t *testing.T) { // For https://github.com/coreos/etcd/issue t.Fatal(err) } + ctx2 := ctlCtx{t: t, epc: epc2} + if v3 { + if err := ctlV3Get(ctx2, []string{"v3key"}, kv{"v3key", "123"}); err != nil { + t.Fatal(err) + } + } else { + if err := ctlV3Get(ctx2, []string{"v3key"}); err != nil { + t.Fatal(err) + } + } + // check if it can serve client requests if err := etcdctlSet(epc2, "foo2", "bar"); err != nil { t.Fatal(err) @@ -451,9 +482,16 @@ func etcdctlAuthEnable(clus *etcdProcessCluster) error { return spawnWithExpect(cmdArgs, "Authentication Enabled") } -func etcdctlBackup(clus *etcdProcessCluster, dataDir, backupDir string) error { +func etcdctlBackup(clus *etcdProcessCluster, dataDir, backupDir string, v3 bool) error { cmdArgs := append(etcdctlPrefixArgs(clus), "backup", "--data-dir", dataDir, "--backup-dir", backupDir) - return spawnWithExpects(cmdArgs) + if v3 { + cmdArgs = append(cmdArgs, "--with-v3") + } + proc, err := spawnCmd(cmdArgs) + if err != nil { + return err + } + return proc.Close() } func mustEtcdctl(t *testing.T) {