From 147ce99b0cbefdbd9445fca8c03eca33b4e4127f Mon Sep 17 00:00:00 2001 From: Cabinfever_B Date: Tue, 16 Nov 2021 14:54:03 +0800 Subject: [PATCH] Fix #3816 Signed-off-by: Cabinfever_B --- server/api/store.go | 63 +++++++++++++++++++++++++++++---- server/api/store_test.go | 59 +++++++++++++++++++++++++----- server/api/trend.go | 4 +-- tests/pdctl/helper.go | 3 +- tests/pdctl/store/store_test.go | 6 ++-- 5 files changed, 114 insertions(+), 21 deletions(-) diff --git a/server/api/store.go b/server/api/store.go index b3caca88643..a6d0936c2f2 100644 --- a/server/api/store.go +++ b/server/api/store.go @@ -36,10 +36,62 @@ import ( "github.com/unrolled/render" ) -// MetaStore contains meta information about a store. +// MetaStore contains meta information about a store which needed to show. type MetaStore struct { - *metapb.Store - StateName string `json:"state_name"` + Id uint64 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"` + Address string `protobuf:"bytes,2,opt,name=address,proto3" json:"address,omitempty"` + Labels []*metapb.StoreLabel `protobuf:"bytes,4,rep,name=labels" json:"labels,omitempty"` + Version string `protobuf:"bytes,5,opt,name=version,proto3" json:"version,omitempty"` + PeerAddress string `protobuf:"bytes,6,opt,name=peer_address,json=peerAddress,proto3" json:"peer_address,omitempty"` + StatusAddress string `protobuf:"bytes,7,opt,name=status_address,json=statusAddress,proto3" json:"status_address,omitempty"` + GitHash string `protobuf:"bytes,8,opt,name=git_hash,json=gitHash,proto3" json:"git_hash,omitempty"` + StartTimestamp int64 `protobuf:"varint,9,opt,name=start_timestamp,json=startTimestamp,proto3" json:"start_timestamp,omitempty"` + DeployPath string `protobuf:"bytes,10,opt,name=deploy_path,json=deployPath,proto3" json:"deploy_path,omitempty"` + LastHeartbeat int64 `protobuf:"varint,11,opt,name=last_heartbeat,json=lastHeartbeat,proto3" json:"last_heartbeat,omitempty"` + PhysicallyDestroyed bool `protobuf:"varint,12,opt,name=physically_destroyed,json=physicallyDestroyed,proto3" json:"physically_destroyed,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` + StateName string `json:"state_name"` +} + +func NewMetaStore(store *metapb.Store, StateName string) *MetaStore { + metaStore := &MetaStore{StateName: StateName} + metaStore.Id = store.GetId() + metaStore.Address = store.GetAddress() + metaStore.Labels = store.GetLabels() + metaStore.Version = store.GetVersion() + metaStore.PeerAddress = store.GetPeerAddress() + metaStore.StatusAddress = store.GetStatusAddress() + metaStore.GitHash = store.GetGitHash() + metaStore.StartTimestamp = store.GetStartTimestamp() + metaStore.DeployPath = store.GetDeployPath() + metaStore.LastHeartbeat = store.GetLastHeartbeat() + metaStore.PhysicallyDestroyed = store.GetPhysicallyDestroyed() + metaStore.XXX_NoUnkeyedLiteral = store.XXX_NoUnkeyedLiteral + metaStore.XXX_unrecognized = store.XXX_unrecognized + metaStore.XXX_sizecache = store.XXX_sizecache + return metaStore +} + +func (m *MetaStore) ConvertToMetapbStore() *metapb.Store { + metapbStore := &metapb.Store{ + Id: m.Id, + Address: m.Address, + State: metapb.StoreState(metapb.StoreState_value[m.StateName]), + Labels: m.Labels, + Version: m.Version, + PeerAddress: m.PeerAddress, + StatusAddress: m.StatusAddress, + GitHash: m.GitHash, + StartTimestamp: m.StartTimestamp, + DeployPath: m.DeployPath, + LastHeartbeat: m.LastHeartbeat, + XXX_NoUnkeyedLiteral: m.XXX_NoUnkeyedLiteral, + XXX_unrecognized: m.XXX_unrecognized, + XXX_sizecache: m.XXX_sizecache, + } + return metapbStore } // StoreStatus contains status about a store. @@ -77,10 +129,7 @@ const ( func newStoreInfo(opt *config.ScheduleConfig, store *core.StoreInfo) *StoreInfo { s := &StoreInfo{ - Store: &MetaStore{ - Store: store.GetMeta(), - StateName: store.GetState().String(), - }, + Store: NewMetaStore(store.GetMeta(), store.GetState().String()), Status: &StoreStatus{ Capacity: typeutil.ByteSize(store.GetCapacity()), Available: typeutil.ByteSize(store.GetAvailable()), diff --git a/server/api/store_test.go b/server/api/store_test.go index 8f65e2730f3..e6d943b764d 100644 --- a/server/api/store_test.go +++ b/server/api/store_test.go @@ -24,6 +24,8 @@ import ( "strings" "time" + "github.com/tikv/pd/server/versioninfo" + "github.com/docker/go-units" "github.com/gogo/protobuf/proto" . "github.com/pingcap/check" @@ -112,7 +114,8 @@ func checkStoresInfo(c *C, ss []*StoreInfo, want []*metapb.Store) { } } for _, s := range ss { - obtained := proto.Clone(s.Store.Store).(*metapb.Store) + metapbStore := s.Store.ConvertToMetapbStore() + obtained := proto.Clone(metapbStore).(*metapb.Store) expected := proto.Clone(mapWant[obtained.Id]).(*metapb.Store) // Ignore lastHeartbeat obtained.LastHeartbeat, expected.LastHeartbeat = 0, 0 @@ -164,6 +167,46 @@ func (s *testStoreSuite) TestStoreGet(c *C) { checkStoresInfo(c, []*StoreInfo{info}, s.stores[:1]) } +func (s *testStoreSuite) TestStoreInfoGet(c *C) { + timeStamp := time.Now().Unix() + url := fmt.Sprintf("%s/store/1112", s.urlPrefix) + _, errPut := s.svr.PutStore(context.Background(), &pdpb.PutStoreRequest{ + Header: &pdpb.RequestHeader{ClusterId: s.svr.ClusterID()}, + Store: &metapb.Store{ + Id: 1112, + Address: fmt.Sprintf("tikv%d", 1112), + State: 1, + Labels: nil, + Version: versioninfo.MinSupportedVersion(versioninfo.Version5_0).String(), + StatusAddress: fmt.Sprintf("tikv%d", 1112), + GitHash: "45ce5b9584d618bc777877bea77cb94f61b8410", + StartTimestamp: timeStamp, + DeployPath: "/home/cabinfever/test", + LastHeartbeat: timeStamp, + }, + }) + c.Assert(errPut, IsNil) + + info := new(StoreInfo) + + err := readJSON(testDialClient, url, info) + c.Assert(err, IsNil) + c.Assert(info.Store.StateName, Equals, metapb.StoreState_Offline.String()) + c.Assert(info.Store.Id, Equals, uint64(1112)) + c.Assert(info.Store.Address, Equals, "tikv1112") + c.Assert(info.Store.Version, Equals, versioninfo.MinSupportedVersion(versioninfo.Version5_0).String()) + c.Assert(info.Store.StatusAddress, Equals, fmt.Sprintf("tikv%d", 1112)) + c.Assert(info.Store.GitHash, Equals, "45ce5b9584d618bc777877bea77cb94f61b8410") + c.Assert(info.Store.StartTimestamp, Equals, timeStamp) + c.Assert(info.Store.DeployPath, Equals, "/home/cabinfever/test") + c.Assert(info.Store.LastHeartbeat, Equals, timeStamp) + + resp, _ := testDialClient.Get(url) + b, _ := io.ReadAll(resp.Body) + str := string(b) + c.Assert(strings.Contains(str, "\"state\""), Equals, false) +} + func (s *testStoreSuite) TestStoreLabel(c *C) { url := fmt.Sprintf("%s/store/1", s.urlPrefix) var info StoreInfo @@ -260,7 +303,7 @@ func (s *testStoreSuite) TestStoreDelete(c *C) { err := readJSON(testDialClient, url, store) c.Assert(err, IsNil) c.Assert(store.Store.PhysicallyDestroyed, IsFalse) - c.Assert(store.Store.State, Equals, metapb.StoreState_Offline) + c.Assert(store.Store.StateName, Equals, metapb.StoreState_Offline.String()) // up store success because it is offline but not physically destroyed status := requestStatusBody(c, testDialClient, http.MethodPost, fmt.Sprintf("%s/state?state=Up", url)) @@ -271,7 +314,7 @@ func (s *testStoreSuite) TestStoreDelete(c *C) { store = new(StoreInfo) err = readJSON(testDialClient, url, store) c.Assert(err, IsNil) - c.Assert(store.Store.State, Equals, metapb.StoreState_Up) + c.Assert(store.Store.StateName, Equals, metapb.StoreState_Up.String()) c.Assert(store.Store.PhysicallyDestroyed, IsFalse) // offline store with physically destroyed @@ -279,7 +322,7 @@ func (s *testStoreSuite) TestStoreDelete(c *C) { c.Assert(status, Equals, http.StatusOK) err = readJSON(testDialClient, url, store) c.Assert(err, IsNil) - c.Assert(store.Store.State, Equals, metapb.StoreState_Offline) + c.Assert(store.Store.StateName, Equals, metapb.StoreState_Offline.String()) c.Assert(store.Store.PhysicallyDestroyed, IsTrue) // try to up store again failed because it is physically destroyed @@ -295,7 +338,7 @@ func (s *testStoreSuite) TestStoreSetState(c *C) { info := StoreInfo{} err := readJSON(testDialClient, url, &info) c.Assert(err, IsNil) - c.Assert(info.Store.State, Equals, metapb.StoreState_Up) + c.Assert(info.Store.StateName, Equals, metapb.StoreState_Up.String()) // Set to Offline. info = StoreInfo{} @@ -303,7 +346,7 @@ func (s *testStoreSuite) TestStoreSetState(c *C) { c.Assert(err, IsNil) err = readJSON(testDialClient, url, &info) c.Assert(err, IsNil) - c.Assert(info.Store.State, Equals, metapb.StoreState_Offline) + c.Assert(info.Store.StateName, Equals, metapb.StoreState_Offline.String()) // store not found info = StoreInfo{} @@ -318,7 +361,7 @@ func (s *testStoreSuite) TestStoreSetState(c *C) { c.Assert(err, NotNil) err = readJSON(testDialClient, url, &info) c.Assert(err, IsNil) - c.Assert(info.Store.State, Equals, metapb.StoreState_Offline) + c.Assert(info.Store.StateName, Equals, metapb.StoreState_Offline.String()) } // Set back to Up. @@ -327,7 +370,7 @@ func (s *testStoreSuite) TestStoreSetState(c *C) { c.Assert(err, IsNil) err = readJSON(testDialClient, url, &info) c.Assert(err, IsNil) - c.Assert(info.Store.State, Equals, metapb.StoreState_Up) + c.Assert(info.Store.StateName, Equals, metapb.StoreState_Up.String()) } func (s *testStoreSuite) TestUrlStoreFilter(c *C) { diff --git a/server/api/trend.go b/server/api/trend.go index 542d2d9e966..4441ca1e7a1 100644 --- a/server/api/trend.go +++ b/server/api/trend.go @@ -130,8 +130,8 @@ func (h *trendHandler) getTrendStores() ([]trendStore, error) { for _, store := range stores { info := newStoreInfo(h.svr.GetScheduleConfig(), store) s := trendStore{ - ID: info.Store.GetId(), - Address: info.Store.GetAddress(), + ID: info.Store.Id, + Address: info.Store.Address, StateName: info.Store.StateName, Capacity: uint64(info.Status.Capacity), Available: uint64(info.Status.Available), diff --git a/tests/pdctl/helper.go b/tests/pdctl/helper.go index 2ff469dcd91..17dea907b18 100644 --- a/tests/pdctl/helper.go +++ b/tests/pdctl/helper.go @@ -51,7 +51,8 @@ func CheckStoresInfo(c *check.C, stores []*api.StoreInfo, want []*metapb.Store) } } for _, s := range stores { - obtained := proto.Clone(s.Store.Store).(*metapb.Store) + metapbStore := s.Store.ConvertToMetapbStore() + obtained := proto.Clone(metapbStore).(*metapb.Store) expected := proto.Clone(mapWant[obtained.Id]).(*metapb.Store) // Ignore lastHeartbeat obtained.LastHeartbeat, expected.LastHeartbeat = 0, 0 diff --git a/tests/pdctl/store/store_test.go b/tests/pdctl/store/store_test.go index 271781ed82d..8a4316b86c4 100644 --- a/tests/pdctl/store/store_test.go +++ b/tests/pdctl/store/store_test.go @@ -248,7 +248,7 @@ func (s *storeTestSuite) TestStore(c *C) { c.Assert(ok, IsFalse) // store delete command - c.Assert(storeInfo.Store.State, Equals, metapb.StoreState_Up) + c.Assert(storeInfo.Store.StateName, Equals, metapb.StoreState_Up.String()) args = []string{"-u", pdAddr, "store", "delete", "1"} _, err = pdctl.ExecuteCommand(cmd, args...) c.Assert(err, IsNil) @@ -256,7 +256,7 @@ func (s *storeTestSuite) TestStore(c *C) { output, err = pdctl.ExecuteCommand(cmd, args...) c.Assert(err, IsNil) c.Assert(json.Unmarshal(output, &storeInfo), IsNil) - c.Assert(storeInfo.Store.State, Equals, metapb.StoreState_Offline) + c.Assert(storeInfo.Store.StateName, Equals, metapb.StoreState_Offline.String()) // store check status args = []string{"-u", pdAddr, "store", "check", "Offline"} @@ -285,7 +285,7 @@ func (s *storeTestSuite) TestStore(c *C) { output, err = pdctl.ExecuteCommand(cmd, args...) c.Assert(err, IsNil) c.Assert(json.Unmarshal(output, &storeInfo), IsNil) - c.Assert(storeInfo.Store.State, Equals, metapb.StoreState_Offline) + c.Assert(storeInfo.Store.StateName, Equals, metapb.StoreState_Offline.String()) // store remove-tombstone args = []string{"-u", pdAddr, "store", "remove-tombstone"}