From 06950e41b43c6772cf6b2ab16e1f451d46c8ff28 Mon Sep 17 00:00:00 2001 From: Gyu-Ho Lee Date: Tue, 17 May 2016 14:40:29 -0700 Subject: [PATCH] e2e: v2 backup test Fix https://github.com/coreos/etcd/issues/5367. --- e2e/ctl_v2_test.go | 53 ++++++++++++++++++++++++++++++++++++++++++++++ e2e/etcd_test.go | 33 ++++++++++++++++++++++------- 2 files changed, 78 insertions(+), 8 deletions(-) diff --git a/e2e/ctl_v2_test.go b/e2e/ctl_v2_test.go index 21ad55e49..d0d84bcd4 100644 --- a/e2e/ctl_v2_test.go +++ b/e2e/ctl_v2_test.go @@ -15,6 +15,8 @@ package e2e import ( + "fmt" + "os" "strings" "testing" "time" @@ -227,6 +229,52 @@ func TestCtlV2RoleList(t *testing.T) { } } +func TestCtlV2Backup(t *testing.T) { // For https://github.com/coreos/etcd/issues/5360 + defer testutil.AfterTest(t) + + var ( + backupDirPrefix = "testbackup" + backupDir = fmt.Sprintf("%s0.etcd", backupDirPrefix) + ) + epc1 := setupEtcdctlTest(t, &configNoTLS, false) + if err := etcdctlSet(epc1, "foo1", "bar"); err != nil { + t.Fatal(err) + } + + if err := etcdctlBackup(epc1, epc1.procs[0].cfg.dataDirPath, backupDir); err != nil { + t.Fatal(err) + } + defer os.RemoveAll(backupDir) + + if err := epc1.Close(); err != nil { + t.Fatalf("error closing etcd processes (%v)", err) + } + + // restart from the backup directory + cfg2 := configNoTLS + cfg2.dataDirPathPrefix = backupDirPrefix + cfg2.keepDataDir = true + cfg2.forceNewCluster = true + epc2 := setupEtcdctlTest(t, &cfg2, false) + + // check if backup went through correctly + if err := etcdctlGet(epc2, "foo1", "bar", false); err != nil { + t.Fatal(err) + } + + // check if it can serve client requests + if err := etcdctlSet(epc2, "foo2", "bar"); err != nil { + t.Fatal(err) + } + if err := etcdctlGet(epc2, "foo2", "bar", false); err != nil { + t.Fatal(err) + } + + if err := epc2.Close(); err != nil { + t.Fatalf("error closing etcd processes (%v)", err) + } +} + func etcdctlPrefixArgs(clus *etcdProcessCluster) []string { endpoints := "" if proxies := clus.proxies(); len(proxies) != 0 { @@ -329,6 +377,11 @@ func etcdctlAuthEnable(clus *etcdProcessCluster) error { return spawnWithExpect(cmdArgs, "Authentication Enabled") } +func etcdctlBackup(clus *etcdProcessCluster, dataDir, backupDir string) error { + cmdArgs := append(etcdctlPrefixArgs(clus), "backup", "--data-dir", dataDir, "--backup-dir", backupDir) + return spawnWithExpect(cmdArgs, "wal: ignored file") +} + func mustEtcdctl(t *testing.T) { if !fileutil.Exist("../bin/etcdctl") { t.Fatalf("could not find etcdctl binary") diff --git a/e2e/etcd_test.go b/e2e/etcd_test.go index f06a603f9..b05e2bc36 100644 --- a/e2e/etcd_test.go +++ b/e2e/etcd_test.go @@ -122,9 +122,12 @@ type etcdProcess struct { } type etcdProcessConfig struct { - args []string + args []string + dataDirPath string - acurl string + keepDataDir bool + + acurl string // additional url for tls connection when the etcd process // serves both http and https acurltls string @@ -132,6 +135,9 @@ type etcdProcessConfig struct { } type etcdProcessClusterConfig struct { + dataDirPathPrefix string + keepDataDir bool + clusterSize int basePort int proxySize int @@ -191,9 +197,13 @@ func newEtcdProcess(cfg *etcdProcessConfig) (*etcdProcess, error) { if !fileutil.Exist("../bin/etcd") { return nil, fmt.Errorf("could not find etcd binary") } - if err := os.RemoveAll(cfg.dataDirPath); err != nil { - return nil, err + + if !cfg.keepDataDir { + if err := os.RemoveAll(cfg.dataDirPath); err != nil { + return nil, err + } } + child, err := spawnCmd(append([]string{"../bin/etcd"}, cfg.args...)) if err != nil { return nil, err @@ -234,9 +244,15 @@ func (cfg *etcdProcessClusterConfig) etcdProcessConfigs() []*etcdProcessConfig { purl := url.URL{Scheme: peerScheme, Host: fmt.Sprintf("localhost:%d", port+1)} name := fmt.Sprintf("testname%d", i) - dataDirPath, derr := ioutil.TempDir("", name+".etcd") - if derr != nil { - panic("could not get tempdir for datadir") + var dataDirPath string + if cfg.dataDirPathPrefix != "" { + dataDirPath = fmt.Sprintf("%s%d.etcd", cfg.dataDirPathPrefix, i) + } else { + var derr error + dataDirPath, derr = ioutil.TempDir("", name+".etcd") + if derr != nil { + panic("could not get tempdir for datadir") + } } initialCluster[i] = fmt.Sprintf("%s=%s", name, purl.String()) @@ -259,10 +275,10 @@ func (cfg *etcdProcessClusterConfig) etcdProcessConfigs() []*etcdProcessConfig { } args = append(args, cfg.tlsArgs()...) - etcdCfgs[i] = &etcdProcessConfig{ args: args, dataDirPath: dataDirPath, + keepDataDir: cfg.keepDataDir, acurl: curl, acurltls: curltls, } @@ -285,6 +301,7 @@ func (cfg *etcdProcessClusterConfig) etcdProcessConfigs() []*etcdProcessConfig { etcdCfgs[cfg.clusterSize+i] = &etcdProcessConfig{ args: args, dataDirPath: dataDirPath, + keepDataDir: cfg.keepDataDir, acurl: curl.String(), isProxy: true, }