github.com/Axway/agent-sdk@v1.1.101/pkg/apic/apiserver/clients/api/v1/fake_test.go (about) 1 package v1_test 2 3 import ( 4 "reflect" 5 "sort" 6 "testing" 7 8 "github.com/stretchr/testify/assert" 9 10 v1 "github.com/Axway/agent-sdk/pkg/apic/apiserver/clients/api/v1" 11 apiv1 "github.com/Axway/agent-sdk/pkg/apic/apiserver/models/api/v1" 12 management "github.com/Axway/agent-sdk/pkg/apic/apiserver/models/management/v1alpha1" 13 ) 14 15 func TestFakeUnscoped(t *testing.T) { 16 cb, err := v1.NewFakeClient(&apiv1.ResourceInstance{ 17 ResourceMeta: apiv1.ResourceMeta{ 18 GroupVersionKind: management.EnvironmentGVK(), 19 Name: "environment", 20 }, 21 Spec: map[string]interface{}{}, 22 }) 23 if err != nil { 24 t.Fatal("Failed due to: ", err) 25 } 26 27 envClient, err := cb.ForKind(management.EnvironmentGVK()) 28 if err != nil { 29 t.Fatal("Failed due to: ", err) 30 } 31 k8s, err := envClient.Get("environment") 32 if err != nil { 33 t.Fatal("Failed due to: ", err) 34 } 35 t.Log(k8s) 36 } 37 38 func TestAddFakeUnscoped(t *testing.T) { 39 cb, err := v1.NewFakeClient(&apiv1.ResourceInstance{ 40 ResourceMeta: apiv1.ResourceMeta{ 41 GroupVersionKind: management.EnvironmentGVK(), 42 Name: "environment", 43 }, 44 Spec: map[string]interface{}{}, 45 }) 46 if err != nil { 47 t.Fatal("Failed due to: ", err) 48 } 49 50 envClient, err := cb.ForKind(management.EnvironmentGVK()) 51 if err != nil { 52 t.Fatal("Failed due to: ", err) 53 } 54 55 _, err = envClient.Create(&apiv1.ResourceInstance{ 56 ResourceMeta: apiv1.ResourceMeta{ 57 GroupVersionKind: management.EnvironmentGVK(), 58 Name: "environment", 59 }, 60 Spec: map[string]interface{}{}, 61 }) 62 if err == nil { 63 t.Fatal("Failed due to: expected error") 64 } 65 66 _, err = envClient.Create(&apiv1.ResourceInstance{ 67 ResourceMeta: apiv1.ResourceMeta{ 68 GroupVersionKind: management.EnvironmentGVK(), 69 Name: "secondEnvironment", 70 }, 71 Spec: map[string]interface{}{}, 72 }) 73 if err != nil { 74 t.Fatal("Failed due to: ", err) 75 } 76 } 77 78 func TestFakeScoped(t *testing.T) { 79 cb, err := v1.NewFakeClient( 80 &apiv1.ResourceInstance{ 81 ResourceMeta: apiv1.ResourceMeta{ 82 GroupVersionKind: management.EnvironmentGVK(), 83 Name: "environment", 84 }, 85 Spec: map[string]interface{}{}, 86 }, 87 &apiv1.ResourceInstance{ 88 ResourceMeta: apiv1.ResourceMeta{ 89 GroupVersionKind: management.APIServiceGVK(), 90 Name: "apiService", 91 Metadata: apiv1.Metadata{ 92 Scope: apiv1.MetadataScope{ 93 Name: "environment", 94 }, 95 }, 96 }, 97 Spec: map[string]interface{}{}, 98 }, 99 ) 100 if err != nil { 101 t.Fatal("Failed due to: ", err) 102 } 103 104 noScope, err := cb.ForKind(management.APIServiceGVK()) 105 if err != nil { 106 t.Fatal("Failed due to: ", err) 107 } 108 _, err = noScope.WithScope("environment").Get("apiService") 109 if err != nil { 110 t.Fatal("Failed due to: ", err) 111 } 112 113 ri, err := noScope.WithScope("environment").Update( 114 &apiv1.ResourceInstance{ 115 ResourceMeta: apiv1.ResourceMeta{ 116 GroupVersionKind: management.APIServiceGVK(), 117 Name: "apiService", 118 Metadata: apiv1.Metadata{ 119 Scope: apiv1.MetadataScope{ 120 Name: "environment", 121 }, 122 }, 123 Attributes: map[string]string{"attribute": "value"}, 124 Tags: []string{"tag"}, 125 }, 126 Spec: map[string]interface{}{}, 127 }) 128 if err != nil { 129 t.Fatal("Failed due to: ", err) 130 } 131 132 t.Logf("%+v", ri) 133 } 134 135 func TestFakeQueries(t *testing.T) { 136 cb, err := v1.NewFakeClient( 137 &apiv1.ResourceInstance{ 138 ResourceMeta: apiv1.ResourceMeta{ 139 Name: "env1", 140 GroupVersionKind: management.EnvironmentGVK(), 141 Attributes: map[string]string{ 142 "attr1": "val1", 143 "attr": "val", 144 "diffattr": "val1", 145 }, 146 Tags: []string{ 147 "tag", "tag1", 148 }, 149 }, 150 Spec: map[string]interface{}{}, 151 }, 152 &apiv1.ResourceInstance{ 153 ResourceMeta: apiv1.ResourceMeta{ 154 Name: "env2", 155 GroupVersionKind: management.EnvironmentGVK(), 156 Attributes: map[string]string{ 157 "attr2": "val2", 158 "attr": "val", 159 "diffattr": "val2", 160 }, 161 Tags: []string{ 162 "tag", "tag2", 163 }, 164 }, 165 Spec: map[string]interface{}{}, 166 }, 167 ) 168 if err != nil { 169 t.Fatalf("Failed due: %s", err) 170 } 171 172 cEnv, err := cb.ForKind(management.EnvironmentGVK()) 173 if err != nil { 174 t.Fatalf("Failed due: %s", err) 175 } 176 177 testCases := []struct { 178 name string 179 query v1.QueryNode 180 expected []string 181 }{{ 182 "query names", 183 v1.Names("env1"), 184 []string{"env1"}, 185 }, 186 187 { 188 "common attribute and value", 189 v1.AttrIn("attr", "val"), 190 []string{"env1", "env2"}, 191 }, { 192 "common tag", 193 v1.TagsIn("tag"), 194 []string{"env1", "env2"}, 195 }, { 196 "tag with one match", 197 v1.TagsIn("tag1"), 198 []string{"env1"}, 199 }, { 200 "two tags", 201 v1.TagsIn("tag1", "tag2"), 202 []string{"env1", "env2"}, 203 }, { 204 "attribute with two values", 205 v1.AttrIn("diffattr", "val1"), 206 []string{"env1"}, 207 }, { 208 "any attr", 209 v1.AnyAttr(map[string]string{"attr1": "val1", "attr2": "val2"}), 210 []string{"env1", "env2"}, 211 }, { 212 "all attr", 213 v1.AllAttr(map[string]string{"attr1": "val1", "diffattr": "val1"}), 214 []string{"env1"}, 215 }, { 216 "all attr and one tag", 217 v1.And(v1.AllAttr(map[string]string{"attr1": "val1", "diffattr": "val1"}), v1.TagsIn("tag")), 218 []string{"env1"}, 219 }, { 220 "all attr and one tag no result", 221 v1.And(v1.AllAttr(map[string]string{"attr1": "val1", "diffattr": "val1"}), v1.TagsIn("tag2")), 222 []string{}, 223 }, { 224 "all attr or one tag", 225 v1.Or(v1.AllAttr(map[string]string{"attr1": "val1", "diffattr": "val1"}), v1.TagsIn("tag2")), 226 []string{"env1", "env2"}, 227 }, 228 } 229 230 for i := range testCases { 231 tc := testCases[i] 232 t.Run(tc.name, func(t *testing.T) { 233 ris, err := cEnv.List(v1.WithQuery(tc.query)) 234 if err != nil { 235 t.Errorf("Failed due: %s", err) 236 } 237 238 names := make([]string, len(ris)) 239 240 for i, ri := range ris { 241 names[i] = ri.Name 242 } 243 244 sort.Slice(names, func(i, j int) bool { return names[i] < names[j] }) 245 246 if !reflect.DeepEqual(tc.expected, names) { 247 t.Errorf("Got %+v, expected %+v", names, tc.expected) 248 } 249 }) 250 } 251 } 252 253 func withAttr(attr map[string]string) func(*apiv1.ResourceInstance) { 254 return func(ri *apiv1.ResourceInstance) { 255 ri.Attributes = attr 256 } 257 } 258 259 func withTags(tags []string) func(*apiv1.ResourceInstance) { 260 return func(ri *apiv1.ResourceInstance) { 261 ri.Tags = tags 262 } 263 } 264 265 type buildOption func(*apiv1.ResourceInstance) 266 267 func env(name string, opts ...buildOption) *apiv1.ResourceInstance { 268 ri := &apiv1.ResourceInstance{ 269 ResourceMeta: apiv1.ResourceMeta{ 270 Name: name, 271 GroupVersionKind: management.EnvironmentGVK(), 272 }, 273 } 274 275 for _, o := range opts { 276 o(ri) 277 } 278 279 return ri 280 } 281 282 func apisvc(name string, scopeName string, opts ...buildOption) *apiv1.ResourceInstance { 283 ri := &apiv1.ResourceInstance{ 284 ResourceMeta: apiv1.ResourceMeta{ 285 Name: name, 286 GroupVersionKind: management.APIServiceGVK(), 287 Metadata: apiv1.Metadata{ 288 Scope: apiv1.MetadataScope{ 289 Name: scopeName, 290 }, 291 }, 292 }, 293 } 294 295 for _, o := range opts { 296 o(ri) 297 } 298 299 return ri 300 } 301 302 func TestFakeUpdateMerge(t *testing.T) { 303 old := &management.APIService{ 304 ResourceMeta: apiv1.ResourceMeta{ 305 GroupVersionKind: apiv1.GroupVersionKind{}, 306 Name: "name", 307 Metadata: apiv1.Metadata{ 308 Scope: apiv1.MetadataScope{ 309 Name: "myenv", 310 }, 311 References: []apiv1.Reference{}, 312 }, 313 Tags: []string{"old"}, 314 }, 315 } 316 317 update := &management.APIService{ 318 ResourceMeta: apiv1.ResourceMeta{ 319 GroupVersionKind: apiv1.GroupVersionKind{}, 320 Name: "name", 321 Metadata: apiv1.Metadata{ 322 Scope: apiv1.MetadataScope{ 323 Name: "myenv", 324 }, 325 References: []apiv1.Reference{}, 326 }, 327 Attributes: map[string]string{}, 328 Tags: []string{"new"}, 329 }, 330 } 331 332 merged := &management.APIService{ 333 ResourceMeta: apiv1.ResourceMeta{ 334 GroupVersionKind: apiv1.GroupVersionKind{}, 335 Name: "name", 336 Metadata: apiv1.Metadata{ 337 Scope: apiv1.MetadataScope{ 338 Name: "myenv", 339 }, 340 References: []apiv1.Reference{}, 341 }, 342 Attributes: map[string]string{}, 343 Tags: []string{"old", "new"}, 344 }, 345 } 346 347 testCases := []struct { 348 name string 349 old apiv1.Interface 350 update apiv1.Interface 351 mf v1.MergeFunc 352 expected apiv1.Interface 353 }{{ 354 name: "it's a create", 355 old: nil, 356 update: update, 357 mf: func(fetched, new apiv1.Interface) (apiv1.Interface, error) { 358 return new, nil 359 }, 360 expected: update, 361 }, { 362 name: "it's an overwrite", 363 old: old, 364 update: update, 365 mf: func(fetched, new apiv1.Interface) (apiv1.Interface, error) { 366 return new, nil 367 }, 368 expected: update, 369 }, { 370 name: "it's a merge", 371 old: old, 372 update: update, 373 mf: func(fetched, new apiv1.Interface) (apiv1.Interface, error) { 374 ri, err := fetched.AsInstance() 375 if err != nil { 376 return nil, err 377 } 378 ri.Tags = append(ri.Tags, new.GetTags()...) 379 380 return ri, nil 381 }, 382 expected: merged, 383 }} 384 385 for i := range testCases { 386 tc := testCases[i] 387 t.Run(tc.name, func(t *testing.T) { 388 b, err := v1.NewFakeClient(&management.Environment{ResourceMeta: apiv1.ResourceMeta{Name: "myenv"}}) 389 if err != nil { 390 t.Fatal(err) 391 } 392 393 us, err := b.ForKind(management.APIServiceGVK()) 394 if err != nil { 395 t.Fatal(err) 396 } 397 398 if tc.old != nil { 399 i, err := tc.old.AsInstance() 400 if err != nil { 401 t.Fatalf("Failed due: %s", err) 402 } 403 _, err = us.Create(i) 404 if err != nil { 405 t.Error("Failed to create old resource: ", err) 406 } 407 } 408 i, err := tc.update.AsInstance() 409 if err != nil { 410 t.Fatalf("Failed due: %s", err) 411 } 412 413 r, err := us.Update(i, v1.Merge(tc.mf)) 414 if err != nil { 415 t.Errorf("Failed to update: %s", err) 416 return 417 } 418 419 if !reflect.DeepEqual(r.GetTags(), tc.expected.GetTags()) { 420 t.Errorf("Expected tags %+v; Got: %+v ", tc.expected.GetTags(), r.GetTags()) 421 } 422 423 }) 424 } 425 } 426 427 func TestFake(t *testing.T) { 428 testCases := []struct { 429 name string 430 init []apiv1.Interface 431 add []*apiv1.ResourceInstance 432 update []*apiv1.ResourceInstance 433 delete []*apiv1.ResourceInstance 434 queryClient func(v1.Base) v1.Scoped 435 query v1.QueryNode 436 expectedBefore []string 437 expectedAfter []string 438 }{{ 439 "attr list after delete", 440 []apiv1.Interface{ 441 env("env1"), 442 apisvc("svc1", "env1", withAttr(map[string]string{"attr": "val"})), 443 }, 444 []*apiv1.ResourceInstance{}, 445 []*apiv1.ResourceInstance{}, 446 []*apiv1.ResourceInstance{apisvc("svc1", "env1")}, 447 func(b v1.Base) v1.Scoped { c, _ := b.ForKind(management.APIServiceGVK()); return c.WithScope("env1") }, 448 v1.AttrIn("attr", "val"), 449 []string{"svc1"}, 450 []string{}, 451 }, { 452 "attr list after update", 453 []apiv1.Interface{ 454 env("env1"), 455 apisvc("svc1", "env1"), 456 }, 457 []*apiv1.ResourceInstance{}, 458 []*apiv1.ResourceInstance{apisvc("svc1", "env1", withAttr(map[string]string{"attr": "val"}))}, 459 []*apiv1.ResourceInstance{}, 460 func(b v1.Base) v1.Scoped { c, _ := b.ForKind(management.APIServiceGVK()); return c.WithScope("env1") }, 461 v1.AttrIn("attr", "val"), 462 []string{}, 463 []string{"svc1"}, 464 }, { 465 "tags list after delete", 466 []apiv1.Interface{ 467 env("env1"), 468 apisvc("svc1", "env1", withTags([]string{"tag1"})), 469 }, 470 []*apiv1.ResourceInstance{}, 471 []*apiv1.ResourceInstance{}, 472 []*apiv1.ResourceInstance{apisvc("svc1", "env1")}, 473 func(b v1.Base) v1.Scoped { c, _ := b.ForKind(management.APIServiceGVK()); return c.WithScope("env1") }, 474 v1.TagsIn("tag1"), 475 []string{"svc1"}, 476 []string{}, 477 }, { 478 "tags list after update", 479 []apiv1.Interface{ 480 env("env1"), 481 apisvc("svc1", "env1"), 482 }, 483 []*apiv1.ResourceInstance{}, 484 []*apiv1.ResourceInstance{apisvc("svc1", "env1", withTags([]string{"tag1"}))}, 485 []*apiv1.ResourceInstance{}, 486 func(b v1.Base) v1.Scoped { c, _ := b.ForKind(management.APIServiceGVK()); return c.WithScope("env1") }, 487 v1.TagsIn("tag1"), 488 []string{}, 489 []string{"svc1"}, 490 }, { 491 "attribute and tags list after add", 492 []apiv1.Interface{ 493 env("env1"), 494 apisvc("svc1", "env1", withAttr(map[string]string{"attr1": "val1"}), withTags([]string{"tag1"})), 495 }, 496 []*apiv1.ResourceInstance{apisvc("svc2", "env1", withAttr(map[string]string{"attr1": "val1"}), withTags([]string{"tag1"}))}, 497 []*apiv1.ResourceInstance{}, 498 []*apiv1.ResourceInstance{}, 499 func(b v1.Base) v1.Scoped { c, _ := b.ForKind(management.APIServiceGVK()); return c.WithScope("env1") }, 500 v1.TagsIn("tag1"), 501 []string{"svc1"}, 502 []string{"svc1", "svc2"}, 503 }, 504 } 505 506 for i := range testCases { 507 tc := testCases[i] 508 t.Run(tc.name, func(t *testing.T) { 509 fk, err := v1.NewFakeClient(tc.init...) 510 if err != nil { 511 t.Fatalf("Failed due: %s", err) 512 } 513 514 ris, err := tc.queryClient(fk).List(v1.WithQuery(tc.query)) 515 if err != nil { 516 t.Fatalf("List query failed due: %s", err) 517 } 518 519 names := make([]string, len(ris)) 520 for i, ri := range ris { 521 names[i] = ri.Name 522 } 523 524 sort.Strings(tc.expectedBefore) 525 sort.Strings(names) 526 527 if !reflect.DeepEqual(tc.expectedBefore, names) { 528 t.Fatalf("Before: got %+v, expected %+v", names, tc.expectedBefore) 529 } 530 531 for _, ri := range tc.add { 532 c, err := fk.ForKind(ri.GroupVersionKind) 533 if err != nil { 534 t.Fatalf("Failed to add %+v: %s", ri, err) 535 } 536 537 s := c.(v1.Scoped) 538 539 if ri.Metadata.Scope.Name != "" { 540 s = c.WithScope(ri.Metadata.Scope.Name) 541 } 542 543 _, err = s.Create(ri) 544 if err != nil { 545 t.Fatalf("Failed to add %+v: %s", ri, err) 546 } 547 } 548 549 for _, ri := range tc.update { 550 c, err := fk.ForKind(ri.GroupVersionKind) 551 if err != nil { 552 t.Fatalf("Failed to update %+v: %s", ri, err) 553 } 554 555 s := c.(v1.Scoped) 556 557 if ri.Metadata.Scope.Name != "" { 558 s = c.WithScope(ri.Metadata.Scope.Name) 559 } 560 561 _, err = s.Update(ri) 562 if err != nil { 563 t.Fatalf("Failed to update %+v: %s", ri, err) 564 } 565 } 566 567 for _, ri := range tc.delete { 568 c, err := fk.ForKind(ri.GroupVersionKind) 569 if err != nil { 570 t.Fatalf("Failed to delete %+v: %s", ri, err) 571 } 572 573 s := c.(v1.Scoped) 574 575 if ri.Metadata.Scope.Name != "" { 576 s = c.WithScope(ri.Metadata.Scope.Name) 577 } 578 579 err = s.Delete(ri) 580 if err != nil { 581 t.Fatalf("Failed to delete %+v: %s", ri, err) 582 } 583 } 584 585 ris, err = tc.queryClient(fk).List(v1.WithQuery(tc.query)) 586 if err != nil { 587 t.Errorf("Failed due: %s", err) 588 } 589 590 names = make([]string, len(ris)) 591 for i, ri := range ris { 592 names[i] = ri.Name 593 } 594 595 sort.Strings(tc.expectedAfter) 596 sort.Strings(names) 597 598 if !reflect.DeepEqual(tc.expectedAfter, names) { 599 t.Errorf("After: got %+v, expected %+v", names, tc.expectedAfter) 600 } 601 602 }) 603 } 604 605 } 606 607 func TestFakeEvents(t *testing.T) { 608 fk, err := v1.NewFakeClient() 609 if err != nil { 610 t.Fatalf("Failed due: %s", err) 611 } 612 613 ri := env("env1") 614 615 fk.SetHandler(v1.EventHandlerFunc(func(e *apiv1.Event) { 616 assert.NotNil(t, e) 617 })) 618 619 c, err := fk.ForKind(management.EnvironmentGVK()) 620 if err != nil { 621 t.Fatalf("Failed due: %s", err) 622 } 623 624 _, err = c.Create(ri) 625 if err != nil { 626 t.Fatalf("Failed due: %s", err) 627 } 628 629 _, err = c.Update(ri) 630 if err != nil { 631 t.Fatalf("Failed due: %s", err) 632 } 633 634 err = c.Delete(ri) 635 if err != nil { 636 t.Fatalf("Failed due: %s", err) 637 } 638 }