github.com/alwitt/goutils@v0.6.4/bus_test.go (about)

     1  package goutils
     2  
     3  import (
     4  	"context"
     5  	"testing"
     6  	"time"
     7  
     8  	"github.com/apex/log"
     9  	"github.com/google/uuid"
    10  	"github.com/stretchr/testify/assert"
    11  )
    12  
    13  func TestMessageTopicOnePubOneSub(t *testing.T) {
    14  	assert := assert.New(t)
    15  	log.SetLevel(log.DebugLevel)
    16  
    17  	ctxt, cancel := context.WithCancel(context.Background())
    18  	defer cancel()
    19  
    20  	testTopic, err := getNewMessageTopicInstance(
    21  		ctxt, uuid.NewString(), log.Fields{"unit-testiung": "testing"},
    22  	)
    23  	assert.Nil(err)
    24  
    25  	type testMsg struct {
    26  		msg string
    27  	}
    28  
    29  	// Case 0: create subscription
    30  	subscriber := uuid.NewString()
    31  	subChan, err := testTopic.CreateSubscription(ctxt, subscriber, 0)
    32  	assert.Nil(err)
    33  
    34  	// Case 1: blocking publish
    35  	{
    36  		test := testMsg{msg: uuid.NewString()}
    37  		complete := make(chan bool, 1)
    38  
    39  		lclCtxt, lclCancel := context.WithTimeout(ctxt, time.Millisecond*100)
    40  
    41  		go func() {
    42  			assert.Nil(testTopic.Publish(lclCtxt, &test, 0))
    43  			complete <- true
    44  		}()
    45  
    46  		select {
    47  		case <-lclCtxt.Done():
    48  			assert.False(true, "msg timed out")
    49  		case msg, ok := <-subChan:
    50  			assert.True(ok)
    51  			asString, ok := msg.(*testMsg)
    52  			assert.True(ok)
    53  			assert.Equal(test.msg, asString.msg)
    54  		}
    55  
    56  		select {
    57  		case <-lclCtxt.Done():
    58  			assert.False(true, "test timed out")
    59  		case <-complete:
    60  			break
    61  		}
    62  
    63  		lclCancel()
    64  	}
    65  
    66  	// Case 2: non-blocking publish, but not receiving
    67  	{
    68  		test := testMsg{msg: uuid.NewString()}
    69  
    70  		lclCtxt, lclCancel := context.WithTimeout(ctxt, time.Millisecond*100)
    71  
    72  		assert.Nil(testTopic.Publish(lclCtxt, &test, time.Millisecond*10))
    73  
    74  		lclCancel()
    75  	}
    76  
    77  	// Case 3: non-blocking publish, prepared to receive
    78  	{
    79  		test := testMsg{msg: uuid.NewString()}
    80  		complete := make(chan bool, 1)
    81  
    82  		lclCtxt, lclCancel := context.WithTimeout(ctxt, time.Millisecond*100)
    83  
    84  		go func() {
    85  			assert.Nil(testTopic.Publish(lclCtxt, &test, time.Millisecond*10))
    86  			complete <- true
    87  		}()
    88  
    89  		select {
    90  		case <-lclCtxt.Done():
    91  			assert.False(true, "msg timed out")
    92  		case msg, ok := <-subChan:
    93  			assert.True(ok)
    94  			asString, ok := msg.(*testMsg)
    95  			assert.True(ok)
    96  			assert.Equal(test.msg, asString.msg)
    97  		}
    98  
    99  		select {
   100  		case <-lclCtxt.Done():
   101  			assert.False(true, "test timed out")
   102  		case <-complete:
   103  			break
   104  		}
   105  
   106  		lclCancel()
   107  	}
   108  
   109  	// Delete subscription
   110  	assert.Nil(testTopic.DeleteSubscription(ctxt, subscriber))
   111  }
   112  
   113  func TestMessageTopicOnePubMultiSub(t *testing.T) {
   114  	assert := assert.New(t)
   115  	log.SetLevel(log.DebugLevel)
   116  
   117  	ctxt, cancel := context.WithCancel(context.Background())
   118  	defer cancel()
   119  
   120  	testTopic, err := getNewMessageTopicInstance(
   121  		ctxt, uuid.NewString(), log.Fields{"unit-testiung": "testing"},
   122  	)
   123  	assert.Nil(err)
   124  
   125  	type testMsg struct {
   126  		msg string
   127  	}
   128  
   129  	// Case 0: create subscriptions
   130  	subNames := []string{}
   131  	subs := map[string]chan interface{}{}
   132  	for itr := 0; itr < 2; itr++ {
   133  		subscriber := uuid.NewString()
   134  		subChan, err := testTopic.CreateSubscription(ctxt, subscriber, 0)
   135  		assert.Nil(err)
   136  		subs[subscriber] = subChan
   137  		subNames = append(subNames, subscriber)
   138  	}
   139  
   140  	// Case 1: blocking publish
   141  	{
   142  		test := testMsg{msg: uuid.NewString()}
   143  		complete := make(chan bool, 3)
   144  
   145  		lclCtxt, lclCancel := context.WithTimeout(ctxt, time.Millisecond*100)
   146  
   147  		go func() {
   148  			assert.Nil(testTopic.Publish(lclCtxt, &test, 0))
   149  			complete <- true
   150  		}()
   151  
   152  		h := func(channel chan interface{}) {
   153  			select {
   154  			case <-lclCtxt.Done():
   155  				assert.False(true, "msg timed out")
   156  			case msg, ok := <-channel:
   157  				assert.True(ok)
   158  				asString, ok := msg.(*testMsg)
   159  				assert.True(ok)
   160  				assert.Equal(test.msg, asString.msg)
   161  				complete <- true
   162  			}
   163  		}
   164  
   165  		for _, channel := range subs {
   166  			go h(channel)
   167  		}
   168  
   169  		for itr := 0; itr < 3; itr++ {
   170  			select {
   171  			case <-lclCtxt.Done():
   172  				assert.False(true, "test timed out")
   173  			case <-complete:
   174  			}
   175  		}
   176  
   177  		lclCancel()
   178  	}
   179  
   180  	// Case 2: non-blocking publish, but one not receiving
   181  	{
   182  		test := testMsg{msg: uuid.NewString()}
   183  		complete := make(chan bool, 1)
   184  
   185  		lclCtxt, lclCancel := context.WithTimeout(ctxt, time.Millisecond*100)
   186  
   187  		go func() {
   188  			assert.Nil(testTopic.Publish(lclCtxt, &test, time.Millisecond*10))
   189  			complete <- true
   190  		}()
   191  
   192  		select {
   193  		case <-lclCtxt.Done():
   194  			assert.False(true, "msg timed out")
   195  		case msg, ok := <-subs[subNames[0]]:
   196  			assert.True(ok)
   197  			asString, ok := msg.(*testMsg)
   198  			assert.True(ok)
   199  			assert.Equal(test.msg, asString.msg)
   200  		}
   201  
   202  		select {
   203  		case <-lclCtxt.Done():
   204  			assert.False(true, "test timed out")
   205  		case <-complete:
   206  		}
   207  
   208  		select {
   209  		case <-lclCtxt.Done():
   210  			break
   211  		case <-subs[subNames[1]]:
   212  			assert.False(true, "should not have received a message")
   213  		}
   214  
   215  		lclCancel()
   216  	}
   217  
   218  	// Case 3: non-blocking publish, prepared to receive
   219  	{
   220  		test := testMsg{msg: uuid.NewString()}
   221  		complete := make(chan bool, 3)
   222  
   223  		lclCtxt, lclCancel := context.WithTimeout(ctxt, time.Millisecond*100)
   224  
   225  		go func() {
   226  			assert.Nil(testTopic.Publish(lclCtxt, &test, time.Millisecond*10))
   227  			complete <- true
   228  		}()
   229  
   230  		h := func(channel chan interface{}) {
   231  			select {
   232  			case <-lclCtxt.Done():
   233  				assert.False(true, "msg timed out")
   234  			case msg, ok := <-channel:
   235  				assert.True(ok)
   236  				asString, ok := msg.(*testMsg)
   237  				assert.True(ok)
   238  				assert.Equal(test.msg, asString.msg)
   239  				complete <- true
   240  			}
   241  		}
   242  
   243  		for _, channel := range subs {
   244  			go h(channel)
   245  		}
   246  
   247  		for itr := 0; itr < 3; itr++ {
   248  			select {
   249  			case <-lclCtxt.Done():
   250  				assert.False(true, "test timed out")
   251  			case <-complete:
   252  			}
   253  		}
   254  
   255  		lclCancel()
   256  	}
   257  
   258  	// Delete subscription
   259  	for subName := range subs {
   260  		assert.Nil(testTopic.DeleteSubscription(ctxt, subName))
   261  	}
   262  }
   263  
   264  func TestMessageBus(t *testing.T) {
   265  	assert := assert.New(t)
   266  	log.SetLevel(log.DebugLevel)
   267  
   268  	ctxt, cancel := context.WithCancel(context.Background())
   269  	defer cancel()
   270  
   271  	testBus, err := GetNewMessageBusInstance(ctxt, log.Fields{"unit-testing": "testing"})
   272  	assert.Nil(err)
   273  
   274  	// Case 0: create topic
   275  	topic := uuid.NewString()
   276  	{
   277  		_, err := testBus.CreateTopic(ctxt, topic, log.Fields{})
   278  		assert.Nil(err)
   279  	}
   280  	// Create same topic again
   281  	{
   282  		_, err := testBus.CreateTopic(ctxt, topic, log.Fields{})
   283  		assert.Nil(err)
   284  	}
   285  
   286  	// Case 1: get topic
   287  	{
   288  		_, err := testBus.GetTopic(ctxt, topic)
   289  		assert.Nil(err)
   290  	}
   291  	// Get unknown topic
   292  	{
   293  		_, err := testBus.GetTopic(ctxt, uuid.NewString())
   294  		assert.NotNil(err)
   295  	}
   296  
   297  	// Case 2: delete topic
   298  	assert.Nil(testBus.DeleteTopic(ctxt, topic))
   299  	// Delete unknown topic
   300  	assert.NotNil(testBus.DeleteTopic(ctxt, uuid.NewString()))
   301  }