github.com/cilium/cilium@v1.16.2/pkg/hubble/peer/service_test.go (about) 1 // SPDX-License-Identifier: Apache-2.0 2 // Copyright Authors of Cilium 3 4 package peer 5 6 import ( 7 "net" 8 "sync" 9 "testing" 10 "time" 11 12 "github.com/google/go-cmp/cmp" 13 "github.com/stretchr/testify/assert" 14 15 peerpb "github.com/cilium/cilium/api/v1/peer" 16 datapath "github.com/cilium/cilium/pkg/datapath/types" 17 "github.com/cilium/cilium/pkg/hubble/peer/serviceoption" 18 "github.com/cilium/cilium/pkg/hubble/testutils" 19 "github.com/cilium/cilium/pkg/lock" 20 "github.com/cilium/cilium/pkg/node/addressing" 21 "github.com/cilium/cilium/pkg/node/manager" 22 "github.com/cilium/cilium/pkg/node/types" 23 ) 24 25 func TestService_Notify(t *testing.T) { 26 type args struct { 27 init []types.Node 28 add []types.Node 29 update []types.Node 30 del []types.Node 31 } 32 tests := []struct { 33 name string 34 svcOptions []serviceoption.Option 35 args args 36 want []*peerpb.ChangeNotification 37 }{ 38 { 39 name: "add 4 nodes with TLS info disabled", 40 svcOptions: []serviceoption.Option{serviceoption.WithoutTLSInfo()}, 41 args: args{ 42 init: []types.Node{ 43 { 44 Name: "zero", 45 IPAddresses: []types.Address{ 46 {Type: addressing.NodeInternalIP, IP: net.ParseIP("192.0.1.1")}, 47 }, 48 }, 49 }, 50 add: []types.Node{ 51 { 52 Name: "one", 53 IPAddresses: []types.Address{ 54 {Type: addressing.NodeInternalIP, IP: net.ParseIP("192.0.2.1")}, 55 }, 56 }, { 57 Name: "two", 58 IPAddresses: []types.Address{ 59 {Type: addressing.NodeInternalIP, IP: net.ParseIP("2001:db8::68")}, 60 }, 61 }, { 62 Name: "one", 63 Cluster: "test", 64 IPAddresses: []types.Address{ 65 {Type: addressing.NodeInternalIP, IP: net.ParseIP("10.0.10.5")}, 66 }, 67 }, { 68 Name: "two", 69 Cluster: "test", 70 IPAddresses: []types.Address{ 71 {Type: addressing.NodeInternalIP, IP: net.ParseIP("10.0.10.6")}, 72 }, 73 }, 74 }, 75 }, 76 want: []*peerpb.ChangeNotification{ 77 { 78 Name: "zero", 79 Address: "192.0.1.1", 80 Type: peerpb.ChangeNotificationType_PEER_ADDED, 81 }, { 82 Name: "one", 83 Address: "192.0.2.1", 84 Type: peerpb.ChangeNotificationType_PEER_ADDED, 85 }, { 86 Name: "two", 87 Address: "2001:db8::68", 88 Type: peerpb.ChangeNotificationType_PEER_ADDED, 89 }, { 90 Name: "test/one", 91 Address: "10.0.10.5", 92 Type: peerpb.ChangeNotificationType_PEER_ADDED, 93 }, { 94 Name: "test/two", 95 Address: "10.0.10.6", 96 Type: peerpb.ChangeNotificationType_PEER_ADDED, 97 }, 98 }, 99 }, { 100 name: "delete 3 nodes with TLS info disabled", 101 svcOptions: []serviceoption.Option{serviceoption.WithoutTLSInfo()}, 102 args: args{ 103 init: []types.Node{ 104 { 105 Name: "zero", 106 IPAddresses: []types.Address{ 107 {Type: addressing.NodeInternalIP, IP: net.ParseIP("192.0.1.1")}, 108 }, 109 }, { 110 Name: "one", 111 IPAddresses: []types.Address{ 112 {Type: addressing.NodeInternalIP, IP: net.ParseIP("192.0.2.1")}, 113 }, 114 }, { 115 Name: "two", 116 IPAddresses: []types.Address{ 117 {Type: addressing.NodeInternalIP, IP: net.ParseIP("2001:db8::68")}, 118 }, 119 }, { 120 Name: "one", 121 Cluster: "test", 122 IPAddresses: []types.Address{ 123 {Type: addressing.NodeInternalIP, IP: net.ParseIP("10.0.10.5")}, 124 }, 125 }, { 126 Name: "two", 127 Cluster: "test", 128 IPAddresses: []types.Address{ 129 {Type: addressing.NodeInternalIP, IP: net.ParseIP("10.0.10.6")}, 130 }, 131 }, 132 }, 133 del: []types.Node{ 134 { 135 Name: "one", 136 IPAddresses: []types.Address{ 137 {Type: addressing.NodeInternalIP, IP: net.ParseIP("192.0.2.1")}, 138 }, 139 }, { 140 Name: "two", 141 IPAddresses: []types.Address{ 142 {Type: addressing.NodeInternalIP, IP: net.ParseIP("2001:db8::68")}, 143 }, 144 }, { 145 Name: "one", 146 Cluster: "test", 147 IPAddresses: []types.Address{ 148 {Type: addressing.NodeInternalIP, IP: net.ParseIP("10.0.10.5")}, 149 }, 150 }, { 151 Name: "two", 152 Cluster: "test", 153 IPAddresses: []types.Address{ 154 {Type: addressing.NodeInternalIP, IP: net.ParseIP("10.0.10.6")}, 155 }, 156 }, 157 }, 158 }, 159 want: []*peerpb.ChangeNotification{ 160 { 161 Name: "zero", 162 Address: "192.0.1.1", 163 Type: peerpb.ChangeNotificationType_PEER_ADDED, 164 }, { 165 Name: "one", 166 Address: "192.0.2.1", 167 Type: peerpb.ChangeNotificationType_PEER_ADDED, 168 }, { 169 Name: "two", 170 Address: "2001:db8::68", 171 Type: peerpb.ChangeNotificationType_PEER_ADDED, 172 }, { 173 Name: "test/one", 174 Address: "10.0.10.5", 175 Type: peerpb.ChangeNotificationType_PEER_ADDED, 176 }, { 177 Name: "test/two", 178 Address: "10.0.10.6", 179 Type: peerpb.ChangeNotificationType_PEER_ADDED, 180 }, { 181 Name: "one", 182 Address: "192.0.2.1", 183 Type: peerpb.ChangeNotificationType_PEER_DELETED, 184 }, { 185 Name: "two", 186 Address: "2001:db8::68", 187 Type: peerpb.ChangeNotificationType_PEER_DELETED, 188 }, { 189 Name: "test/one", 190 Address: "10.0.10.5", 191 Type: peerpb.ChangeNotificationType_PEER_DELETED, 192 }, { 193 Name: "test/two", 194 Address: "10.0.10.6", 195 Type: peerpb.ChangeNotificationType_PEER_DELETED, 196 }, 197 }, 198 }, { 199 name: "update 2 nodes with TLS info disabled", 200 svcOptions: []serviceoption.Option{serviceoption.WithoutTLSInfo()}, 201 args: args{ 202 init: []types.Node{ 203 { 204 Name: "zero", 205 IPAddresses: []types.Address{ 206 {Type: addressing.NodeInternalIP, IP: net.ParseIP("192.0.1.1")}, 207 }, 208 }, { 209 Name: "one", 210 IPAddresses: []types.Address{ 211 {Type: addressing.NodeInternalIP, IP: net.ParseIP("192.0.2.1")}, 212 }, 213 }, { 214 Name: "two", 215 IPAddresses: []types.Address{ 216 {Type: addressing.NodeInternalIP, IP: net.ParseIP("2001:db8::68")}, 217 }, 218 }, 219 }, 220 update: []types.Node{ 221 { 222 Name: "one", 223 IPAddresses: []types.Address{ 224 {Type: addressing.NodeInternalIP, IP: net.ParseIP("192.0.2.1")}, 225 }, 226 }, { 227 Name: "one", 228 IPAddresses: []types.Address{ 229 {Type: addressing.NodeInternalIP, IP: net.ParseIP("192.0.2.2")}, 230 }, 231 }, { 232 Name: "two", 233 IPAddresses: []types.Address{ 234 {Type: addressing.NodeInternalIP, IP: net.ParseIP("2001:db8::68")}, 235 }, 236 }, { 237 Name: "two", 238 IPAddresses: []types.Address{ 239 {Type: addressing.NodeInternalIP, IP: net.ParseIP("2001:db8::65")}, 240 }, 241 }, 242 }, 243 }, 244 want: []*peerpb.ChangeNotification{ 245 { 246 Name: "zero", 247 Address: "192.0.1.1", 248 Type: peerpb.ChangeNotificationType_PEER_ADDED, 249 }, { 250 Name: "one", 251 Address: "192.0.2.1", 252 Type: peerpb.ChangeNotificationType_PEER_ADDED, 253 }, { 254 Name: "two", 255 Address: "2001:db8::68", 256 Type: peerpb.ChangeNotificationType_PEER_ADDED, 257 }, { 258 Name: "one", 259 Address: "192.0.2.2", 260 Type: peerpb.ChangeNotificationType_PEER_UPDATED, 261 }, { 262 Name: "two", 263 Address: "2001:db8::65", 264 Type: peerpb.ChangeNotificationType_PEER_UPDATED, 265 }, 266 }, 267 }, { 268 name: "rename 2 nodes with TLS info disabled", 269 svcOptions: []serviceoption.Option{serviceoption.WithoutTLSInfo()}, 270 args: args{ 271 init: []types.Node{ 272 { 273 Name: "zero", 274 IPAddresses: []types.Address{ 275 {Type: addressing.NodeInternalIP, IP: net.ParseIP("192.0.1.1")}, 276 }, 277 }, { 278 Name: "one", 279 IPAddresses: []types.Address{ 280 {Type: addressing.NodeInternalIP, IP: net.ParseIP("192.0.2.1")}, 281 }, 282 }, { 283 Name: "two", 284 IPAddresses: []types.Address{ 285 {Type: addressing.NodeInternalIP, IP: net.ParseIP("2001:db8::68")}, 286 }, 287 }, 288 }, 289 update: []types.Node{ 290 { 291 Name: "one", 292 IPAddresses: []types.Address{ 293 {Type: addressing.NodeInternalIP, IP: net.ParseIP("192.0.2.1")}, 294 }, 295 }, { 296 Name: "1", 297 IPAddresses: []types.Address{ 298 {Type: addressing.NodeInternalIP, IP: net.ParseIP("192.0.2.1")}, 299 }, 300 }, { 301 Name: "two", 302 IPAddresses: []types.Address{ 303 {Type: addressing.NodeInternalIP, IP: net.ParseIP("2001:db8::68")}, 304 }, 305 }, { 306 Name: "2", 307 IPAddresses: []types.Address{ 308 {Type: addressing.NodeInternalIP, IP: net.ParseIP("2001:db8::68")}, 309 }, 310 }, 311 }, 312 }, 313 want: []*peerpb.ChangeNotification{ 314 { 315 Name: "zero", 316 Address: "192.0.1.1", 317 Type: peerpb.ChangeNotificationType_PEER_ADDED, 318 }, { 319 Name: "one", 320 Address: "192.0.2.1", 321 Type: peerpb.ChangeNotificationType_PEER_ADDED, 322 }, { 323 Name: "two", 324 Address: "2001:db8::68", 325 Type: peerpb.ChangeNotificationType_PEER_ADDED, 326 }, { 327 Name: "one", 328 Address: "192.0.2.1", 329 Type: peerpb.ChangeNotificationType_PEER_DELETED, 330 }, { 331 Name: "1", 332 Address: "192.0.2.1", 333 Type: peerpb.ChangeNotificationType_PEER_ADDED, 334 }, { 335 Name: "two", 336 Address: "2001:db8::68", 337 Type: peerpb.ChangeNotificationType_PEER_DELETED, 338 }, { 339 Name: "2", 340 Address: "2001:db8::68", 341 Type: peerpb.ChangeNotificationType_PEER_ADDED, 342 }, 343 }, 344 }, { 345 name: "add 4 nodes", 346 args: args{ 347 init: []types.Node{ 348 { 349 Name: "zero", 350 IPAddresses: []types.Address{ 351 {Type: addressing.NodeInternalIP, IP: net.ParseIP("192.0.1.1")}, 352 }, 353 }, 354 }, 355 add: []types.Node{ 356 { 357 Name: "one", 358 IPAddresses: []types.Address{ 359 {Type: addressing.NodeInternalIP, IP: net.ParseIP("192.0.2.1")}, 360 }, 361 }, { 362 Name: "two", 363 IPAddresses: []types.Address{ 364 {Type: addressing.NodeInternalIP, IP: net.ParseIP("2001:db8::68")}, 365 }, 366 }, { 367 Name: "one", 368 Cluster: "test", 369 IPAddresses: []types.Address{ 370 {Type: addressing.NodeInternalIP, IP: net.ParseIP("10.0.10.5")}, 371 }, 372 }, { 373 Name: "two", 374 Cluster: "test", 375 IPAddresses: []types.Address{ 376 {Type: addressing.NodeInternalIP, IP: net.ParseIP("10.0.10.6")}, 377 }, 378 }, 379 }, 380 }, 381 want: []*peerpb.ChangeNotification{ 382 { 383 Name: "zero", 384 Address: "192.0.1.1", 385 Type: peerpb.ChangeNotificationType_PEER_ADDED, 386 Tls: &peerpb.TLS{ 387 ServerName: "zero.default.hubble-grpc.cilium.io", 388 }, 389 }, { 390 Name: "one", 391 Address: "192.0.2.1", 392 Type: peerpb.ChangeNotificationType_PEER_ADDED, 393 Tls: &peerpb.TLS{ 394 ServerName: "one.default.hubble-grpc.cilium.io", 395 }, 396 }, { 397 Name: "two", 398 Address: "2001:db8::68", 399 Type: peerpb.ChangeNotificationType_PEER_ADDED, 400 Tls: &peerpb.TLS{ 401 ServerName: "two.default.hubble-grpc.cilium.io", 402 }, 403 }, { 404 Name: "test/one", 405 Address: "10.0.10.5", 406 Type: peerpb.ChangeNotificationType_PEER_ADDED, 407 Tls: &peerpb.TLS{ 408 ServerName: "one.test.hubble-grpc.cilium.io", 409 }, 410 }, { 411 Name: "test/two", 412 Address: "10.0.10.6", 413 Type: peerpb.ChangeNotificationType_PEER_ADDED, 414 Tls: &peerpb.TLS{ 415 ServerName: "two.test.hubble-grpc.cilium.io", 416 }, 417 }, 418 }, 419 }, { 420 name: "delete 3 nodes", 421 args: args{ 422 init: []types.Node{ 423 { 424 Name: "zero", 425 IPAddresses: []types.Address{ 426 {Type: addressing.NodeInternalIP, IP: net.ParseIP("192.0.1.1")}, 427 }, 428 }, { 429 Name: "one", 430 IPAddresses: []types.Address{ 431 {Type: addressing.NodeInternalIP, IP: net.ParseIP("192.0.2.1")}, 432 }, 433 }, { 434 Name: "two", 435 IPAddresses: []types.Address{ 436 {Type: addressing.NodeInternalIP, IP: net.ParseIP("2001:db8::68")}, 437 }, 438 }, { 439 Name: "one", 440 Cluster: "test", 441 IPAddresses: []types.Address{ 442 {Type: addressing.NodeInternalIP, IP: net.ParseIP("10.0.10.5")}, 443 }, 444 }, { 445 Name: "two", 446 Cluster: "test", 447 IPAddresses: []types.Address{ 448 {Type: addressing.NodeInternalIP, IP: net.ParseIP("10.0.10.6")}, 449 }, 450 }, 451 }, 452 del: []types.Node{ 453 { 454 Name: "one", 455 IPAddresses: []types.Address{ 456 {Type: addressing.NodeInternalIP, IP: net.ParseIP("192.0.2.1")}, 457 }, 458 }, { 459 Name: "two", 460 IPAddresses: []types.Address{ 461 {Type: addressing.NodeInternalIP, IP: net.ParseIP("2001:db8::68")}, 462 }, 463 }, { 464 Name: "one", 465 Cluster: "test", 466 IPAddresses: []types.Address{ 467 {Type: addressing.NodeInternalIP, IP: net.ParseIP("10.0.10.5")}, 468 }, 469 }, { 470 Name: "two", 471 Cluster: "test", 472 IPAddresses: []types.Address{ 473 {Type: addressing.NodeInternalIP, IP: net.ParseIP("10.0.10.6")}, 474 }, 475 }, 476 }, 477 }, 478 want: []*peerpb.ChangeNotification{ 479 { 480 Name: "zero", 481 Address: "192.0.1.1", 482 Type: peerpb.ChangeNotificationType_PEER_ADDED, 483 Tls: &peerpb.TLS{ 484 ServerName: "zero.default.hubble-grpc.cilium.io", 485 }, 486 }, { 487 Name: "one", 488 Address: "192.0.2.1", 489 Type: peerpb.ChangeNotificationType_PEER_ADDED, 490 Tls: &peerpb.TLS{ 491 ServerName: "one.default.hubble-grpc.cilium.io", 492 }, 493 }, { 494 Name: "two", 495 Address: "2001:db8::68", 496 Type: peerpb.ChangeNotificationType_PEER_ADDED, 497 Tls: &peerpb.TLS{ 498 ServerName: "two.default.hubble-grpc.cilium.io", 499 }, 500 }, { 501 Name: "test/one", 502 Address: "10.0.10.5", 503 Type: peerpb.ChangeNotificationType_PEER_ADDED, 504 Tls: &peerpb.TLS{ 505 ServerName: "one.test.hubble-grpc.cilium.io", 506 }, 507 }, { 508 Name: "test/two", 509 Address: "10.0.10.6", 510 Type: peerpb.ChangeNotificationType_PEER_ADDED, 511 Tls: &peerpb.TLS{ 512 ServerName: "two.test.hubble-grpc.cilium.io", 513 }, 514 }, { 515 Name: "one", 516 Address: "192.0.2.1", 517 Type: peerpb.ChangeNotificationType_PEER_DELETED, 518 Tls: &peerpb.TLS{ 519 ServerName: "one.default.hubble-grpc.cilium.io", 520 }, 521 }, { 522 Name: "two", 523 Address: "2001:db8::68", 524 Type: peerpb.ChangeNotificationType_PEER_DELETED, 525 Tls: &peerpb.TLS{ 526 ServerName: "two.default.hubble-grpc.cilium.io", 527 }, 528 }, { 529 Name: "test/one", 530 Address: "10.0.10.5", 531 Type: peerpb.ChangeNotificationType_PEER_DELETED, 532 Tls: &peerpb.TLS{ 533 ServerName: "one.test.hubble-grpc.cilium.io", 534 }, 535 }, { 536 Name: "test/two", 537 Address: "10.0.10.6", 538 Type: peerpb.ChangeNotificationType_PEER_DELETED, 539 Tls: &peerpb.TLS{ 540 ServerName: "two.test.hubble-grpc.cilium.io", 541 }, 542 }, 543 }, 544 }, { 545 name: "update 2 nodes", 546 args: args{ 547 init: []types.Node{ 548 { 549 Name: "zero", 550 IPAddresses: []types.Address{ 551 {Type: addressing.NodeInternalIP, IP: net.ParseIP("192.0.1.1")}, 552 }, 553 }, { 554 Name: "one", 555 IPAddresses: []types.Address{ 556 {Type: addressing.NodeInternalIP, IP: net.ParseIP("192.0.2.1")}, 557 }, 558 }, { 559 Name: "two", 560 IPAddresses: []types.Address{ 561 {Type: addressing.NodeInternalIP, IP: net.ParseIP("2001:db8::68")}, 562 }, 563 }, 564 }, 565 update: []types.Node{ 566 { 567 Name: "one", 568 IPAddresses: []types.Address{ 569 {Type: addressing.NodeInternalIP, IP: net.ParseIP("192.0.2.1")}, 570 }, 571 }, { 572 Name: "one", 573 IPAddresses: []types.Address{ 574 {Type: addressing.NodeInternalIP, IP: net.ParseIP("192.0.2.2")}, 575 }, 576 }, { 577 Name: "two", 578 IPAddresses: []types.Address{ 579 {Type: addressing.NodeInternalIP, IP: net.ParseIP("2001:db8::68")}, 580 }, 581 }, { 582 Name: "two", 583 IPAddresses: []types.Address{ 584 {Type: addressing.NodeInternalIP, IP: net.ParseIP("2001:db8::65")}, 585 }, 586 }, 587 }, 588 }, 589 want: []*peerpb.ChangeNotification{ 590 { 591 Name: "zero", 592 Address: "192.0.1.1", 593 Type: peerpb.ChangeNotificationType_PEER_ADDED, 594 Tls: &peerpb.TLS{ 595 ServerName: "zero.default.hubble-grpc.cilium.io", 596 }, 597 }, { 598 Name: "one", 599 Address: "192.0.2.1", 600 Type: peerpb.ChangeNotificationType_PEER_ADDED, 601 Tls: &peerpb.TLS{ 602 ServerName: "one.default.hubble-grpc.cilium.io", 603 }, 604 }, { 605 Name: "two", 606 Address: "2001:db8::68", 607 Type: peerpb.ChangeNotificationType_PEER_ADDED, 608 Tls: &peerpb.TLS{ 609 ServerName: "two.default.hubble-grpc.cilium.io", 610 }, 611 }, { 612 Name: "one", 613 Address: "192.0.2.2", 614 Type: peerpb.ChangeNotificationType_PEER_UPDATED, 615 Tls: &peerpb.TLS{ 616 ServerName: "one.default.hubble-grpc.cilium.io", 617 }, 618 }, { 619 Name: "two", 620 Address: "2001:db8::65", 621 Type: peerpb.ChangeNotificationType_PEER_UPDATED, 622 Tls: &peerpb.TLS{ 623 ServerName: "two.default.hubble-grpc.cilium.io", 624 }, 625 }, 626 }, 627 }, { 628 name: "rename 2 nodes", 629 args: args{ 630 init: []types.Node{ 631 { 632 Name: "zero", 633 IPAddresses: []types.Address{ 634 {Type: addressing.NodeInternalIP, IP: net.ParseIP("192.0.1.1")}, 635 }, 636 }, { 637 Name: "one", 638 IPAddresses: []types.Address{ 639 {Type: addressing.NodeInternalIP, IP: net.ParseIP("192.0.2.1")}, 640 }, 641 }, { 642 Name: "two", 643 IPAddresses: []types.Address{ 644 {Type: addressing.NodeInternalIP, IP: net.ParseIP("2001:db8::68")}, 645 }, 646 }, 647 }, 648 update: []types.Node{ 649 { 650 Name: "one", 651 IPAddresses: []types.Address{ 652 {Type: addressing.NodeInternalIP, IP: net.ParseIP("192.0.2.1")}, 653 }, 654 }, { 655 Name: "1", 656 IPAddresses: []types.Address{ 657 {Type: addressing.NodeInternalIP, IP: net.ParseIP("192.0.2.1")}, 658 }, 659 }, { 660 Name: "two", 661 IPAddresses: []types.Address{ 662 {Type: addressing.NodeInternalIP, IP: net.ParseIP("2001:db8::68")}, 663 }, 664 }, { 665 Name: "2", 666 IPAddresses: []types.Address{ 667 {Type: addressing.NodeInternalIP, IP: net.ParseIP("2001:db8::68")}, 668 }, 669 }, 670 }, 671 }, 672 want: []*peerpb.ChangeNotification{ 673 { 674 Name: "zero", 675 Address: "192.0.1.1", 676 Type: peerpb.ChangeNotificationType_PEER_ADDED, 677 Tls: &peerpb.TLS{ 678 ServerName: "zero.default.hubble-grpc.cilium.io", 679 }, 680 }, { 681 Name: "one", 682 Address: "192.0.2.1", 683 Type: peerpb.ChangeNotificationType_PEER_ADDED, 684 Tls: &peerpb.TLS{ 685 ServerName: "one.default.hubble-grpc.cilium.io", 686 }, 687 }, { 688 Name: "two", 689 Address: "2001:db8::68", 690 Type: peerpb.ChangeNotificationType_PEER_ADDED, 691 Tls: &peerpb.TLS{ 692 ServerName: "two.default.hubble-grpc.cilium.io", 693 }, 694 }, { 695 Name: "one", 696 Address: "192.0.2.1", 697 Type: peerpb.ChangeNotificationType_PEER_DELETED, 698 Tls: &peerpb.TLS{ 699 ServerName: "one.default.hubble-grpc.cilium.io", 700 }, 701 }, { 702 Name: "1", 703 Address: "192.0.2.1", 704 Type: peerpb.ChangeNotificationType_PEER_ADDED, 705 Tls: &peerpb.TLS{ 706 ServerName: "1.default.hubble-grpc.cilium.io", 707 }, 708 }, { 709 Name: "two", 710 Address: "2001:db8::68", 711 Type: peerpb.ChangeNotificationType_PEER_DELETED, 712 Tls: &peerpb.TLS{ 713 ServerName: "two.default.hubble-grpc.cilium.io", 714 }, 715 }, { 716 Name: "2", 717 Address: "2001:db8::68", 718 Type: peerpb.ChangeNotificationType_PEER_ADDED, 719 Tls: &peerpb.TLS{ 720 ServerName: "2.default.hubble-grpc.cilium.io", 721 }, 722 }, 723 }, 724 }, 725 } 726 for _, tt := range tests { 727 t.Run(tt.name, func(t *testing.T) { 728 var got []*peerpb.ChangeNotification 729 var wg sync.WaitGroup 730 fakeServer := &testutils.FakePeerNotifyServer{ 731 OnSend: func(resp *peerpb.ChangeNotification) error { 732 got = append(got, resp) 733 wg.Done() 734 return nil 735 }, 736 } 737 ready := make(chan struct{}) 738 cb := func(nh datapath.NodeHandler) { 739 ready <- struct{}{} 740 } 741 notif := newNotifier(cb, tt.args.init) 742 wg.Add(len(tt.args.init)) 743 svc := NewService(notif, tt.svcOptions...) 744 done := make(chan struct{}) 745 go func() { 746 err := svc.Notify(&peerpb.NotifyRequest{}, fakeServer) 747 assert.NoError(t, err) 748 close(done) 749 }() 750 <-ready 751 for _, n := range tt.args.add { 752 wg.Add(1) 753 notif.notifyAdd(n) 754 } 755 for _, n := range tt.args.del { 756 wg.Add(1) 757 notif.notifyDelete(n) 758 } 759 // the update slice shall always be even with odd entry 760 // corresponding to the old node and following even entries to the 761 // updated one 762 var o types.Node 763 for i, n := range tt.args.update { 764 if i%2 == 0 { 765 n := n 766 o = n 767 continue 768 } 769 // the number of notifications we expect depends on the change 770 // - identical: no notification 771 // - name change: 2 notifications 772 // - other change: 1 notification 773 switch { 774 case cmp.Diff(o, n) == "": 775 // no-op 776 case o.Name != n.Name: 777 wg.Add(2) 778 default: 779 wg.Add(1) 780 } 781 notif.notifyUpdate(o, n) 782 } 783 wg.Wait() 784 svc.Close() 785 assert.Equal(t, tt.want, got) 786 // wait for the notify call routine to finish 787 <-done 788 }) 789 } 790 } 791 792 func TestService_NotifyWithBlockedSend(t *testing.T) { 793 fakeServer := &testutils.FakePeerNotifyServer{ 794 OnSend: func(resp *peerpb.ChangeNotification) error { 795 <-time.After(100 * time.Millisecond) 796 return nil 797 }, 798 } 799 ready := make(chan struct{}) 800 cb := func(nh datapath.NodeHandler) { 801 ready <- struct{}{} 802 } 803 init := []types.Node{ 804 { 805 Name: "one", 806 IPAddresses: []types.Address{ 807 {Type: addressing.NodeInternalIP, IP: net.ParseIP("192.0.2.1")}, 808 }, 809 }, { 810 Name: "two", 811 IPAddresses: []types.Address{ 812 {Type: addressing.NodeInternalIP, IP: net.ParseIP("2001:db8::68")}, 813 }, 814 }, { 815 Name: "one", 816 Cluster: "test", 817 IPAddresses: []types.Address{ 818 {Type: addressing.NodeInternalIP, IP: net.ParseIP("10.0.10.5")}, 819 }, 820 }, { 821 Name: "two", 822 Cluster: "test", 823 IPAddresses: []types.Address{ 824 {Type: addressing.NodeInternalIP, IP: net.ParseIP("10.0.10.6")}, 825 }, 826 }, 827 } 828 notif := newNotifier(cb, init) 829 svc := NewService(notif, serviceoption.WithMaxSendBufferSize(2), serviceoption.WithoutTLSInfo()) 830 done := make(chan struct{}) 831 go func() { 832 err := svc.Notify(&peerpb.NotifyRequest{}, fakeServer) 833 assert.Equal(t, ErrStreamSendBlocked, err) 834 close(done) 835 }() 836 <-ready 837 for _, n := range init { 838 notif.notifyAdd(n) 839 } 840 svc.Close() 841 // wait for the notify call routine to finish 842 <-done 843 } 844 845 type notifier struct { 846 nodes []types.Node 847 subscribers map[datapath.NodeHandler]struct{} 848 cb func(nh datapath.NodeHandler) 849 mu lock.Mutex 850 } 851 852 var _ manager.Notifier = (*notifier)(nil) 853 854 func newNotifier(subCallback func(nh datapath.NodeHandler), nodes []types.Node) *notifier { 855 return ¬ifier{ 856 nodes: nodes, 857 subscribers: make(map[datapath.NodeHandler]struct{}), 858 cb: subCallback, 859 } 860 } 861 862 func (n *notifier) Subscribe(nh datapath.NodeHandler) { 863 n.mu.Lock() 864 n.subscribers[nh] = struct{}{} 865 n.mu.Unlock() 866 for _, e := range n.nodes { 867 nh.NodeAdd(e) 868 } 869 if n.cb != nil { 870 n.cb(nh) 871 } 872 } 873 874 func (n *notifier) Unsubscribe(nh datapath.NodeHandler) { 875 n.mu.Lock() 876 delete(n.subscribers, nh) 877 n.mu.Unlock() 878 } 879 880 func (n *notifier) notifyAdd(e types.Node) { 881 n.mu.Lock() 882 for s := range n.subscribers { 883 s.NodeAdd(e) 884 } 885 n.mu.Unlock() 886 } 887 888 func (n *notifier) notifyDelete(e types.Node) { 889 n.mu.Lock() 890 for s := range n.subscribers { 891 s.NodeDelete(e) 892 } 893 n.mu.Unlock() 894 } 895 896 func (n *notifier) notifyUpdate(o, e types.Node) { 897 n.mu.Lock() 898 for s := range n.subscribers { 899 s.NodeUpdate(o, e) 900 } 901 n.mu.Unlock() 902 }