github.com/nginxinc/kubernetes-ingress@v1.12.5/internal/configs/configurator_test.go (about)

     1  package configs
     2  
     3  import (
     4  	"os"
     5  	"reflect"
     6  	"testing"
     7  
     8  	"github.com/prometheus/client_golang/prometheus"
     9  	networking "k8s.io/api/networking/v1beta1"
    10  	meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    11  	"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
    12  
    13  	"github.com/nginxinc/kubernetes-ingress/internal/configs/version1"
    14  	"github.com/nginxinc/kubernetes-ingress/internal/configs/version2"
    15  	"github.com/nginxinc/kubernetes-ingress/internal/nginx"
    16  	conf_v1 "github.com/nginxinc/kubernetes-ingress/pkg/apis/configuration/v1"
    17  	conf_v1alpha1 "github.com/nginxinc/kubernetes-ingress/pkg/apis/configuration/v1alpha1"
    18  )
    19  
    20  func createTestStaticConfigParams() *StaticConfigParams {
    21  	return &StaticConfigParams{
    22  		HealthStatus:                   true,
    23  		HealthStatusURI:                "/nginx-health",
    24  		NginxStatus:                    true,
    25  		NginxStatusAllowCIDRs:          []string{"127.0.0.1"},
    26  		NginxStatusPort:                8080,
    27  		StubStatusOverUnixSocketForOSS: false,
    28  	}
    29  }
    30  
    31  func createTestConfigurator() (*Configurator, error) {
    32  	templateExecutor, err := version1.NewTemplateExecutor("version1/nginx-plus.tmpl", "version1/nginx-plus.ingress.tmpl")
    33  	if err != nil {
    34  		return nil, err
    35  	}
    36  
    37  	templateExecutorV2, err := version2.NewTemplateExecutor("version2/nginx-plus.virtualserver.tmpl", "version2/nginx-plus.transportserver.tmpl")
    38  	if err != nil {
    39  		return nil, err
    40  	}
    41  
    42  	manager := nginx.NewFakeManager("/etc/nginx")
    43  
    44  	return NewConfigurator(manager, createTestStaticConfigParams(), NewDefaultConfigParams(), templateExecutor, templateExecutorV2, false, false, nil, false, nil, false), nil
    45  }
    46  
    47  func createTestConfiguratorInvalidIngressTemplate() (*Configurator, error) {
    48  	templateExecutor, err := version1.NewTemplateExecutor("version1/nginx-plus.tmpl", "version1/nginx-plus.ingress.tmpl")
    49  	if err != nil {
    50  		return nil, err
    51  	}
    52  
    53  	invalidIngressTemplate := "{{.Upstreams.This.Field.Does.Not.Exist}}"
    54  	if err := templateExecutor.UpdateIngressTemplate(&invalidIngressTemplate); err != nil {
    55  		return nil, err
    56  	}
    57  
    58  	manager := nginx.NewFakeManager("/etc/nginx")
    59  
    60  	return NewConfigurator(manager, createTestStaticConfigParams(), NewDefaultConfigParams(), templateExecutor, &version2.TemplateExecutor{}, false, false, nil, false, nil, false), nil
    61  }
    62  
    63  func TestAddOrUpdateIngress(t *testing.T) {
    64  	cnf, err := createTestConfigurator()
    65  	if err != nil {
    66  		t.Errorf("Failed to create a test configurator: %v", err)
    67  	}
    68  
    69  	ingress := createCafeIngressEx()
    70  
    71  	warnings, err := cnf.AddOrUpdateIngress(&ingress)
    72  	if err != nil {
    73  		t.Errorf("AddOrUpdateIngress returned:  \n%v, but expected: \n%v", err, nil)
    74  	}
    75  	if len(warnings) != 0 {
    76  		t.Errorf("AddOrUpdateIngress returned warnings: %v", warnings)
    77  	}
    78  
    79  	cnfHasIngress := cnf.HasIngress(ingress.Ingress)
    80  	if !cnfHasIngress {
    81  		t.Errorf("AddOrUpdateIngress didn't add ingress successfully. HasIngress returned %v, expected %v", cnfHasIngress, true)
    82  	}
    83  }
    84  
    85  func TestAddOrUpdateMergeableIngress(t *testing.T) {
    86  	cnf, err := createTestConfigurator()
    87  	if err != nil {
    88  		t.Errorf("Failed to create a test configurator: %v", err)
    89  	}
    90  
    91  	mergeableIngess := createMergeableCafeIngress()
    92  
    93  	warnings, err := cnf.AddOrUpdateMergeableIngress(mergeableIngess)
    94  	if err != nil {
    95  		t.Errorf("AddOrUpdateMergeableIngress returned \n%v, expected \n%v", err, nil)
    96  	}
    97  	if len(warnings) != 0 {
    98  		t.Errorf("AddOrUpdateMergeableIngress returned warnings: %v", warnings)
    99  	}
   100  
   101  	cnfHasMergeableIngress := cnf.HasIngress(mergeableIngess.Master.Ingress)
   102  	if !cnfHasMergeableIngress {
   103  		t.Errorf("AddOrUpdateMergeableIngress didn't add mergeable ingress successfully. HasIngress returned %v, expected %v", cnfHasMergeableIngress, true)
   104  	}
   105  }
   106  
   107  func TestAddOrUpdateIngressFailsWithInvalidIngressTemplate(t *testing.T) {
   108  	cnf, err := createTestConfiguratorInvalidIngressTemplate()
   109  	if err != nil {
   110  		t.Errorf("Failed to create a test configurator: %v", err)
   111  	}
   112  
   113  	ingress := createCafeIngressEx()
   114  
   115  	warnings, err := cnf.AddOrUpdateIngress(&ingress)
   116  	if err == nil {
   117  		t.Errorf("AddOrUpdateIngress returned \n%v,  but expected \n%v", nil, "template execution error")
   118  	}
   119  	if len(warnings) != 0 {
   120  		t.Errorf("AddOrUpdateIngress returned warnings: %v", warnings)
   121  	}
   122  }
   123  
   124  func TestAddOrUpdateMergeableIngressFailsWithInvalidIngressTemplate(t *testing.T) {
   125  	cnf, err := createTestConfiguratorInvalidIngressTemplate()
   126  	if err != nil {
   127  		t.Errorf("Failed to create a test configurator: %v", err)
   128  	}
   129  
   130  	mergeableIngess := createMergeableCafeIngress()
   131  
   132  	warnings, err := cnf.AddOrUpdateMergeableIngress(mergeableIngess)
   133  	if err == nil {
   134  		t.Errorf("AddOrUpdateMergeableIngress returned \n%v, but expected \n%v", nil, "template execution error")
   135  	}
   136  	if len(warnings) != 0 {
   137  		t.Errorf("AddOrUpdateMergeableIngress returned warnings: %v", warnings)
   138  	}
   139  }
   140  
   141  func TestUpdateEndpoints(t *testing.T) {
   142  	cnf, err := createTestConfigurator()
   143  	if err != nil {
   144  		t.Errorf("Failed to create a test configurator: %v", err)
   145  	}
   146  
   147  	ingress := createCafeIngressEx()
   148  	ingresses := []*IngressEx{&ingress}
   149  
   150  	err = cnf.UpdateEndpoints(ingresses)
   151  	if err != nil {
   152  		t.Errorf("UpdateEndpoints returned\n%v, but expected \n%v", err, nil)
   153  	}
   154  
   155  	err = cnf.UpdateEndpoints(ingresses)
   156  	if err != nil {
   157  		t.Errorf("UpdateEndpoints returned\n%v, but expected \n%v", err, nil)
   158  	}
   159  }
   160  
   161  func TestUpdateEndpointsMergeableIngress(t *testing.T) {
   162  	cnf, err := createTestConfigurator()
   163  	if err != nil {
   164  		t.Errorf("Failed to create a test configurator: %v", err)
   165  	}
   166  
   167  	mergeableIngress := createMergeableCafeIngress()
   168  	mergeableIngresses := []*MergeableIngresses{mergeableIngress}
   169  
   170  	err = cnf.UpdateEndpointsMergeableIngress(mergeableIngresses)
   171  	if err != nil {
   172  		t.Errorf("UpdateEndpointsMergeableIngress returned \n%v, but expected \n%v", err, nil)
   173  	}
   174  
   175  	err = cnf.UpdateEndpointsMergeableIngress(mergeableIngresses)
   176  	if err != nil {
   177  		t.Errorf("UpdateEndpointsMergeableIngress returned \n%v, but expected \n%v", err, nil)
   178  	}
   179  }
   180  
   181  func TestUpdateEndpointsFailsWithInvalidTemplate(t *testing.T) {
   182  	cnf, err := createTestConfiguratorInvalidIngressTemplate()
   183  	if err != nil {
   184  		t.Errorf("Failed to create a test configurator: %v", err)
   185  	}
   186  
   187  	ingress := createCafeIngressEx()
   188  	ingresses := []*IngressEx{&ingress}
   189  
   190  	err = cnf.UpdateEndpoints(ingresses)
   191  	if err == nil {
   192  		t.Errorf("UpdateEndpoints returned\n%v, but expected \n%v", nil, "template execution error")
   193  	}
   194  }
   195  
   196  func TestUpdateEndpointsMergeableIngressFailsWithInvalidTemplate(t *testing.T) {
   197  	cnf, err := createTestConfiguratorInvalidIngressTemplate()
   198  	if err != nil {
   199  		t.Errorf("Failed to create a test configurator: %v", err)
   200  	}
   201  
   202  	mergeableIngress := createMergeableCafeIngress()
   203  	mergeableIngresses := []*MergeableIngresses{mergeableIngress}
   204  
   205  	err = cnf.UpdateEndpointsMergeableIngress(mergeableIngresses)
   206  	if err == nil {
   207  		t.Errorf("UpdateEndpointsMergeableIngress returned \n%v, but expected \n%v", nil, "template execution error")
   208  	}
   209  }
   210  
   211  func TestGetVirtualServerConfigFileName(t *testing.T) {
   212  	vs := conf_v1.VirtualServer{
   213  		ObjectMeta: meta_v1.ObjectMeta{
   214  			Namespace: "test",
   215  			Name:      "virtual-server",
   216  		},
   217  	}
   218  
   219  	expected := "vs_test_virtual-server"
   220  
   221  	result := getFileNameForVirtualServer(&vs)
   222  	if result != expected {
   223  		t.Errorf("getFileNameForVirtualServer returned %v, but expected %v", result, expected)
   224  	}
   225  }
   226  
   227  func TestGetFileNameForVirtualServerFromKey(t *testing.T) {
   228  	key := "default/cafe"
   229  
   230  	expected := "vs_default_cafe"
   231  
   232  	result := getFileNameForVirtualServerFromKey(key)
   233  	if result != expected {
   234  		t.Errorf("getFileNameForVirtualServerFromKey returned %v, but expected %v", result, expected)
   235  	}
   236  }
   237  
   238  func TestGetFileNameForTransportServer(t *testing.T) {
   239  	transportServer := &conf_v1alpha1.TransportServer{
   240  		ObjectMeta: meta_v1.ObjectMeta{
   241  			Namespace: "default",
   242  			Name:      "test-server",
   243  		},
   244  	}
   245  
   246  	expected := "ts_default_test-server"
   247  
   248  	result := getFileNameForTransportServer(transportServer)
   249  	if result != expected {
   250  		t.Errorf("getFileNameForTransportServer() returned %q but expected %q", result, expected)
   251  	}
   252  }
   253  
   254  func TestGetFileNameForTransportServerFromKey(t *testing.T) {
   255  	key := "default/test-server"
   256  
   257  	expected := "ts_default_test-server"
   258  
   259  	result := getFileNameForTransportServerFromKey(key)
   260  	if result != expected {
   261  		t.Errorf("getFileNameForTransportServerFromKey(%q) returned %q but expected %q", key, result, expected)
   262  	}
   263  }
   264  
   265  func TestGenerateNamespaceNameKey(t *testing.T) {
   266  	objectMeta := &meta_v1.ObjectMeta{
   267  		Namespace: "default",
   268  		Name:      "test-server",
   269  	}
   270  
   271  	expected := "default/test-server"
   272  
   273  	result := generateNamespaceNameKey(objectMeta)
   274  	if result != expected {
   275  		t.Errorf("generateNamespaceNameKey() returned %q but expected %q", result, expected)
   276  	}
   277  }
   278  
   279  func TestGenerateTLSPassthroughHostsConfig(t *testing.T) {
   280  	tlsPassthroughPairs := map[string]tlsPassthroughPair{
   281  		"default/ts-1": {
   282  			Host:       "one.example.com",
   283  			UnixSocket: "socket1.sock",
   284  		},
   285  		"default/ts-2": {
   286  			Host:       "two.example.com",
   287  			UnixSocket: "socket2.sock",
   288  		},
   289  	}
   290  
   291  	expectedCfg := &version2.TLSPassthroughHostsConfig{
   292  		"one.example.com": "socket1.sock",
   293  		"two.example.com": "socket2.sock",
   294  	}
   295  
   296  	resultCfg := generateTLSPassthroughHostsConfig(tlsPassthroughPairs)
   297  	if !reflect.DeepEqual(resultCfg, expectedCfg) {
   298  		t.Errorf("generateTLSPassthroughHostsConfig() returned %v but expected %v", resultCfg, expectedCfg)
   299  	}
   300  }
   301  
   302  func TestAddInternalRouteConfig(t *testing.T) {
   303  	cnf, err := createTestConfigurator()
   304  	if err != nil {
   305  		t.Errorf("Failed to create a test configurator: %v", err)
   306  	}
   307  	// set pod name in env
   308  	err = os.Setenv("POD_NAME", "nginx-ingress")
   309  	if err != nil {
   310  		t.Errorf("Failed to set pod name in environment: %v", err)
   311  	}
   312  	err = cnf.AddInternalRouteConfig()
   313  	if err != nil {
   314  		t.Errorf("AddInternalRouteConfig returned:  \n%v, but expected: \n%v", err, nil)
   315  	}
   316  
   317  	if !cnf.staticCfgParams.EnableInternalRoutes {
   318  		t.Errorf("AddInternalRouteConfig failed to set EnableInteralRoutes field of staticCfgParams to true")
   319  	}
   320  	if cnf.staticCfgParams.PodName != "nginx-ingress" {
   321  		t.Errorf("AddInternalRouteConfig failed to set PodName field of staticCfgParams")
   322  	}
   323  }
   324  
   325  func TestFindRemovedKeys(t *testing.T) {
   326  	tests := []struct {
   327  		currentKeys []string
   328  		newKeys     map[string]bool
   329  		expected    []string
   330  	}{
   331  		{
   332  			currentKeys: []string{"key1", "key2"},
   333  			newKeys:     map[string]bool{"key1": true, "key2": true},
   334  			expected:    nil,
   335  		},
   336  		{
   337  			currentKeys: []string{"key1", "key2"},
   338  			newKeys:     map[string]bool{"key2": true, "key3": true},
   339  			expected:    []string{"key1"},
   340  		},
   341  		{
   342  			currentKeys: []string{"key1", "key2"},
   343  			newKeys:     map[string]bool{"key3": true, "key4": true},
   344  			expected:    []string{"key1", "key2"},
   345  		},
   346  		{
   347  			currentKeys: []string{"key1", "key2"},
   348  			newKeys:     map[string]bool{"key3": true},
   349  			expected:    []string{"key1", "key2"},
   350  		},
   351  	}
   352  	for _, test := range tests {
   353  		result := findRemovedKeys(test.currentKeys, test.newKeys)
   354  		if !reflect.DeepEqual(result, test.expected) {
   355  			t.Errorf("findRemovedKeys(%v, %v) returned %v but expected %v", test.currentKeys, test.newKeys, result, test.expected)
   356  		}
   357  	}
   358  }
   359  
   360  type mockLabelUpdater struct {
   361  	upstreamServerLabels           map[string][]string
   362  	serverZoneLabels               map[string][]string
   363  	upstreamServerPeerLabels       map[string][]string
   364  	streamUpstreamServerPeerLabels map[string][]string
   365  	streamUpstreamServerLabels     map[string][]string
   366  	streamServerZoneLabels         map[string][]string
   367  }
   368  
   369  func newFakeLabelUpdater() *mockLabelUpdater {
   370  	return &mockLabelUpdater{
   371  		upstreamServerLabels:           make(map[string][]string),
   372  		serverZoneLabels:               make(map[string][]string),
   373  		upstreamServerPeerLabels:       make(map[string][]string),
   374  		streamUpstreamServerPeerLabels: make(map[string][]string),
   375  		streamUpstreamServerLabels:     make(map[string][]string),
   376  		streamServerZoneLabels:         make(map[string][]string),
   377  	}
   378  }
   379  
   380  // UpdateUpstreamServerPeerLabels updates the Upstream Server Peer Labels
   381  func (u *mockLabelUpdater) UpdateUpstreamServerPeerLabels(upstreamServerPeerLabels map[string][]string) {
   382  	for k, v := range upstreamServerPeerLabels {
   383  		u.upstreamServerPeerLabels[k] = v
   384  	}
   385  }
   386  
   387  // DeleteUpstreamServerPeerLabels deletes the Upstream Server Peer Labels
   388  func (u *mockLabelUpdater) DeleteUpstreamServerPeerLabels(peers []string) {
   389  	for _, k := range peers {
   390  		delete(u.upstreamServerPeerLabels, k)
   391  	}
   392  }
   393  
   394  // UpdateStreamUpstreamServerPeerLabels updates the Upstream Server Peer Labels
   395  func (u *mockLabelUpdater) UpdateStreamUpstreamServerPeerLabels(upstreamServerPeerLabels map[string][]string) {
   396  	for k, v := range upstreamServerPeerLabels {
   397  		u.streamUpstreamServerPeerLabels[k] = v
   398  	}
   399  }
   400  
   401  // DeleteStreamUpstreamServerPeerLabels deletes the Upstream Server Peer Labels
   402  func (u *mockLabelUpdater) DeleteStreamUpstreamServerPeerLabels(peers []string) {
   403  	for _, k := range peers {
   404  		delete(u.streamUpstreamServerPeerLabels, k)
   405  	}
   406  }
   407  
   408  // UpdateUpstreamServerLabels updates the Upstream Server Labels
   409  func (u *mockLabelUpdater) UpdateUpstreamServerLabels(upstreamServerLabelValues map[string][]string) {
   410  	for k, v := range upstreamServerLabelValues {
   411  		u.upstreamServerLabels[k] = v
   412  	}
   413  }
   414  
   415  // DeleteUpstreamServerLabels deletes the Upstream Server Labels
   416  func (u *mockLabelUpdater) DeleteUpstreamServerLabels(upstreamNames []string) {
   417  	for _, k := range upstreamNames {
   418  		delete(u.upstreamServerLabels, k)
   419  	}
   420  }
   421  
   422  // UpdateStreamUpstreamServerLabels updates the Stream Upstream Server Labels
   423  func (u *mockLabelUpdater) UpdateStreamUpstreamServerLabels(streamUpstreamServerLabelValues map[string][]string) {
   424  	for k, v := range streamUpstreamServerLabelValues {
   425  		u.streamUpstreamServerLabels[k] = v
   426  	}
   427  }
   428  
   429  // DeleteStreamUpstreamServerLabels deletes the Stream Upstream Server Labels
   430  func (u *mockLabelUpdater) DeleteStreamUpstreamServerLabels(streamUpstreamServerNames []string) {
   431  	for _, k := range streamUpstreamServerNames {
   432  		delete(u.streamUpstreamServerLabels, k)
   433  	}
   434  }
   435  
   436  // UpdateServerZoneLabels updates the Server Zone Labels
   437  func (u *mockLabelUpdater) UpdateServerZoneLabels(serverZoneLabelValues map[string][]string) {
   438  	for k, v := range serverZoneLabelValues {
   439  		u.serverZoneLabels[k] = v
   440  	}
   441  }
   442  
   443  // DeleteServerZoneLabels deletes the Server Zone Labels
   444  func (u *mockLabelUpdater) DeleteServerZoneLabels(zoneNames []string) {
   445  	for _, k := range zoneNames {
   446  		delete(u.serverZoneLabels, k)
   447  	}
   448  }
   449  
   450  // UpdateStreamServerZoneLabels updates the Server Zone Labels
   451  func (u *mockLabelUpdater) UpdateStreamServerZoneLabels(streamServerZoneLabelValues map[string][]string) {
   452  	for k, v := range streamServerZoneLabelValues {
   453  		u.streamServerZoneLabels[k] = v
   454  	}
   455  }
   456  
   457  // DeleteStreamServerZoneLabels deletes the Server Zone Labels
   458  func (u *mockLabelUpdater) DeleteStreamServerZoneLabels(zoneNames []string) {
   459  	for _, k := range zoneNames {
   460  		delete(u.streamServerZoneLabels, k)
   461  	}
   462  }
   463  
   464  type mockLatencyCollector struct {
   465  	upstreamServerLabels        map[string][]string
   466  	upstreamServerPeerLabels    map[string][]string
   467  	upstreamServerPeersToDelete []string
   468  }
   469  
   470  func newMockLatencyCollector() *mockLatencyCollector {
   471  	return &mockLatencyCollector{
   472  		upstreamServerLabels:     make(map[string][]string),
   473  		upstreamServerPeerLabels: make(map[string][]string),
   474  	}
   475  }
   476  
   477  // DeleteMetrics deletes metrics for the given upstream server peers
   478  func (u *mockLatencyCollector) DeleteMetrics(upstreamServerPeerNames []string) {
   479  	u.upstreamServerPeersToDelete = upstreamServerPeerNames
   480  }
   481  
   482  // UpdateUpstreamServerLabels updates the Upstream Server Labels
   483  func (u *mockLatencyCollector) UpdateUpstreamServerLabels(upstreamServerLabelValues map[string][]string) {
   484  	for k, v := range upstreamServerLabelValues {
   485  		u.upstreamServerLabels[k] = v
   486  	}
   487  }
   488  
   489  // DeleteUpstreamServerLabels deletes the Upstream Server Labels
   490  func (u *mockLatencyCollector) DeleteUpstreamServerLabels(upstreamNames []string) {
   491  	for _, k := range upstreamNames {
   492  		delete(u.upstreamServerLabels, k)
   493  	}
   494  }
   495  
   496  // UpdateUpstreamServerPeerLabels updates the Upstream Server Peer Labels
   497  func (u *mockLatencyCollector) UpdateUpstreamServerPeerLabels(upstreamServerPeerLabels map[string][]string) {
   498  	for k, v := range upstreamServerPeerLabels {
   499  		u.upstreamServerPeerLabels[k] = v
   500  	}
   501  }
   502  
   503  // DeleteUpstreamServerPeerLabels deletes the Upstream Server Peer Labels
   504  func (u *mockLatencyCollector) DeleteUpstreamServerPeerLabels(peers []string) {
   505  	for _, k := range peers {
   506  		delete(u.upstreamServerPeerLabels, k)
   507  	}
   508  }
   509  
   510  // RecordLatency implements a fake RecordLatency method
   511  func (u *mockLatencyCollector) RecordLatency(string) {}
   512  
   513  // Register implements a fake Register method
   514  func (u *mockLatencyCollector) Register(*prometheus.Registry) error { return nil }
   515  
   516  func TestUpdateIngressMetricsLabels(t *testing.T) {
   517  	cnf, err := createTestConfigurator()
   518  	if err != nil {
   519  		t.Fatalf("Failed to create a test configurator: %v", err)
   520  	}
   521  
   522  	cnf.isPlus = true
   523  	cnf.labelUpdater = newFakeLabelUpdater()
   524  	testLatencyCollector := newMockLatencyCollector()
   525  	cnf.latencyCollector = testLatencyCollector
   526  
   527  	ingEx := &IngressEx{
   528  		Ingress: &networking.Ingress{
   529  			ObjectMeta: meta_v1.ObjectMeta{
   530  				Name:      "test-ingress",
   531  				Namespace: "default",
   532  			},
   533  			Spec: networking.IngressSpec{
   534  				Rules: []networking.IngressRule{
   535  					{
   536  						Host: "example.com",
   537  					},
   538  				},
   539  			},
   540  		},
   541  		PodsByIP: map[string]PodInfo{
   542  			"10.0.0.1:80": {Name: "pod-1"},
   543  			"10.0.0.2:80": {Name: "pod-2"},
   544  		},
   545  	}
   546  
   547  	upstreams := []version1.Upstream{
   548  		{
   549  			Name: "upstream-1",
   550  			UpstreamServers: []version1.UpstreamServer{
   551  				{
   552  					Address: "10.0.0.1",
   553  					Port:    "80",
   554  				},
   555  			},
   556  			UpstreamLabels: version1.UpstreamLabels{
   557  				Service:           "service-1",
   558  				ResourceType:      "ingress",
   559  				ResourceName:      ingEx.Ingress.Name,
   560  				ResourceNamespace: ingEx.Ingress.Namespace,
   561  			},
   562  		},
   563  		{
   564  			Name: "upstream-2",
   565  			UpstreamServers: []version1.UpstreamServer{
   566  				{
   567  					Address: "10.0.0.2",
   568  					Port:    "80",
   569  				},
   570  			},
   571  			UpstreamLabels: version1.UpstreamLabels{
   572  				Service:           "service-2",
   573  				ResourceType:      "ingress",
   574  				ResourceName:      ingEx.Ingress.Name,
   575  				ResourceNamespace: ingEx.Ingress.Namespace,
   576  			},
   577  		},
   578  	}
   579  	upstreamServerLabels := map[string][]string{
   580  		"upstream-1": {"service-1", "ingress", "test-ingress", "default"},
   581  		"upstream-2": {"service-2", "ingress", "test-ingress", "default"},
   582  	}
   583  	upstreamServerPeerLabels := map[string][]string{
   584  		"upstream-1/10.0.0.1:80": {"pod-1"},
   585  		"upstream-2/10.0.0.2:80": {"pod-2"},
   586  	}
   587  	expectedLabelUpdater := &mockLabelUpdater{
   588  		upstreamServerLabels: upstreamServerLabels,
   589  		serverZoneLabels: map[string][]string{
   590  			"example.com": {"ingress", "test-ingress", "default"},
   591  		},
   592  		upstreamServerPeerLabels:       upstreamServerPeerLabels,
   593  		streamUpstreamServerPeerLabels: make(map[string][]string),
   594  		streamUpstreamServerLabels:     make(map[string][]string),
   595  		streamServerZoneLabels:         make(map[string][]string),
   596  	}
   597  	expectedLatencyCollector := &mockLatencyCollector{
   598  		upstreamServerLabels:     upstreamServerLabels,
   599  		upstreamServerPeerLabels: upstreamServerPeerLabels,
   600  	}
   601  
   602  	// add labels for a new Ingress resource
   603  	cnf.updateIngressMetricsLabels(ingEx, upstreams)
   604  	if !reflect.DeepEqual(cnf.labelUpdater, expectedLabelUpdater) {
   605  		t.Errorf("updateIngressMetricsLabels() updated labels to \n%+v but expected \n%+v", cnf.labelUpdater, expectedLabelUpdater)
   606  	}
   607  	if !reflect.DeepEqual(testLatencyCollector, expectedLatencyCollector) {
   608  		t.Errorf("updateIngressMetricsLabels() updated latency collector labels to \n%+v but expected \n%+v", testLatencyCollector, expectedLatencyCollector)
   609  	}
   610  
   611  	updatedUpstreams := []version1.Upstream{
   612  		{
   613  			Name: "upstream-1",
   614  			UpstreamServers: []version1.UpstreamServer{
   615  				{
   616  					Address: "10.0.0.1",
   617  					Port:    "80",
   618  				},
   619  			},
   620  			UpstreamLabels: version1.UpstreamLabels{
   621  				Service:           "service-1",
   622  				ResourceType:      "ingress",
   623  				ResourceName:      ingEx.Ingress.Name,
   624  				ResourceNamespace: ingEx.Ingress.Namespace,
   625  			},
   626  		},
   627  	}
   628  
   629  	upstreamServerLabels = map[string][]string{
   630  		"upstream-1": {"service-1", "ingress", "test-ingress", "default"},
   631  	}
   632  
   633  	upstreamServerPeerLabels = map[string][]string{
   634  		"upstream-1/10.0.0.1:80": {"pod-1"},
   635  	}
   636  
   637  	expectedLabelUpdater = &mockLabelUpdater{
   638  		upstreamServerLabels: upstreamServerLabels,
   639  		serverZoneLabels: map[string][]string{
   640  			"example.com": {"ingress", "test-ingress", "default"},
   641  		},
   642  		upstreamServerPeerLabels:       upstreamServerPeerLabels,
   643  		streamUpstreamServerPeerLabels: make(map[string][]string),
   644  		streamUpstreamServerLabels:     make(map[string][]string),
   645  		streamServerZoneLabels:         map[string][]string{},
   646  	}
   647  	expectedLatencyCollector = &mockLatencyCollector{
   648  		upstreamServerLabels:        upstreamServerLabels,
   649  		upstreamServerPeerLabels:    upstreamServerPeerLabels,
   650  		upstreamServerPeersToDelete: []string{"upstream-2/10.0.0.2:80"},
   651  	}
   652  
   653  	// update labels for an updated Ingress with deleted upstream-2
   654  	cnf.updateIngressMetricsLabels(ingEx, updatedUpstreams)
   655  	if !reflect.DeepEqual(cnf.labelUpdater, expectedLabelUpdater) {
   656  		t.Errorf("updateIngressMetricsLabels() updated labels to \n%+v but expected \n%+v", cnf.labelUpdater, expectedLabelUpdater)
   657  	}
   658  	if !reflect.DeepEqual(testLatencyCollector, expectedLatencyCollector) {
   659  		t.Errorf("updateIngressMetricsLabels() updated latency collector labels to \n%+v but expected \n%+v", testLatencyCollector, expectedLatencyCollector)
   660  	}
   661  
   662  	upstreamServerLabels = map[string][]string{}
   663  	upstreamServerPeerLabels = map[string][]string{}
   664  
   665  	expectedLabelUpdater = &mockLabelUpdater{
   666  		upstreamServerLabels:           map[string][]string{},
   667  		serverZoneLabels:               map[string][]string{},
   668  		upstreamServerPeerLabels:       map[string][]string{},
   669  		streamUpstreamServerPeerLabels: map[string][]string{},
   670  		streamUpstreamServerLabels:     map[string][]string{},
   671  		streamServerZoneLabels:         map[string][]string{},
   672  	}
   673  	expectedLatencyCollector = &mockLatencyCollector{
   674  		upstreamServerLabels:        upstreamServerLabels,
   675  		upstreamServerPeerLabels:    upstreamServerPeerLabels,
   676  		upstreamServerPeersToDelete: []string{"upstream-1/10.0.0.1:80"},
   677  	}
   678  
   679  	// delete labels for a deleted Ingress
   680  	cnf.deleteIngressMetricsLabels("default/test-ingress")
   681  	if !reflect.DeepEqual(cnf.labelUpdater, expectedLabelUpdater) {
   682  		t.Errorf("deleteIngressMetricsLabels() updated labels to \n%+v but expected \n%+v", cnf.labelUpdater, expectedLabelUpdater)
   683  	}
   684  	if !reflect.DeepEqual(testLatencyCollector, expectedLatencyCollector) {
   685  		t.Errorf("updateIngressMetricsLabels() updated latency collector labels to \n%+v but expected \n%+v", testLatencyCollector, expectedLatencyCollector)
   686  	}
   687  }
   688  
   689  func TestUpdateVirtualServerMetricsLabels(t *testing.T) {
   690  	cnf, err := createTestConfigurator()
   691  	if err != nil {
   692  		t.Fatalf("Failed to create a test configurator: %v", err)
   693  	}
   694  
   695  	cnf.isPlus = true
   696  	cnf.labelUpdater = newFakeLabelUpdater()
   697  	testLatencyCollector := newMockLatencyCollector()
   698  	cnf.latencyCollector = testLatencyCollector
   699  
   700  	vsEx := &VirtualServerEx{
   701  		VirtualServer: &conf_v1.VirtualServer{
   702  			ObjectMeta: meta_v1.ObjectMeta{
   703  				Name:      "test-vs",
   704  				Namespace: "default",
   705  			},
   706  			Spec: conf_v1.VirtualServerSpec{
   707  				Host: "example.com",
   708  			},
   709  		},
   710  		PodsByIP: map[string]PodInfo{
   711  			"10.0.0.1:80": {Name: "pod-1"},
   712  			"10.0.0.2:80": {Name: "pod-2"},
   713  		},
   714  	}
   715  
   716  	upstreams := []version2.Upstream{
   717  		{
   718  			Name: "upstream-1",
   719  			Servers: []version2.UpstreamServer{
   720  				{
   721  					Address: "10.0.0.1:80",
   722  				},
   723  			},
   724  			UpstreamLabels: version2.UpstreamLabels{
   725  				Service:           "service-1",
   726  				ResourceType:      "virtualserver",
   727  				ResourceName:      vsEx.VirtualServer.Name,
   728  				ResourceNamespace: vsEx.VirtualServer.Namespace,
   729  			},
   730  		},
   731  		{
   732  			Name: "upstream-2",
   733  			Servers: []version2.UpstreamServer{
   734  				{
   735  					Address: "10.0.0.2:80",
   736  				},
   737  			},
   738  			UpstreamLabels: version2.UpstreamLabels{
   739  				Service:           "service-2",
   740  				ResourceType:      "virtualserver",
   741  				ResourceName:      vsEx.VirtualServer.Name,
   742  				ResourceNamespace: vsEx.VirtualServer.Namespace,
   743  			},
   744  		},
   745  	}
   746  
   747  	upstreamServerLabels := map[string][]string{
   748  		"upstream-1": {"service-1", "virtualserver", "test-vs", "default"},
   749  		"upstream-2": {"service-2", "virtualserver", "test-vs", "default"},
   750  	}
   751  
   752  	upstreamServerPeerLabels := map[string][]string{
   753  		"upstream-1/10.0.0.1:80": {"pod-1"},
   754  		"upstream-2/10.0.0.2:80": {"pod-2"},
   755  	}
   756  
   757  	expectedLabelUpdater := &mockLabelUpdater{
   758  		upstreamServerLabels: upstreamServerLabels,
   759  		serverZoneLabels: map[string][]string{
   760  			"example.com": {"virtualserver", "test-vs", "default"},
   761  		},
   762  		upstreamServerPeerLabels:       upstreamServerPeerLabels,
   763  		streamUpstreamServerPeerLabels: map[string][]string{},
   764  		streamUpstreamServerLabels:     map[string][]string{},
   765  		streamServerZoneLabels:         map[string][]string{},
   766  	}
   767  
   768  	expectedLatencyCollector := &mockLatencyCollector{
   769  		upstreamServerLabels:     upstreamServerLabels,
   770  		upstreamServerPeerLabels: upstreamServerPeerLabels,
   771  	}
   772  
   773  	// add labels for a new VirtualServer resource
   774  	cnf.updateVirtualServerMetricsLabels(vsEx, upstreams)
   775  	if !reflect.DeepEqual(cnf.labelUpdater, expectedLabelUpdater) {
   776  		t.Errorf("updateVirtualServerMetricsLabels() updated labels to \n%+v but expected \n%+v", cnf.labelUpdater, expectedLabelUpdater)
   777  	}
   778  	if !reflect.DeepEqual(testLatencyCollector, expectedLatencyCollector) {
   779  		t.Errorf("updateVirtualServerMetricsLabels() updated latency collector's labels to \n%+v but expected \n%+v", testLatencyCollector, expectedLatencyCollector)
   780  	}
   781  
   782  	updatedUpstreams := []version2.Upstream{
   783  		{
   784  			Name: "upstream-1",
   785  			Servers: []version2.UpstreamServer{
   786  				{
   787  					Address: "10.0.0.1:80",
   788  				},
   789  			},
   790  			UpstreamLabels: version2.UpstreamLabels{
   791  				Service:           "service-1",
   792  				ResourceType:      "virtualserver",
   793  				ResourceName:      vsEx.VirtualServer.Name,
   794  				ResourceNamespace: vsEx.VirtualServer.Namespace,
   795  			},
   796  		},
   797  	}
   798  
   799  	upstreamServerLabels = map[string][]string{
   800  		"upstream-1": {"service-1", "virtualserver", "test-vs", "default"},
   801  	}
   802  	upstreamServerPeerLabels = map[string][]string{
   803  		"upstream-1/10.0.0.1:80": {"pod-1"},
   804  	}
   805  
   806  	expectedLabelUpdater = &mockLabelUpdater{
   807  		upstreamServerLabels: upstreamServerLabels,
   808  		serverZoneLabels: map[string][]string{
   809  			"example.com": {"virtualserver", "test-vs", "default"},
   810  		},
   811  		upstreamServerPeerLabels:       upstreamServerPeerLabels,
   812  		streamUpstreamServerPeerLabels: map[string][]string{},
   813  		streamUpstreamServerLabels:     map[string][]string{},
   814  		streamServerZoneLabels:         map[string][]string{},
   815  	}
   816  
   817  	expectedLatencyCollector = &mockLatencyCollector{
   818  		upstreamServerLabels:        upstreamServerLabels,
   819  		upstreamServerPeerLabels:    upstreamServerPeerLabels,
   820  		upstreamServerPeersToDelete: []string{"upstream-2/10.0.0.2:80"},
   821  	}
   822  
   823  	// update labels for an updated VirtualServer with deleted upstream-2
   824  	cnf.updateVirtualServerMetricsLabels(vsEx, updatedUpstreams)
   825  	if !reflect.DeepEqual(cnf.labelUpdater, expectedLabelUpdater) {
   826  		t.Errorf("updateVirtualServerMetricsLabels() updated labels to \n%+v but expected \n%+v", cnf.labelUpdater, expectedLabelUpdater)
   827  	}
   828  	if !reflect.DeepEqual(testLatencyCollector, expectedLatencyCollector) {
   829  		t.Errorf("updateVirtualServerMetricsLabels() updated latency collector's labels to \n%+v but expected \n%+v", testLatencyCollector, expectedLatencyCollector)
   830  	}
   831  
   832  	expectedLabelUpdater = &mockLabelUpdater{
   833  		upstreamServerLabels:           map[string][]string{},
   834  		serverZoneLabels:               map[string][]string{},
   835  		upstreamServerPeerLabels:       map[string][]string{},
   836  		streamUpstreamServerPeerLabels: map[string][]string{},
   837  		streamUpstreamServerLabels:     map[string][]string{},
   838  		streamServerZoneLabels:         map[string][]string{},
   839  	}
   840  
   841  	expectedLatencyCollector = &mockLatencyCollector{
   842  		upstreamServerLabels:        map[string][]string{},
   843  		upstreamServerPeerLabels:    map[string][]string{},
   844  		upstreamServerPeersToDelete: []string{"upstream-1/10.0.0.1:80"},
   845  	}
   846  
   847  	// delete labels for a deleted VirtualServer
   848  	cnf.deleteVirtualServerMetricsLabels("default/test-vs")
   849  	if !reflect.DeepEqual(cnf.labelUpdater, expectedLabelUpdater) {
   850  		t.Errorf("deleteVirtualServerMetricsLabels() updated labels to \n%+v but expected \n%+v", cnf.labelUpdater, expectedLabelUpdater)
   851  	}
   852  
   853  	if !reflect.DeepEqual(testLatencyCollector, expectedLatencyCollector) {
   854  		t.Errorf("updateVirtualServerMetricsLabels() updated latency collector's labels to \n%+v but expected \n%+v", testLatencyCollector, expectedLatencyCollector)
   855  	}
   856  }
   857  
   858  func TestUpdateTransportServerMetricsLabels(t *testing.T) {
   859  	cnf, err := createTestConfigurator()
   860  	if err != nil {
   861  		t.Fatalf("Failed to create a test configurator: %v", err)
   862  	}
   863  
   864  	cnf.isPlus = true
   865  	cnf.labelUpdater = newFakeLabelUpdater()
   866  
   867  	tsEx := &TransportServerEx{
   868  		TransportServer: &conf_v1alpha1.TransportServer{
   869  			ObjectMeta: meta_v1.ObjectMeta{
   870  				Name:      "test-transportserver",
   871  				Namespace: "default",
   872  			},
   873  			Spec: conf_v1alpha1.TransportServerSpec{
   874  				Listener: conf_v1alpha1.TransportServerListener{
   875  					Name:     "dns-tcp",
   876  					Protocol: "TCP",
   877  				},
   878  			},
   879  		},
   880  		PodsByIP: map[string]string{
   881  			"10.0.0.1:80": "pod-1",
   882  			"10.0.0.2:80": "pod-2",
   883  		},
   884  	}
   885  
   886  	streamUpstreams := []version2.StreamUpstream{
   887  		{
   888  			Name: "upstream-1",
   889  			Servers: []version2.StreamUpstreamServer{
   890  				{
   891  					Address: "10.0.0.1:80",
   892  				},
   893  			},
   894  			UpstreamLabels: version2.UpstreamLabels{
   895  				Service:           "service-1",
   896  				ResourceType:      "transportserver",
   897  				ResourceName:      tsEx.TransportServer.Name,
   898  				ResourceNamespace: tsEx.TransportServer.Namespace,
   899  			},
   900  		},
   901  		{
   902  			Name: "upstream-2",
   903  			Servers: []version2.StreamUpstreamServer{
   904  				{
   905  					Address: "10.0.0.2:80",
   906  				},
   907  			},
   908  			UpstreamLabels: version2.UpstreamLabels{
   909  				Service:           "service-2",
   910  				ResourceType:      "transportserver",
   911  				ResourceName:      tsEx.TransportServer.Name,
   912  				ResourceNamespace: tsEx.TransportServer.Namespace,
   913  			},
   914  		},
   915  	}
   916  
   917  	streamUpstreamServerLabels := map[string][]string{
   918  		"upstream-1": {"service-1", "transportserver", "test-transportserver", "default"},
   919  		"upstream-2": {"service-2", "transportserver", "test-transportserver", "default"},
   920  	}
   921  
   922  	streamUpstreamServerPeerLabels := map[string][]string{
   923  		"upstream-1/10.0.0.1:80": {"pod-1"},
   924  		"upstream-2/10.0.0.2:80": {"pod-2"},
   925  	}
   926  
   927  	expectedLabelUpdater := &mockLabelUpdater{
   928  		streamUpstreamServerLabels: streamUpstreamServerLabels,
   929  		streamServerZoneLabels: map[string][]string{
   930  			"dns-tcp": {"transportserver", "test-transportserver", "default"},
   931  		},
   932  		streamUpstreamServerPeerLabels: streamUpstreamServerPeerLabels,
   933  		upstreamServerPeerLabels:       make(map[string][]string),
   934  		upstreamServerLabels:           make(map[string][]string),
   935  		serverZoneLabels:               make(map[string][]string),
   936  	}
   937  
   938  	cnf.updateTransportServerMetricsLabels(tsEx, streamUpstreams)
   939  	if !reflect.DeepEqual(cnf.labelUpdater, expectedLabelUpdater) {
   940  		t.Errorf("updateTransportServerMetricsLabels() updated labels to \n%+v but expected \n%+v", cnf.labelUpdater, expectedLabelUpdater)
   941  	}
   942  
   943  	updatedStreamUpstreams := []version2.StreamUpstream{
   944  		{
   945  			Name: "upstream-1",
   946  			Servers: []version2.StreamUpstreamServer{
   947  				{
   948  					Address: "10.0.0.1:80",
   949  				},
   950  			},
   951  			UpstreamLabels: version2.UpstreamLabels{
   952  				Service:           "service-1",
   953  				ResourceType:      "transportserver",
   954  				ResourceName:      tsEx.TransportServer.Name,
   955  				ResourceNamespace: tsEx.TransportServer.Namespace,
   956  			},
   957  		},
   958  	}
   959  
   960  	streamUpstreamServerLabels = map[string][]string{
   961  		"upstream-1": {"service-1", "transportserver", "test-transportserver", "default"},
   962  	}
   963  
   964  	streamUpstreamServerPeerLabels = map[string][]string{
   965  		"upstream-1/10.0.0.1:80": {"pod-1"},
   966  	}
   967  
   968  	expectedLabelUpdater = &mockLabelUpdater{
   969  		streamUpstreamServerLabels: streamUpstreamServerLabels,
   970  		streamServerZoneLabels: map[string][]string{
   971  			"dns-tcp": {"transportserver", "test-transportserver", "default"},
   972  		},
   973  		streamUpstreamServerPeerLabels: streamUpstreamServerPeerLabels,
   974  		upstreamServerPeerLabels:       map[string][]string{},
   975  		upstreamServerLabels:           map[string][]string{},
   976  		serverZoneLabels:               map[string][]string{},
   977  	}
   978  
   979  	cnf.updateTransportServerMetricsLabels(tsEx, updatedStreamUpstreams)
   980  	if !reflect.DeepEqual(cnf.labelUpdater, expectedLabelUpdater) {
   981  		t.Errorf("updateTransportServerMetricsLabels() updated labels to \n%+v but expected \n%+v", cnf.labelUpdater, expectedLabelUpdater)
   982  	}
   983  
   984  	expectedLabelUpdater = &mockLabelUpdater{
   985  		upstreamServerLabels:           map[string][]string{},
   986  		serverZoneLabels:               map[string][]string{},
   987  		upstreamServerPeerLabels:       map[string][]string{},
   988  		streamUpstreamServerPeerLabels: map[string][]string{},
   989  		streamUpstreamServerLabels:     map[string][]string{},
   990  		streamServerZoneLabels:         map[string][]string{},
   991  	}
   992  
   993  	cnf.deleteTransportServerMetricsLabels("default/test-transportserver")
   994  	if !reflect.DeepEqual(cnf.labelUpdater, expectedLabelUpdater) {
   995  		t.Errorf("deleteTransportServerMetricsLabels() updated labels to \n%+v but expected \n%+v", cnf.labelUpdater, expectedLabelUpdater)
   996  	}
   997  
   998  	tsExTLS := &TransportServerEx{
   999  		TransportServer: &conf_v1alpha1.TransportServer{
  1000  			ObjectMeta: meta_v1.ObjectMeta{
  1001  				Name:      "test-transportserver-tls",
  1002  				Namespace: "default",
  1003  			},
  1004  			Spec: conf_v1alpha1.TransportServerSpec{
  1005  				Listener: conf_v1alpha1.TransportServerListener{
  1006  					Name:     "tls-passthrough",
  1007  					Protocol: "TLS_PASSTHROUGH",
  1008  				},
  1009  				Host: "example.com",
  1010  			},
  1011  		},
  1012  		PodsByIP: map[string]string{
  1013  			"10.0.0.3:80": "pod-3",
  1014  		},
  1015  	}
  1016  
  1017  	streamUpstreams = []version2.StreamUpstream{
  1018  		{
  1019  			Name: "upstream-3",
  1020  			Servers: []version2.StreamUpstreamServer{
  1021  				{
  1022  					Address: "10.0.0.3:80",
  1023  				},
  1024  			},
  1025  			UpstreamLabels: version2.UpstreamLabels{
  1026  				Service:           "service-3",
  1027  				ResourceType:      "transportserver",
  1028  				ResourceName:      tsExTLS.TransportServer.Name,
  1029  				ResourceNamespace: tsExTLS.TransportServer.Namespace,
  1030  			},
  1031  		},
  1032  	}
  1033  
  1034  	streamUpstreamServerLabels = map[string][]string{
  1035  		"upstream-3": {"service-3", "transportserver", "test-transportserver-tls", "default"},
  1036  	}
  1037  
  1038  	streamUpstreamServerPeerLabels = map[string][]string{
  1039  		"upstream-3/10.0.0.3:80": {"pod-3"},
  1040  	}
  1041  
  1042  	expectedLabelUpdater = &mockLabelUpdater{
  1043  		streamUpstreamServerLabels: streamUpstreamServerLabels,
  1044  		streamServerZoneLabels: map[string][]string{
  1045  			"example.com": {"transportserver", "test-transportserver-tls", "default"},
  1046  		},
  1047  		streamUpstreamServerPeerLabels: streamUpstreamServerPeerLabels,
  1048  		upstreamServerPeerLabels:       make(map[string][]string),
  1049  		upstreamServerLabels:           make(map[string][]string),
  1050  		serverZoneLabels:               make(map[string][]string),
  1051  	}
  1052  
  1053  	cnf.updateTransportServerMetricsLabels(tsExTLS, streamUpstreams)
  1054  	if !reflect.DeepEqual(cnf.labelUpdater, expectedLabelUpdater) {
  1055  		t.Errorf("updateTransportServerMetricsLabels() updated labels to \n%+v but expected \n%+v", cnf.labelUpdater, expectedLabelUpdater)
  1056  	}
  1057  
  1058  	expectedLabelUpdater = &mockLabelUpdater{
  1059  		upstreamServerLabels:           map[string][]string{},
  1060  		serverZoneLabels:               map[string][]string{},
  1061  		upstreamServerPeerLabels:       map[string][]string{},
  1062  		streamUpstreamServerPeerLabels: map[string][]string{},
  1063  		streamUpstreamServerLabels:     map[string][]string{},
  1064  		streamServerZoneLabels:         map[string][]string{},
  1065  	}
  1066  
  1067  	cnf.deleteTransportServerMetricsLabels("default/test-transportserver-tls")
  1068  	if !reflect.DeepEqual(cnf.labelUpdater, expectedLabelUpdater) {
  1069  		t.Errorf("deleteTransportServerMetricsLabels() updated labels to \n%+v but expected \n%+v", cnf.labelUpdater, expectedLabelUpdater)
  1070  	}
  1071  }
  1072  
  1073  func TestUpdateApResources(t *testing.T) {
  1074  	appProtectPolicy := &unstructured.Unstructured{
  1075  		Object: map[string]interface{}{
  1076  			"metadata": map[string]interface{}{
  1077  				"namespace": "test-ns",
  1078  				"name":      "test-name",
  1079  			},
  1080  		},
  1081  	}
  1082  	appProtectLogConf := &unstructured.Unstructured{
  1083  		Object: map[string]interface{}{
  1084  			"metadata": map[string]interface{}{
  1085  				"namespace": "test-ns",
  1086  				"name":      "test-name",
  1087  			},
  1088  		},
  1089  	}
  1090  	appProtectLogDst := "test-dst"
  1091  
  1092  	tests := []struct {
  1093  		ingEx    *IngressEx
  1094  		expected AppProtectResources
  1095  		msg      string
  1096  	}{
  1097  		{
  1098  			ingEx: &IngressEx{
  1099  				Ingress: &networking.Ingress{
  1100  					ObjectMeta: meta_v1.ObjectMeta{},
  1101  				},
  1102  			},
  1103  			expected: AppProtectResources{},
  1104  			msg:      "no app protect resources",
  1105  		},
  1106  		{
  1107  			ingEx: &IngressEx{
  1108  				Ingress: &networking.Ingress{
  1109  					ObjectMeta: meta_v1.ObjectMeta{},
  1110  				},
  1111  				AppProtectPolicy: appProtectPolicy,
  1112  			},
  1113  			expected: AppProtectResources{
  1114  				AppProtectPolicy: "/etc/nginx/waf/nac-policies/test-ns_test-name",
  1115  			},
  1116  			msg: "app protect policy",
  1117  		},
  1118  		{
  1119  			ingEx: &IngressEx{
  1120  				Ingress: &networking.Ingress{
  1121  					ObjectMeta: meta_v1.ObjectMeta{},
  1122  				},
  1123  				AppProtectLogs: []AppProtectLog{
  1124  					{
  1125  						LogConf: appProtectLogConf,
  1126  						Dest:    appProtectLogDst,
  1127  					},
  1128  				},
  1129  			},
  1130  			expected: AppProtectResources{
  1131  				AppProtectLogconfs: []string{"/etc/nginx/waf/nac-logconfs/test-ns_test-name test-dst"},
  1132  			},
  1133  			msg: "app protect log conf",
  1134  		},
  1135  		{
  1136  			ingEx: &IngressEx{
  1137  				Ingress: &networking.Ingress{
  1138  					ObjectMeta: meta_v1.ObjectMeta{},
  1139  				},
  1140  				AppProtectPolicy: appProtectPolicy,
  1141  				AppProtectLogs: []AppProtectLog{
  1142  					{
  1143  						LogConf: appProtectLogConf,
  1144  						Dest:    appProtectLogDst,
  1145  					},
  1146  				},
  1147  			},
  1148  			expected: AppProtectResources{
  1149  				AppProtectPolicy:   "/etc/nginx/waf/nac-policies/test-ns_test-name",
  1150  				AppProtectLogconfs: []string{"/etc/nginx/waf/nac-logconfs/test-ns_test-name test-dst"},
  1151  			},
  1152  			msg: "app protect policy and log conf",
  1153  		},
  1154  	}
  1155  
  1156  	conf, err := createTestConfigurator()
  1157  	if err != nil {
  1158  		t.Errorf("Failed to create a test configurator: %v", err)
  1159  	}
  1160  
  1161  	for _, test := range tests {
  1162  		result := conf.updateApResources(test.ingEx)
  1163  		if !reflect.DeepEqual(result, test.expected) {
  1164  			t.Errorf("updateApResources() returned \n%v but exexpected\n%v for the case of %s", result, test.expected, test.msg)
  1165  		}
  1166  	}
  1167  }
  1168  
  1169  func TestUpdateApResourcesForVs(t *testing.T) {
  1170  	apPolRefs := map[string]*unstructured.Unstructured{
  1171  		"test-ns-1/test-name-1": {
  1172  			Object: map[string]interface{}{
  1173  				"metadata": map[string]interface{}{
  1174  					"namespace": "test-ns-1",
  1175  					"name":      "test-name-1",
  1176  				},
  1177  			},
  1178  		},
  1179  		"test-ns-2/test-name-2": {
  1180  			Object: map[string]interface{}{
  1181  				"metadata": map[string]interface{}{
  1182  					"namespace": "test-ns-2",
  1183  					"name":      "test-name-2",
  1184  				},
  1185  			},
  1186  		},
  1187  	}
  1188  	logConfRefs := map[string]*unstructured.Unstructured{
  1189  		"test-ns-1/test-name-1": {
  1190  			Object: map[string]interface{}{
  1191  				"metadata": map[string]interface{}{
  1192  					"namespace": "test-ns-1",
  1193  					"name":      "test-name-1",
  1194  				},
  1195  			},
  1196  		},
  1197  		"test-ns-2/test-name-2": {
  1198  			Object: map[string]interface{}{
  1199  				"metadata": map[string]interface{}{
  1200  					"namespace": "test-ns-2",
  1201  					"name":      "test-name-2",
  1202  				},
  1203  			},
  1204  		},
  1205  	}
  1206  
  1207  	tests := []struct {
  1208  		vsEx     *VirtualServerEx
  1209  		expected map[string]string
  1210  		msg      string
  1211  	}{
  1212  		{
  1213  			vsEx: &VirtualServerEx{
  1214  				VirtualServer: &conf_v1.VirtualServer{
  1215  					ObjectMeta: meta_v1.ObjectMeta{},
  1216  				},
  1217  			},
  1218  			expected: map[string]string{},
  1219  			msg:      "no app protect resources",
  1220  		},
  1221  		{
  1222  			vsEx: &VirtualServerEx{
  1223  				VirtualServer: &conf_v1.VirtualServer{
  1224  					ObjectMeta: meta_v1.ObjectMeta{},
  1225  				},
  1226  				ApPolRefs: apPolRefs,
  1227  			},
  1228  			expected: map[string]string{
  1229  				"test-ns-1/test-name-1": "/etc/nginx/waf/nac-policies/test-ns-1_test-name-1",
  1230  				"test-ns-2/test-name-2": "/etc/nginx/waf/nac-policies/test-ns-2_test-name-2",
  1231  			},
  1232  			msg: "app protect policies",
  1233  		},
  1234  		{
  1235  			vsEx: &VirtualServerEx{
  1236  				VirtualServer: &conf_v1.VirtualServer{
  1237  					ObjectMeta: meta_v1.ObjectMeta{},
  1238  				},
  1239  				LogConfRefs: logConfRefs,
  1240  			},
  1241  			expected: map[string]string{
  1242  				"test-ns-1/test-name-1": "/etc/nginx/waf/nac-logconfs/test-ns-1_test-name-1",
  1243  				"test-ns-2/test-name-2": "/etc/nginx/waf/nac-logconfs/test-ns-2_test-name-2",
  1244  			},
  1245  			msg: "app protect log confs",
  1246  		},
  1247  		{
  1248  			vsEx: &VirtualServerEx{
  1249  				VirtualServer: &conf_v1.VirtualServer{
  1250  					ObjectMeta: meta_v1.ObjectMeta{},
  1251  				},
  1252  				ApPolRefs:   apPolRefs,
  1253  				LogConfRefs: logConfRefs,
  1254  			},
  1255  			expected: map[string]string{
  1256  				// this is a bug - the result needs to include both policies and log confs
  1257  				"test-ns-1/test-name-1": "/etc/nginx/waf/nac-logconfs/test-ns-1_test-name-1",
  1258  				"test-ns-2/test-name-2": "/etc/nginx/waf/nac-logconfs/test-ns-2_test-name-2",
  1259  			},
  1260  			msg: "app protect policies and log confs",
  1261  		},
  1262  	}
  1263  
  1264  	conf, err := createTestConfigurator()
  1265  	if err != nil {
  1266  		t.Errorf("Failed to create a test configurator: %v", err)
  1267  	}
  1268  
  1269  	for _, test := range tests {
  1270  		result := conf.updateApResourcesForVs(test.vsEx)
  1271  		if !reflect.DeepEqual(result, test.expected) {
  1272  			t.Errorf("updateApResourcesForVs() returned \n%v but exexpected\n%v for the case of %s", result, test.expected, test.msg)
  1273  		}
  1274  	}
  1275  }