github.com/demonoid81/moby@v0.0.0-20200517203328-62dd8e17c460/pkg/pubsub/publisher_test.go (about) 1 package pubsub // import "github.com/demonoid81/moby/pkg/pubsub" 2 3 import ( 4 "fmt" 5 "testing" 6 "time" 7 ) 8 9 func TestSendToOneSub(t *testing.T) { 10 p := NewPublisher(100*time.Millisecond, 10) 11 c := p.Subscribe() 12 13 p.Publish("hi") 14 15 msg := <-c 16 if msg.(string) != "hi" { 17 t.Fatalf("expected message hi but received %v", msg) 18 } 19 } 20 21 func TestSendToMultipleSubs(t *testing.T) { 22 p := NewPublisher(100*time.Millisecond, 10) 23 var subs []chan interface{} 24 subs = append(subs, p.Subscribe(), p.Subscribe(), p.Subscribe()) 25 26 p.Publish("hi") 27 28 for _, c := range subs { 29 msg := <-c 30 if msg.(string) != "hi" { 31 t.Fatalf("expected message hi but received %v", msg) 32 } 33 } 34 } 35 36 func TestEvictOneSub(t *testing.T) { 37 p := NewPublisher(100*time.Millisecond, 10) 38 s1 := p.Subscribe() 39 s2 := p.Subscribe() 40 41 p.Evict(s1) 42 p.Publish("hi") 43 if _, ok := <-s1; ok { 44 t.Fatal("expected s1 to not receive the published message") 45 } 46 47 msg := <-s2 48 if msg.(string) != "hi" { 49 t.Fatalf("expected message hi but received %v", msg) 50 } 51 } 52 53 func TestClosePublisher(t *testing.T) { 54 p := NewPublisher(100*time.Millisecond, 10) 55 var subs []chan interface{} 56 subs = append(subs, p.Subscribe(), p.Subscribe(), p.Subscribe()) 57 p.Close() 58 59 for _, c := range subs { 60 if _, ok := <-c; ok { 61 t.Fatal("expected all subscriber channels to be closed") 62 } 63 } 64 } 65 66 const sampleText = "test" 67 68 type testSubscriber struct { 69 dataCh chan interface{} 70 ch chan error 71 } 72 73 func (s *testSubscriber) Wait() error { 74 return <-s.ch 75 } 76 77 func newTestSubscriber(p *Publisher) *testSubscriber { 78 ts := &testSubscriber{ 79 dataCh: p.Subscribe(), 80 ch: make(chan error), 81 } 82 go func() { 83 for data := range ts.dataCh { 84 s, ok := data.(string) 85 if !ok { 86 ts.ch <- fmt.Errorf("Unexpected type %T", data) 87 break 88 } 89 if s != sampleText { 90 ts.ch <- fmt.Errorf("Unexpected text %s", s) 91 break 92 } 93 } 94 close(ts.ch) 95 }() 96 return ts 97 } 98 99 // for testing with -race 100 func TestPubSubRace(t *testing.T) { 101 p := NewPublisher(0, 1024) 102 var subs []*testSubscriber 103 for j := 0; j < 50; j++ { 104 subs = append(subs, newTestSubscriber(p)) 105 } 106 for j := 0; j < 1000; j++ { 107 p.Publish(sampleText) 108 } 109 time.AfterFunc(1*time.Second, func() { 110 for _, s := range subs { 111 p.Evict(s.dataCh) 112 } 113 }) 114 for _, s := range subs { 115 s.Wait() 116 } 117 } 118 119 func BenchmarkPubSub(b *testing.B) { 120 for i := 0; i < b.N; i++ { 121 b.StopTimer() 122 p := NewPublisher(0, 1024) 123 var subs []*testSubscriber 124 for j := 0; j < 50; j++ { 125 subs = append(subs, newTestSubscriber(p)) 126 } 127 b.StartTimer() 128 for j := 0; j < 1000; j++ { 129 p.Publish(sampleText) 130 } 131 time.AfterFunc(1*time.Second, func() { 132 for _, s := range subs { 133 p.Evict(s.dataCh) 134 } 135 }) 136 for _, s := range subs { 137 if err := s.Wait(); err != nil { 138 b.Fatal(err) 139 } 140 } 141 } 142 }