mirror of
https://github.com/etcd-io/etcd.git
synced 2024-09-27 06:25:44 +00:00
etcdserver: add cluster id check for hashKVHandler
Signed-off-by: caojiamingalan <alan.c.19971111@gmail.com> Signed-off-by: Marek Siarkowicz <siarkowicz@google.com>
This commit is contained in:
committed by
Marek Siarkowicz
parent
7ed8970e2d
commit
04cfb4c660
@@ -181,6 +181,17 @@ type etcdProcessClusterConfig struct {
|
||||
// newEtcdProcessCluster launches a new cluster from etcd processes, returning
|
||||
// a new etcdProcessCluster once all nodes are ready to accept client requests.
|
||||
func newEtcdProcessCluster(t testing.TB, cfg *etcdProcessClusterConfig) (*etcdProcessCluster, error) {
|
||||
epc, err := initEtcdProcessCluster(t, cfg)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return startEtcdProcessCluster(epc, cfg)
|
||||
}
|
||||
|
||||
// initEtcdProcessCluster initializes a new cluster based on the given config.
|
||||
// It doesn't start the cluster.
|
||||
func initEtcdProcessCluster(t testing.TB, cfg *etcdProcessClusterConfig) (*etcdProcessCluster, error) {
|
||||
skipInShortMode(t)
|
||||
|
||||
etcdCfgs := cfg.etcdServerProcessConfigs(t)
|
||||
@@ -199,7 +210,11 @@ func newEtcdProcessCluster(t testing.TB, cfg *etcdProcessClusterConfig) (*etcdPr
|
||||
}
|
||||
epc.procs[i] = proc
|
||||
}
|
||||
return epc, nil
|
||||
}
|
||||
|
||||
// startEtcdProcessCluster launches a new cluster from etcd processes.
|
||||
func startEtcdProcessCluster(epc *etcdProcessCluster, cfg *etcdProcessClusterConfig) (*etcdProcessCluster, error) {
|
||||
if cfg.rollingStart {
|
||||
if err := epc.RollingStart(); err != nil {
|
||||
return nil, fmt.Errorf("Cannot rolling-start: %v", err)
|
||||
|
||||
@@ -96,6 +96,91 @@ func corruptTest(cx ctlCtx) {
|
||||
waitReadyExpectProc(proc, []string{fmt.Sprintf("etcdmain: %016x found data inconsistency with peers", id0)})
|
||||
}
|
||||
|
||||
func TestInPlaceRecovery(t *testing.T) {
|
||||
basePort := 20000
|
||||
BeforeTest(t)
|
||||
|
||||
// Initialize the cluster.
|
||||
epcOld, err := newEtcdProcessCluster(t,
|
||||
&etcdProcessClusterConfig{
|
||||
clusterSize: 3,
|
||||
initialToken: "old",
|
||||
keepDataDir: false,
|
||||
CorruptCheckTime: time.Second,
|
||||
basePort: basePort,
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
t.Fatalf("could not start etcd process cluster (%v)", err)
|
||||
}
|
||||
t.Cleanup(func() {
|
||||
if errC := epcOld.Close(); errC != nil {
|
||||
t.Fatalf("error closing etcd processes (%v)", errC)
|
||||
}
|
||||
})
|
||||
t.Log("old cluster started.")
|
||||
|
||||
//Put some data into the old cluster, so that after recovering from a blank db, the hash diverges.
|
||||
t.Log("putting 10 keys...")
|
||||
|
||||
oldCc := NewEtcdctl(epcOld.EndpointsV3(), clientNonTLS, false, false)
|
||||
for i := 0; i < 10; i++ {
|
||||
err := oldCc.Put(testutil.PickKey(int64(i)), fmt.Sprint(i))
|
||||
assert.NoError(t, err, "error on put")
|
||||
}
|
||||
|
||||
// Create a new cluster config, but with the same port numbers. In this way the new servers can stay in
|
||||
// contact with the old ones.
|
||||
epcNewConfig := &etcdProcessClusterConfig{
|
||||
clusterSize: 3,
|
||||
initialToken: "new",
|
||||
keepDataDir: false,
|
||||
CorruptCheckTime: time.Second,
|
||||
basePort: basePort,
|
||||
initialCorruptCheck: true,
|
||||
}
|
||||
epcNew, err := initEtcdProcessCluster(t, epcNewConfig)
|
||||
if err != nil {
|
||||
t.Fatalf("could not init etcd process cluster (%v)", err)
|
||||
}
|
||||
t.Cleanup(func() {
|
||||
if errC := epcNew.Close(); errC != nil {
|
||||
t.Fatalf("error closing etcd processes (%v)", errC)
|
||||
}
|
||||
})
|
||||
|
||||
newCc := NewEtcdctl(epcNew.EndpointsV3(), clientNonTLS, false, false)
|
||||
assert.NoError(t, err)
|
||||
|
||||
// Rolling recovery of the servers.
|
||||
t.Log("rolling updating servers in place...")
|
||||
for i, newProc := range epcNew.procs {
|
||||
oldProc := epcOld.procs[i]
|
||||
err = oldProc.Close()
|
||||
if err != nil {
|
||||
t.Fatalf("could not stop etcd process (%v)", err)
|
||||
}
|
||||
t.Logf("old cluster server %d: %s stopped.", i, oldProc.Config().name)
|
||||
err = newProc.Start()
|
||||
if err != nil {
|
||||
t.Fatalf("could not start etcd process (%v)", err)
|
||||
}
|
||||
t.Logf("new cluster server %d: %s started in-place with blank db.", i, newProc.Config().name)
|
||||
t.Log("sleeping 5 sec to let nodes do periodical check...")
|
||||
time.Sleep(5 * time.Second)
|
||||
}
|
||||
t.Log("new cluster started.")
|
||||
|
||||
alarmResponse, err := newCc.AlarmList()
|
||||
assert.NoError(t, err, "error on alarm list")
|
||||
for _, alarm := range alarmResponse.Alarms {
|
||||
if alarm.Alarm == etcdserverpb.AlarmType_CORRUPT {
|
||||
t.Fatalf("there is no corruption after in-place recovery, but corruption reported.")
|
||||
}
|
||||
}
|
||||
t.Log("no corruption detected.")
|
||||
}
|
||||
|
||||
func TestPeriodicCheckDetectsCorruption(t *testing.T) {
|
||||
checkTime := time.Second
|
||||
BeforeTest(t)
|
||||
|
||||
@@ -52,13 +52,14 @@ func TestCompactionHash(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
testutil.TestCompactionHash(context.Background(), t, hashTestCase{cc, clus.Members[0].GRPCURL(), client}, 1000)
|
||||
testutil.TestCompactionHash(context.Background(), t, hashTestCase{cc, clus.Members[0].GRPCURL(), client, clus.Members[0].s}, 1000)
|
||||
}
|
||||
|
||||
type hashTestCase struct {
|
||||
*clientv3.Client
|
||||
url string
|
||||
http *http.Client
|
||||
url string
|
||||
http *http.Client
|
||||
server *etcdserver.EtcdServer
|
||||
}
|
||||
|
||||
func (tc hashTestCase) Put(ctx context.Context, key, value string) error {
|
||||
@@ -72,7 +73,7 @@ func (tc hashTestCase) Delete(ctx context.Context, key string) error {
|
||||
}
|
||||
|
||||
func (tc hashTestCase) HashByRev(ctx context.Context, rev int64) (testutil.KeyValueHash, error) {
|
||||
resp, err := etcdserver.HashByRev(ctx, tc.http, "http://unix", rev)
|
||||
resp, err := etcdserver.HashByRev(ctx, tc.server.Cluster().ID(), tc.http, "http://unix", rev)
|
||||
return testutil.KeyValueHash{Hash: resp.Hash, CompactRevision: resp.CompactRevision, Revision: resp.Header.Revision}, err
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user