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  }