github.com/tenywen/fabric@v1.0.0-beta.0.20170620030522-a5b1ed380643/gossip/util/pubsub_test.go (about)

     1  /*
     2  Copyright IBM Corp. 2017 All Rights Reserved.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8  		 http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package util
    18  
    19  import (
    20  	"sync"
    21  	"testing"
    22  	"time"
    23  
    24  	"github.com/stretchr/testify/assert"
    25  )
    26  
    27  func TestNewPubsub(t *testing.T) {
    28  	ps := NewPubSub()
    29  	// Check a publishing to a topic with a subscription succeeds
    30  	sub1 := ps.Subscribe("test", time.Second)
    31  	sub2 := ps.Subscribe("test2", time.Second)
    32  	assert.NotNil(t, sub1)
    33  	go func() {
    34  		err := ps.Publish("test", 5)
    35  		assert.NoError(t, err)
    36  	}()
    37  	item, err := sub1.Listen()
    38  	assert.NoError(t, err)
    39  	assert.Equal(t, 5, item)
    40  	// Check that a publishing to a topic with no subscribers fails
    41  	err = ps.Publish("test3", 5)
    42  	assert.Error(t, err)
    43  	assert.Contains(t, "no subscribers", err.Error())
    44  	// Check that a listen on a topic that its publish is too late, times out
    45  	// and returns an error
    46  	go func() {
    47  		time.Sleep(time.Second * 2)
    48  		ps.Publish("test2", 10)
    49  	}()
    50  	item, err = sub2.Listen()
    51  	assert.Error(t, err)
    52  	assert.Contains(t, "timed out", err.Error())
    53  	assert.Nil(t, item)
    54  	// Have multiple subscribers subscribe to the same topic
    55  	subscriptions := []Subscription{}
    56  	n := 100
    57  	for i := 0; i < n; i++ {
    58  		subscriptions = append(subscriptions, ps.Subscribe("test4", time.Second))
    59  	}
    60  	go func() {
    61  		// Send items and fill the buffer and overflow
    62  		// it by 1 item
    63  		for i := 0; i <= subscriptionBuffSize; i++ {
    64  			err := ps.Publish("test4", 100+i)
    65  			assert.NoError(t, err)
    66  		}
    67  	}()
    68  	wg := sync.WaitGroup{}
    69  	wg.Add(n)
    70  	for _, s := range subscriptions {
    71  		go func(s Subscription) {
    72  			time.Sleep(time.Second)
    73  			defer wg.Done()
    74  			for i := 0; i < subscriptionBuffSize; i++ {
    75  				item, err := s.Listen()
    76  				assert.NoError(t, err)
    77  				assert.Equal(t, 100+i, item)
    78  			}
    79  			// The last item that we published was dropped
    80  			// due to the buffer being full
    81  			item, err := s.Listen()
    82  			assert.Nil(t, item)
    83  			assert.Error(t, err)
    84  		}(s)
    85  	}
    86  	wg.Wait()
    87  
    88  	// Ensure subscriptions are cleaned after use
    89  	for i := 0; i < 10; i++ {
    90  		time.Sleep(time.Second)
    91  		ps.Lock()
    92  		empty := len(ps.subscriptions) == 0
    93  		ps.Unlock()
    94  		if empty {
    95  			break
    96  		}
    97  	}
    98  	ps.Lock()
    99  	defer ps.Unlock()
   100  	assert.Empty(t, ps.subscriptions)
   101  }