mirror of
https://github.com/etcd-io/etcd.git
synced 2024-09-27 06:25:44 +00:00
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:
@@ -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) {
|
||||
|
||||
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user