go-micro.dev/v5@v5.12.0/broker/http_test.go (about) 1 package broker_test 2 3 import ( 4 "sync" 5 "testing" 6 "time" 7 8 "github.com/google/uuid" 9 "go-micro.dev/v5/broker" 10 "go-micro.dev/v5/registry" 11 ) 12 13 var ( 14 // mock data. 15 testData = map[string][]*registry.Service{ 16 "foo": { 17 { 18 Name: "foo", 19 Version: "1.0.0", 20 Nodes: []*registry.Node{ 21 { 22 Id: "foo-1.0.0-123", 23 Address: "localhost:9999", 24 }, 25 { 26 Id: "foo-1.0.0-321", 27 Address: "localhost:9999", 28 }, 29 }, 30 }, 31 { 32 Name: "foo", 33 Version: "1.0.1", 34 Nodes: []*registry.Node{ 35 { 36 Id: "foo-1.0.1-321", 37 Address: "localhost:6666", 38 }, 39 }, 40 }, 41 { 42 Name: "foo", 43 Version: "1.0.3", 44 Nodes: []*registry.Node{ 45 { 46 Id: "foo-1.0.3-345", 47 Address: "localhost:8888", 48 }, 49 }, 50 }, 51 }, 52 } 53 ) 54 55 func newTestRegistry() registry.Registry { 56 return registry.NewMemoryRegistry(registry.Services(testData)) 57 } 58 59 func sub(b *testing.B, c int) { 60 b.StopTimer() 61 m := newTestRegistry() 62 63 brker := broker.NewHttpBroker(broker.Registry(m)) 64 topic := uuid.New().String() 65 66 if err := brker.Init(); err != nil { 67 b.Fatalf("Unexpected init error: %v", err) 68 } 69 70 if err := brker.Connect(); err != nil { 71 b.Fatalf("Unexpected connect error: %v", err) 72 } 73 74 msg := &broker.Message{ 75 Header: map[string]string{ 76 "Content-Type": "application/json", 77 }, 78 Body: []byte(`{"message": "Hello World"}`), 79 } 80 81 var subs []broker.Subscriber 82 done := make(chan bool, c) 83 84 for i := 0; i < c; i++ { 85 sub, err := brker.Subscribe(topic, func(p broker.Event) error { 86 done <- true 87 m := p.Message() 88 89 if string(m.Body) != string(msg.Body) { 90 b.Fatalf("Unexpected msg %s, expected %s", string(m.Body), string(msg.Body)) 91 } 92 93 return nil 94 }, broker.Queue("shared")) 95 if err != nil { 96 b.Fatalf("Unexpected subscribe error: %v", err) 97 } 98 subs = append(subs, sub) 99 } 100 101 for i := 0; i < b.N; i++ { 102 b.StartTimer() 103 if err := brker.Publish(topic, msg); err != nil { 104 b.Fatalf("Unexpected publish error: %v", err) 105 } 106 <-done 107 b.StopTimer() 108 } 109 110 for _, sub := range subs { 111 if err := sub.Unsubscribe(); err != nil { 112 b.Fatalf("Unexpected unsubscribe error: %v", err) 113 } 114 } 115 116 if err := brker.Disconnect(); err != nil { 117 b.Fatalf("Unexpected disconnect error: %v", err) 118 } 119 } 120 121 func pub(b *testing.B, c int) { 122 b.StopTimer() 123 m := newTestRegistry() 124 brk := broker.NewHttpBroker(broker.Registry(m)) 125 topic := uuid.New().String() 126 127 if err := brk.Init(); err != nil { 128 b.Fatalf("Unexpected init error: %v", err) 129 } 130 131 if err := brk.Connect(); err != nil { 132 b.Fatalf("Unexpected connect error: %v", err) 133 } 134 135 msg := &broker.Message{ 136 Header: map[string]string{ 137 "Content-Type": "application/json", 138 }, 139 Body: []byte(`{"message": "Hello World"}`), 140 } 141 142 done := make(chan bool, c*4) 143 144 sub, err := brk.Subscribe(topic, func(p broker.Event) error { 145 done <- true 146 m := p.Message() 147 if string(m.Body) != string(msg.Body) { 148 b.Fatalf("Unexpected msg %s, expected %s", string(m.Body), string(msg.Body)) 149 } 150 return nil 151 }, broker.Queue("shared")) 152 if err != nil { 153 b.Fatalf("Unexpected subscribe error: %v", err) 154 } 155 156 var wg sync.WaitGroup 157 ch := make(chan int, c*4) 158 b.StartTimer() 159 160 for i := 0; i < c; i++ { 161 go func() { 162 for range ch { 163 if err := brk.Publish(topic, msg); err != nil { 164 b.Fatalf("Unexpected publish error: %v", err) 165 } 166 select { 167 case <-done: 168 case <-time.After(time.Second): 169 } 170 wg.Done() 171 } 172 }() 173 } 174 175 for i := 0; i < b.N; i++ { 176 wg.Add(1) 177 ch <- i 178 } 179 180 wg.Wait() 181 b.StopTimer() 182 sub.Unsubscribe() 183 close(ch) 184 close(done) 185 186 if err := brk.Disconnect(); err != nil { 187 b.Fatalf("Unexpected disconnect error: %v", err) 188 } 189 } 190 191 func TestBroker(t *testing.T) { 192 m := newTestRegistry() 193 b := broker.NewHttpBroker(broker.Registry(m)) 194 195 if err := b.Init(); err != nil { 196 t.Fatalf("Unexpected init error: %v", err) 197 } 198 199 if err := b.Connect(); err != nil { 200 t.Fatalf("Unexpected connect error: %v", err) 201 } 202 203 msg := &broker.Message{ 204 Header: map[string]string{ 205 "Content-Type": "application/json", 206 }, 207 Body: []byte(`{"message": "Hello World"}`), 208 } 209 210 done := make(chan bool) 211 212 sub, err := b.Subscribe("test", func(p broker.Event) error { 213 m := p.Message() 214 215 if string(m.Body) != string(msg.Body) { 216 t.Fatalf("Unexpected msg %s, expected %s", string(m.Body), string(msg.Body)) 217 } 218 219 close(done) 220 return nil 221 }) 222 if err != nil { 223 t.Fatalf("Unexpected subscribe error: %v", err) 224 } 225 226 if err := b.Publish("test", msg); err != nil { 227 t.Fatalf("Unexpected publish error: %v", err) 228 } 229 230 <-done 231 if err := sub.Unsubscribe(); err != nil { 232 t.Fatalf("Unexpected unsubscribe error: %v", err) 233 } 234 235 if err := b.Disconnect(); err != nil { 236 t.Fatalf("Unexpected disconnect error: %v", err) 237 } 238 } 239 240 func TestConcurrentSubBroker(t *testing.T) { 241 m := newTestRegistry() 242 b := broker.NewHttpBroker(broker.Registry(m)) 243 244 if err := b.Init(); err != nil { 245 t.Fatalf("Unexpected init error: %v", err) 246 } 247 248 if err := b.Connect(); err != nil { 249 t.Fatalf("Unexpected connect error: %v", err) 250 } 251 252 msg := &broker.Message{ 253 Header: map[string]string{ 254 "Content-Type": "application/json", 255 }, 256 Body: []byte(`{"message": "Hello World"}`), 257 } 258 259 var subs []broker.Subscriber 260 var wg sync.WaitGroup 261 262 for i := 0; i < 10; i++ { 263 sub, err := b.Subscribe("test", func(p broker.Event) error { 264 defer wg.Done() 265 266 m := p.Message() 267 268 if string(m.Body) != string(msg.Body) { 269 t.Fatalf("Unexpected msg %s, expected %s", string(m.Body), string(msg.Body)) 270 } 271 272 return nil 273 }) 274 if err != nil { 275 t.Fatalf("Unexpected subscribe error: %v", err) 276 } 277 278 wg.Add(1) 279 subs = append(subs, sub) 280 } 281 282 if err := b.Publish("test", msg); err != nil { 283 t.Fatalf("Unexpected publish error: %v", err) 284 } 285 286 wg.Wait() 287 288 for _, sub := range subs { 289 if err := sub.Unsubscribe(); err != nil { 290 t.Fatalf("Unexpected unsubscribe error: %v", err) 291 } 292 } 293 294 if err := b.Disconnect(); err != nil { 295 t.Fatalf("Unexpected disconnect error: %v", err) 296 } 297 } 298 299 func TestConcurrentPubBroker(t *testing.T) { 300 m := newTestRegistry() 301 b := broker.NewHttpBroker(broker.Registry(m)) 302 303 if err := b.Init(); err != nil { 304 t.Fatalf("Unexpected init error: %v", err) 305 } 306 307 if err := b.Connect(); err != nil { 308 t.Fatalf("Unexpected connect error: %v", err) 309 } 310 311 msg := &broker.Message{ 312 Header: map[string]string{ 313 "Content-Type": "application/json", 314 }, 315 Body: []byte(`{"message": "Hello World"}`), 316 } 317 318 var wg sync.WaitGroup 319 320 sub, err := b.Subscribe("test", func(p broker.Event) error { 321 defer wg.Done() 322 323 m := p.Message() 324 325 if string(m.Body) != string(msg.Body) { 326 t.Fatalf("Unexpected msg %s, expected %s", string(m.Body), string(msg.Body)) 327 } 328 329 return nil 330 }) 331 if err != nil { 332 t.Fatalf("Unexpected subscribe error: %v", err) 333 } 334 335 for i := 0; i < 10; i++ { 336 wg.Add(1) 337 338 if err := b.Publish("test", msg); err != nil { 339 t.Fatalf("Unexpected publish error: %v", err) 340 } 341 } 342 343 wg.Wait() 344 345 if err := sub.Unsubscribe(); err != nil { 346 t.Fatalf("Unexpected unsubscribe error: %v", err) 347 } 348 349 if err := b.Disconnect(); err != nil { 350 t.Fatalf("Unexpected disconnect error: %v", err) 351 } 352 } 353 354 func BenchmarkSub1(b *testing.B) { 355 sub(b, 1) 356 } 357 func BenchmarkSub8(b *testing.B) { 358 sub(b, 8) 359 } 360 361 func BenchmarkSub32(b *testing.B) { 362 sub(b, 32) 363 } 364 365 func BenchmarkPub1(b *testing.B) { 366 pub(b, 1) 367 } 368 369 func BenchmarkPub8(b *testing.B) { 370 pub(b, 8) 371 } 372 373 func BenchmarkPub32(b *testing.B) { 374 pub(b, 32) 375 }