github.com/moleculer-go/moleculer@v0.3.3/broker/broker_internals_test.go (about) 1 package broker 2 3 import ( 4 "fmt" 5 "os" 6 7 "time" 8 9 "github.com/moleculer-go/cupaloy/v2" 10 "github.com/moleculer-go/moleculer" 11 "github.com/moleculer-go/moleculer/context" 12 "github.com/moleculer-go/moleculer/test" 13 "github.com/moleculer-go/moleculer/transit/memory" 14 . "github.com/onsi/ginkgo" 15 . "github.com/onsi/gomega" 16 log "github.com/sirupsen/logrus" 17 ) 18 19 var snap = cupaloy.New(cupaloy.FailOnUpdate(os.Getenv("UPDATE_SNAPSHOTS") == "true")) 20 21 func hasKey(m map[string]moleculer.Payload, k string) bool { 22 _, foundKey := m[k] 23 return foundKey 24 } 25 26 var _ = Describe("Broker Internals", func() { 27 28 Describe("Broker events", func() { 29 It("Should trigger Local and remote events", func() { 30 logLevel := "ERROR" 31 verse := "3 little birds..." 32 chorus := "don't worry..." 33 mem := &memory.SharedMemory{} 34 baseConfig := &moleculer.Config{ 35 LogLevel: logLevel, 36 TransporterFactory: func() interface{} { 37 transport := memory.Create(log.WithField("transport", "memory"), mem) 38 return &transport 39 }, 40 } 41 counters := test.Counter() 42 43 soundsBroker := New(baseConfig, &moleculer.Config{ 44 DiscoverNodeID: func() string { return "SoundsBroker" }, 45 }) 46 soundsBroker.Publish(moleculer.ServiceSchema{ 47 Name: "music", 48 Actions: []moleculer.Action{ 49 moleculer.Action{ 50 Name: "start", 51 Handler: func(ctx moleculer.Context, verse moleculer.Payload) interface{} { 52 ctx.Logger().Debug(" ** !!! ### music.start ### !!! ** ") 53 ctx.Emit("music.verse", verse) 54 counters.Inc(ctx.(*context.Context).BrokerDelegates().LocalNode().GetID(), "music.start") 55 return nil 56 }, 57 }, 58 moleculer.Action{ 59 Name: "end", 60 Handler: func(ctx moleculer.Context, chorus moleculer.Payload) interface{} { 61 ctx.Emit("music.chorus", chorus) 62 counters.Inc(ctx.(*context.Context).BrokerDelegates().LocalNode().GetID(), "music.end") 63 return nil 64 }, 65 }, 66 }, 67 Events: []moleculer.Event{ 68 moleculer.Event{ 69 Name: "music.verse", 70 Handler: func(ctx moleculer.Context, verse moleculer.Payload) { 71 ctx.Logger().Debug("music.verse --> ", verse.String()) 72 ctx.Emit("music.chorus", verse) 73 counters.Inc(ctx.(*context.Context).BrokerDelegates().LocalNode().GetID(), "music.music.verse") 74 }, 75 }, 76 moleculer.Event{ 77 Name: "music.chorus", 78 Handler: func(ctx moleculer.Context, chorus moleculer.Payload) { 79 ctx.Logger().Debug("music.chorus --> ", chorus.String()) 80 counters.Inc(ctx.(*context.Context).BrokerDelegates().LocalNode().GetID(), "music.music.chorus") 81 }, 82 }, 83 }, 84 }) 85 djService := moleculer.ServiceSchema{ 86 Name: "dj", 87 Dependencies: []string{"music"}, 88 Events: []moleculer.Event{ 89 moleculer.Event{ 90 Name: "music.verse", 91 Handler: func(ctx moleculer.Context, verse moleculer.Payload) { 92 ctx.Logger().Debug("DJ music.verse --> ", verse.String()) 93 ctx.Emit("music.chorus", verse) 94 counters.Inc(ctx.(*context.Context).BrokerDelegates().LocalNode().GetID(), "dj.music.verse") 95 }, 96 }, 97 moleculer.Event{ 98 Name: "music.chorus", 99 Handler: func(ctx moleculer.Context, chorus moleculer.Payload) { 100 ctx.Logger().Debug("DJ music.chorus --> ", chorus.String()) 101 counters.Inc(ctx.(*context.Context).BrokerDelegates().LocalNode().GetID(), "dj.music.chorus") 102 }, 103 }, 104 moleculer.Event{ 105 Name: "music.tone", 106 Handler: func(ctx moleculer.Context, ring moleculer.Payload) { 107 ctx.Logger().Debug("DJ music.tone ring --> ", ring.String()) 108 counters.Inc(ctx.(*context.Context).BrokerDelegates().LocalNode().GetID(), "dj.music.tone") 109 }, 110 }, 111 }, 112 } 113 soundsBroker.Publish(djService) 114 115 // soundsBroker.delegates.EmitEvent = func(context moleculer.BrokerContext) { 116 // entries := soundsBroker.registry.LoadBalanceEvent(context) 117 // fmt.Println("entries -> ", entries) 118 // Expect(snap.SnapshotMulti("entries_1-music.verse_2-music.chorus", entries)).Should(Succeed()) 119 // } 120 soundsBroker.Start() 121 Expect(snap.SnapshotMulti("soundsBroker-KnownNodes", soundsBroker.registry.KnownNodes())).Should(Succeed()) 122 123 //Scenario: action music.start will emit music.verse wich emits music.chorus - becuase there are 2 listeners for music.serve 124 //there should be too emits to music.chorus 125 <-soundsBroker.Call("music.start", verse) 126 127 Expect(counters.Check("music.music.verse", 1)).ShouldNot(HaveOccurred()) 128 Expect(counters.Check("dj.music.verse", 1)).ShouldNot(HaveOccurred()) 129 130 Expect(counters.Check("music.music.chorus", 2)).ShouldNot(HaveOccurred()) //failed here 131 Expect(counters.Check("dj.music.chorus", 2)).ShouldNot(HaveOccurred()) 132 133 //Scenario: music.end will emit music.chorus once. 134 <-soundsBroker.Call("music.end", chorus) 135 136 Expect(counters.Check("music.music.verse", 1)).ShouldNot(HaveOccurred()) 137 Expect(counters.Check("dj.music.verse", 1)).ShouldNot(HaveOccurred()) 138 139 Expect(counters.Check("music.music.chorus", 3)).ShouldNot(HaveOccurred()) 140 Expect(counters.Check("dj.music.chorus", 3)).ShouldNot(HaveOccurred()) 141 142 visualBroker := New(baseConfig, &moleculer.Config{ 143 DiscoverNodeID: func() string { return "VisualBroker" }, 144 }) 145 vjService := moleculer.ServiceSchema{ 146 Name: "vj", 147 Dependencies: []string{"music", "dj"}, 148 Events: []moleculer.Event{ 149 moleculer.Event{ 150 Name: "music.verse", 151 Handler: func(ctx moleculer.Context, verse moleculer.Payload) { 152 ctx.Logger().Debug("VJ music.verse --> ", verse.String()) 153 counters.Inc(ctx.(*context.Context).BrokerDelegates().LocalNode().GetID(), "vj.music.verse") 154 }, 155 }, 156 moleculer.Event{ 157 Name: "music.chorus", 158 Handler: func(ctx moleculer.Context, chorus moleculer.Payload) { 159 ctx.Logger().Debug("VJ music.chorus --> ", chorus.String()) 160 counters.Inc(ctx.(*context.Context).BrokerDelegates().LocalNode().GetID(), "vj.music.chorus") 161 }, 162 }, 163 moleculer.Event{ 164 Name: "music.tone", 165 Handler: func(ctx moleculer.Context, ring moleculer.Payload) { 166 ctx.Logger().Debug("VJ music.tone ring --> ", ring.String()) 167 counters.Inc(ctx.(*context.Context).BrokerDelegates().LocalNode().GetID(), "vj.music.tone") 168 }, 169 }, 170 }, 171 } 172 visualBroker.Publish(vjService) 173 visualBroker.Publish(moleculer.ServiceSchema{ 174 Name: "visualBrokerService", 175 Dependencies: []string{"music"}, 176 }) 177 visualBroker.Start() 178 visualBroker.WaitForNodes("SoundsBroker") 179 Expect(snap.SnapshotMulti("visualBroker-KnownNodes", visualBroker.registry.KnownNodes())).Should(Succeed()) 180 181 counters.Clear() 182 time.Sleep(time.Millisecond) 183 //Scenario: same action music.start as before, but now we added a new broker and new service. 184 visualBroker.Call("music.start", verse) 185 186 time.Sleep(time.Millisecond) 187 Expect(counters.Check("music.start", 1)).ShouldNot(HaveOccurred()) 188 Expect(counters.Check("music.music.verse", 1)).ShouldNot(HaveOccurred()) 189 Expect(counters.Check("dj.music.verse", 1)).ShouldNot(HaveOccurred()) 190 Expect(counters.Check("vj.music.verse", 1)).ShouldNot(HaveOccurred()) 191 192 Expect(counters.Check("music.music.chorus", 2)).ShouldNot(HaveOccurred()) 193 Expect(counters.Check("dj.music.chorus", 2)).ShouldNot(HaveOccurred()) 194 Expect(counters.Check("vj.music.chorus", 2)).ShouldNot(HaveOccurred()) 195 196 <-visualBroker.Call("music.end", chorus) 197 198 Expect(counters.Check("music.end", 1)).ShouldNot(HaveOccurred()) 199 Expect(counters.Check("music.music.verse", 1)).ShouldNot(HaveOccurred()) 200 Expect(counters.Check("dj.music.verse", 1)).ShouldNot(HaveOccurred()) 201 Expect(counters.Check("vj.music.verse", 1)).ShouldNot(HaveOccurred()) 202 203 Expect(counters.Check("music.music.chorus", 3)).ShouldNot(HaveOccurred()) 204 Expect(counters.Check("dj.music.chorus", 3)).ShouldNot(HaveOccurred()) 205 Expect(counters.Check("vj.music.chorus", 3)).ShouldNot(HaveOccurred()) 206 207 //add a second instance of the vj service, but only one should receive emit events. 208 aquaBroker := New(baseConfig, &moleculer.Config{ 209 DiscoverNodeID: func() string { return "AquaBroker" }, 210 }) 211 aquaBroker.Publish(vjService) 212 aquaBroker.Publish(moleculer.ServiceSchema{ 213 Name: "aquaBrokerService", 214 Dependencies: []string{"music", "dj"}, 215 }) 216 aquaBroker.Start() 217 for { 218 if len(aquaBroker.registry.KnownNodes()) == 3 { 219 break 220 } 221 time.Sleep(time.Microsecond) 222 } 223 Expect(snap.SnapshotMulti("aquaBroker-KnownNodes", aquaBroker.registry.KnownNodes())).Should(Succeed()) 224 for { 225 if len(aquaBroker.registry.KnownEventListeners(true)) == 11 { 226 break 227 } 228 time.Sleep(time.Microsecond) 229 } 230 Expect(snap.SnapshotMulti("aquaBroker-KnownEventListeners", aquaBroker.registry.KnownEventListeners(true))).Should(Succeed()) 231 232 counters.Clear() 233 234 aquaBroker.Call("music.start", chorus) 235 236 Expect(counters.Check("music.start", 1)).ShouldNot(HaveOccurred()) 237 Expect(counters.Check("music.music.verse", 1)).ShouldNot(HaveOccurred()) 238 Expect(counters.Check("dj.music.verse", 1)).ShouldNot(HaveOccurred()) 239 Expect(counters.Check("vj.music.verse", 1)).ShouldNot(HaveOccurred()) 240 241 Expect(counters.Check("music.music.chorus", 2)).ShouldNot(HaveOccurred()) 242 Expect(counters.Check("dj.music.chorus", 2)).ShouldNot(HaveOccurred()) //failed here 243 Expect(counters.Check("vj.music.chorus", 2)).ShouldNot(HaveOccurred()) 244 245 <-visualBroker.Call("music.end", chorus) 246 247 Expect(counters.Check("music.end", 1)).ShouldNot(HaveOccurred()) 248 Expect(counters.Check("music.music.verse", 1)).ShouldNot(HaveOccurred()) 249 Expect(counters.Check("dj.music.verse", 1)).ShouldNot(HaveOccurred()) 250 Expect(counters.Check("vj.music.verse", 1)).ShouldNot(HaveOccurred()) 251 252 Expect(counters.Check("music.music.chorus", 3)).ShouldNot(HaveOccurred()) 253 Expect(counters.Check("dj.music.chorus", 3)).ShouldNot(HaveOccurred()) 254 Expect(counters.Check("vj.music.chorus", 3)).ShouldNot(HaveOccurred()) 255 256 //add a second instance of the dj service 257 stormBroker := New(baseConfig, &moleculer.Config{ 258 DiscoverNodeID: func() string { return "StormBroker" }, 259 }) 260 stormBroker.Publish(djService) 261 stormBroker.Start() 262 for { 263 if len(stormBroker.registry.KnownNodes()) == 4 { 264 break 265 } 266 time.Sleep(time.Microsecond) 267 } 268 Expect(snap.SnapshotMulti("stormBroker-KnownNodes", stormBroker.registry.KnownNodes())).Should(Succeed()) 269 for { 270 if len(stormBroker.registry.KnownEventListeners(true)) == 14 { 271 break 272 } 273 time.Sleep(time.Microsecond) 274 } 275 Expect(snap.SnapshotMulti("stormBroker-KnownEventListeners", stormBroker.registry.KnownEventListeners(true))).Should(Succeed()) 276 277 counters.Clear() 278 279 stormBroker.Call("music.start", verse) 280 281 Expect(counters.Check("music.start", 1)).ShouldNot(HaveOccurred()) 282 Expect(counters.Check("music.music.verse", 1)).ShouldNot(HaveOccurred()) 283 Expect(counters.Check("dj.music.verse", 1)).ShouldNot(HaveOccurred()) 284 Expect(counters.Check("vj.music.verse", 1)).ShouldNot(HaveOccurred()) 285 286 Expect(counters.Check("music.music.chorus", 2)).ShouldNot(HaveOccurred()) 287 Expect(counters.Check("dj.music.chorus", 2)).ShouldNot(HaveOccurred()) 288 Expect(counters.Check("vj.music.chorus", 2)).ShouldNot(HaveOccurred()) 289 290 <-stormBroker.Call("music.end", chorus) 291 292 Expect(counters.Check("music.end", 1)).ShouldNot(HaveOccurred()) 293 Expect(counters.Check("music.music.verse", 1)).ShouldNot(HaveOccurred()) 294 Expect(counters.Check("dj.music.verse", 1)).ShouldNot(HaveOccurred()) 295 Expect(counters.Check("vj.music.verse", 1)).ShouldNot(HaveOccurred()) 296 297 Expect(counters.Check("music.music.chorus", 3)).ShouldNot(HaveOccurred()) 298 Expect(counters.Check("dj.music.chorus", 3)).ShouldNot(HaveOccurred()) 299 Expect(counters.Check("vj.music.chorus", 3)).ShouldNot(HaveOccurred()) 300 301 counters.Clear() 302 303 //now broadcast and every music.tone event listener should receive it. 304 stormBroker.Broadcast("music.tone", "broad< storm >cast") 305 306 Expect(counters.Check("dj.music.tone", 2)).ShouldNot(HaveOccurred()) 307 Expect(counters.Check("vj.music.tone", 2)).ShouldNot(HaveOccurred()) 308 309 counters.Clear() 310 311 //emit and only 2 shuold be accounted 312 stormBroker.Emit("music.tone", "Emit< storm >cast") 313 314 Expect(counters.Check("dj.music.tone", 1)).ShouldNot(HaveOccurred()) 315 Expect(counters.Check("vj.music.tone", 1)).ShouldNot(HaveOccurred()) 316 317 //remove one dj service 318 stormBroker.Stop() 319 counters.Clear() 320 time.Sleep(time.Millisecond) 321 322 Expect(snap.SnapshotMulti("stormBroker-stopped-aquaBroker-KnownNodes", aquaBroker.registry.KnownNodes())).Should(Succeed()) 323 Expect(snap.SnapshotMulti("stormBroker-stopped-visualBroker-KnownNodes", visualBroker.registry.KnownNodes())).Should(Succeed()) 324 Expect(snap.SnapshotMulti("stormBroker-stopped-soundsBroker-KnownNodes", soundsBroker.registry.KnownNodes())).Should(Succeed()) 325 326 aquaBroker.Broadcast("music.tone", "broad< aqua 1 >cast") 327 328 time.Sleep(time.Millisecond) 329 Expect(counters.Check("dj.music.tone", 1)).ShouldNot(HaveOccurred()) 330 Expect(counters.Check("vj.music.tone", 2)).ShouldNot(HaveOccurred()) 331 332 //remove the other dj service 333 soundsBroker.Stop() 334 counters.Clear() 335 336 Expect(snap.SnapshotMulti("soundsBroker-Stopped-aquaBroker-KnownNodes", aquaBroker.registry.KnownNodes())).Should(Succeed()) 337 Expect(snap.SnapshotMulti("soundsBroker-Stopped-visualBroker-KnownNodes", visualBroker.registry.KnownNodes())).Should(Succeed()) 338 339 aquaBroker.Broadcast("music.tone", "broad< aqua 2 >cast") 340 341 Expect(counters.Check("dj.music.tone", 0)).ShouldNot(HaveOccurred()) 342 Expect(counters.Check("vj.music.tone", 2)).ShouldNot(HaveOccurred()) 343 344 counters.Clear() 345 aquaBroker.Emit("music.tone", "Emit< aqua >cast") 346 347 Expect(counters.Check("dj.music.tone", 0)).ShouldNot(HaveOccurred()) 348 Expect(counters.Check("vj.music.tone", 1)).ShouldNot(HaveOccurred()) 349 350 visualBroker.Stop() 351 aquaBroker.Stop() 352 353 }) 354 }) 355 356 //TODO: MCalls current implementation works ?most of the time" :( ... enought to continue 357 //the dev of other features that need it.. but it need to be refactored so the tests pass everytime.. or maybe the issue is with the testing. 358 Describe("Broker.MCall", func() { 359 360 It("MCall on $node service actions with all params false", func() { 361 MCallTimeout := 20 * time.Second 362 actionHandler := func(result string) func(moleculer.Context, moleculer.Payload) interface{} { 363 return func(ctx moleculer.Context, param moleculer.Payload) interface{} { 364 result := fmt.Sprint("input: (", param.String(), " ) -> output: ( ", result, " )") 365 //fmt.Println("MCALL Action --> ", result) 366 return result 367 } 368 } 369 logLevel := "FATAL" 370 mem := &memory.SharedMemory{} 371 bkr1 := New( 372 &moleculer.Config{ 373 MCallTimeout: MCallTimeout, 374 LogLevel: logLevel, 375 DiscoverNodeID: func() string { return "test-broker1" }, 376 TransporterFactory: func() interface{} { 377 transport := memory.Create(log.WithField("transport", "memory"), mem) 378 return &transport 379 }, 380 }, 381 ) 382 bkr1.Publish(moleculer.ServiceSchema{ 383 Name: "music", 384 Actions: []moleculer.Action{ 385 moleculer.Action{ 386 Name: "start", 387 Handler: actionHandler("start result"), 388 }, 389 moleculer.Action{ 390 Name: "end", 391 Handler: actionHandler("end result"), 392 }, 393 }, 394 }) 395 396 bkr2 := New( 397 &moleculer.Config{ 398 MCallTimeout: MCallTimeout, 399 LogLevel: logLevel, 400 DiscoverNodeID: func() string { return "test-broker2" }, 401 TransporterFactory: func() interface{} { 402 transport := memory.Create(log.WithField("transport", "memory"), mem) 403 return &transport 404 }, 405 }, 406 ) 407 bkr2.Publish(moleculer.ServiceSchema{ 408 Name: "food", 409 Dependencies: []string{"music"}, 410 Actions: []moleculer.Action{ 411 moleculer.Action{ 412 Name: "lunch", 413 Handler: actionHandler("lunch result"), 414 }, 415 moleculer.Action{ 416 Name: "dinner", 417 Handler: actionHandler("dinner result"), 418 }, 419 }, 420 }) 421 422 bkr1.Start() 423 bkr2.Start() 424 425 mParams := map[string]map[string]interface{}{ 426 "food-lunch": map[string]interface{}{ 427 "action": "food.lunch", 428 "params": "lunch param", 429 }, 430 "food-dinner": map[string]interface{}{ 431 "action": "food.dinner", 432 "params": "dinner param", 433 }, 434 "music-start": map[string]interface{}{ 435 "action": "music.start", 436 "params": "start param", 437 }, 438 "music-end": map[string]interface{}{ 439 "action": "music.end", 440 "params": "end param", 441 }, 442 } 443 444 mcallResults := <-bkr2.MCall(mParams) 445 Expect(hasKey(mcallResults, "music-start")).Should(BeTrue()) 446 Expect(hasKey(mcallResults, "music-end")).Should(BeTrue()) 447 Expect(hasKey(mcallResults, "food-dinner")).Should(BeTrue()) 448 Expect(hasKey(mcallResults, "food-lunch")).Should(BeTrue()) 449 450 mcallResults = <-bkr1.MCall(mParams) 451 Expect(hasKey(mcallResults, "music-start")).Should(BeTrue()) 452 Expect(hasKey(mcallResults, "music-end")).Should(BeTrue()) 453 Expect(hasKey(mcallResults, "food-dinner")).Should(BeTrue()) 454 Expect(hasKey(mcallResults, "food-lunch")).Should(BeTrue()) 455 456 bkr1.Stop() 457 bkr2.Stop() 458 }) 459 460 // } 461 462 // orderResults := func(values map[string]moleculer.Payload) interface{} { 463 // result := make(map[string][]map[string]interface{}) 464 // for key, payload := range values { 465 // orderBy := "name" 466 // if key == "nodes" { 467 // orderBy = "id" 468 // } 469 // result[key] = test.OrderMapArray(payload.MapArray(), orderBy) 470 // } 471 // return result 472 // } 473 474 // It("MCall on $node service actions with all params false", 475 // harness("all-false", 476 // map[string]interface{}{ 477 // "withServices": false, 478 // "withActions": false, 479 // "onlyAvailable": false, 480 // "withEndpoints": false, 481 // "skipInternal": false, 482 // }, orderResults)) 483 484 // It("MCall on $node service actions with all params true", 485 // harness("all-true", 486 // map[string]interface{}{ 487 // "withServices": true, 488 // "withActions": true, 489 // "onlyAvailable": true, 490 // "withEndpoints": true, 491 // "skipInternal": true, 492 // }, orderResults)) 493 494 }) 495 496 Context("Middlewares", func() { 497 498 It("Should register user middlewares", func() { 499 500 config := moleculer.Config{DisableInternalMiddlewares: true} 501 bkr := New(&config) 502 Expect(bkr.middlewares.Has("Config")).Should(BeFalse()) 503 504 config = moleculer.Config{ 505 DisableInternalMiddlewares: true, 506 Middlewares: []moleculer.Middlewares{ 507 map[string]moleculer.MiddlewareHandler{ 508 "Config": func(params interface{}, next func(...interface{})) { 509 next() 510 }, 511 }, 512 }, 513 } 514 bkr = New(&config) 515 Expect(bkr.middlewares.Has("Config")).Should(BeTrue()) 516 Expect(bkr.middlewares.Has("anotherOne")).Should(BeFalse()) 517 }) 518 519 It("Should call Config middleware on Start and not change the config", func() { 520 521 ConfigCalls := 0 522 config := moleculer.Config{ 523 DontWaitForNeighbours: true, 524 DisableInternalMiddlewares: true, 525 Middlewares: []moleculer.Middlewares{ 526 map[string]moleculer.MiddlewareHandler{ 527 "Config": func(params interface{}, next func(...interface{})) { 528 ConfigCalls++ 529 next() 530 }, 531 }, 532 }, 533 } 534 bkr := New(&config) 535 Expect(bkr.middlewares.Has("Config")).Should(BeTrue()) 536 bkr.Start() 537 Expect(ConfigCalls).Should(Equal(1)) 538 bkr.Stop() 539 }) 540 541 It("Should call Config middleware on Start and not change the config", func() { 542 543 ConfigCalls := 0 544 config := moleculer.Config{ 545 DontWaitForNeighbours: true, 546 Metrics: true, 547 Middlewares: []moleculer.Middlewares{ 548 map[string]moleculer.MiddlewareHandler{ 549 "Config": func(params interface{}, next func(...interface{})) { 550 Config := params.(moleculer.Config) 551 Config.Metrics = false 552 ConfigCalls++ 553 next(Config) 554 }, 555 }, 556 }, 557 } 558 Expect(config.Metrics).Should(BeTrue()) 559 bkr := New(&config) 560 bkr.Start() 561 Expect(ConfigCalls).Should(Equal(1)) 562 Expect(bkr.config.Metrics).Should(BeFalse()) 563 bkr.Stop() 564 }) 565 566 }) 567 568 Describe("Publish()services...interface{}", func() { 569 It("should panic when passing invalid service", func() { 570 bkr := New() 571 Expect(func() { 572 bkr.Publish("some string") 573 }).Should(Panic()) 574 Expect(func() { 575 bkr.Publish(10) 576 }).Should(Panic()) 577 Expect(func() { 578 bkr.Publish(invalidObj{}) 579 }).Should(Panic()) 580 Expect(func() { 581 bkr.Publish(validService{}) 582 }).ShouldNot(Panic()) 583 }) 584 585 It("should add service strict obj to broker when valid", func() { 586 bkr := New() 587 Expect(len(bkr.services)).Should(Equal(0)) 588 bkr.Publish(validService{}) 589 Expect(len(bkr.services)).Should(Equal(1)) 590 }) 591 592 It("should add service schema obj to broker", func() { 593 bkr := New() 594 Expect(len(bkr.services)).Should(Equal(0)) 595 bkr.Publish(moleculer.ServiceSchema{Name: "service from schema"}) 596 Expect(len(bkr.services)).Should(Equal(1)) 597 }) 598 }) 599 600 }) 601 602 type invalidObj struct { 603 } 604 605 type validService struct { 606 } 607 608 func (s validService) Name() string { 609 return "validService" 610 }