feat(discovery): adjust boot order to find peers

The boot order for peers is -discovery, -peers, log data, forming
new cluster itself.

Special rules:
1. If discovery succeeds, it would find peers specified by discover URL
only.
2. Etcd would fail when meeting bad -discovery, no -peers and log data.

Add TestDiscoveryDownNoBackupPeersWithDataDir as the test.
This commit is contained in:
Yicheng Qin
2014-02-13 12:30:52 -08:00
parent bd56b15b6e
commit 3a4df1612c
8 changed files with 170 additions and 71 deletions

View File

@@ -111,6 +111,59 @@ func TestDiscoveryNoWithBackupPeers(t *testing.T) {
})
}
// TestDiscoveryDownNoBackupPeersWithDataDir ensures that etcd runs if it is
// started with a bad discovery URL, no backups and valid data dir.
func TestDiscoveryDownNoBackupPeersWithDataDir(t *testing.T) {
etcdtest.RunServer(func(s *server.Server) {
u, ok := s.PeerHost("ETCDTEST")
if !ok {
t.Fatalf("Couldn't find the URL")
}
// run etcd and connect to ETCDTEST server
proc, err := startServer([]string{"-peers", u})
if err != nil {
t.Fatal(err.Error())
}
// check it runs well
client := http.Client{}
err = assertServerFunctional(client, "http")
if err != nil {
t.Fatal(err.Error())
}
// stop etcd, and leave valid data dir for later usage
stopServer(proc)
g := garbageHandler{t: t}
ts := httptest.NewServer(&g)
defer ts.Close()
discover := ts.URL + "/v2/keys/_etcd/registry/1"
// connect to ETCDTEST server again with previous data dir
proc, err = startServerWithDataDir([]string{"-discovery", discover})
if err != nil {
t.Fatal(err.Error())
}
defer stopServer(proc)
// TODO(yichengq): it needs some time to do leader election
// improve to get rid of it
time.Sleep(1 * time.Second)
client = http.Client{}
err = assertServerFunctional(client, "http")
if err != nil {
t.Fatal(err.Error())
}
if !g.success {
t.Fatal("Discovery server never called")
}
})
}
// TestDiscoveryFirstPeer ensures that etcd starts as the leader if it
// registers as the first peer.
func TestDiscoveryFirstPeer(t *testing.T) {

View File

@@ -167,6 +167,18 @@ func startServer(extra []string) (*os.Process, error) {
return os.StartProcess(EtcdBinPath, cmd, procAttr)
}
func startServerWithDataDir(extra []string) (*os.Process, error) {
procAttr := new(os.ProcAttr)
procAttr.Files = []*os.File{nil, os.Stdout, os.Stderr}
cmd := []string{"etcd", "-data-dir=/tmp/node1", "-name=node1"}
cmd = append(cmd, extra...)
println(strings.Join(cmd, " "))
return os.StartProcess(EtcdBinPath, cmd, procAttr)
}
func stopServer(proc *os.Process) {
err := proc.Kill()
if err != nil {
@@ -194,7 +206,8 @@ func assertServerFunctional(client http.Client, scheme string) error {
}
if err == nil {
if resp.StatusCode != 201 {
// Internal error may mean that servers are in leader election
if resp.StatusCode != http.StatusCreated && resp.StatusCode != http.StatusInternalServerError {
return errors.New(fmt.Sprintf("resp.StatusCode == %s", resp.Status))
} else {
return nil
@@ -202,7 +215,7 @@ func assertServerFunctional(client http.Client, scheme string) error {
}
}
return errors.New("etcd server was not reachable in time")
return errors.New("etcd server was not reachable in time / had internal error")
}
func assertServerNotFunctional(client http.Client, scheme string) error {