github.com/Axway/agent-sdk@v1.1.101/pkg/agent/events/watchtopic_test.go (about) 1 package events 2 3 import ( 4 "fmt" 5 "testing" 6 7 apiv1 "github.com/Axway/agent-sdk/pkg/apic/apiserver/models/api/v1" 8 management "github.com/Axway/agent-sdk/pkg/apic/apiserver/models/management/v1alpha1" 9 "github.com/Axway/agent-sdk/pkg/config" 10 "github.com/stretchr/testify/assert" 11 ) 12 13 func TestCreateWatchTopic(t *testing.T) { 14 tests := []struct { 15 name string 16 ri *apiv1.ResourceInstance 17 hasErr bool 18 err error 19 }{ 20 { 21 name: "Should call create and return a WatchTopic", 22 hasErr: false, 23 err: nil, 24 ri: &apiv1.ResourceInstance{ 25 ResourceMeta: apiv1.ResourceMeta{ 26 Name: "wt-name", 27 }, 28 }, 29 }, 30 { 31 name: "Should return an error when calling create", 32 hasErr: true, 33 err: fmt.Errorf("error"), 34 ri: &apiv1.ResourceInstance{ 35 ResourceMeta: apiv1.ResourceMeta{}, 36 }, 37 }, 38 } 39 40 for _, tc := range tests { 41 t.Run(tc.name, func(t *testing.T) { 42 rc := &mockAPIClient{ 43 ri: tc.ri, 44 createErr: tc.err, 45 } 46 47 wt := management.NewWatchTopic("") 48 err := wt.FromInstance(tc.ri) 49 assert.Nil(t, err) 50 51 wt, err = createOrUpdateWatchTopic(wt, rc) 52 if tc.hasErr { 53 assert.NotNil(t, err) 54 } else { 55 assert.Nil(t, err) 56 assert.Equal(t, tc.ri.Name, wt.Name) 57 } 58 }) 59 } 60 61 } 62 63 type mockWatchTopicFeatures struct { 64 agentType config.AgentType 65 filterList []config.ResourceFilter 66 } 67 68 func (m *mockWatchTopicFeatures) GetAgentType() config.AgentType { 69 return m.agentType 70 } 71 72 func (m *mockWatchTopicFeatures) GetWatchResourceFilters() []config.ResourceFilter { 73 return m.filterList 74 } 75 76 func Test_parseWatchTopic(t *testing.T) { 77 tests := []struct { 78 name string 79 isMPSEnabled bool 80 }{ 81 { 82 name: "Should create a watch topic without marketplace subs enabled", 83 }, 84 { 85 name: "Should create a watch topic with marketplace subs enabled", 86 isMPSEnabled: true, 87 }, 88 } 89 90 for _, tc := range tests { 91 t.Run(tc.name, func(t *testing.T) { 92 features := &mockWatchTopicFeatures{} 93 94 wt, err := parseWatchTopicTemplate(NewDiscoveryWatchTopic("name", "scope", management.DiscoveryAgentGVK().GroupKind, features)) 95 assert.Nil(t, err) 96 assert.NotNil(t, wt) 97 98 wt, err = parseWatchTopicTemplate(NewTraceWatchTopic("name", "scope", management.TraceabilityAgentGVK().GroupKind, features)) 99 assert.Nil(t, err) 100 assert.NotNil(t, wt) 101 }) 102 } 103 } 104 105 func TestGetOrCreateWatchTopic(t *testing.T) { 106 tests := []struct { 107 name string 108 client *mockAPIClient 109 hasErr bool 110 agentType config.AgentType 111 filterList []config.ResourceFilter 112 }{ 113 { 114 name: "should retrieve a watch topic if it exists", 115 hasErr: false, 116 agentType: config.DiscoveryAgent, 117 client: &mockAPIClient{ 118 ri: &apiv1.ResourceInstance{ 119 ResourceMeta: apiv1.ResourceMeta{ 120 Name: "wt-name", 121 }, 122 }, 123 }, 124 filterList: []config.ResourceFilter{}, 125 }, 126 { 127 name: "should create a watch topic for a trace agent if it does not exist", 128 agentType: config.TraceabilityAgent, 129 hasErr: false, 130 client: &mockAPIClient{ 131 getErr: fmt.Errorf("not found"), 132 ri: &apiv1.ResourceInstance{ 133 ResourceMeta: apiv1.ResourceMeta{ 134 Name: "wt-name", 135 }, 136 }, 137 }, 138 filterList: []config.ResourceFilter{}, 139 }, 140 { 141 name: "should create a watch topic for a discovery agent if it does not exist", 142 agentType: config.DiscoveryAgent, 143 hasErr: false, 144 client: &mockAPIClient{ 145 getErr: fmt.Errorf("not found"), 146 ri: &apiv1.ResourceInstance{ 147 ResourceMeta: apiv1.ResourceMeta{ 148 Name: "wt-name", 149 }, 150 }, 151 }, 152 filterList: []config.ResourceFilter{}, 153 }, 154 { 155 name: "should create a watch topic for a trace agent with custom filter if it does not exist", 156 agentType: config.TraceabilityAgent, 157 hasErr: false, 158 client: &mockAPIClient{ 159 getErr: fmt.Errorf("not found"), 160 ri: &apiv1.ResourceInstance{ 161 ResourceMeta: apiv1.ResourceMeta{ 162 Name: "wt-name", 163 }, 164 }, 165 }, 166 filterList: []config.ResourceFilter{ 167 { 168 Group: management.CredentialGVK().Group, 169 Kind: management.CredentialGVK().Kind, 170 Name: "*", 171 EventTypes: []config.ResourceEventType{"created"}, 172 Scope: &config.ResourceScope{ 173 Kind: management.EnvironmentGVK().Kind, 174 Name: "test-env", 175 }, 176 }, 177 }, 178 }, 179 } 180 181 for _, tc := range tests { 182 t.Run(tc.name, func(t *testing.T) { 183 name := "agent-name" 184 features := &mockWatchTopicFeatures{agentType: tc.agentType, filterList: tc.filterList} 185 186 wt, err := getOrCreateWatchTopic(name, "scope", tc.client, features) 187 if tc.hasErr == true { 188 assert.NotNil(t, err) 189 } else { 190 assert.Nil(t, err) 191 assert.Equal(t, tc.client.ri.Name, wt.Name) 192 } 193 // validate watch topic with custom filter 194 for _, filter := range tc.filterList { 195 found := false 196 for _, wtFilter := range wt.Spec.Filters { 197 if wtFilter.Group == filter.Group && wtFilter.Kind == filter.Kind && wtFilter.Name == filter.Name { 198 fs := filter.Scope 199 wts := wtFilter.Scope 200 if fs != nil && wts != nil && wts.Kind == fs.Kind && wts.Name == fs.Name { 201 found = true 202 break 203 } 204 } 205 } 206 assert.True(t, found) 207 } 208 }) 209 } 210 } 211 212 func Test_shouldPushUpdate(t *testing.T) { 213 type args struct { 214 cur []management.WatchTopicSpecFilters 215 new []management.WatchTopicSpecFilters 216 } 217 tests := []struct { 218 name string 219 args args 220 want bool 221 }{ 222 { 223 name: "should not push update", 224 args: args{ 225 cur: []management.WatchTopicSpecFilters{ 226 { 227 Group: "group", 228 Scope: nil, 229 Kind: "kind", 230 Name: "name", 231 Type: []string{"type1", "type2", "type3"}, 232 }, 233 }, 234 new: []management.WatchTopicSpecFilters{ 235 { 236 Group: "group", 237 Scope: nil, 238 Kind: "kind", 239 Name: "name", 240 Type: []string{"type1", "type2", "type3"}, 241 }, 242 }, 243 }, 244 want: false, 245 }, 246 { 247 name: "should push update, second more", 248 args: args{ 249 cur: []management.WatchTopicSpecFilters{ 250 { 251 Group: "group", 252 Scope: nil, 253 Kind: "kind", 254 Name: "name", 255 Type: []string{"type1", "type2", "type3"}, 256 }, 257 }, 258 new: []management.WatchTopicSpecFilters{ 259 { 260 Group: "group", 261 Scope: nil, 262 Kind: "kind", 263 Name: "name", 264 Type: []string{"type1", "type2", "type3"}, 265 }, 266 { 267 Group: "group", 268 Scope: nil, 269 Kind: "kind1", 270 Name: "name", 271 Type: []string{"type1", "type2", "type3"}, 272 }, 273 }, 274 }, 275 want: true, 276 }, 277 { 278 name: "should push update, first more", 279 args: args{ 280 cur: []management.WatchTopicSpecFilters{ 281 { 282 Group: "group", 283 Scope: nil, 284 Kind: "kind", 285 Name: "name", 286 Type: []string{"type1", "type2", "type3"}, 287 }, 288 { 289 Group: "group", 290 Scope: nil, 291 Kind: "kind1", 292 Name: "name", 293 Type: []string{"type1", "type2", "type3"}, 294 }, 295 }, 296 new: []management.WatchTopicSpecFilters{ 297 { 298 Group: "group", 299 Scope: nil, 300 Kind: "kind", 301 Name: "name", 302 Type: []string{"type1", "type2", "type3"}, 303 }, 304 }, 305 }, 306 want: true, 307 }, 308 } 309 for _, tt := range tests { 310 t.Run(tt.name, func(t *testing.T) { 311 createWatchTopic := func(filters []management.WatchTopicSpecFilters) *management.WatchTopic { 312 wt := management.NewWatchTopic("") 313 wt.Spec.Filters = filters 314 return wt 315 } 316 317 if got := shouldPushUpdate(createWatchTopic(tt.args.cur), createWatchTopic(tt.args.new)); got != tt.want { 318 t.Errorf("shouldPushUpdate() = %v, want %v", got, tt.want) 319 } 320 }) 321 } 322 } 323 324 func Test_filtersEqual(t *testing.T) { 325 type args struct { 326 a management.WatchTopicSpecFilters 327 b management.WatchTopicSpecFilters 328 } 329 tests := []struct { 330 name string 331 args args 332 wantEqual bool 333 }{ 334 { 335 name: "group diff", 336 args: args{ 337 a: management.WatchTopicSpecFilters{ 338 Group: "group", 339 Scope: nil, 340 Kind: "kind", 341 Name: "name", 342 Type: []string{"type1", "type2", "type3"}, 343 }, 344 b: management.WatchTopicSpecFilters{ 345 Group: "group1", 346 Scope: nil, 347 Kind: "kind", 348 Name: "name", 349 Type: []string{"type1", "type2", "type3"}, 350 }, 351 }, 352 wantEqual: false, 353 }, 354 { 355 name: "kind diff", 356 args: args{ 357 a: management.WatchTopicSpecFilters{ 358 Group: "group", 359 Scope: nil, 360 Kind: "kind", 361 Name: "name", 362 Type: []string{"type1", "type2", "type3"}, 363 }, 364 b: management.WatchTopicSpecFilters{ 365 Group: "group", 366 Scope: nil, 367 Kind: "kind1", 368 Name: "name", 369 Type: []string{"type1", "type2", "type3"}, 370 }, 371 }, 372 wantEqual: false, 373 }, 374 { 375 name: "name diff", 376 args: args{ 377 a: management.WatchTopicSpecFilters{ 378 Group: "group", 379 Scope: nil, 380 Kind: "kind", 381 Name: "name", 382 Type: []string{"type1", "type2", "type3"}, 383 }, 384 b: management.WatchTopicSpecFilters{ 385 Group: "group", 386 Scope: nil, 387 Kind: "kind", 388 Name: "name1", 389 Type: []string{"type1", "type2", "type3"}, 390 }, 391 }, 392 wantEqual: false, 393 }, 394 { 395 name: "scope diff 1", 396 args: args{ 397 a: management.WatchTopicSpecFilters{ 398 Group: "group", 399 Scope: nil, 400 Kind: "kind", 401 Name: "name", 402 Type: []string{"type1", "type2", "type3"}, 403 }, 404 b: management.WatchTopicSpecFilters{ 405 Group: "group", 406 Scope: &management.WatchTopicSpecScope{ 407 Kind: "kind", 408 Name: "name", 409 }, 410 Kind: "kind", 411 Name: "name", 412 Type: []string{"type1", "type2", "type3"}, 413 }, 414 }, 415 wantEqual: false, 416 }, 417 { 418 name: "scope diff 2", 419 args: args{ 420 a: management.WatchTopicSpecFilters{ 421 Group: "group", 422 Scope: &management.WatchTopicSpecScope{ 423 Kind: "kind", 424 Name: "name", 425 }, 426 Kind: "kind", 427 Name: "name", 428 Type: []string{"type1", "type2", "type3"}, 429 }, 430 b: management.WatchTopicSpecFilters{ 431 Group: "group", 432 Scope: nil, 433 Kind: "kind", 434 Name: "name", 435 Type: []string{"type1", "type2", "type3"}, 436 }, 437 }, 438 wantEqual: false, 439 }, 440 { 441 name: "scope diff name", 442 args: args{ 443 a: management.WatchTopicSpecFilters{ 444 Group: "group", 445 Scope: &management.WatchTopicSpecScope{ 446 Kind: "kind", 447 Name: "name", 448 }, 449 Kind: "kind", 450 Name: "name", 451 Type: []string{"type1", "type2", "type3"}, 452 }, 453 b: management.WatchTopicSpecFilters{ 454 Group: "group", 455 Scope: &management.WatchTopicSpecScope{ 456 Kind: "kind", 457 Name: "name1", 458 }, 459 Kind: "kind", 460 Name: "name", 461 Type: []string{"type1", "type2", "type3"}, 462 }, 463 }, 464 wantEqual: false, 465 }, 466 { 467 name: "scope diff name", 468 args: args{ 469 a: management.WatchTopicSpecFilters{ 470 Group: "group", 471 Scope: &management.WatchTopicSpecScope{ 472 Kind: "kind", 473 Name: "name", 474 }, 475 Kind: "kind", 476 Name: "name", 477 Type: []string{"type1", "type2", "type3"}, 478 }, 479 b: management.WatchTopicSpecFilters{ 480 Group: "group", 481 Scope: &management.WatchTopicSpecScope{ 482 Kind: "kind1", 483 Name: "name", 484 }, 485 Kind: "kind", 486 Name: "name", 487 Type: []string{"type1", "type2", "type3"}, 488 }, 489 }, 490 wantEqual: false, 491 }, 492 { 493 name: "scope diff types 1", 494 args: args{ 495 a: management.WatchTopicSpecFilters{ 496 Group: "group", 497 Scope: &management.WatchTopicSpecScope{ 498 Kind: "kind", 499 Name: "name", 500 }, 501 Kind: "kind", 502 Name: "name", 503 Type: []string{"type1", "type2", "type3"}, 504 }, 505 b: management.WatchTopicSpecFilters{ 506 Group: "group", 507 Scope: &management.WatchTopicSpecScope{ 508 Kind: "kind", 509 Name: "name", 510 }, 511 Kind: "kind", 512 Name: "name", 513 Type: []string{"type1", "type2"}, 514 }, 515 }, 516 wantEqual: false, 517 }, 518 { 519 name: "scope diff types 2", 520 args: args{ 521 a: management.WatchTopicSpecFilters{ 522 Group: "group", 523 Scope: &management.WatchTopicSpecScope{ 524 Kind: "kind", 525 Name: "name", 526 }, 527 Kind: "kind", 528 Name: "name", 529 Type: []string{"type1", "type2"}, 530 }, 531 b: management.WatchTopicSpecFilters{ 532 Group: "group", 533 Scope: &management.WatchTopicSpecScope{ 534 Kind: "kind", 535 Name: "name", 536 }, 537 Kind: "kind", 538 Name: "name", 539 Type: []string{"type1", "type2", "type3"}, 540 }, 541 }, 542 wantEqual: false, 543 }, 544 { 545 name: "equal", 546 args: args{ 547 a: management.WatchTopicSpecFilters{ 548 Group: "group", 549 Scope: &management.WatchTopicSpecScope{ 550 Kind: "kind", 551 Name: "name", 552 }, 553 Kind: "kind", 554 Name: "name", 555 Type: []string{"type1", "type2", "type3"}, 556 }, 557 b: management.WatchTopicSpecFilters{ 558 Group: "group", 559 Scope: &management.WatchTopicSpecScope{ 560 Kind: "kind", 561 Name: "name", 562 }, 563 Kind: "kind", 564 Name: "name", 565 Type: []string{"type1", "type2", "type3"}, 566 }, 567 }, 568 wantEqual: true, 569 }, 570 } 571 for _, tt := range tests { 572 t.Run(tt.name, func(t *testing.T) { 573 if gotEqual := filtersEqual(tt.args.a, tt.args.b); gotEqual != tt.wantEqual { 574 t.Errorf("filtersEqual() = %v, want %v", gotEqual, tt.wantEqual) 575 } 576 }) 577 } 578 } 579 580 func Test_getWatchTopic(t *testing.T) { 581 wt := &management.WatchTopic{} 582 ri, _ := wt.AsInstance() 583 httpClient := &mockAPIClient{ 584 ri: ri, 585 } 586 cfg := &config.CentralConfiguration{ 587 AgentType: 1, 588 TenantID: "12345", 589 Environment: "stream-test", 590 EnvironmentID: "123", 591 AgentName: "discoveryagents", 592 URL: "http://abc.com", 593 TLS: &config.TLSConfiguration{}, 594 } 595 596 wt, err := GetWatchTopic(cfg, httpClient) 597 assert.NotNil(t, wt) 598 assert.Nil(t, err) 599 600 wt, err = GetWatchTopic(cfg, httpClient) 601 assert.NotNil(t, wt) 602 assert.Nil(t, err) 603 } 604 605 type mockAPIClient struct { 606 ri *apiv1.ResourceInstance 607 getErr error 608 createErr error 609 updateErr error 610 deleteErr error 611 } 612 613 func (m mockAPIClient) GetResource(url string) (*apiv1.ResourceInstance, error) { 614 return m.ri, m.getErr 615 } 616 617 func (m mockAPIClient) CreateResourceInstance(_ apiv1.Interface) (*apiv1.ResourceInstance, error) { 618 return m.ri, m.createErr 619 } 620 621 func (m mockAPIClient) UpdateResourceInstance(_ apiv1.Interface) (*apiv1.ResourceInstance, error) { 622 return m.ri, m.updateErr 623 } 624 625 func (m mockAPIClient) DeleteResourceInstance(_ apiv1.Interface) error { 626 return m.deleteErr 627 } 628 629 func (m *mockAPIClient) GetAPIV1ResourceInstances(_ map[string]string, _ string) ([]*apiv1.ResourceInstance, error) { 630 return nil, nil 631 }