github.com/moleculer-go/moleculer@v0.3.3/transit/nats/nats_test.go (about) 1 package nats_test 2 3 import ( 4 "os" 5 "time" 6 7 "github.com/moleculer-go/moleculer/payload" 8 "github.com/moleculer-go/moleculer/util" 9 . "github.com/onsi/ginkgo" 10 . "github.com/onsi/gomega" 11 12 "github.com/moleculer-go/moleculer" 13 "github.com/moleculer-go/moleculer/broker" 14 "github.com/moleculer-go/moleculer/context" 15 "github.com/moleculer-go/moleculer/serializer" 16 "github.com/moleculer-go/moleculer/transit/nats" 17 ) 18 19 func natsTestHost() string { 20 env := os.Getenv("NATS_HOST") 21 if env == "" { 22 return "localhost" 23 } 24 return env 25 } 26 27 var NatsTestHost = natsTestHost() 28 29 var _ = Describe("NATS Streaming Transit", func() { 30 //log.SetLevel(log.TraceLevel) 31 brokerDelegates := BrokerDelegates() 32 contextA := context.BrokerContext(brokerDelegates) 33 url := "nats://" + NatsTestHost + ":4222" 34 35 stringSize := 50 36 arraySize := 100 37 var longList []interface{} 38 for i := 0; i < arraySize; i++ { 39 randomString := util.RandomString(stringSize) 40 longList = append(longList, randomString) 41 } 42 43 Describe("Remote Calls", func() { 44 logLevel := "fatal" 45 transporter := "nats://" + NatsTestHost + ":4222" 46 47 var userBroker, profileBroker *broker.ServiceBroker 48 BeforeEach(func() { 49 50 userBroker = broker.New(&moleculer.Config{ 51 LogLevel: logLevel, 52 Transporter: transporter, 53 DiscoverNodeID: func() string { 54 return "user_broker" 55 }, 56 RequestTimeout: time.Second, 57 }) 58 userBroker.Publish(userService()) 59 60 profileBroker = broker.New(&moleculer.Config{ 61 LogLevel: logLevel, 62 Transporter: transporter, 63 DiscoverNodeID: func() string { 64 return "profile_broker" 65 }, 66 RequestTimeout: time.Second, 67 }) 68 profileBroker.Publish(profileService()) 69 70 }) 71 72 It("should make a remote call from profile broker a to user broker", func() { 73 userBroker.Start() 74 profileBroker.Start() 75 profileBroker.WaitFor("user") 76 result := <-profileBroker.Call("user.update", longList) 77 Expect(result.Error()).Should(Succeed()) 78 Expect(len(result.StringArray())).Should(Equal(arraySize + 1)) 79 80 userBroker.Stop() 81 profileBroker.Stop() 82 }) 83 84 It("should fail after brokers are stopped", func() { 85 userBroker.Start() 86 profileBroker.Start() 87 88 profileBroker.WaitFor("user") 89 p := (<-profileBroker.Call("user.update", longList)) 90 Expect(p.Error()).Should(Succeed()) 91 userBroker.Stop() 92 93 r := <-profileBroker.Call("user.update", longList) 94 Expect(r.IsError()).Should(BeTrue()) 95 96 profileBroker.Stop() 97 }) 98 }) 99 100 Describe("Start / Stop Cycles.", func() { 101 logLevel := "error" 102 numberOfLoops := 5 103 loopNumber := 0 104 Measure("Creation of multiple brokers with connect/disconnect cycles running on nats transporter.", func(bench Benchmarker) { 105 transporter := "nats://" + NatsTestHost + ":4222" 106 var userBroker, contactBroker, profileBroker *broker.ServiceBroker 107 bench.Time("brokers creation", func() { 108 userBroker = broker.New(&moleculer.Config{ 109 LogLevel: logLevel, 110 Transporter: transporter, 111 RequestTimeout: time.Second, 112 }) 113 userBroker.Publish(userService()) 114 userBroker.Start() 115 116 contactBroker = broker.New(&moleculer.Config{ 117 LogLevel: logLevel, 118 Transporter: transporter, 119 RequestTimeout: time.Second, 120 }) 121 contactBroker.Publish(contactService()) 122 contactBroker.Start() 123 124 profileBroker = broker.New(&moleculer.Config{ 125 LogLevel: logLevel, 126 Transporter: transporter, 127 RequestTimeout: time.Second, 128 }) 129 profileBroker.Publish(profileService()) 130 profileBroker.Start() 131 132 userBroker.WaitFor("contact", "profile") 133 contactBroker.WaitFor("user", "profile") 134 profileBroker.WaitFor("contact", "user") 135 }) 136 137 bench.Time("local calls", func() { 138 result := <-userBroker.Call("user.update", longList) 139 Expect(len(result.StringArray())).Should(Equal(arraySize + 1)) 140 141 result = <-contactBroker.Call("contact.update", longList) 142 Expect(len(result.StringArray())).Should(Equal(arraySize + 1)) 143 }) 144 145 bench.Time("5 remote calls", func() { 146 result := <-userBroker.Call("contact.update", longList) 147 Expect(len(result.StringArray())).Should(Equal(arraySize + 1)) 148 149 result = <-contactBroker.Call("user.update", longList) 150 Expect(len(result.StringArray())).Should(Equal(arraySize + 1)) 151 152 result = <-profileBroker.Call("profile.update", longList) 153 Expect(len(result.StringArray())).Should(Equal(arraySize + 3)) 154 155 result = <-contactBroker.Call("profile.update", longList) 156 Expect(len(result.StringArray())).Should(Equal(arraySize + 3)) 157 158 result = <-userBroker.Call("profile.update", longList) 159 Expect(len(result.StringArray())).Should(Equal(arraySize + 3)) 160 }) 161 162 bench.Time("stop and fail on action call", func() { 163 stopBrokers(userBroker) 164 165 Expect((<-contactBroker.Call("user.update", longList)).IsError()).Should(BeTrue()) 166 Expect((<-profileBroker.Call("user.update", longList)).IsError()).Should(BeTrue()) 167 168 stopBrokers(contactBroker) 169 Expect((<-profileBroker.Call("contact.update", longList)).IsError()).Should(BeTrue()) 170 171 stopBrokers(profileBroker) 172 Expect(func() { 173 <-profileBroker.Call("profile.update", longList) 174 }).Should(Panic()) 175 }) 176 177 loopNumber++ 178 179 }, numberOfLoops) 180 181 }) 182 183 It("Should fail to connect", func() { 184 logger := contextA.Logger() 185 var serializer serializer.Serializer = serializer.CreateJSONSerializer(logger) 186 options := nats.NATSOptions{ 187 URL: "some ivalid URL", 188 Name: "test-cluster", 189 Logger: logger, 190 Serializer: serializer, 191 ValidateMsg: func(msg moleculer.Payload) bool { 192 return true 193 }, 194 } 195 transporter := nats.CreateNatsTransporter(options) 196 transporter.SetPrefix("MOL") 197 Expect(<-transporter.Connect()).ShouldNot(Succeed()) 198 }) 199 200 It("Should not fail on double disconnect", func() { 201 logger := contextA.Logger() 202 var serializer serializer.Serializer = serializer.CreateJSONSerializer(logger) 203 options := nats.NATSOptions{ 204 URL: url, 205 Name: "test-cluster", 206 Logger: logger, 207 Serializer: serializer, 208 ValidateMsg: func(msg moleculer.Payload) bool { 209 return true 210 }, 211 } 212 transporter := nats.CreateNatsTransporter(options) 213 transporter.SetPrefix("MOL") 214 Expect(<-transporter.Connect()).Should(Succeed()) 215 Expect(<-transporter.Disconnect()).Should(Succeed()) 216 Expect(<-transporter.Disconnect()).Should(Succeed()) 217 }) 218 219 It("Should fail Subscribe() and Publish() when is not connected", func() { 220 transporter := nats.CreateNatsTransporter(nats.NATSOptions{}) 221 Expect(func() { transporter.Subscribe("", "", func(moleculer.Payload) {}) }).Should(Panic()) 222 Expect(func() { transporter.Publish("", "", payload.Empty()) }).Should(Panic()) 223 }) 224 225 It("Should connect, subscribe, publish and disconnect", func() { 226 logger := contextA.Logger() 227 var serializer serializer.Serializer = serializer.CreateJSONSerializer(logger) 228 options := nats.NATSOptions{ 229 URL: url, 230 Name: "test-cluster", 231 Logger: logger, 232 Serializer: serializer, 233 ValidateMsg: func(msg moleculer.Payload) bool { 234 return true 235 }, 236 } 237 238 params := map[string]string{ 239 "name": "John", 240 "lastName": "Snow", 241 } 242 243 actionName := "some.service.action" 244 actionContext := contextA.ChildActionContext(actionName, payload.New(params)) 245 246 transporter := nats.CreateNatsTransporter(options) 247 transporter.SetPrefix("MOL") 248 Expect(<-transporter.Connect()).Should(Succeed()) 249 250 received := make(chan bool) 251 transporter.Subscribe("topicA", "node1", func(message moleculer.Payload) { 252 253 contextMap := serializer.PayloadToContextMap(message) 254 255 newContext := context.ActionContext(brokerDelegates, contextMap) 256 Expect(newContext.ActionName()).Should(Equal(actionName)) 257 contextParams := newContext.Payload() 258 Expect(contextParams.Get("name").String()).Should(Equal("John")) 259 Expect(contextParams.Get("lastName").String()).Should(Equal("Snow")) 260 261 received <- true 262 }) 263 264 contextMap := actionContext.AsMap() 265 contextMap["sender"] = "someone" 266 267 msg, _ := serializer.MapToPayload(&contextMap) 268 269 transporter.Publish("topicA", "node1", msg) 270 271 Expect(<-received).Should(Equal(true)) 272 273 Expect(<-transporter.Disconnect()).Should(Succeed()) 274 275 }) 276 277 })