github.com/vmware/transport-go@v1.3.4/bus/channel_manager_test.go (about)

     1  // Copyright 2019-2020 VMware, Inc.
     2  // SPDX-License-Identifier: BSD-2-Clause
     3  
     4  package bus
     5  
     6  import (
     7  	"github.com/google/uuid"
     8  	"github.com/stretchr/testify/assert"
     9  	"github.com/vmware/transport-go/model"
    10  	"sync"
    11  	"testing"
    12  	"time"
    13  )
    14  
    15  var testChannelManager ChannelManager
    16  var testChannelManagerChannelName = "melody"
    17  
    18  func createManager() (ChannelManager, EventBus) {
    19  	b := newTestEventBus()
    20  	manager := NewBusChannelManager(b)
    21  	return manager, b
    22  }
    23  
    24  func TestChannelManager_Boot(t *testing.T) {
    25  	testChannelManager, _ = createManager()
    26  	assert.Len(t, testChannelManager.GetAllChannels(), 0)
    27  }
    28  
    29  func TestChannelManager_CreateChannel(t *testing.T) {
    30  	var bus EventBus
    31  	testChannelManager, bus = createManager()
    32  
    33  	wg := sync.WaitGroup{}
    34  	wg.Add(1)
    35  	bus.AddMonitorEventListener(
    36  		func(monitorEvt *MonitorEvent) {
    37  			if monitorEvt.EntityName == testChannelManagerChannelName {
    38  				assert.Equal(t, monitorEvt.EventType, ChannelCreatedEvt)
    39  				wg.Done()
    40  			}
    41  		})
    42  
    43  	testChannelManager.CreateChannel(testChannelManagerChannelName)
    44  
    45  	wg.Wait()
    46  
    47  	assert.Len(t, testChannelManager.GetAllChannels(), 1)
    48  
    49  	fetchedChannel, _ := testChannelManager.GetChannel(testChannelManagerChannelName)
    50  	assert.NotNil(t, fetchedChannel)
    51  	assert.True(t, testChannelManager.CheckChannelExists(testChannelManagerChannelName))
    52  }
    53  
    54  func TestChannelManager_GetNotExistentChannel(t *testing.T) {
    55  	testChannelManager, _ = createManager()
    56  
    57  	fetchedChannel, err := testChannelManager.GetChannel(testChannelManagerChannelName)
    58  	assert.NotNil(t, err)
    59  	assert.Nil(t, fetchedChannel)
    60  }
    61  
    62  func TestChannelManager_DestroyChannel(t *testing.T) {
    63  	testChannelManager, _ = createManager()
    64  
    65  	testChannelManager.CreateChannel(testChannelManagerChannelName)
    66  	testChannelManager.DestroyChannel(testChannelManagerChannelName)
    67  	fetchedChannel, err := testChannelManager.GetChannel(testChannelManagerChannelName)
    68  	assert.Len(t, testChannelManager.GetAllChannels(), 0)
    69  	assert.NotNil(t, err)
    70  	assert.Nil(t, fetchedChannel)
    71  }
    72  
    73  func TestChannelManager_SubscribeChannelHandler(t *testing.T) {
    74  	testChannelManager, _ = createManager()
    75  	testChannelManager.CreateChannel(testChannelManagerChannelName)
    76  
    77  	handler := func(*model.Message) {}
    78  	uuid, err := testChannelManager.SubscribeChannelHandler(testChannelManagerChannelName, handler, false)
    79  	assert.Nil(t, err)
    80  	assert.NotNil(t, uuid)
    81  	channel, _ := testChannelManager.GetChannel(testChannelManagerChannelName)
    82  	assert.Len(t, channel.eventHandlers, 1)
    83  }
    84  
    85  func TestChannelManager_SubscribeChannelHandlerMissingChannel(t *testing.T) {
    86  	testChannelManager, _ = createManager()
    87  	handler := func(*model.Message) {}
    88  	_, err := testChannelManager.SubscribeChannelHandler(testChannelManagerChannelName, handler, false)
    89  	assert.NotNil(t, err)
    90  }
    91  
    92  func TestChannelManager_UnsubscribeChannelHandler(t *testing.T) {
    93  	testChannelManager, _ = createManager()
    94  	testChannelManager.CreateChannel(testChannelManagerChannelName)
    95  
    96  	handler := func(*model.Message) {}
    97  	uuid, _ := testChannelManager.SubscribeChannelHandler(testChannelManagerChannelName, handler, false)
    98  	channel, _ := testChannelManager.GetChannel(testChannelManagerChannelName)
    99  	assert.Len(t, channel.eventHandlers, 1)
   100  
   101  	err := testChannelManager.UnsubscribeChannelHandler(testChannelManagerChannelName, uuid)
   102  	assert.Nil(t, err)
   103  	assert.Len(t, channel.eventHandlers, 0)
   104  }
   105  
   106  func TestChannelManager_UnsubscribeChannelHandlerMissingChannel(t *testing.T) {
   107  	testChannelManager, _ = createManager()
   108  	uuid := uuid.New()
   109  	err := testChannelManager.UnsubscribeChannelHandler(testChannelManagerChannelName, &uuid)
   110  	assert.NotNil(t, err)
   111  }
   112  
   113  func TestChannelManager_UnsubscribeChannelHandlerNoId(t *testing.T) {
   114  	testChannelManager, _ = createManager()
   115  	testChannelManager.CreateChannel(testChannelManagerChannelName)
   116  
   117  	handler := func(*model.Message) {}
   118  	testChannelManager.SubscribeChannelHandler(testChannelManagerChannelName, handler, false)
   119  	channel, _ := testChannelManager.GetChannel(testChannelManagerChannelName)
   120  	assert.Len(t, channel.eventHandlers, 1)
   121  	id := uuid.New()
   122  	err := testChannelManager.UnsubscribeChannelHandler(testChannelManagerChannelName, &id)
   123  	assert.NotNil(t, err)
   124  	assert.Len(t, channel.eventHandlers, 1)
   125  }
   126  
   127  func TestChannelManager_TestWaitForGroupOnBadChannel(t *testing.T) {
   128  	testChannelManager, _ = createManager()
   129  	err := testChannelManager.WaitForChannel("unknown")
   130  	assert.Error(t, err, "no such Channel as 'unknown'")
   131  }
   132  
   133  func TestChannelManager_TestGalacticChannelOpen(t *testing.T) {
   134  
   135  	testChannelManager, _ = createManager()
   136  	galacticChannel := testChannelManager.CreateChannel(testChannelManagerChannelName)
   137  	id := uuid.New()
   138  
   139  	// mark channel as galactic.
   140  
   141  	subId := uuid.New()
   142  	sub := &MockBridgeSubscription{
   143  		Id: &subId,
   144  	}
   145  
   146  	c := &MockBridgeConnection{Id: &id}
   147  	c.On("Subscribe", "/topic/testy-test").Return(sub, nil).Once()
   148  	e := testChannelManager.MarkChannelAsGalactic(testChannelManagerChannelName, "/topic/testy-test", c)
   149  
   150  	assert.Nil(t, e)
   151  	c.AssertExpectations(t)
   152  
   153  	assert.True(t, galacticChannel.galactic)
   154  
   155  	assert.Equal(t, len(galacticChannel.brokerConns), 1)
   156  	assert.Equal(t, galacticChannel.brokerConns[0], c)
   157  
   158  	assert.Equal(t, len(galacticChannel.brokerSubs), 1)
   159  	assert.Equal(t, galacticChannel.brokerSubs[0].s, sub)
   160  	assert.Equal(t, galacticChannel.brokerSubs[0].c, c)
   161  
   162  	testChannelManager.MarkChannelAsLocal(testChannelManagerChannelName)
   163  	assert.False(t, galacticChannel.galactic)
   164  
   165  	assert.Equal(t, len(galacticChannel.brokerConns), 0)
   166  	assert.Equal(t, len(galacticChannel.brokerSubs), 0)
   167  }
   168  
   169  func TestChannelManager_TestGalacticChannelOpenError(t *testing.T) {
   170  	// channel is not open / does not exist, so this should fail.
   171  	e := testChannelManager.MarkChannelAsGalactic(evtbusTestChannelName, "/topic/testy-test", nil)
   172  	assert.Error(t, e)
   173  }
   174  
   175  func TestChannelManager_TestGalacticChannelCloseError(t *testing.T) {
   176  	// channel is not open / does not exist, so this should fail.
   177  	e := testChannelManager.MarkChannelAsLocal(evtbusTestChannelName)
   178  	assert.Error(t, e)
   179  }
   180  
   181  func TestChannelManager_TestListenToMonitorGalactic(t *testing.T) {
   182  	myChan := "mychan"
   183  
   184  	b := newTestEventBus()
   185  
   186  	testChannelManager = b.GetChannelManager()
   187  	c := testChannelManager.CreateChannel(myChan)
   188  
   189  	// mark channel as galactic.
   190  	id := uuid.New()
   191  	subId := uuid.New()
   192  	mockSub := &MockBridgeSubscription{
   193  		Id:          &subId,
   194  		Channel:     make(chan *model.Message, 10),
   195  		Destination: "/queue/hiya",
   196  	}
   197  
   198  	mockCon := &MockBridgeConnection{Id: &id}
   199  	mockCon.On("Subscribe", "/queue/hiya").Return(mockSub, nil).Once()
   200  
   201  	x := 0
   202  
   203  	h, e := b.ListenOnce(myChan)
   204  	assert.Nil(t, e)
   205  
   206  	var m1 = make(chan bool)
   207  	var m2 = make(chan bool)
   208  
   209  	h.Handle(
   210  		func(msg *model.Message) {
   211  			x++
   212  			m1 <- true
   213  		},
   214  		func(err error) {
   215  
   216  		})
   217  
   218  	testChannelManager.MarkChannelAsGalactic(myChan, "/queue/hiya", mockCon)
   219  	testChannelManager.MarkChannelAsGalactic(myChan, "/queue/hiya", mockCon) // double up for fun
   220  	<-c.brokerMappedEvent
   221  	assert.Len(t, c.brokerConns, 1)
   222  	mockSub.GetMsgChannel() <- &model.Message{Payload: "test-message", Direction: model.ResponseDir}
   223  	<-m1
   224  
   225  	// lets add another connection to the same channel.
   226  
   227  	id2 := uuid.New()
   228  	subId2 := uuid.New()
   229  	mockSub2 := &MockBridgeSubscription{
   230  		Id:          &subId2,
   231  		Channel:     make(chan *model.Message, 10),
   232  		Destination: "/queue/hiya",
   233  	}
   234  
   235  	mockCon2 := &MockBridgeConnection{Id: &id2}
   236  	mockCon2.On("Subscribe", "/queue/hiya").Return(mockSub2, nil).Once()
   237  
   238  	h, e = b.ListenOnce(myChan)
   239  
   240  	h.Handle(
   241  		func(msg *model.Message) {
   242  			x++
   243  			m2 <- true
   244  		},
   245  		func(err error) {})
   246  
   247  	testChannelManager.MarkChannelAsGalactic(myChan, "/queue/hiya", mockCon2)
   248  	testChannelManager.MarkChannelAsGalactic(myChan, "/queue/hiya", mockCon2) // trigger double (should ignore)
   249  
   250  	select {
   251  	case <-c.brokerMappedEvent:
   252  	case <-time.After(5 * time.Second):
   253  		assert.FailNow(t, "TestChannelManager_TestListenToMonitorGalactic timeout on brokerMappedEvent")
   254  	}
   255  
   256  	mockSub.GetMsgChannel() <- &model.Message{Payload: "Hi baby melody!", Direction: model.ResponseDir}
   257  
   258  	<-m2
   259  	assert.Equal(t, 2, x)
   260  }
   261  
   262  // This test performs a end to end run of the monitor.
   263  // it will create a ws broker subscription, map it to a single channel
   264  // then it will unsubscribe and check that the unsubscription went through ok.
   265  func TestChannelManager_TestListenToMonitorLocal(t *testing.T) {
   266  
   267  	myChan := "mychan-local"
   268  
   269  	b := newTestEventBus()
   270  
   271  	// run ws broker
   272  	testChannelManager = b.GetChannelManager()
   273  
   274  	c := testChannelManager.CreateChannel(myChan)
   275  
   276  	subId := uuid.New()
   277  	sub := &MockBridgeSubscription{
   278  		Id: &subId,
   279  	}
   280  
   281  	id := uuid.New()
   282  	mockCon := &MockBridgeConnection{Id: &id}
   283  	mockCon.On("Subscribe", "/queue/seeya").Return(sub, nil).Once()
   284  
   285  	testChannelManager.MarkChannelAsGalactic(myChan, "/queue/seeya", mockCon)
   286  	<-c.brokerMappedEvent
   287  	assert.Len(t, c.brokerConns, 1)
   288  
   289  	testChannelManager.MarkChannelAsLocal(myChan)
   290  	<-c.brokerMappedEvent
   291  	assert.Len(t, c.brokerConns, 0)
   292  	assert.Len(t, c.brokerSubs, 0)
   293  }
   294  
   295  func TestChannelManager_TestGalacticMonitorInvalidChannel(t *testing.T) {
   296  	testChannelManager, _ = createManager()
   297  	testChannelManager.CreateChannel("fun-chan")
   298  
   299  	err := testChannelManager.MarkChannelAsGalactic("fun-chan", "/queue/woo", nil)
   300  	assert.Nil(t, err)
   301  
   302  }
   303  
   304  func TestChannelManager_TestLocalMonitorInvalidChannel(t *testing.T) {
   305  	testChannelManager, _ = createManager()
   306  	testChannelManager.CreateChannel("fun-chan")
   307  
   308  	err := testChannelManager.MarkChannelAsLocal("fun-chan")
   309  	assert.Nil(t, err)
   310  }