You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
178 lines
4.6 KiB
178 lines
4.6 KiB
package shell
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"fmt"
|
|
"github.com/chrislusf/seaweedfs/weed/pb/master_pb"
|
|
"github.com/chrislusf/seaweedfs/weed/sequence"
|
|
"github.com/chrislusf/seaweedfs/weed/storage"
|
|
"github.com/chrislusf/seaweedfs/weed/storage/needle"
|
|
"github.com/chrislusf/seaweedfs/weed/topology"
|
|
"github.com/chrislusf/seaweedfs/weed/wdclient"
|
|
"google.golang.org/grpc"
|
|
"strconv"
|
|
"strings"
|
|
"testing"
|
|
)
|
|
|
|
var topologyLayout = `
|
|
{
|
|
"dc1":{
|
|
"rack1":{
|
|
"server111":{
|
|
"volumes":[
|
|
{"id":1, "size":12312},
|
|
{"id":2, "size":12312},
|
|
{"id":3, "size":12312}
|
|
],
|
|
"limit":3
|
|
},
|
|
"server112":{
|
|
"volumes":[
|
|
{"id":4, "size":12312},
|
|
{"id":5, "size":12312},
|
|
{"id":6, "size":12312}
|
|
],
|
|
"limit":10
|
|
}
|
|
},
|
|
"rack2":{
|
|
"server121":{
|
|
"volumes":[
|
|
{"id":4, "size":12312},
|
|
{"id":5, "size":12312},
|
|
{"id":6, "size":12312}
|
|
],
|
|
"limit":4
|
|
},
|
|
"server122":{
|
|
"volumes":[],
|
|
"limit":4
|
|
},
|
|
"server123":{
|
|
"volumes":[
|
|
{"id":2, "size":12312},
|
|
{"id":3, "size":12311},
|
|
{"id":4, "size":12312}
|
|
],
|
|
"limit":5
|
|
}
|
|
}
|
|
},
|
|
"dc3":{
|
|
}
|
|
}
|
|
`
|
|
|
|
func setup(topologyLayout string) *topology.Topology {
|
|
var data interface{}
|
|
err := json.Unmarshal([]byte(topologyLayout), &data)
|
|
if err != nil {
|
|
fmt.Println("error:", err)
|
|
}
|
|
fmt.Println("data:", data)
|
|
|
|
//need to connect all nodes first before server adding volumes
|
|
var portT int
|
|
topo := topology.NewTopology("weedfs", sequence.NewMemorySequencer(), 32*1024, 5)
|
|
mTopology := data.(map[string]interface{})
|
|
for dcKey, dcValue := range mTopology {
|
|
dc := topology.NewDataCenter(dcKey)
|
|
dcMap := dcValue.(map[string]interface{})
|
|
topo.LinkChildNode(dc)
|
|
for rackKey, rackValue := range dcMap {
|
|
rack := topology.NewRack(rackKey)
|
|
rackMap := rackValue.(map[string]interface{})
|
|
dc.LinkChildNode(rack)
|
|
for serverKey, serverValue := range rackMap {
|
|
server := topology.NewDataNode(serverKey)
|
|
server.Ip = "localhost"
|
|
portT += 2
|
|
server.Port = portT
|
|
server.PublicUrl = server.Ip + ":" + strconv.FormatUint(uint64(server.Port), 10)
|
|
serverMap := serverValue.(map[string]interface{})
|
|
rack.LinkChildNode(server)
|
|
for _, v := range serverMap["volumes"].([]interface{}) {
|
|
m := v.(map[string]interface{})
|
|
vi := storage.VolumeInfo{
|
|
Id: needle.VolumeId(int64(m["id"].(float64))),
|
|
Size: uint64(m["size"].(float64)),
|
|
Version: needle.CurrentVersion,
|
|
ReplicaPlacement: &storage.ReplicaPlacement{1, 0, 0},
|
|
Ttl: needle.EMPTY_TTL,
|
|
Collection: "",
|
|
}
|
|
server.AddOrUpdateVolume(vi)
|
|
}
|
|
server.UpAdjustMaxVolumeCountDelta(int64(serverMap["limit"].(float64)))
|
|
}
|
|
}
|
|
}
|
|
|
|
return topo
|
|
}
|
|
|
|
func TestGetVolumeList(t *testing.T) {
|
|
topo := setup(topologyLayout)
|
|
topoInfo := topo.ToTopologyInfo()
|
|
if nil == topoInfo {
|
|
t.Errorf("failed.")
|
|
}
|
|
}
|
|
|
|
func TestReplicationHealthChecker_GetErrorReplications(t *testing.T) {
|
|
topo := setup(topologyLayout)
|
|
topoInfo := topo.ToTopologyInfo()
|
|
if nil == topoInfo {
|
|
t.Errorf("failed.")
|
|
}
|
|
|
|
checker := NewReplicationHealthChecker(context.Background(), grpc.EmptyDialOption{})
|
|
errVids, err := checker.Check(topoInfo)
|
|
if err != nil {
|
|
t.Error(err)
|
|
return
|
|
} else {
|
|
fmt.Printf("error vids : %v\n", errVids)
|
|
}
|
|
}
|
|
|
|
// this UT need mock or real seaweedfs service
|
|
func TestReplicationHealthChecker_GetErrorReplications2(t *testing.T) {
|
|
masters := "localhost:9633,localhost:9733,localhost:9833"
|
|
ctx := context.Background()
|
|
masterClient := wdclient.NewMasterClient(ctx, grpc.WithInsecure(), "shell", strings.Split(masters, ","))
|
|
go masterClient.KeepConnectedToMaster()
|
|
masterClient.WaitUntilConnected()
|
|
|
|
var resp *master_pb.VolumeListResponse
|
|
if err := masterClient.WithClient(ctx, func(client master_pb.SeaweedClient) error {
|
|
var err error
|
|
resp, err = client.VolumeList(ctx, &master_pb.VolumeListRequest{})
|
|
return err
|
|
}); err != nil {
|
|
t.Error(err)
|
|
}
|
|
|
|
//respBytes, err := json.Marshal(resp)
|
|
//if err != nil {
|
|
// t.Error(err)
|
|
//}
|
|
//t.Log(string(respBytes[:]))
|
|
|
|
checker := NewReplicationHealthChecker(ctx, grpc.WithInsecure())
|
|
errVids, err := checker.Check(resp.TopologyInfo)
|
|
if err != nil {
|
|
t.Error(err)
|
|
return
|
|
}
|
|
fmt.Printf("error vids : %v\n", errVids)
|
|
|
|
repair := NewReplicationHealthRepair(ctx, grpc.WithInsecure())
|
|
success, failed, err := repair.Repair(resp.TopologyInfo, errVids)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
fmt.Printf("success:%v, failed:%v", success, failed)
|
|
}
|