123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454 |
- package dao
- import (
- "context"
- "encoding/json"
- "fmt"
- "sync"
- "testing"
- "time"
- "go-common/app/infra/discovery/model"
- "go-common/library/ecode"
- . "github.com/smartystreets/goconvey/convey"
- )
- var reg = &model.ArgRegister{Appid: "main.arch.test", Hostname: "reg", RPC: "127.0.0.1:8080", Region: "shsb", Zone: "sh0001", Env: "pre", Status: 1}
- var regH1 = &model.ArgRegister{Appid: "main.arch.test", Hostname: "regH1", RPC: "127.0.0.1:8080", Region: "shsb", Zone: "sh0001", Env: "pre", Status: 1}
- var reg2 = &model.ArgRegister{Appid: "main.arch.test2", Hostname: "reg2", RPC: "127.0.0.1:8080", Region: "shsb", Zone: "sh0001", Env: "pre", Status: 1}
- var arg = &model.ArgRenew{Region: "shsb", Zone: "sh0001", Env: "pre", Appid: "main.arch.test", Hostname: "reg"}
- var cancel = &model.ArgCancel{Region: "shsb", Zone: "sh0001", Env: "pre", Appid: "main.arch.test", Hostname: "reg"}
- var cancel2 = &model.ArgCancel{Region: "shsb", Zone: "sh0001", Env: "pre", Appid: "main.arch.test", Hostname: "regH1"}
- func TestReigster(t *testing.T) {
- i := model.NewInstance(reg)
- register(t, i)
- }
- func TestDiscovery(t *testing.T) {
- i1 := model.NewInstance(reg)
- i2 := model.NewInstance(regH1)
- fmt.Println(_evictThreshold)
- r := register(t, i1, i2)
- Convey("test discovery", t, func() {
- pollArg := &model.ArgPolls{Region: "shsb", Zone: "sh0001", Env: "pre", Appid: []string{"main.arch.test"}, Hostname: "test"}
- fetchArg := &model.ArgFetch{Region: "shsb", Zone: "sh0001", Env: "pre", Appid: "main.arch.test", Status: 3}
- info, err := r.Fetch(fetchArg.Zone, fetchArg.Env, fetchArg.Appid, 0, fetchArg.Status)
- So(err, ShouldBeNil)
- So(len(info.Instances), ShouldEqual, 2)
- ch, _, err := r.Polls(pollArg)
- So(err, ShouldBeNil)
- apps := <-ch
- So(len(apps["main.arch.test"].Instances), ShouldEqual, 2)
- pollArg.LatestTimestamp[0] = apps["main.arch.test"].LatestTimestamp
- fmt.Println(apps["main.arch.test"])
- r.Cancel(cancel)
- ch, _, err = r.Polls(pollArg)
- So(err, ShouldBeNil)
- apps = <-ch
- So(len(apps["main.arch.test"].Instances), ShouldEqual, 1)
- pollArg.LatestTimestamp[0] = apps["main.arch.test"].LatestTimestamp
- r.Cancel(cancel2)
- })
- }
- func TestRenew(t *testing.T) {
- src := model.NewInstance(reg)
- r := register(t, src)
- Convey("test renew", t, func() {
- i, ok := r.Renew(arg)
- So(ok, ShouldBeTrue)
- So(i, ShouldResemble, src)
- })
- }
- func BenchmarkRenew(b *testing.B) {
- var (
- i *model.Instance
- ok bool
- )
- b.RunParallel(func(pb *testing.PB) {
- for pb.Next() {
- r, src := benchRegister(b)
- if i, ok = r.Renew(arg); !ok {
- b.Errorf("Renew(%v)", src.Appid)
- }
- benchCompareInstance(b, src, i)
- }
- })
- }
- func TestCancel(t *testing.T) {
- src := model.NewInstance(reg)
- r := register(t, src)
- Convey("test cancel", t, func() {
- i, ok := r.Cancel(cancel)
- So(ok, ShouldBeTrue)
- So(i, ShouldResemble, src)
- fetchArg := &model.ArgFetch{Region: "shsb", Zone: "sh0001", Env: "pre", Appid: "main.arch.test", Status: 3}
- _, err := r.Fetch(fetchArg.Zone, fetchArg.Env, fetchArg.Appid, 0, fetchArg.Status)
- So(err, ShouldResemble, ecode.NothingFound)
- })
- }
- func BenchmarkCancel(b *testing.B) {
- var (
- i *model.Instance
- ok bool
- err error
- )
- b.RunParallel(func(pb *testing.PB) {
- for pb.Next() {
- r, src := benchRegister(b)
- if i, ok = r.Cancel(cancel); !ok {
- b.Errorf("Cancel(%v) error", src.Appid)
- }
- benchCompareInstance(b, src, i)
- fetchArg := &model.ArgFetch{Region: "shsb", Zone: "sh0001", Env: "pre", Appid: "main.arch.test", Status: 3}
- if _, err = r.Fetch(fetchArg.Zone, fetchArg.Env, fetchArg.Appid, 0, fetchArg.Status); err != ecode.NothingFound {
- b.Errorf("Fetch(%v) error(%v)", src.Appid, err)
- }
- }
- })
- }
- func TestFetchAll(t *testing.T) {
- i := model.NewInstance(reg)
- r := register(t, i)
- Convey("test fetch all", t, func() {
- am := r.FetchAll()
- So(len(am), ShouldResemble, 1)
- })
- }
- func BenchmarkFetchAll(b *testing.B) {
- b.RunParallel(func(pb *testing.PB) {
- for pb.Next() {
- r, _ := benchRegister(b)
- if am := r.FetchAll(); len(am) != 1 {
- b.Errorf("FetchAll() error")
- }
- }
- })
- }
- func TestFetch(t *testing.T) {
- i := model.NewInstance(reg)
- r := register(t, i)
- Convey("test fetch", t, func() {
- fetchArg2 := &model.ArgFetch{Region: "shsb", Zone: "sh0001", Env: "pre", Appid: "main.arch.test", Status: 1}
- c, err := r.Fetch(fetchArg2.Zone, fetchArg2.Env, fetchArg2.Appid, 0, fetchArg2.Status)
- So(err, ShouldBeNil)
- So(len(c.Instances), ShouldResemble, 1)
- })
- }
- func BenchmarkFetch(b *testing.B) {
- var (
- err error
- c *model.InstanceInfo
- )
- b.RunParallel(func(pb *testing.PB) {
- for pb.Next() {
- r, _ := benchRegister(b)
- fetchArg := &model.ArgFetch{Region: "shsb", Zone: "sh0001", Env: "pre", Appid: "main.arch.test", Status: 1}
- if c, err = r.Fetch(fetchArg.Zone, fetchArg.Env, fetchArg.Appid, 0, fetchArg.Status); err != nil {
- b.Errorf("Fetch(%v) error(%v)", arg.Appid, err)
- }
- fetchArg2 := &model.ArgFetch{Region: "shsb", Zone: "sh0001", Env: "pre", Appid: "main.arch.test", Status: 2}
- if c, err = r.Fetch(fetchArg2.Zone, fetchArg2.Env, fetchArg2.Appid, 0, fetchArg2.Status); err != nil {
- b.Errorf("Fetch(%v) error(%v)", arg.Appid, err)
- }
- _ = c
- }
- })
- }
- func TestPoll(t *testing.T) {
- i := model.NewInstance(reg)
- r := register(t, i)
- Convey("test poll", t, func() {
- pollArg := &model.ArgPolls{Region: "shsb", Zone: "sh0001", Env: "pre", Appid: []string{"main.arch.test"}, Hostname: "csq"}
- ch, _, err := r.Polls(pollArg)
- So(err, ShouldBeNil)
- c := <-ch
- So(len(c[pollArg.Appid[0]].Instances), ShouldEqual, 1)
- })
- }
- func TestPolls(t *testing.T) {
- i1 := model.NewInstance(reg)
- i2 := model.NewInstance(reg2)
- r := register(t, i1, i2)
- Convey("test polls", t, func() {
- pollArg := &model.ArgPolls{Region: "shsb", Zone: "sh0001", Env: "pre", LatestTimestamp: []int64{0, 0}, Appid: []string{"main.arch.test", "main.arch.test2"}, Hostname: "csq"}
- ch, new, err := r.Polls(pollArg)
- So(err, ShouldBeNil)
- So(new, ShouldBeTrue)
- c := <-ch
- So(len(c), ShouldResemble, 2)
- })
- }
- func TestPollsParallel(t *testing.T) {
- i1 := model.NewInstance(reg)
- i2 := model.NewInstance(reg2)
- r := register(t, i1, i2)
- Convey("test polls parallel", t, func(c C) {
- var (
- wg sync.WaitGroup
- ch1, ch2 chan map[string]*model.InstanceInfo
- new bool
- err error
- )
- pollArg := &model.ArgPolls{Region: "shsb", Zone: "sh0001", Env: "pre", LatestTimestamp: []int64{time.Now().UnixNano(), time.Now().UnixNano()}, Appid: []string{"main.arch.test", "main.arch.test2"}, Hostname: "csq"}
- ch1, new, err = r.Polls(pollArg)
- c.So(err, ShouldEqual, ecode.NotModified)
- c.So(new, ShouldBeFalse)
- c.So(ch1, ShouldNotBeNil)
- ch2, new, err = r.Polls(pollArg)
- c.So(err, ShouldEqual, ecode.NotModified)
- c.So(new, ShouldBeFalse)
- c.So(ch2, ShouldNotBeNil)
- // wait group
- wg.Add(2)
- go func() {
- res := <-ch1
- c.So(len(res), ShouldResemble, 1)
- ress, _ := json.Marshal(res)
- fmt.Println("chenggongle 1!!!", string(ress))
- wg.Done()
- }()
- go func() {
- res := <-ch2
- c.So(len(res), ShouldResemble, 1)
- ress, _ := json.Marshal(res)
- fmt.Println("chenggongle 2!!!", string(ress))
- wg.Done()
- }()
- // re register when 1s later, make sure latest_timestamp changed
- time.Sleep(time.Second)
- h1 := model.NewInstance(regH1)
- r.Register(h1, 0)
- // wait
- wg.Wait()
- })
- }
- func BenchmarkPoll(b *testing.B) {
- b.RunParallel(func(pb *testing.PB) {
- for pb.Next() {
- var (
- err error
- ch chan map[string]*model.InstanceInfo
- c map[string]*model.InstanceInfo
- )
- r, _ := benchRegister(b)
- pollArg := &model.ArgPolls{Region: "shsb", Zone: "sh0001", Env: "pre", Appid: []string{"main.arch.test"}, Hostname: "csq"}
- if ch, _, err = r.Polls(pollArg); err != nil {
- b.Errorf("Poll(%v) error(%v)", arg.Appid, err)
- }
- if c = <-ch; len(c[pollArg.Appid[0]].Instances) != 1 {
- b.Errorf("Poll(%v) lenth error", arg.Appid)
- }
- }
- })
- }
- func TestBroadcast(t *testing.T) {
- i := model.NewInstance(reg)
- r := register(t, i)
- Convey("test poll push connection", t, func() {
- go func() {
- Convey("must poll ahead of time", t, func() {
- time.Sleep(time.Microsecond * 5)
- var arg2 = &model.ArgRegister{Appid: "main.arch.test", Hostname: "go", RPC: "127.0.0.1:8080", Region: "shsb", Zone: "sh0001", Env: "pre", Status: 1}
- m2 := model.NewInstance(arg2)
- err2 := r.Register(m2, 0)
- So(err2, ShouldBeNil)
- })
- }()
- pollArg := &model.ArgPolls{Region: "shsb", Zone: "sh0001", Env: "pre", Appid: []string{"main.arch.test"}, LatestTimestamp: []int64{time.Now().UnixNano()}}
- ch, _, err := r.Polls(pollArg)
- So(err, ShouldResemble, ecode.NotModified)
- c := <-ch
- So(len(c[pollArg.Appid[0]].Instances), ShouldResemble, 2)
- So(c[pollArg.Appid[0]].ZoneInstances, ShouldNotBeNil)
- So(len(c[pollArg.Appid[0]].ZoneInstances["sh0001"]), ShouldResemble, 2)
- })
- }
- func BenchmarkBroadcast(b *testing.B) {
- for i := 0; i < b.N; i++ {
- var (
- err error
- err2 error
- ch chan map[string]*model.InstanceInfo
- c map[string]*model.InstanceInfo
- )
- r, _ := benchRegister(b)
- go func() {
- time.Sleep(time.Millisecond * 1)
- var arg2 = &model.ArgRegister{Appid: "main.arch.test", Hostname: "go", RPC: "127.0.0.1:8080", Region: "shsb", Zone: "sh0001", Env: "pre", Status: 1}
- m2 := model.NewInstance(arg2)
- if err2 = r.Register(m2, 0); err2 != nil {
- b.Errorf("Reigster(%v) error(%v)", m2.Appid, err2)
- }
- }()
- pollArg := &model.ArgPolls{Region: "shsb", Zone: "sh0001", Env: "pre", Appid: []string{"main.arch.test"}, LatestTimestamp: []int64{time.Now().UnixNano()}}
- if ch, _, err = r.Polls(pollArg); err != nil && err != ecode.NotModified {
- b.Errorf("Poll(%v) error(%v)", pollArg.Appid, err)
- }
- c = <-ch
- if len(c[pollArg.Appid[0]].Instances) != 2 {
- b.Errorf("Poll(%v) length error", pollArg.Appid)
- }
- if c[pollArg.Appid[0]].ZoneInstances == nil {
- b.Errorf("Poll(%v) zone instances nil error", pollArg.Appid)
- }
- if len(c[pollArg.Appid[0]].ZoneInstances["sh0001"]) != 2 {
- b.Errorf("Poll(%v) zone instances length error", pollArg.Appid)
- }
- }
- }
- func TestRegistrySet(t *testing.T) {
- i := model.NewInstance(reg)
- r := register(t, i)
- changes := make(map[string]string)
- changes["reg"] = "1"
- Convey("test set weight to 1", t, func() {
- set := &model.ArgSet{
- Region: "shsb",
- Env: "pre",
- Appid: "main.arch.test",
- Hostname: []string{"reg"},
- Metadata: []string{`{"weight":"1"}`},
- }
- ok := r.Set(context.TODO(), set)
- So(ok, ShouldBeTrue)
- fetchArg := &model.ArgFetch{Region: "shsb", Zone: "sh0001", Env: "pre", Appid: "main.arch.test", Status: 3}
- c, err := r.Fetch(fetchArg.Zone, fetchArg.Env, fetchArg.Appid, 0, fetchArg.Status)
- So(err, ShouldBeNil)
- So(c.Instances[0].Metadata["weight"], ShouldResemble, "1")
- })
- }
- func BenchmarkSet(b *testing.B) {
- b.RunParallel(func(pb *testing.PB) {
- for pb.Next() {
- var (
- c *model.InstanceInfo
- err error
- ok bool
- )
- r, _ := benchRegister(b)
- set := &model.ArgSet{
- Region: "shsb",
- Env: "pre",
- Appid: "main.arch.account-service",
- Hostname: []string{"test1"},
- Status: []int64{1},
- Metadata: []string{`{"weight":"1"}`},
- }
- if ok = r.Set(context.TODO(), set); !ok {
- b.Errorf("SetWeight(%v) error", arg.Appid)
- }
- fetchArg := &model.ArgFetch{Region: "shsb", Zone: "sh0001", Env: "pre", Appid: "main.arch.test", Status: 3}
- if c, err = r.Fetch(fetchArg.Zone, fetchArg.Env, fetchArg.Appid, 0, fetchArg.Status); err != nil {
- b.Errorf("Fetch(%v) error(%v)", fetchArg.Appid, err)
- }
- if c.Instances[0].Metadata["weight"] != "1" {
- b.Errorf("SetWeight(%v) change error", fetchArg.Appid)
- }
- }
- })
- }
- func TestResetExp(t *testing.T) {
- i := model.NewInstance(reg)
- r := register(t, i)
- Convey("test ResetExp", t, func() {
- r.resetExp()
- So(r.gd.expPerMin, ShouldResemble, int64(2))
- })
- }
- func benchCompareInstance(b *testing.B, src *model.Instance, i *model.Instance) {
- if src.Appid != i.Appid || src.Env != i.Env || src.Hostname != i.Hostname ||
- src.Region != i.Region {
- b.Errorf("instance compare error")
- }
- }
- func register(t *testing.T, is ...*model.Instance) (r *Registry) {
- Convey("test register", t, func() {
- r = NewRegistry()
- var num int
- for _, i := range is {
- err := r.Register(i, 0)
- So(err, ShouldBeNil)
- if i.Appid == "main.arch.test" {
- num++
- }
- }
- fetchArg := &model.ArgFetch{Region: "shsb", Zone: "sh0001", Env: "pre", Appid: "main.arch.test", Status: 3}
- instancesInfo, err := r.Fetch(fetchArg.Zone, fetchArg.Env, fetchArg.Appid, 0, fetchArg.Status)
- So(err, ShouldBeNil)
- So(len(instancesInfo.Instances), ShouldResemble, num)
- })
- return r
- }
- func benchRegister(b *testing.B) (r *Registry, i *model.Instance) {
- r = NewRegistry()
- i = model.NewInstance(reg)
- if err := r.Register(i, 0); err != nil {
- b.Errorf("Reigster(%v) error(%v)", i.Appid, err)
- }
- return r, i
- }
- func TestEvict(t *testing.T) {
- Convey("test evict for protect", t, func() {
- r := NewRegistry()
- m := model.NewInstance(reg)
- // promise the renewtime of instance is expire
- m.RenewTimestamp -= 100
- err := r.Register(m, 0)
- So(err, ShouldBeNil)
- // move up the statistics of heartbeat for evict
- r.gd.facLastMin = r.gd.facInMin
- r.evict()
- fetchArg := &model.ArgFetch{Region: "shsb", Zone: "sh0001", Env: "pre", Appid: "main.arch.test", Status: 3}
- c, err := r.Fetch(fetchArg.Zone, fetchArg.Env, fetchArg.Appid, 0, fetchArg.Status)
- So(err, ShouldBeNil)
- // protect
- So(len(c.Instances), ShouldResemble, 1)
- })
- }
- func TestEvict2(t *testing.T) {
- Convey("test evict for cancel", t, func() {
- r := NewRegistry()
- m := model.NewInstance(reg)
- err := r.Register(m, 0)
- So(err, ShouldBeNil)
- _, ok := r.Renew(arg)
- So(ok, ShouldBeTrue)
- // promise the renewtime of instance is expire
- m.RenewTimestamp -= int64(time.Second * 100)
- r.Register(m, 0)
- // move up the statistics of heartbeat for evict
- r.gd.facLastMin = r.gd.facInMin
- r.evict()
- fetchArg := &model.ArgFetch{Region: "shsb", Zone: "sh0001", Env: "pre", Appid: "main.arch.test", Status: 1}
- _, err = r.Fetch(fetchArg.Zone, fetchArg.Env, fetchArg.Appid, 0, fetchArg.Status)
- So(err, ShouldResemble, ecode.NothingFound)
- })
- }
|