github.com/ewagmig/fabric@v2.1.1+incompatible/gossip/util/pubsub_test.go (about) 1 /* 2 Copyright IBM Corp. All Rights Reserved. 3 4 SPDX-License-Identifier: Apache-2.0 5 */ 6 7 package util 8 9 import ( 10 "sync" 11 "testing" 12 "time" 13 14 "github.com/stretchr/testify/assert" 15 ) 16 17 func TestNewPubsub(t *testing.T) { 18 ps := NewPubSub() 19 // Check a publishing to a topic with a subscription succeeds 20 sub1 := ps.Subscribe("test", time.Second) 21 sub2 := ps.Subscribe("test2", time.Second) 22 assert.NotNil(t, sub1) 23 go func() { 24 err := ps.Publish("test", 5) 25 assert.NoError(t, err) 26 }() 27 item, err := sub1.Listen() 28 assert.NoError(t, err) 29 assert.Equal(t, 5, item) 30 // Check that a publishing to a topic with no subscribers fails 31 err = ps.Publish("test3", 5) 32 assert.Error(t, err) 33 assert.Contains(t, "no subscribers", err.Error()) 34 // Check that a listen on a topic that its publish is too late, times out 35 // and returns an error 36 go func() { 37 time.Sleep(time.Second * 2) 38 ps.Publish("test2", 10) 39 }() 40 item, err = sub2.Listen() 41 assert.Error(t, err) 42 assert.Contains(t, "timed out", err.Error()) 43 assert.Nil(t, item) 44 // Have multiple subscribers subscribe to the same topic 45 subscriptions := []Subscription{} 46 n := 100 47 for i := 0; i < n; i++ { 48 subscriptions = append(subscriptions, ps.Subscribe("test4", time.Second)) 49 } 50 go func() { 51 // Send items and fill the buffer and overflow 52 // it by 1 item 53 for i := 0; i <= subscriptionBuffSize; i++ { 54 err := ps.Publish("test4", 100+i) 55 assert.NoError(t, err) 56 } 57 }() 58 wg := sync.WaitGroup{} 59 wg.Add(n) 60 for _, s := range subscriptions { 61 go func(s Subscription) { 62 time.Sleep(time.Second) 63 defer wg.Done() 64 for i := 0; i < subscriptionBuffSize; i++ { 65 item, err := s.Listen() 66 assert.NoError(t, err) 67 assert.Equal(t, 100+i, item) 68 } 69 // The last item that we published was dropped 70 // due to the buffer being full 71 item, err := s.Listen() 72 assert.Nil(t, item) 73 assert.Error(t, err) 74 }(s) 75 } 76 wg.Wait() 77 78 // Ensure subscriptions are cleaned after use 79 for i := 0; i < 10; i++ { 80 time.Sleep(time.Second) 81 ps.Lock() 82 empty := len(ps.subscriptions) == 0 83 ps.Unlock() 84 if empty { 85 break 86 } 87 } 88 ps.Lock() 89 defer ps.Unlock() 90 assert.Empty(t, ps.subscriptions) 91 }