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  }