366 lines
7.7 KiB
Go
366 lines
7.7 KiB
Go
|
package discovery
|
||
|
|
||
|
import (
|
||
|
"context"
|
||
|
"flag"
|
||
|
"fmt"
|
||
|
"os"
|
||
|
"testing"
|
||
|
"time"
|
||
|
|
||
|
"go-common/library/conf/env"
|
||
|
"go-common/library/ecode"
|
||
|
"go-common/library/exp/feature"
|
||
|
"go-common/library/naming"
|
||
|
"go-common/library/net/http/blademaster"
|
||
|
|
||
|
. "github.com/smartystreets/goconvey/convey"
|
||
|
)
|
||
|
|
||
|
var appdID = "main.arch.test66"
|
||
|
var appID2 = "main.arch.test22"
|
||
|
|
||
|
func TestMain(m *testing.M) {
|
||
|
feature.DefaultGate.AddFlag(flag.CommandLine)
|
||
|
flag.Set("feature-gates", fmt.Sprintf("%s=true", _selfDiscoveryFeatrue))
|
||
|
|
||
|
os.Exit(m.Run())
|
||
|
}
|
||
|
|
||
|
var c = &Config{
|
||
|
Nodes: []string{"172.18.33.51:7171"},
|
||
|
Zone: "sh001",
|
||
|
Env: "pre",
|
||
|
Key: "0c4b8fe3ff35a4b6",
|
||
|
Secret: "b370880d1aca7d3a289b9b9a7f4d6812",
|
||
|
Host: "host_1",
|
||
|
}
|
||
|
var indis = &naming.Instance{
|
||
|
AppID: appdID,
|
||
|
Zone: env.Zone,
|
||
|
Addrs: []string{
|
||
|
"grpc://172.18.33.51:8080",
|
||
|
"http://172.18.33.51:7171",
|
||
|
},
|
||
|
Version: "1",
|
||
|
Metadata: map[string]string{
|
||
|
"test": "1",
|
||
|
"weight": "12",
|
||
|
"color": "blue",
|
||
|
},
|
||
|
}
|
||
|
|
||
|
var in = &naming.Instance{
|
||
|
AppID: appdID,
|
||
|
Addrs: []string{
|
||
|
"grpc://127.0.0.1:8080",
|
||
|
},
|
||
|
Version: "1",
|
||
|
Metadata: map[string]string{
|
||
|
"test": "1",
|
||
|
"weight": "12",
|
||
|
"color": "blue",
|
||
|
},
|
||
|
}
|
||
|
|
||
|
var intest2 = &naming.Instance{
|
||
|
AppID: appID2,
|
||
|
Addrs: []string{
|
||
|
"grpc://127.0.0.1:8080",
|
||
|
},
|
||
|
Version: "1",
|
||
|
Metadata: map[string]string{
|
||
|
"test": "1",
|
||
|
"weight": "12",
|
||
|
"color": "blue",
|
||
|
},
|
||
|
}
|
||
|
|
||
|
var in2 = &naming.Instance{
|
||
|
AppID: appdID,
|
||
|
Addrs: []string{
|
||
|
"grpc://127.0.0.1:8081",
|
||
|
},
|
||
|
Version: "1",
|
||
|
Metadata: map[string]string{
|
||
|
"test": "2",
|
||
|
"weight": "6",
|
||
|
"color": "red",
|
||
|
},
|
||
|
}
|
||
|
|
||
|
func TestDiscoverySelf(t *testing.T) {
|
||
|
Convey("test TestDiscoverySelf ", t, func() {
|
||
|
So(feature.DefaultGate.Enabled(_selfDiscoveryFeatrue), ShouldBeTrue)
|
||
|
d := New(c)
|
||
|
So(len(d.node.Load().([]string)), ShouldNotEqual, 0)
|
||
|
})
|
||
|
}
|
||
|
|
||
|
func TestRegister(t *testing.T) {
|
||
|
Convey("test register and cancel", t, func() {
|
||
|
env.Hostname = "host_1"
|
||
|
d := New(c)
|
||
|
defer d.Close()
|
||
|
ctx := context.TODO()
|
||
|
cancel, err := d.Register(ctx, in)
|
||
|
defer cancel()
|
||
|
So(err, ShouldBeNil)
|
||
|
rs := d.Build(appdID)
|
||
|
ch := rs.Watch()
|
||
|
So(ch, ShouldNotBeNil)
|
||
|
<-ch
|
||
|
ins, ok := rs.Fetch(ctx)
|
||
|
So(ok, ShouldBeTrue)
|
||
|
So(err, ShouldBeNil)
|
||
|
var count int
|
||
|
for _, data := range ins {
|
||
|
count += len(data)
|
||
|
}
|
||
|
So(count, ShouldEqual, 1)
|
||
|
c.Host = "host_2"
|
||
|
env.Hostname = "host_2"
|
||
|
|
||
|
d2 := New(c)
|
||
|
defer d2.Close()
|
||
|
cancel2, err := d2.Register(ctx, in2)
|
||
|
So(err, ShouldBeNil)
|
||
|
<-ch
|
||
|
ins, _ = rs.Fetch(ctx)
|
||
|
So(err, ShouldBeNil)
|
||
|
count = 0
|
||
|
for _, data := range ins {
|
||
|
count += len(data)
|
||
|
}
|
||
|
So(count, ShouldEqual, 2)
|
||
|
time.Sleep(time.Millisecond * 500)
|
||
|
cancel2()
|
||
|
<-ch
|
||
|
ins, _ = rs.Fetch(ctx)
|
||
|
So(err, ShouldBeNil)
|
||
|
count = 0
|
||
|
for _, data := range ins {
|
||
|
count += len(data)
|
||
|
}
|
||
|
So(count, ShouldEqual, 1)
|
||
|
Convey("test discovery set", func() {
|
||
|
c.Host = "host_1"
|
||
|
inSet := &naming.Instance{
|
||
|
AppID: appdID,
|
||
|
Addrs: []string{
|
||
|
"grpc://127.0.0.1:8080",
|
||
|
},
|
||
|
Status: 1,
|
||
|
Metadata: map[string]string{
|
||
|
"test": "1",
|
||
|
"weight": "111",
|
||
|
"color": "blue",
|
||
|
},
|
||
|
}
|
||
|
ins, _ = rs.Fetch(context.TODO())
|
||
|
fmt.Println("ins", ins["sh001"][0])
|
||
|
err = d2.Set(inSet)
|
||
|
// So(err, ShouldBeNil)
|
||
|
<-ch
|
||
|
ins, _ = rs.Fetch(context.TODO())
|
||
|
fmt.Println("ins1", ins["sh001"][0])
|
||
|
So(ins["sh001"][0].Metadata["weight"], ShouldResemble, "111")
|
||
|
})
|
||
|
})
|
||
|
}
|
||
|
|
||
|
func TestMultiZone(t *testing.T) {
|
||
|
Convey("test multi zone", t, func() {
|
||
|
env.Hostname = "host_1"
|
||
|
d := New(c)
|
||
|
defer d.Close()
|
||
|
ctx := context.TODO()
|
||
|
cancel, err := d.Register(ctx, in)
|
||
|
So(err, ShouldBeNil)
|
||
|
defer cancel()
|
||
|
rs := d.Build(appdID)
|
||
|
ch := rs.Watch()
|
||
|
So(ch, ShouldNotBeNil)
|
||
|
<-ch
|
||
|
ins, ok := rs.Fetch(ctx)
|
||
|
So(ok, ShouldBeTrue)
|
||
|
count := 0
|
||
|
for _, data := range ins {
|
||
|
count += len(data)
|
||
|
}
|
||
|
So(count, ShouldEqual, 1)
|
||
|
env.Hostname = "host_2"
|
||
|
env.Zone = "other_zone"
|
||
|
d2 := New(c)
|
||
|
defer d2.Close()
|
||
|
cancel2, err := d2.Register(ctx, in2)
|
||
|
So(err, ShouldBeNil)
|
||
|
defer func() {
|
||
|
cancel2()
|
||
|
time.Sleep(time.Millisecond * 300)
|
||
|
}()
|
||
|
<-ch
|
||
|
ins, ok = rs.Fetch(ctx)
|
||
|
So(ok, ShouldBeTrue)
|
||
|
count = 0
|
||
|
zoneCount := 0
|
||
|
for _, data := range ins {
|
||
|
zoneCount++
|
||
|
count += len(data)
|
||
|
}
|
||
|
So(count, ShouldEqual, 2)
|
||
|
So(zoneCount, ShouldEqual, 2)
|
||
|
})
|
||
|
}
|
||
|
|
||
|
func TestDiscoveryFailOver(t *testing.T) {
|
||
|
Convey("test failover", t, func() {
|
||
|
var conf = &Config{
|
||
|
Nodes: []string{"127.0.0.1:8080"},
|
||
|
Zone: "sh001",
|
||
|
Env: "pre",
|
||
|
Key: "0c4b8fe3ff35a4b6",
|
||
|
Secret: "b370880d1aca7d3a289b9b9a7f4d6812",
|
||
|
Host: "host_1",
|
||
|
}
|
||
|
for _, a := range []string{":8080"} {
|
||
|
go func(addr string) {
|
||
|
e := blademaster.DefaultServer(nil)
|
||
|
e.GET("/discovery/nodes", func(ctx *blademaster.Context) {
|
||
|
type v struct {
|
||
|
Addr string `json:"addr"`
|
||
|
}
|
||
|
ctx.JSON([]v{{Addr: "127.0.0.1:8080"}}, nil)
|
||
|
})
|
||
|
e.GET("/discovery/polls", func(ctx *blademaster.Context) {
|
||
|
params := ctx.Request.Form
|
||
|
ts := params.Get("latest_timestamp")
|
||
|
if ts == "0" {
|
||
|
ctx.JSON(map[string]appData{
|
||
|
appdID: {LastTs: time.Now().UnixNano(), ZoneInstances: map[string][]*naming.Instance{"zone": {in}}},
|
||
|
"infra.discovery": {LastTs: time.Now().UnixNano(), ZoneInstances: map[string][]*naming.Instance{conf.Zone: {indis}}},
|
||
|
}, nil)
|
||
|
} else {
|
||
|
ctx.JSON(nil, ecode.ServerErr)
|
||
|
}
|
||
|
})
|
||
|
e.Run(addr)
|
||
|
}(a)
|
||
|
}
|
||
|
time.Sleep(time.Millisecond * 30)
|
||
|
d := New(conf)
|
||
|
defer d.Close()
|
||
|
rs := d.Build(appdID)
|
||
|
ch := rs.Watch()
|
||
|
<-ch
|
||
|
ins, _ := rs.Fetch(context.TODO())
|
||
|
count := 0
|
||
|
zoneCount := 0
|
||
|
for _, data := range ins {
|
||
|
zoneCount++
|
||
|
count += len(data)
|
||
|
}
|
||
|
So(count, ShouldEqual, 1)
|
||
|
So(zoneCount, ShouldEqual, 1)
|
||
|
})
|
||
|
}
|
||
|
|
||
|
func TestWatchContinuosly(t *testing.T) {
|
||
|
Convey("test TestWatchContinuosly ", t, func() {
|
||
|
env.Hostname = "host_1"
|
||
|
d := New(c)
|
||
|
defer d.Close()
|
||
|
in1 := *in
|
||
|
in1.AppID = "test.test"
|
||
|
ctx := context.TODO()
|
||
|
cancel, err := d.Register(ctx, &in1)
|
||
|
So(err, ShouldBeNil)
|
||
|
defer cancel()
|
||
|
in2 := *in
|
||
|
in2.AppID = "test.test2"
|
||
|
cancel2, err := d.Register(ctx, &in2)
|
||
|
So(err, ShouldBeNil)
|
||
|
defer cancel2()
|
||
|
in3 := *in
|
||
|
in3.AppID = "test.test3"
|
||
|
cancel3, err := d.Register(ctx, &in3)
|
||
|
So(err, ShouldBeNil)
|
||
|
defer cancel3()
|
||
|
rs := d.Build("test.test")
|
||
|
ch := rs.Watch()
|
||
|
<-ch
|
||
|
ins, ok := rs.Fetch(ctx)
|
||
|
So(ok, ShouldBeTrue)
|
||
|
count := 0
|
||
|
for _, data := range ins {
|
||
|
count += len(data)
|
||
|
}
|
||
|
So(count, ShouldBeGreaterThanOrEqualTo, 1)
|
||
|
time.Sleep(time.Millisecond * 10)
|
||
|
rs = d.Build("test.test2")
|
||
|
ch2 := rs.Watch()
|
||
|
<-ch2
|
||
|
ins, ok = rs.Fetch(ctx)
|
||
|
So(ok, ShouldBeTrue)
|
||
|
count = 0
|
||
|
for _, data := range ins {
|
||
|
count += len(data)
|
||
|
}
|
||
|
So(count, ShouldBeGreaterThanOrEqualTo, 1)
|
||
|
rs = d.Build("test.test3")
|
||
|
ch3 := rs.Watch()
|
||
|
<-ch3
|
||
|
ins, ok = rs.Fetch(ctx)
|
||
|
So(ok, ShouldBeTrue)
|
||
|
count = 0
|
||
|
for _, data := range ins {
|
||
|
count += len(data)
|
||
|
}
|
||
|
So(count, ShouldBeGreaterThanOrEqualTo, 1)
|
||
|
})
|
||
|
}
|
||
|
|
||
|
func TestSameBuilder(t *testing.T) {
|
||
|
Convey("test multi watch", t, func() {
|
||
|
env.Hostname = "host_1"
|
||
|
d := New(c)
|
||
|
defer d.Close()
|
||
|
ctx := context.TODO()
|
||
|
cancel, err := d.Register(ctx, in)
|
||
|
d.Register(ctx, intest2)
|
||
|
defer cancel()
|
||
|
So(err, ShouldBeNil)
|
||
|
// first builder
|
||
|
rs := d.Build(appdID)
|
||
|
ch := rs.Watch()
|
||
|
So(ch, ShouldNotBeNil)
|
||
|
<-ch
|
||
|
_, ok := rs.Fetch(ctx)
|
||
|
So(ok, ShouldBeTrue)
|
||
|
So(err, ShouldBeNil)
|
||
|
var count int
|
||
|
// for _, data := range ins {
|
||
|
// count += len(data)
|
||
|
// }
|
||
|
// So(count, ShouldEqual, 1)
|
||
|
// same appd builder
|
||
|
rs2 := d.Build(appdID)
|
||
|
ch2 := rs2.Watch()
|
||
|
<-ch2
|
||
|
_, ok = rs2.Fetch(ctx)
|
||
|
So(ok, ShouldBeTrue)
|
||
|
So(err, ShouldBeNil)
|
||
|
rs3 := d.Build(appID2)
|
||
|
ch3 := rs3.Watch()
|
||
|
<-ch3
|
||
|
ins, _ := rs3.Fetch(ctx)
|
||
|
So(ok, ShouldBeTrue)
|
||
|
So(err, ShouldBeNil)
|
||
|
count = 0
|
||
|
for _, data := range ins {
|
||
|
count += len(data)
|
||
|
}
|
||
|
So(count, ShouldEqual, 1)
|
||
|
})
|
||
|
}
|