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

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)
}