github.com/moleculer-go/moleculer@v0.3.3/transit/nats/stan_test.go (about)

     1  package nats_test
     2  
     3  import (
     4  	"os"
     5  
     6  	"github.com/moleculer-go/moleculer/payload"
     7  	"github.com/moleculer-go/moleculer/util"
     8  	. "github.com/onsi/ginkgo"
     9  	. "github.com/onsi/gomega"
    10  
    11  	"github.com/moleculer-go/moleculer"
    12  	"github.com/moleculer-go/moleculer/broker"
    13  	"github.com/moleculer-go/moleculer/context"
    14  	"github.com/moleculer-go/moleculer/serializer"
    15  	"github.com/moleculer-go/moleculer/transit/nats"
    16  )
    17  
    18  var StanTestHost = os.Getenv("STAN_HOST")
    19  var _ = Describe("NATS Streaming Transit", func() {
    20  	brokerDelegates := BrokerDelegates()
    21  	contextA := context.BrokerContext(brokerDelegates)
    22  	logger := contextA.Logger()
    23  	var serializer serializer.Serializer = serializer.CreateJSONSerializer(logger)
    24  	url := "stan://" + StanTestHost + ":4222"
    25  	options := nats.StanOptions{
    26  		url,
    27  		"test-cluster",
    28  		"unit-test-client-id",
    29  		logger,
    30  		serializer,
    31  		func(msg moleculer.Payload) bool {
    32  			return true
    33  		},
    34  	}
    35  
    36  	stringSize := 50
    37  	arraySize := 100
    38  	var longList []interface{}
    39  	for i := 0; i < arraySize; i++ {
    40  		randomString := util.RandomString(stringSize)
    41  		longList = append(longList, randomString)
    42  	}
    43  
    44  	Describe("Start / Stop Cycles.", func() {
    45  		logLevel := "FATAL"
    46  		numberOfLoops := 5
    47  		loopNumber := 0
    48  		Measure("Creation of multiple brokers with connect/disconnect cycles running on stan transporter.", func(bench Benchmarker) {
    49  
    50  			var userBroker, contactBroker, profileBroker *broker.ServiceBroker
    51  			bench.Time("brokers creation", func() {
    52  				userBroker = broker.New(&moleculer.Config{
    53  					LogLevel:    logLevel,
    54  					Transporter: "STAN",
    55  				})
    56  				userBroker.Publish(userService())
    57  				userBroker.Start()
    58  
    59  				contactBroker = broker.New(&moleculer.Config{
    60  					LogLevel:    logLevel,
    61  					Transporter: "STAN",
    62  				})
    63  				contactBroker.Publish(contactService())
    64  				contactBroker.Start()
    65  
    66  				profileBroker = broker.New(&moleculer.Config{
    67  					LogLevel:    logLevel,
    68  					Transporter: "STAN",
    69  				})
    70  				profileBroker.Publish(profileService())
    71  				profileBroker.Start()
    72  			})
    73  
    74  			bench.Time("local calls", func() {
    75  				result := <-userBroker.Call("user.update", longList)
    76  				Expect(len(result.StringArray())).Should(Equal(arraySize + 1))
    77  
    78  				result = <-contactBroker.Call("contact.update", longList)
    79  				Expect(len(result.StringArray())).Should(Equal(arraySize + 1))
    80  			})
    81  
    82  			bench.Time("5 remote calls", func() {
    83  				result := <-userBroker.Call("contact.update", longList)
    84  				Expect(len(result.StringArray())).Should(Equal(arraySize + 1))
    85  
    86  				result = <-contactBroker.Call("user.update", longList)
    87  				Expect(len(result.StringArray())).Should(Equal(arraySize + 1))
    88  
    89  				result = <-profileBroker.Call("profile.update", longList)
    90  				Expect(len(result.StringArray())).Should(Equal(arraySize + 3))
    91  
    92  				result = <-contactBroker.Call("profile.update", longList)
    93  				Expect(len(result.StringArray())).Should(Equal(arraySize + 3))
    94  
    95  				result = <-userBroker.Call("profile.update", longList)
    96  				Expect(len(result.StringArray())).Should(Equal(arraySize + 3))
    97  			})
    98  
    99  			bench.Time("stop and fail on action call", func() {
   100  				stopBrokers(userBroker)
   101  
   102  				Expect((<-contactBroker.Call("user.update", longList)).IsError()).Should(BeTrue())
   103  				Expect((<-profileBroker.Call("user.update", longList)).IsError()).Should(BeTrue())
   104  
   105  				stopBrokers(contactBroker)
   106  				Expect((<-profileBroker.Call("contact.update", longList)).IsError()).Should(BeTrue())
   107  
   108  				stopBrokers(profileBroker)
   109  				Expect(func() {
   110  					<-profileBroker.Call("profile.update", longList)
   111  				}).Should(Panic())
   112  			})
   113  
   114  			loopNumber++
   115  
   116  		}, numberOfLoops)
   117  
   118  	})
   119  
   120  	It("Should connect, subscribe, publish and disconnect", func() {
   121  		params := map[string]string{
   122  			"name":     "John",
   123  			"lastName": "Snow",
   124  		}
   125  
   126  		actionName := "some.service.action"
   127  		actionContext := contextA.ChildActionContext(actionName, payload.New(params))
   128  
   129  		transporter := nats.CreateStanTransporter(options)
   130  		transporter.SetPrefix("MOL")
   131  		Expect(<-transporter.Connect()).Should(Succeed())
   132  
   133  		received := make(chan bool)
   134  		transporter.Subscribe("topicA", "node1", func(message moleculer.Payload) {
   135  
   136  			contextMap := serializer.PayloadToContextMap(message)
   137  
   138  			newContext := context.ActionContext(brokerDelegates, contextMap)
   139  			Expect(newContext.ActionName()).Should(Equal(actionName))
   140  			contextParams := newContext.Payload()
   141  			Expect(contextParams.Get("name").String()).Should(Equal("John"))
   142  			Expect(contextParams.Get("lastName").String()).Should(Equal("Snow"))
   143  
   144  			received <- true
   145  		})
   146  
   147  		contextMap := actionContext.AsMap()
   148  		contextMap["sender"] = "someone"
   149  
   150  		msg, _ := serializer.MapToPayload(&contextMap)
   151  
   152  		transporter.Publish("topicA", "node1", msg)
   153  
   154  		Expect(<-received).Should(Equal(true))
   155  
   156  		Expect(<-transporter.Disconnect()).Should(Succeed())
   157  
   158  	})
   159  
   160  	It("Should fail to connect", func() {
   161  		logger := contextA.Logger()
   162  		options := nats.StanOptions{
   163  			URL:        "some ivalid URL",
   164  			ClientID:   "test-cluster",
   165  			Logger:     logger,
   166  			Serializer: serializer,
   167  			ValidateMsg: func(msg moleculer.Payload) bool {
   168  				return true
   169  			},
   170  		}
   171  		transporter := nats.CreateStanTransporter(options)
   172  		transporter.SetPrefix("MOL")
   173  		Expect(<-transporter.Connect()).ShouldNot(Succeed())
   174  	})
   175  
   176  	It("Should not fail on double disconnect", func() {
   177  		logger := contextA.Logger()
   178  		options := nats.StanOptions{
   179  			url,
   180  			"test-cluster",
   181  			"unit-test-client-id",
   182  			logger,
   183  			serializer,
   184  			func(msg moleculer.Payload) bool {
   185  				return true
   186  			},
   187  		}
   188  		transporter := nats.CreateStanTransporter(options)
   189  		transporter.SetPrefix("MOL")
   190  		Expect(<-transporter.Connect()).Should(Succeed())
   191  		Expect(<-transporter.Disconnect()).Should(Succeed())
   192  		Expect(<-transporter.Disconnect()).Should(Succeed())
   193  	})
   194  
   195  	It("Should fail Subscribe() and Publish() when is not connected", func() {
   196  		transporter := nats.CreateStanTransporter(nats.StanOptions{})
   197  		Expect(func() { transporter.Subscribe("", "", func(moleculer.Payload) {}) }).Should(Panic())
   198  		Expect(func() { transporter.Publish("", "", payload.Empty()) }).Should(Panic())
   199  	})
   200  
   201  })