1 package instance
2
3 import (
4 "context"
5 "fmt"
6 "io"
7 "reflect"
8 "testing"
9 "time"
10
11 "github.com/go-kit/kit/endpoint"
12 "github.com/go-kit/kit/sd"
13 "github.com/go-kit/log"
14 )
15
16 var _ sd.Instancer = (*Cache)(nil)
17
18
19
20
21
22
23
24 func TestCache(t *testing.T) {
25 e1 := sd.Event{Instances: []string{"y", "x"}}
26 e2 := sd.Event{Instances: []string{"c", "a", "b"}}
27
28 cache := NewCache()
29 if want, have := 0, len(cache.State().Instances); want != have {
30 t.Fatalf("want %v instances, have %v", want, have)
31 }
32
33 cache.Update(e1)
34 if want, have := 2, len(cache.State().Instances); want != have {
35 t.Fatalf("want %v instances, have %v", want, have)
36 }
37
38 r1 := make(chan sd.Event)
39 go cache.Register(r1)
40 expectUpdate(t, r1, []string{"x", "y"})
41
42 go cache.Update(e2)
43 expectUpdate(t, r1, []string{"a", "b", "c"})
44
45 cache.Deregister(r1)
46 close(r1)
47 }
48
49 func expectUpdate(t *testing.T, r chan sd.Event, expect []string) {
50 select {
51 case e := <-r:
52 if want, have := expect, e.Instances; !reflect.DeepEqual(want, have) {
53 t.Fatalf("want: %v, have: %v", want, have)
54 }
55 case <-time.After(time.Second):
56 t.Fatalf("did not receive expected update %v", expect)
57 }
58 }
59
60 func TestRegistry(t *testing.T) {
61 reg := make(registry)
62 c1 := make(chan sd.Event, 1)
63 c2 := make(chan sd.Event, 1)
64 reg.register(c1)
65 reg.register(c2)
66
67
68 reg.broadcast(sd.Event{Instances: []string{"x", "y"}})
69 if want, have := []string{"x", "y"}, (<-c1).Instances; !reflect.DeepEqual(want, have) {
70 t.Fatalf("want: %v, have: %v", want, have)
71 }
72 if want, have := []string{"x", "y"}, (<-c2).Instances; !reflect.DeepEqual(want, have) {
73 t.Fatalf("want: %v, have: %v", want, have)
74 }
75
76 reg.deregister(c1)
77 reg.deregister(c2)
78 close(c1)
79 close(c2)
80
81 reg.broadcast(sd.Event{Instances: []string{"x", "y"}})
82 }
83
84
85
86
87
88 func TestDataRace(t *testing.T) {
89 instances := make([]string, 0)
90
91
92 for i := 1; i < 1000; i++ {
93 instances = append(instances, fmt.Sprintf("%v", i))
94 }
95 e1 := sd.Event{Instances: instances}
96 cache := NewCache()
97 cache.Update(e1)
98 nullEndpoint := func(_ context.Context, _ interface{}) (interface{}, error) {
99 return nil, nil
100 }
101 nullFactory := func(instance string) (endpoint.Endpoint, io.Closer, error) {
102 return nullEndpoint, nil, nil
103 }
104 logger := log.Logger(log.LoggerFunc(func(keyvals ...interface{}) error {
105 return nil
106 }))
107
108 sd.NewEndpointer(cache, nullFactory, logger)
109 sd.NewEndpointer(cache, nullFactory, logger)
110 }
111
View as plain text