Merge pull request #5380 from gyuho/backup_e2e_test

e2e: v2 backup test
This commit is contained in:
Gyu-Ho Lee 2016-05-17 15:56:24 -07:00
commit ecf192556e
2 changed files with 78 additions and 8 deletions

View File

@ -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")

View File

@ -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,
}