github.com/alibaba/ilogtail/pkg@v0.0.0-20250526110833-c53b480d046c/helper/k8smeta/k8s_meta_link_test.go (about)

     1  package k8smeta
     2  
     3  import (
     4  	"testing"
     5  
     6  	"github.com/stretchr/testify/assert"
     7  	app "k8s.io/api/apps/v1"
     8  	batch "k8s.io/api/batch/v1"
     9  	corev1 "k8s.io/api/core/v1"
    10  	networking "k8s.io/api/networking/v1"
    11  	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    12  )
    13  
    14  func TestGetPodNodeLink(t *testing.T) {
    15  	podCache := newK8sMetaCache(make(chan struct{}), POD)
    16  	nodeCache := newK8sMetaCache(make(chan struct{}), NODE)
    17  	nodeCache.metaStore.handleAddOrUpdateEvent(&K8sMetaEvent{
    18  		EventType: "add",
    19  		Object: &ObjectWrapper{
    20  			Raw: &corev1.Node{
    21  				ObjectMeta: metav1.ObjectMeta{
    22  					Name: "node1",
    23  				},
    24  			},
    25  		},
    26  	})
    27  	nodeCache.metaStore.handleAddOrUpdateEvent(&K8sMetaEvent{
    28  		EventType: "add",
    29  		Object: &ObjectWrapper{
    30  			Raw: &corev1.Node{
    31  				ObjectMeta: metav1.ObjectMeta{
    32  					Name: "node2",
    33  				},
    34  			},
    35  		},
    36  	})
    37  	pod1 := generateMockPod("1")
    38  	pod1.Raw.(*corev1.Pod).Spec.NodeName = "node1"
    39  	pod2 := generateMockPod("2")
    40  	pod2.Raw.(*corev1.Pod).Spec.NodeName = "node2"
    41  	podCache.metaStore.handleAddOrUpdateEvent(&K8sMetaEvent{
    42  		EventType: "add",
    43  		Object:    pod1,
    44  	})
    45  	podCache.metaStore.handleAddOrUpdateEvent(&K8sMetaEvent{
    46  		EventType: "add",
    47  		Object:    pod2,
    48  	})
    49  	linkGenerator := NewK8sMetaLinkGenerator(map[string]MetaCache{
    50  		POD:  podCache,
    51  		NODE: nodeCache,
    52  	})
    53  	podList := []*K8sMetaEvent{
    54  		{
    55  			EventType: "update",
    56  			Object:    podCache.metaStore.Items["default/pod1"],
    57  		},
    58  		{
    59  			EventType: "update",
    60  			Object:    podCache.metaStore.Items["default/pod2"],
    61  		},
    62  	}
    63  	results := linkGenerator.getPodNodeLink(podList)
    64  	assert.Equal(t, 2, len(results))
    65  	assert.Equal(t, "node1", results[0].Object.Raw.(*PodNode).Node.Name)
    66  	assert.Equal(t, "node2", results[1].Object.Raw.(*PodNode).Node.Name)
    67  }
    68  
    69  func TestGetPodDeploymentLink(t *testing.T) {
    70  	podCache := newK8sMetaCache(make(chan struct{}), POD)
    71  	replicasetCache := newK8sMetaCache(make(chan struct{}), REPLICASET)
    72  	deploymentCache := newK8sMetaCache(make(chan struct{}), DEPLOYMENT)
    73  	deploymentCache.metaStore.handleAddOrUpdateEvent(&K8sMetaEvent{
    74  		EventType: "add",
    75  		Object: &ObjectWrapper{
    76  			Raw: &app.Deployment{
    77  				ObjectMeta: metav1.ObjectMeta{
    78  					Name:      "deployment1",
    79  					Namespace: "default",
    80  				},
    81  			},
    82  		},
    83  	})
    84  	deploymentCache.metaStore.handleAddOrUpdateEvent(&K8sMetaEvent{
    85  		EventType: "add",
    86  		Object: &ObjectWrapper{
    87  			Raw: &app.Deployment{
    88  				ObjectMeta: metav1.ObjectMeta{
    89  					Name:      "deployment2",
    90  					Namespace: "default",
    91  				},
    92  			},
    93  		},
    94  	})
    95  	replicasetCache.metaStore.handleAddOrUpdateEvent(&K8sMetaEvent{
    96  		EventType: "add",
    97  		Object: &ObjectWrapper{
    98  			Raw: &app.ReplicaSet{
    99  				ObjectMeta: metav1.ObjectMeta{
   100  					Name:      "replicaset1",
   101  					Namespace: "default",
   102  					OwnerReferences: []metav1.OwnerReference{
   103  						{
   104  							Kind: "Deployment",
   105  							Name: "deployment1",
   106  						},
   107  					},
   108  				},
   109  				Spec: app.ReplicaSetSpec{
   110  					Selector: &metav1.LabelSelector{
   111  						MatchLabels: map[string]string{
   112  							"app": "test",
   113  						},
   114  					},
   115  				},
   116  			},
   117  		},
   118  	})
   119  	replicasetCache.metaStore.handleAddOrUpdateEvent(&K8sMetaEvent{
   120  		EventType: "add",
   121  		Object: &ObjectWrapper{
   122  			Raw: &app.ReplicaSet{
   123  				ObjectMeta: metav1.ObjectMeta{
   124  					Name:      "replicaset2",
   125  					Namespace: "default",
   126  					OwnerReferences: []metav1.OwnerReference{
   127  						{
   128  							Kind: "Deployment",
   129  							Name: "deployment2",
   130  						},
   131  					},
   132  				},
   133  				Spec: app.ReplicaSetSpec{
   134  					Selector: &metav1.LabelSelector{
   135  						MatchLabels: map[string]string{
   136  							"app": "test2",
   137  						},
   138  					},
   139  				},
   140  			},
   141  		},
   142  	})
   143  	pod1 := generateMockPod("1")
   144  	pod1.Raw.(*corev1.Pod).OwnerReferences = []metav1.OwnerReference{
   145  		{
   146  			Kind: "ReplicaSet",
   147  			Name: "replicaset1",
   148  		},
   149  	}
   150  	pod2 := generateMockPod("2")
   151  	pod2.Raw.(*corev1.Pod).OwnerReferences = []metav1.OwnerReference{
   152  		{
   153  			Kind: "ReplicaSet",
   154  			Name: "replicaset2",
   155  		},
   156  	}
   157  	podCache.metaStore.handleAddOrUpdateEvent(&K8sMetaEvent{
   158  		EventType: "add",
   159  		Object:    pod1,
   160  	})
   161  	podCache.metaStore.handleAddOrUpdateEvent(&K8sMetaEvent{
   162  		EventType: "add",
   163  		Object:    pod2,
   164  	})
   165  	linkGenerator := NewK8sMetaLinkGenerator(map[string]MetaCache{
   166  		POD:        podCache,
   167  		REPLICASET: replicasetCache,
   168  		DEPLOYMENT: deploymentCache,
   169  	})
   170  	podList := []*K8sMetaEvent{
   171  		{
   172  			EventType: "update",
   173  			Object:    podCache.metaStore.Items["default/pod1"],
   174  		},
   175  		{
   176  			EventType: "update",
   177  			Object:    podCache.metaStore.Items["default/pod2"],
   178  		},
   179  	}
   180  	results := linkGenerator.getPodDeploymentLink(podList)
   181  	assert.Equal(t, 2, len(results))
   182  	assert.Equal(t, "deployment1", results[0].Object.Raw.(*PodDeployment).Deployment.Name)
   183  	assert.Equal(t, "deployment2", results[1].Object.Raw.(*PodDeployment).Deployment.Name)
   184  }
   185  
   186  func TestGetReplicaSetDeploymentLink(t *testing.T) {
   187  	replicasetCache := newK8sMetaCache(make(chan struct{}), REPLICASET)
   188  	deploymentCache := newK8sMetaCache(make(chan struct{}), DEPLOYMENT)
   189  	deploymentCache.metaStore.handleAddOrUpdateEvent(&K8sMetaEvent{
   190  		EventType: "add",
   191  		Object: &ObjectWrapper{
   192  			Raw: &app.Deployment{
   193  				ObjectMeta: metav1.ObjectMeta{
   194  					Name:      "deployment1",
   195  					Namespace: "default",
   196  				},
   197  			},
   198  		},
   199  	})
   200  	deploymentCache.metaStore.handleAddOrUpdateEvent(&K8sMetaEvent{
   201  		EventType: "add",
   202  		Object: &ObjectWrapper{
   203  			Raw: &app.Deployment{
   204  				ObjectMeta: metav1.ObjectMeta{
   205  					Name:      "deployment2",
   206  					Namespace: "default",
   207  				},
   208  			},
   209  		},
   210  	})
   211  	replicasetCache.metaStore.handleAddOrUpdateEvent(&K8sMetaEvent{
   212  		EventType: "add",
   213  		Object: &ObjectWrapper{
   214  			Raw: &app.ReplicaSet{
   215  				ObjectMeta: metav1.ObjectMeta{
   216  					Name:      "replicaset1",
   217  					Namespace: "default",
   218  					OwnerReferences: []metav1.OwnerReference{
   219  						{
   220  							Kind: "Deployment",
   221  							Name: "deployment1",
   222  						},
   223  					},
   224  				},
   225  				Spec: app.ReplicaSetSpec{
   226  					Selector: &metav1.LabelSelector{
   227  						MatchLabels: map[string]string{
   228  							"app": "test",
   229  						},
   230  					},
   231  				},
   232  			},
   233  		},
   234  	})
   235  	replicasetCache.metaStore.handleAddOrUpdateEvent(&K8sMetaEvent{
   236  		EventType: "add",
   237  		Object: &ObjectWrapper{
   238  			Raw: &app.ReplicaSet{
   239  				ObjectMeta: metav1.ObjectMeta{
   240  					Name:      "replicaset2",
   241  					Namespace: "default",
   242  					OwnerReferences: []metav1.OwnerReference{
   243  						{
   244  							Kind: "Deployment",
   245  							Name: "deployment2",
   246  						},
   247  					},
   248  				},
   249  				Spec: app.ReplicaSetSpec{
   250  					Selector: &metav1.LabelSelector{
   251  						MatchLabels: map[string]string{
   252  							"app": "test2",
   253  						},
   254  					},
   255  				},
   256  			},
   257  		},
   258  	})
   259  	linkGenerator := NewK8sMetaLinkGenerator(map[string]MetaCache{
   260  		REPLICASET: replicasetCache,
   261  		DEPLOYMENT: deploymentCache,
   262  	})
   263  	replicasetList := []*K8sMetaEvent{
   264  		{
   265  			EventType: "update",
   266  			Object:    replicasetCache.metaStore.Items["default/replicaset1"],
   267  		},
   268  		{
   269  			EventType: "update",
   270  			Object:    replicasetCache.metaStore.Items["default/replicaset2"],
   271  		},
   272  	}
   273  	results := linkGenerator.getReplicaSetDeploymentLink(replicasetList)
   274  	assert.Equal(t, 2, len(results))
   275  	assert.Equal(t, "deployment1", results[0].Object.Raw.(*ReplicaSetDeployment).Deployment.Name)
   276  	assert.Equal(t, "deployment2", results[1].Object.Raw.(*ReplicaSetDeployment).Deployment.Name)
   277  }
   278  
   279  func TestGetPodReplicaSetLink(t *testing.T) {
   280  	podCache := newK8sMetaCache(make(chan struct{}), POD)
   281  	replicasetCache := newK8sMetaCache(make(chan struct{}), REPLICASET)
   282  	replicasetCache.metaStore.handleAddOrUpdateEvent(&K8sMetaEvent{
   283  		EventType: "add",
   284  		Object: &ObjectWrapper{
   285  			Raw: &app.ReplicaSet{
   286  				ObjectMeta: metav1.ObjectMeta{
   287  					Name:      "replicaset1",
   288  					Namespace: "default",
   289  				},
   290  				Spec: app.ReplicaSetSpec{
   291  					Selector: &metav1.LabelSelector{
   292  						MatchLabels: map[string]string{
   293  							"app": "test",
   294  						},
   295  					},
   296  				},
   297  			},
   298  		},
   299  	})
   300  	replicasetCache.metaStore.handleAddOrUpdateEvent(&K8sMetaEvent{
   301  		EventType: "add",
   302  		Object: &ObjectWrapper{
   303  			Raw: &app.ReplicaSet{
   304  				ObjectMeta: metav1.ObjectMeta{
   305  					Name:      "replicaset2",
   306  					Namespace: "default",
   307  				},
   308  				Spec: app.ReplicaSetSpec{
   309  					Selector: &metav1.LabelSelector{
   310  						MatchLabels: map[string]string{
   311  							"app": "test2",
   312  						},
   313  					},
   314  				},
   315  			},
   316  		},
   317  	})
   318  	pod1 := generateMockPod("1")
   319  	pod1.Raw.(*corev1.Pod).OwnerReferences = []metav1.OwnerReference{
   320  		{
   321  			Kind: "ReplicaSet",
   322  			Name: "replicaset1",
   323  		},
   324  	}
   325  	pod2 := generateMockPod("2")
   326  	pod2.Raw.(*corev1.Pod).OwnerReferences = []metav1.OwnerReference{
   327  		{
   328  			Kind: "ReplicaSet",
   329  			Name: "replicaset2",
   330  		},
   331  	}
   332  	podCache.metaStore.handleAddOrUpdateEvent(&K8sMetaEvent{
   333  		EventType: "add",
   334  		Object:    pod1,
   335  	})
   336  	podCache.metaStore.handleAddOrUpdateEvent(&K8sMetaEvent{
   337  		EventType: "add",
   338  		Object:    pod2,
   339  	})
   340  	linkGenerator := NewK8sMetaLinkGenerator(map[string]MetaCache{
   341  		POD:        podCache,
   342  		REPLICASET: replicasetCache,
   343  	})
   344  	podList := []*K8sMetaEvent{
   345  		{
   346  			EventType: "update",
   347  			Object:    podCache.metaStore.Items["default/pod1"],
   348  		},
   349  		{
   350  			EventType: "update",
   351  			Object:    podCache.metaStore.Items["default/pod2"],
   352  		},
   353  	}
   354  	results := linkGenerator.getPodReplicaSetLink(podList)
   355  	assert.Equal(t, 2, len(results))
   356  	assert.Equal(t, "replicaset1", results[0].Object.Raw.(*PodReplicaSet).ReplicaSet.Name)
   357  	assert.Equal(t, "replicaset2", results[1].Object.Raw.(*PodReplicaSet).ReplicaSet.Name)
   358  }
   359  
   360  func TestGetPodDaemonSetLink(t *testing.T) {
   361  	podCache := newK8sMetaCache(make(chan struct{}), POD)
   362  	daemonsetCache := newK8sMetaCache(make(chan struct{}), DAEMONSET)
   363  	daemonsetCache.metaStore.handleAddOrUpdateEvent(&K8sMetaEvent{
   364  		EventType: "add",
   365  		Object: &ObjectWrapper{
   366  			Raw: &app.DaemonSet{
   367  				ObjectMeta: metav1.ObjectMeta{
   368  					Name:      "daemonset1",
   369  					Namespace: "default",
   370  				},
   371  			},
   372  		},
   373  	})
   374  	daemonsetCache.metaStore.handleAddOrUpdateEvent(&K8sMetaEvent{
   375  		EventType: "add",
   376  		Object: &ObjectWrapper{
   377  			Raw: &app.DaemonSet{
   378  				ObjectMeta: metav1.ObjectMeta{
   379  					Name:      "daemonset2",
   380  					Namespace: "default",
   381  				},
   382  			},
   383  		},
   384  	})
   385  	pod1 := generateMockPod("1")
   386  	pod1.Raw.(*corev1.Pod).OwnerReferences = []metav1.OwnerReference{
   387  		{
   388  			Kind: "DaemonSet",
   389  			Name: "daemonset1",
   390  		},
   391  	}
   392  	pod2 := generateMockPod("2")
   393  	pod2.Raw.(*corev1.Pod).OwnerReferences = []metav1.OwnerReference{
   394  		{
   395  			Kind: "DaemonSet",
   396  			Name: "daemonset2",
   397  		},
   398  	}
   399  	podCache.metaStore.handleAddOrUpdateEvent(&K8sMetaEvent{
   400  		EventType: "add",
   401  		Object:    pod1,
   402  	})
   403  	podCache.metaStore.handleAddOrUpdateEvent(&K8sMetaEvent{
   404  		EventType: "add",
   405  		Object:    pod2,
   406  	})
   407  	linkGenerator := NewK8sMetaLinkGenerator(map[string]MetaCache{
   408  		POD:       podCache,
   409  		DAEMONSET: daemonsetCache,
   410  	})
   411  	podList := []*K8sMetaEvent{
   412  		{
   413  			EventType: "update",
   414  			Object:    podCache.metaStore.Items["default/pod1"],
   415  		},
   416  		{
   417  			EventType: "update",
   418  			Object:    podCache.metaStore.Items["default/pod2"],
   419  		},
   420  	}
   421  	results := linkGenerator.getPodDaemonSetLink(podList)
   422  	assert.Equal(t, 2, len(results))
   423  	assert.Equal(t, "daemonset1", results[0].Object.Raw.(*PodDaemonSet).DaemonSet.Name)
   424  	assert.Equal(t, "daemonset2", results[1].Object.Raw.(*PodDaemonSet).DaemonSet.Name)
   425  }
   426  
   427  func TestGetPodStatefulSetLink(t *testing.T) {
   428  	podCache := newK8sMetaCache(make(chan struct{}), POD)
   429  	statefulsetCache := newK8sMetaCache(make(chan struct{}), STATEFULSET)
   430  	statefulsetCache.metaStore.handleAddOrUpdateEvent(&K8sMetaEvent{
   431  		EventType: "add",
   432  		Object: &ObjectWrapper{
   433  			Raw: &app.StatefulSet{
   434  				ObjectMeta: metav1.ObjectMeta{
   435  					Name:      "statefulset1",
   436  					Namespace: "default",
   437  				},
   438  			},
   439  		},
   440  	})
   441  	statefulsetCache.metaStore.handleAddOrUpdateEvent(&K8sMetaEvent{
   442  		EventType: "add",
   443  		Object: &ObjectWrapper{
   444  			Raw: &app.StatefulSet{
   445  				ObjectMeta: metav1.ObjectMeta{
   446  					Name:      "statefulset2",
   447  					Namespace: "default",
   448  				},
   449  			},
   450  		},
   451  	})
   452  	pod1 := generateMockPod("1")
   453  	pod1.Raw.(*corev1.Pod).OwnerReferences = []metav1.OwnerReference{
   454  		{
   455  			Kind: "StatefulSet",
   456  			Name: "statefulset1",
   457  		},
   458  	}
   459  	pod2 := generateMockPod("2")
   460  	pod2.Raw.(*corev1.Pod).OwnerReferences = []metav1.OwnerReference{
   461  		{
   462  			Kind: "StatefulSet",
   463  			Name: "statefulset2",
   464  		},
   465  	}
   466  	podCache.metaStore.handleAddOrUpdateEvent(&K8sMetaEvent{
   467  		EventType: "add",
   468  		Object:    pod1,
   469  	})
   470  	podCache.metaStore.handleAddOrUpdateEvent(&K8sMetaEvent{
   471  		EventType: "add",
   472  		Object:    pod2,
   473  	})
   474  	linkGenerator := NewK8sMetaLinkGenerator(map[string]MetaCache{
   475  		POD:         podCache,
   476  		STATEFULSET: statefulsetCache,
   477  	})
   478  	podList := []*K8sMetaEvent{
   479  		{
   480  			EventType: "update",
   481  			Object:    podCache.metaStore.Items["default/pod1"],
   482  		},
   483  		{
   484  			EventType: "update",
   485  			Object:    podCache.metaStore.Items["default/pod2"],
   486  		},
   487  	}
   488  	results := linkGenerator.getPodStatefulSetLink(podList)
   489  	assert.Equal(t, 2, len(results))
   490  	assert.Equal(t, "statefulset1", results[0].Object.Raw.(*PodStatefulSet).StatefulSet.Name)
   491  	assert.Equal(t, "statefulset2", results[1].Object.Raw.(*PodStatefulSet).StatefulSet.Name)
   492  }
   493  
   494  func TestGetPodJobLink(t *testing.T) {
   495  	podCache := newK8sMetaCache(make(chan struct{}), POD)
   496  	jobCache := newK8sMetaCache(make(chan struct{}), JOB)
   497  	jobCache.metaStore.handleAddOrUpdateEvent(&K8sMetaEvent{
   498  		EventType: "add",
   499  		Object: &ObjectWrapper{
   500  			Raw: &batch.Job{
   501  				ObjectMeta: metav1.ObjectMeta{
   502  					Name:      "job1",
   503  					Namespace: "default",
   504  				},
   505  			},
   506  		},
   507  	})
   508  	jobCache.metaStore.handleAddOrUpdateEvent(&K8sMetaEvent{
   509  		EventType: "add",
   510  		Object: &ObjectWrapper{
   511  			Raw: &batch.Job{
   512  				ObjectMeta: metav1.ObjectMeta{
   513  					Name:      "job2",
   514  					Namespace: "default",
   515  				},
   516  			},
   517  		},
   518  	})
   519  	pod1 := generateMockPod("1")
   520  	pod1.Raw.(*corev1.Pod).OwnerReferences = []metav1.OwnerReference{
   521  		{
   522  			Kind: "Job",
   523  			Name: "job1",
   524  		},
   525  	}
   526  	pod2 := generateMockPod("2")
   527  	pod2.Raw.(*corev1.Pod).OwnerReferences = []metav1.OwnerReference{
   528  		{
   529  			Kind: "Job",
   530  			Name: "job2",
   531  		},
   532  	}
   533  	podCache.metaStore.handleAddOrUpdateEvent(&K8sMetaEvent{
   534  		EventType: "add",
   535  		Object:    pod1,
   536  	})
   537  	podCache.metaStore.handleAddOrUpdateEvent(&K8sMetaEvent{
   538  		EventType: "add",
   539  		Object:    pod2,
   540  	})
   541  	linkGenerator := NewK8sMetaLinkGenerator(map[string]MetaCache{
   542  		POD: podCache,
   543  		JOB: jobCache,
   544  	})
   545  	podList := []*K8sMetaEvent{
   546  		{
   547  			EventType: "update",
   548  			Object:    podCache.metaStore.Items["default/pod1"],
   549  		},
   550  		{
   551  			EventType: "update",
   552  			Object:    podCache.metaStore.Items["default/pod2"],
   553  		},
   554  	}
   555  	results := linkGenerator.getPodJobLink(podList)
   556  	assert.Equal(t, 2, len(results))
   557  	assert.Equal(t, "job1", results[0].Object.Raw.(*PodJob).Job.Name)
   558  	assert.Equal(t, "job2", results[1].Object.Raw.(*PodJob).Job.Name)
   559  }
   560  
   561  func TestGetJobCronJobLink(t *testing.T) {
   562  	jobCache := newK8sMetaCache(make(chan struct{}), JOB)
   563  	cronJobCache := newK8sMetaCache(make(chan struct{}), CRONJOB)
   564  	cronJobCache.metaStore.handleAddOrUpdateEvent(&K8sMetaEvent{
   565  		EventType: "add",
   566  		Object: &ObjectWrapper{
   567  			Raw: &batch.CronJob{
   568  				ObjectMeta: metav1.ObjectMeta{
   569  					Name:      "cronjob1",
   570  					Namespace: "default",
   571  				},
   572  			},
   573  		},
   574  	})
   575  	cronJobCache.metaStore.handleAddOrUpdateEvent(&K8sMetaEvent{
   576  		EventType: "add",
   577  		Object: &ObjectWrapper{
   578  			Raw: &batch.CronJob{
   579  				ObjectMeta: metav1.ObjectMeta{
   580  					Name:      "cronjob2",
   581  					Namespace: "default",
   582  				},
   583  			},
   584  		},
   585  	})
   586  	job1 := &ObjectWrapper{
   587  		Raw: &batch.Job{
   588  			ObjectMeta: metav1.ObjectMeta{
   589  				Name:      "job1",
   590  				Namespace: "default",
   591  			},
   592  		},
   593  	}
   594  	job1.Raw.(*batch.Job).OwnerReferences = []metav1.OwnerReference{
   595  		{
   596  			Kind: "CronJob",
   597  			Name: "cronjob1",
   598  		},
   599  	}
   600  	job2 := &ObjectWrapper{
   601  		Raw: &batch.Job{
   602  			ObjectMeta: metav1.ObjectMeta{
   603  				Name:      "job2",
   604  				Namespace: "default",
   605  			},
   606  		},
   607  	}
   608  	job2.Raw.(*batch.Job).OwnerReferences = []metav1.OwnerReference{
   609  		{
   610  			Kind: "CronJob",
   611  			Name: "cronjob2",
   612  		},
   613  	}
   614  	jobCache.metaStore.handleAddOrUpdateEvent(&K8sMetaEvent{
   615  		EventType: "add",
   616  		Object:    job1,
   617  	})
   618  	jobCache.metaStore.handleAddOrUpdateEvent(&K8sMetaEvent{
   619  		EventType: "add",
   620  		Object:    job2,
   621  	})
   622  	linkGenerator := NewK8sMetaLinkGenerator(map[string]MetaCache{
   623  		JOB:     jobCache,
   624  		CRONJOB: cronJobCache,
   625  	})
   626  	jobList := []*K8sMetaEvent{
   627  		{
   628  			EventType: "update",
   629  			Object:    jobCache.metaStore.Items["default/job1"],
   630  		},
   631  		{
   632  			EventType: "update",
   633  			Object:    jobCache.metaStore.Items["default/job2"],
   634  		},
   635  	}
   636  	results := linkGenerator.getJobCronJobLink(jobList)
   637  	assert.Equal(t, 2, len(results))
   638  	assert.Equal(t, "cronjob1", results[0].Object.Raw.(*JobCronJob).CronJob.Name)
   639  	assert.Equal(t, "cronjob2", results[1].Object.Raw.(*JobCronJob).CronJob.Name)
   640  }
   641  
   642  func TestGetPodPVCLink(t *testing.T) {
   643  	podCache := newK8sMetaCache(make(chan struct{}), POD)
   644  	pvcCache := newK8sMetaCache(make(chan struct{}), PERSISTENTVOLUMECLAIM)
   645  	pvcCache.metaStore.handleAddOrUpdateEvent(&K8sMetaEvent{
   646  		EventType: "add",
   647  		Object: &ObjectWrapper{
   648  			Raw: &corev1.PersistentVolumeClaim{
   649  				ObjectMeta: metav1.ObjectMeta{
   650  					Name:      "pvc1",
   651  					Namespace: "default",
   652  				},
   653  			},
   654  		},
   655  	})
   656  	pvcCache.metaStore.handleAddOrUpdateEvent(&K8sMetaEvent{
   657  		EventType: "add",
   658  		Object: &ObjectWrapper{
   659  			Raw: &corev1.PersistentVolumeClaim{
   660  				ObjectMeta: metav1.ObjectMeta{
   661  					Name:      "pvc2",
   662  					Namespace: "default",
   663  				},
   664  			},
   665  		},
   666  	})
   667  	pod1 := generateMockPod("1")
   668  	pod1.Raw.(*corev1.Pod).Spec.Volumes = []corev1.Volume{
   669  		{
   670  			Name: "volume1",
   671  			VolumeSource: corev1.VolumeSource{
   672  				PersistentVolumeClaim: &corev1.PersistentVolumeClaimVolumeSource{
   673  					ClaimName: "pvc1",
   674  				},
   675  			},
   676  		},
   677  	}
   678  	pod2 := generateMockPod("2")
   679  	pod2.Raw.(*corev1.Pod).Spec.Volumes = []corev1.Volume{
   680  		{
   681  			Name: "volume2",
   682  			VolumeSource: corev1.VolumeSource{
   683  				PersistentVolumeClaim: &corev1.PersistentVolumeClaimVolumeSource{
   684  					ClaimName: "pvc2",
   685  				},
   686  			},
   687  		},
   688  	}
   689  	podCache.metaStore.handleAddOrUpdateEvent(&K8sMetaEvent{
   690  		EventType: "add",
   691  		Object:    pod1,
   692  	})
   693  	podCache.metaStore.handleAddOrUpdateEvent(&K8sMetaEvent{
   694  		EventType: "add",
   695  		Object:    pod2,
   696  	})
   697  	linkGenerator := NewK8sMetaLinkGenerator(map[string]MetaCache{
   698  		POD:                   podCache,
   699  		PERSISTENTVOLUMECLAIM: pvcCache,
   700  	})
   701  	podList := []*K8sMetaEvent{
   702  		{
   703  			EventType: "update",
   704  			Object:    podCache.metaStore.Items["default/pod1"],
   705  		},
   706  		{
   707  			EventType: "update",
   708  			Object:    podCache.metaStore.Items["default/pod2"],
   709  		},
   710  	}
   711  	results := linkGenerator.getPodPVCLink(podList)
   712  	assert.Equal(t, 2, len(results))
   713  	assert.Equal(t, "pvc1", results[0].Object.Raw.(*PodPersistentVolumeClaim).PersistentVolumeClaim.Name)
   714  	assert.Equal(t, "pvc2", results[1].Object.Raw.(*PodPersistentVolumeClaim).PersistentVolumeClaim.Name)
   715  }
   716  
   717  func TestGetPodConfigMapLink(t *testing.T) {
   718  	podCache := newK8sMetaCache(make(chan struct{}), POD)
   719  	configMapCache := newK8sMetaCache(make(chan struct{}), CONFIGMAP)
   720  	configMapCache.metaStore.handleAddOrUpdateEvent(&K8sMetaEvent{
   721  		EventType: "add",
   722  		Object: &ObjectWrapper{
   723  			Raw: &corev1.ConfigMap{
   724  				ObjectMeta: metav1.ObjectMeta{
   725  					Name:      "configmap1",
   726  					Namespace: "default",
   727  				},
   728  			},
   729  		},
   730  	})
   731  	configMapCache.metaStore.handleAddOrUpdateEvent(&K8sMetaEvent{
   732  		EventType: "add",
   733  		Object: &ObjectWrapper{
   734  			Raw: &corev1.ConfigMap{
   735  				ObjectMeta: metav1.ObjectMeta{
   736  					Name:      "configmap2",
   737  					Namespace: "default",
   738  				},
   739  			},
   740  		},
   741  	})
   742  	pod1 := generateMockPod("1")
   743  	pod1.Raw.(*corev1.Pod).Spec.Volumes = []corev1.Volume{
   744  		{
   745  			Name: "volume1",
   746  			VolumeSource: corev1.VolumeSource{
   747  				ConfigMap: &corev1.ConfigMapVolumeSource{
   748  					LocalObjectReference: corev1.LocalObjectReference{
   749  						Name: "configmap1",
   750  					},
   751  				},
   752  			},
   753  		},
   754  	}
   755  	pod2 := generateMockPod("2")
   756  	pod2.Raw.(*corev1.Pod).Spec.Volumes = []corev1.Volume{
   757  		{
   758  			Name: "volume2",
   759  			VolumeSource: corev1.VolumeSource{
   760  				ConfigMap: &corev1.ConfigMapVolumeSource{
   761  					LocalObjectReference: corev1.LocalObjectReference{
   762  						Name: "configmap2",
   763  					},
   764  				},
   765  			},
   766  		},
   767  	}
   768  	podCache.metaStore.handleAddOrUpdateEvent(&K8sMetaEvent{
   769  		EventType: "add",
   770  		Object:    pod1,
   771  	})
   772  	podCache.metaStore.handleAddOrUpdateEvent(&K8sMetaEvent{
   773  		EventType: "add",
   774  		Object:    pod2,
   775  	})
   776  	linkGenerator := NewK8sMetaLinkGenerator(map[string]MetaCache{
   777  		POD:       podCache,
   778  		CONFIGMAP: configMapCache,
   779  	})
   780  	podList := []*K8sMetaEvent{
   781  		{
   782  			EventType: "update",
   783  			Object:    podCache.metaStore.Items["default/pod1"],
   784  		},
   785  		{
   786  			EventType: "update",
   787  			Object:    podCache.metaStore.Items["default/pod2"],
   788  		},
   789  	}
   790  	results := linkGenerator.getPodConfigMapLink(podList)
   791  	assert.Equal(t, 2, len(results))
   792  	assert.Equal(t, "configmap1", results[0].Object.Raw.(*PodConfigMap).ConfigMap.Name)
   793  	assert.Equal(t, "configmap2", results[1].Object.Raw.(*PodConfigMap).ConfigMap.Name)
   794  }
   795  
   796  func TestGetPodServiceLink(t *testing.T) {
   797  	podCache := newK8sMetaCache(make(chan struct{}), POD)
   798  	serviceCache := newK8sMetaCache(make(chan struct{}), SERVICE)
   799  	serviceCache.metaStore.handleAddOrUpdateEvent(&K8sMetaEvent{
   800  		EventType: "add",
   801  		Object: &ObjectWrapper{
   802  			Raw: &corev1.Service{
   803  				ObjectMeta: metav1.ObjectMeta{
   804  					Name:      "service1",
   805  					Namespace: "default",
   806  				},
   807  				Spec: corev1.ServiceSpec{
   808  					Selector: map[string]string{
   809  						"app": "test",
   810  					},
   811  				},
   812  			},
   813  		},
   814  	})
   815  	serviceCache.metaStore.handleAddOrUpdateEvent(&K8sMetaEvent{
   816  		EventType: "add",
   817  		Object: &ObjectWrapper{
   818  			Raw: &corev1.Service{
   819  				ObjectMeta: metav1.ObjectMeta{
   820  					Name:      "service2",
   821  					Namespace: "default",
   822  				},
   823  				Spec: corev1.ServiceSpec{
   824  					Selector: map[string]string{
   825  						"app": "test2",
   826  					},
   827  				},
   828  			},
   829  		},
   830  	})
   831  	pod1 := generateMockPod("1")
   832  	pod1.Raw.(*corev1.Pod).Labels = map[string]string{
   833  		"app": "test",
   834  	}
   835  	pod2 := generateMockPod("2")
   836  	pod2.Raw.(*corev1.Pod).Labels = map[string]string{
   837  		"app": "test2",
   838  	}
   839  	podCache.metaStore.handleAddOrUpdateEvent(&K8sMetaEvent{
   840  		EventType: "add",
   841  		Object:    pod1,
   842  	})
   843  	podCache.metaStore.handleAddOrUpdateEvent(&K8sMetaEvent{
   844  		EventType: "add",
   845  		Object:    pod2,
   846  	})
   847  	linkGenerator := NewK8sMetaLinkGenerator(map[string]MetaCache{
   848  		POD:     podCache,
   849  		SERVICE: serviceCache,
   850  	})
   851  	podList := []*K8sMetaEvent{
   852  		{
   853  			EventType: "update",
   854  			Object:    podCache.metaStore.Items["default/pod1"],
   855  		},
   856  		{
   857  			EventType: "update",
   858  			Object:    podCache.metaStore.Items["default/pod2"],
   859  		},
   860  	}
   861  	results := linkGenerator.getPodServiceLink(podList)
   862  	assert.Equal(t, 2, len(results))
   863  	assert.Equal(t, "service1", results[0].Object.Raw.(*PodService).Service.Name)
   864  	assert.Equal(t, "service2", results[1].Object.Raw.(*PodService).Service.Name)
   865  }
   866  
   867  func TestGetPodContainerLink(t *testing.T) {
   868  	podCache := newK8sMetaCache(make(chan struct{}), POD)
   869  	podCache.metaStore.handleAddOrUpdateEvent(&K8sMetaEvent{
   870  		EventType: "add",
   871  		Object:    generateMockPod("1"),
   872  	})
   873  	podCache.metaStore.handleAddOrUpdateEvent(&K8sMetaEvent{
   874  		EventType: "add",
   875  		Object:    generateMockPod("2"),
   876  	})
   877  	linkGenerator := NewK8sMetaLinkGenerator(map[string]MetaCache{
   878  		POD: podCache,
   879  	})
   880  	podList := []*K8sMetaEvent{
   881  		{
   882  			EventType: "update",
   883  			Object:    podCache.metaStore.Items["default/pod1"],
   884  		},
   885  		{
   886  			EventType: "update",
   887  			Object:    podCache.metaStore.Items["default/pod2"],
   888  		},
   889  	}
   890  	results := linkGenerator.getPodContainerLink(podList)
   891  	assert.Equal(t, 2, len(results))
   892  	assert.Equal(t, "test1", results[0].Object.Raw.(*PodContainer).Container.Name)
   893  	assert.Equal(t, "test2", results[1].Object.Raw.(*PodContainer).Container.Name)
   894  }
   895  
   896  func TestGetIngressServiceLink(t *testing.T) {
   897  	ingressCache := newK8sMetaCache(make(chan struct{}), INGRESS)
   898  	serviceCache := newK8sMetaCache(make(chan struct{}), SERVICE)
   899  	serviceCache.metaStore.handleAddOrUpdateEvent(&K8sMetaEvent{
   900  		EventType: "add",
   901  		Object: &ObjectWrapper{
   902  			Raw: &corev1.Service{
   903  				ObjectMeta: metav1.ObjectMeta{
   904  					Name:      "service1",
   905  					Namespace: "default",
   906  				},
   907  				Spec: corev1.ServiceSpec{
   908  					Selector: map[string]string{
   909  						"app": "test",
   910  					},
   911  				},
   912  			},
   913  		},
   914  	})
   915  	serviceCache.metaStore.handleAddOrUpdateEvent(&K8sMetaEvent{
   916  		EventType: "add",
   917  		Object: &ObjectWrapper{
   918  			Raw: &corev1.Service{
   919  				ObjectMeta: metav1.ObjectMeta{
   920  					Name:      "service2",
   921  					Namespace: "default",
   922  				},
   923  				Spec: corev1.ServiceSpec{
   924  					Selector: map[string]string{
   925  						"app": "test2",
   926  					},
   927  				},
   928  			},
   929  		},
   930  	})
   931  	ingressCache.metaStore.handleAddOrUpdateEvent(&K8sMetaEvent{
   932  		EventType: "add",
   933  		Object: &ObjectWrapper{
   934  			Raw: &networking.Ingress{
   935  				ObjectMeta: metav1.ObjectMeta{
   936  					Name:      "ingress1",
   937  					Namespace: "default",
   938  				},
   939  				Spec: networking.IngressSpec{
   940  					Rules: []networking.IngressRule{
   941  						{
   942  							IngressRuleValue: networking.IngressRuleValue{
   943  								HTTP: &networking.HTTPIngressRuleValue{
   944  									Paths: []networking.HTTPIngressPath{
   945  										{
   946  											Backend: networking.IngressBackend{
   947  												Service: &networking.IngressServiceBackend{
   948  													Name: "service1",
   949  												},
   950  											},
   951  										},
   952  									},
   953  								},
   954  							},
   955  						},
   956  					},
   957  				},
   958  			},
   959  		},
   960  	})
   961  	ingressCache.metaStore.handleAddOrUpdateEvent(&K8sMetaEvent{
   962  		EventType: "add",
   963  		Object: &ObjectWrapper{
   964  			Raw: &networking.Ingress{
   965  				ObjectMeta: metav1.ObjectMeta{
   966  					Name:      "ingress2",
   967  					Namespace: "default",
   968  				},
   969  				Spec: networking.IngressSpec{
   970  					Rules: []networking.IngressRule{
   971  						{
   972  							IngressRuleValue: networking.IngressRuleValue{
   973  								HTTP: &networking.HTTPIngressRuleValue{
   974  									Paths: []networking.HTTPIngressPath{
   975  										{
   976  											Backend: networking.IngressBackend{
   977  												Service: &networking.IngressServiceBackend{
   978  													Name: "service2",
   979  												},
   980  											},
   981  										},
   982  									},
   983  								},
   984  							},
   985  						},
   986  					},
   987  				},
   988  			},
   989  		},
   990  	})
   991  	linkGenerator := NewK8sMetaLinkGenerator(map[string]MetaCache{
   992  		INGRESS: ingressCache,
   993  		SERVICE: serviceCache,
   994  	})
   995  	ingressList := []*K8sMetaEvent{
   996  		{
   997  			EventType: "update",
   998  			Object:    ingressCache.metaStore.Items["default/ingress1"],
   999  		},
  1000  		{
  1001  			EventType: "update",
  1002  			Object:    ingressCache.metaStore.Items["default/ingress2"],
  1003  		},
  1004  	}
  1005  	results := linkGenerator.getIngressServiceLink(ingressList)
  1006  	assert.Equal(t, 2, len(results))
  1007  	assert.Equal(t, "service1", results[0].Object.Raw.(*IngressService).Service.Name)
  1008  	assert.Equal(t, "service2", results[1].Object.Raw.(*IngressService).Service.Name)
  1009  }
  1010  
  1011  func TestGetPodNamespaceLink(t *testing.T) {
  1012  	podCache := newK8sMetaCache(make(chan struct{}), POD)
  1013  	namespaceCache := newK8sMetaCache(make(chan struct{}), NAMESPACE)
  1014  	namespaceCache.metaStore.handleAddOrUpdateEvent(&K8sMetaEvent{
  1015  		EventType: "add",
  1016  		Object:    generateMockNamespace("default"),
  1017  	})
  1018  	namespaceCache.metaStore.handleAddOrUpdateEvent(&K8sMetaEvent{
  1019  		EventType: "add",
  1020  		Object:    generateMockNamespace("kube-system"),
  1021  	})
  1022  	pod1 := generateMockPod("1")
  1023  	pod1.Raw.(*corev1.Pod).Namespace = "default"
  1024  	pod2 := generateMockPod("2")
  1025  	pod2.Raw.(*corev1.Pod).Namespace = "kube-system"
  1026  	pod3 := generateMockPod("3")
  1027  	pod3.Raw.(*corev1.Pod).Namespace = "kube-system"
  1028  	podCache.metaStore.handleAddOrUpdateEvent(&K8sMetaEvent{
  1029  		EventType: "add",
  1030  		Object:    pod1,
  1031  	})
  1032  	podCache.metaStore.handleAddOrUpdateEvent(&K8sMetaEvent{
  1033  		EventType: "add",
  1034  		Object:    pod2,
  1035  	})
  1036  	podCache.metaStore.handleAddOrUpdateEvent(&K8sMetaEvent{
  1037  		EventType: "add",
  1038  		Object:    pod3,
  1039  	})
  1040  	linkGenerator := NewK8sMetaLinkGenerator(map[string]MetaCache{
  1041  		POD:       podCache,
  1042  		NAMESPACE: namespaceCache,
  1043  	})
  1044  	podList := []*K8sMetaEvent{
  1045  		{
  1046  			EventType: "update",
  1047  			Object:    podCache.metaStore.Items["default/pod1"],
  1048  		},
  1049  		{
  1050  			EventType: "update",
  1051  			Object:    podCache.metaStore.Items["kube-system/pod2"],
  1052  		},
  1053  		{
  1054  			EventType: "update",
  1055  			Object:    podCache.metaStore.Items["kube-system/pod3"],
  1056  		},
  1057  	}
  1058  	results := linkGenerator.getPodNamespaceLink(podList)
  1059  	assert.Equal(t, 3, len(results))
  1060  	assert.Equal(t, "default", results[0].Object.Raw.(*PodNamespace).Namespace.Name)
  1061  	assert.Equal(t, "pod1", results[0].Object.Raw.(*PodNamespace).Pod.Name)
  1062  	assert.Equal(t, "kube-system", results[1].Object.Raw.(*PodNamespace).Namespace.Name)
  1063  	assert.Equal(t, "pod2", results[1].Object.Raw.(*PodNamespace).Pod.Name)
  1064  	assert.Equal(t, "kube-system", results[2].Object.Raw.(*PodNamespace).Namespace.Name)
  1065  	assert.Equal(t, "pod3", results[2].Object.Raw.(*PodNamespace).Pod.Name)
  1066  	assert.Equal(t, POD_NAMESPACE, results[0].Object.ResourceType)
  1067  }
  1068  
  1069  func TestGetServiceNamespaceLink(t *testing.T) {
  1070  	serviceCache := newK8sMetaCache(make(chan struct{}), SERVICE)
  1071  	namespaceCache := newK8sMetaCache(make(chan struct{}), NAMESPACE)
  1072  	namespaceCache.metaStore.handleAddOrUpdateEvent(&K8sMetaEvent{
  1073  		EventType: "add",
  1074  		Object:    generateMockNamespace("default"),
  1075  	})
  1076  	namespaceCache.metaStore.handleAddOrUpdateEvent(&K8sMetaEvent{
  1077  		EventType: "add",
  1078  		Object:    generateMockNamespace("kube-system"),
  1079  	})
  1080  	service1 := &ObjectWrapper{
  1081  		Raw: &corev1.Service{
  1082  			ObjectMeta: metav1.ObjectMeta{
  1083  				Name:      "service1",
  1084  				Namespace: "default",
  1085  			},
  1086  			Spec: corev1.ServiceSpec{
  1087  				Selector: map[string]string{
  1088  					"app": "test",
  1089  				},
  1090  			},
  1091  		},
  1092  	}
  1093  	service2 := &ObjectWrapper{
  1094  		Raw: &corev1.Service{
  1095  			ObjectMeta: metav1.ObjectMeta{
  1096  				Name:      "service2",
  1097  				Namespace: "kube-system",
  1098  			},
  1099  			Spec: corev1.ServiceSpec{
  1100  				Selector: map[string]string{
  1101  					"app": "test",
  1102  				},
  1103  			},
  1104  		},
  1105  	}
  1106  	serviceCache.metaStore.handleAddOrUpdateEvent(&K8sMetaEvent{
  1107  		EventType: "add",
  1108  		Object:    service1,
  1109  	})
  1110  	serviceCache.metaStore.handleAddOrUpdateEvent(&K8sMetaEvent{
  1111  		EventType: "add",
  1112  		Object:    service2,
  1113  	})
  1114  
  1115  	serviceList := []*K8sMetaEvent{
  1116  		{
  1117  			EventType: "update",
  1118  			Object:    service1,
  1119  		},
  1120  		{
  1121  			EventType: "update",
  1122  			Object:    service2,
  1123  		},
  1124  	}
  1125  	linkGenerator := NewK8sMetaLinkGenerator(map[string]MetaCache{
  1126  		SERVICE:   serviceCache,
  1127  		NAMESPACE: namespaceCache,
  1128  	})
  1129  
  1130  	results := linkGenerator.getServiceNamespaceLink(serviceList)
  1131  	assert.Equal(t, 2, len(results))
  1132  	assert.Equal(t, "default", results[0].Object.Raw.(*ServiceNamespace).Namespace.Name)
  1133  	assert.Equal(t, "service1", results[0].Object.Raw.(*ServiceNamespace).Service.Name)
  1134  	assert.Equal(t, "kube-system", results[1].Object.Raw.(*ServiceNamespace).Namespace.Name)
  1135  	assert.Equal(t, "service2", results[1].Object.Raw.(*ServiceNamespace).Service.Name)
  1136  	assert.Equal(t, SERVICE_NAMESPACE, results[0].Object.ResourceType)
  1137  
  1138  }
  1139  
  1140  func TestGetDeploymentNamespaceLink(t *testing.T) {
  1141  	deploymentCache := newK8sMetaCache(make(chan struct{}), DEPLOYMENT)
  1142  	namespaceCache := newK8sMetaCache(make(chan struct{}), NAMESPACE)
  1143  	namespaceCache.metaStore.handleAddOrUpdateEvent(&K8sMetaEvent{
  1144  		EventType: "add",
  1145  		Object:    generateMockNamespace("default"),
  1146  	})
  1147  	namespaceCache.metaStore.handleAddOrUpdateEvent(&K8sMetaEvent{
  1148  		EventType: "add",
  1149  		Object:    generateMockNamespace("kube-system"),
  1150  	})
  1151  	deployment1 := &ObjectWrapper{
  1152  		Raw: &app.Deployment{
  1153  			ObjectMeta: metav1.ObjectMeta{
  1154  				Name:      "deployment1",
  1155  				Namespace: "default",
  1156  			},
  1157  		},
  1158  	}
  1159  	deployment2 := &ObjectWrapper{
  1160  		Raw: &app.Deployment{
  1161  			ObjectMeta: metav1.ObjectMeta{
  1162  				Name:      "deployment2",
  1163  				Namespace: "kube-system",
  1164  			},
  1165  		},
  1166  	}
  1167  	deploymentCache.metaStore.handleAddOrUpdateEvent(&K8sMetaEvent{
  1168  		EventType: "add",
  1169  		Object:    deployment1,
  1170  	})
  1171  	deploymentCache.metaStore.handleAddOrUpdateEvent(&K8sMetaEvent{
  1172  		EventType: "add",
  1173  		Object:    deployment2,
  1174  	})
  1175  
  1176  	deploymentList := []*K8sMetaEvent{
  1177  		{
  1178  			EventType: "update",
  1179  			Object:    deployment1,
  1180  		},
  1181  		{
  1182  			EventType: "update",
  1183  			Object:    deployment2,
  1184  		},
  1185  	}
  1186  	linkGenerator := NewK8sMetaLinkGenerator(map[string]MetaCache{
  1187  		DEPLOYMENT: deploymentCache,
  1188  		NAMESPACE:  namespaceCache,
  1189  	})
  1190  
  1191  	results := linkGenerator.getDeploymentNamespaceLink(deploymentList)
  1192  	assert.Equal(t, 2, len(results))
  1193  	assert.Equal(t, "default", results[0].Object.Raw.(*DeploymentNamespace).Namespace.Name)
  1194  	assert.Equal(t, "deployment1", results[0].Object.Raw.(*DeploymentNamespace).Deployment.Name)
  1195  	assert.Equal(t, "kube-system", results[1].Object.Raw.(*DeploymentNamespace).Namespace.Name)
  1196  	assert.Equal(t, "deployment2", results[1].Object.Raw.(*DeploymentNamespace).Deployment.Name)
  1197  	assert.Equal(t, DEPLOYMENT_NAMESPACE, results[0].Object.ResourceType)
  1198  
  1199  }
  1200  
  1201  func TestGetDaemonSetNamespaceLink(t *testing.T) {
  1202  	daemonSetCache := newK8sMetaCache(make(chan struct{}), DAEMONSET)
  1203  	namespaceCache := newK8sMetaCache(make(chan struct{}), NAMESPACE)
  1204  	namespaceCache.metaStore.handleAddOrUpdateEvent(&K8sMetaEvent{
  1205  		EventType: "add",
  1206  		Object:    generateMockNamespace("default"),
  1207  	})
  1208  	namespaceCache.metaStore.handleAddOrUpdateEvent(&K8sMetaEvent{
  1209  		EventType: "add",
  1210  		Object:    generateMockNamespace("kube-system"),
  1211  	})
  1212  	daemonset1 := &ObjectWrapper{
  1213  		Raw: &app.DaemonSet{
  1214  			ObjectMeta: metav1.ObjectMeta{
  1215  				Name:      "daemonset1",
  1216  				Namespace: "default",
  1217  			},
  1218  		},
  1219  	}
  1220  	daemonset2 := &ObjectWrapper{
  1221  		Raw: &app.DaemonSet{
  1222  			ObjectMeta: metav1.ObjectMeta{
  1223  				Name:      "daemonset2",
  1224  				Namespace: "kube-system",
  1225  			},
  1226  		},
  1227  	}
  1228  	daemonSetCache.metaStore.handleAddOrUpdateEvent(&K8sMetaEvent{
  1229  		EventType: "add",
  1230  		Object:    daemonset1,
  1231  	})
  1232  	daemonSetCache.metaStore.handleAddOrUpdateEvent(&K8sMetaEvent{
  1233  		EventType: "add",
  1234  		Object:    daemonset2,
  1235  	})
  1236  
  1237  	daemonsetList := []*K8sMetaEvent{
  1238  		{
  1239  			EventType: "update",
  1240  			Object:    daemonset1,
  1241  		},
  1242  		{
  1243  			EventType: "update",
  1244  			Object:    daemonset2,
  1245  		},
  1246  	}
  1247  	linkGenerator := NewK8sMetaLinkGenerator(map[string]MetaCache{
  1248  		DAEMONSET: daemonSetCache,
  1249  		NAMESPACE: namespaceCache,
  1250  	})
  1251  
  1252  	results := linkGenerator.getDaemonSetNamespaceLink(daemonsetList)
  1253  	assert.Equal(t, 2, len(results))
  1254  	assert.Equal(t, "default", results[0].Object.Raw.(*DaemonSetNamespace).Namespace.Name)
  1255  	assert.Equal(t, "daemonset1", results[0].Object.Raw.(*DaemonSetNamespace).DaemonSet.Name)
  1256  	assert.Equal(t, "kube-system", results[1].Object.Raw.(*DaemonSetNamespace).Namespace.Name)
  1257  	assert.Equal(t, "daemonset2", results[1].Object.Raw.(*DaemonSetNamespace).DaemonSet.Name)
  1258  	assert.Equal(t, DAEMONSET_NAMESPACE, results[0].Object.ResourceType)
  1259  }
  1260  
  1261  func TestGetStatefulSetNamespaceLink(t *testing.T) {
  1262  	statefulSetCache := newK8sMetaCache(make(chan struct{}), STATEFULSET)
  1263  	namespaceCache := newK8sMetaCache(make(chan struct{}), NAMESPACE)
  1264  	namespaceCache.metaStore.handleAddOrUpdateEvent(&K8sMetaEvent{
  1265  		EventType: "add",
  1266  		Object:    generateMockNamespace("default"),
  1267  	})
  1268  	namespaceCache.metaStore.handleAddOrUpdateEvent(&K8sMetaEvent{
  1269  		EventType: "add",
  1270  		Object:    generateMockNamespace("kube-system"),
  1271  	})
  1272  	statefulSet1 := &ObjectWrapper{
  1273  		Raw: &app.StatefulSet{
  1274  			ObjectMeta: metav1.ObjectMeta{
  1275  				Name:      "statefulSet1",
  1276  				Namespace: "default",
  1277  			},
  1278  		},
  1279  	}
  1280  	statefulSet2 := &ObjectWrapper{
  1281  		Raw: &app.StatefulSet{
  1282  			ObjectMeta: metav1.ObjectMeta{
  1283  				Name:      "statefulSet2",
  1284  				Namespace: "kube-system",
  1285  			},
  1286  		},
  1287  	}
  1288  	statefulSetCache.metaStore.handleAddOrUpdateEvent(&K8sMetaEvent{
  1289  		EventType: "add",
  1290  		Object:    statefulSet1,
  1291  	})
  1292  	statefulSetCache.metaStore.handleAddOrUpdateEvent(&K8sMetaEvent{
  1293  		EventType: "add",
  1294  		Object:    statefulSet2,
  1295  	})
  1296  
  1297  	statefulSetList := []*K8sMetaEvent{
  1298  		{
  1299  			EventType: "update",
  1300  			Object:    statefulSet1,
  1301  		},
  1302  		{
  1303  			EventType: "update",
  1304  			Object:    statefulSet2,
  1305  		},
  1306  	}
  1307  	linkGenerator := NewK8sMetaLinkGenerator(map[string]MetaCache{
  1308  		DAEMONSET: statefulSetCache,
  1309  		NAMESPACE: namespaceCache,
  1310  	})
  1311  
  1312  	results := linkGenerator.getStatefulsetNamespaceLink(statefulSetList)
  1313  	assert.Equal(t, 2, len(results))
  1314  	assert.Equal(t, "default", results[0].Object.Raw.(*StatefulSetNamespace).Namespace.Name)
  1315  	assert.Equal(t, "statefulSet1", results[0].Object.Raw.(*StatefulSetNamespace).StatefulSet.Name)
  1316  	assert.Equal(t, "kube-system", results[1].Object.Raw.(*StatefulSetNamespace).Namespace.Name)
  1317  	assert.Equal(t, "statefulSet2", results[1].Object.Raw.(*StatefulSetNamespace).StatefulSet.Name)
  1318  	assert.Equal(t, STATEFULSET_NAMESPACE, results[0].Object.ResourceType)
  1319  }
  1320  
  1321  func TestGetConfigMapNamespaceLink(t *testing.T) {
  1322  	configmapCache := newK8sMetaCache(make(chan struct{}), CONFIGMAP)
  1323  	namespaceCache := newK8sMetaCache(make(chan struct{}), NAMESPACE)
  1324  	namespaceCache.metaStore.handleAddOrUpdateEvent(&K8sMetaEvent{
  1325  		EventType: "add",
  1326  		Object:    generateMockNamespace("default"),
  1327  	})
  1328  	namespaceCache.metaStore.handleAddOrUpdateEvent(&K8sMetaEvent{
  1329  		EventType: "add",
  1330  		Object:    generateMockNamespace("kube-system"),
  1331  	})
  1332  	configmap1 := &ObjectWrapper{
  1333  		Raw: &corev1.ConfigMap{
  1334  			ObjectMeta: metav1.ObjectMeta{
  1335  				Name:      "configmap1",
  1336  				Namespace: "default",
  1337  			},
  1338  		},
  1339  	}
  1340  	configmap2 := &ObjectWrapper{
  1341  		Raw: &corev1.ConfigMap{
  1342  			ObjectMeta: metav1.ObjectMeta{
  1343  				Name:      "configmap2",
  1344  				Namespace: "kube-system",
  1345  			},
  1346  		},
  1347  	}
  1348  	configmapCache.metaStore.handleAddOrUpdateEvent(&K8sMetaEvent{
  1349  		EventType: "add",
  1350  		Object:    configmap1,
  1351  	})
  1352  	configmapCache.metaStore.handleAddOrUpdateEvent(&K8sMetaEvent{
  1353  		EventType: "add",
  1354  		Object:    configmap2,
  1355  	})
  1356  
  1357  	configmapList := []*K8sMetaEvent{
  1358  		{
  1359  			EventType: "update",
  1360  			Object:    configmap1,
  1361  		},
  1362  		{
  1363  			EventType: "update",
  1364  			Object:    configmap2,
  1365  		},
  1366  	}
  1367  	linkGenerator := NewK8sMetaLinkGenerator(map[string]MetaCache{
  1368  		CONFIGMAP: configmapCache,
  1369  		NAMESPACE: namespaceCache,
  1370  	})
  1371  
  1372  	results := linkGenerator.getConfigMapNamesapceLink(configmapList)
  1373  	assert.Equal(t, 2, len(results))
  1374  	assert.Equal(t, "default", results[0].Object.Raw.(*ConfigMapNamespace).Namespace.Name)
  1375  	assert.Equal(t, "configmap1", results[0].Object.Raw.(*ConfigMapNamespace).ConfigMap.Name)
  1376  	assert.Equal(t, "kube-system", results[1].Object.Raw.(*ConfigMapNamespace).Namespace.Name)
  1377  	assert.Equal(t, "configmap2", results[1].Object.Raw.(*ConfigMapNamespace).ConfigMap.Name)
  1378  	assert.Equal(t, CONFIGMAP_NAMESPACE, results[0].Object.ResourceType)
  1379  }
  1380  
  1381  func TestGetJobNamespaceLink(t *testing.T) {
  1382  	jobCache := newK8sMetaCache(make(chan struct{}), JOB)
  1383  	namespaceCache := newK8sMetaCache(make(chan struct{}), NAMESPACE)
  1384  	namespaceCache.metaStore.handleAddOrUpdateEvent(&K8sMetaEvent{
  1385  		EventType: "add",
  1386  		Object:    generateMockNamespace("default"),
  1387  	})
  1388  	namespaceCache.metaStore.handleAddOrUpdateEvent(&K8sMetaEvent{
  1389  		EventType: "add",
  1390  		Object:    generateMockNamespace("kube-system"),
  1391  	})
  1392  	job1 := &ObjectWrapper{
  1393  		Raw: &batch.Job{
  1394  			ObjectMeta: metav1.ObjectMeta{
  1395  				Name:      "job1",
  1396  				Namespace: "default",
  1397  			},
  1398  		},
  1399  	}
  1400  	job2 := &ObjectWrapper{
  1401  		Raw: &batch.Job{
  1402  			ObjectMeta: metav1.ObjectMeta{
  1403  				Name:      "job2",
  1404  				Namespace: "kube-system",
  1405  			},
  1406  		},
  1407  	}
  1408  	jobCache.metaStore.handleAddOrUpdateEvent(&K8sMetaEvent{
  1409  		EventType: "add",
  1410  		Object:    job1,
  1411  	})
  1412  	jobCache.metaStore.handleAddOrUpdateEvent(&K8sMetaEvent{
  1413  		EventType: "add",
  1414  		Object:    job2,
  1415  	})
  1416  
  1417  	jobList := []*K8sMetaEvent{
  1418  		{
  1419  			EventType: "update",
  1420  			Object:    job1,
  1421  		},
  1422  		{
  1423  			EventType: "update",
  1424  			Object:    job2,
  1425  		},
  1426  	}
  1427  	linkGenerator := NewK8sMetaLinkGenerator(map[string]MetaCache{
  1428  		JOB:       jobCache,
  1429  		NAMESPACE: namespaceCache,
  1430  	})
  1431  
  1432  	results := linkGenerator.getJobNamesapceLink(jobList)
  1433  	assert.Equal(t, 2, len(results))
  1434  	assert.Equal(t, "default", results[0].Object.Raw.(*JobNamespace).Namespace.Name)
  1435  	assert.Equal(t, "job1", results[0].Object.Raw.(*JobNamespace).Job.Name)
  1436  	assert.Equal(t, "kube-system", results[1].Object.Raw.(*JobNamespace).Namespace.Name)
  1437  	assert.Equal(t, "job2", results[1].Object.Raw.(*JobNamespace).Job.Name)
  1438  	assert.Equal(t, JOB_NAMESPACE, results[0].Object.ResourceType)
  1439  }
  1440  
  1441  func TestGetCronJobNamespaceLink(t *testing.T) {
  1442  	cronjobCache := newK8sMetaCache(make(chan struct{}), CRONJOB)
  1443  	namespaceCache := newK8sMetaCache(make(chan struct{}), NAMESPACE)
  1444  	namespaceCache.metaStore.handleAddOrUpdateEvent(&K8sMetaEvent{
  1445  		EventType: "add",
  1446  		Object:    generateMockNamespace("default"),
  1447  	})
  1448  	namespaceCache.metaStore.handleAddOrUpdateEvent(&K8sMetaEvent{
  1449  		EventType: "add",
  1450  		Object:    generateMockNamespace("kube-system"),
  1451  	})
  1452  	cronjob1 := &ObjectWrapper{
  1453  		Raw: &batch.CronJob{
  1454  			ObjectMeta: metav1.ObjectMeta{
  1455  				Name:      "cronjob1",
  1456  				Namespace: "default",
  1457  			},
  1458  		},
  1459  	}
  1460  	cronjob2 := &ObjectWrapper{
  1461  		Raw: &batch.CronJob{
  1462  			ObjectMeta: metav1.ObjectMeta{
  1463  				Name:      "cronjob2",
  1464  				Namespace: "kube-system",
  1465  			},
  1466  		},
  1467  	}
  1468  	cronjobCache.metaStore.handleAddOrUpdateEvent(&K8sMetaEvent{
  1469  		EventType: "add",
  1470  		Object:    cronjob1,
  1471  	})
  1472  	cronjobCache.metaStore.handleAddOrUpdateEvent(&K8sMetaEvent{
  1473  		EventType: "add",
  1474  		Object:    cronjob2,
  1475  	})
  1476  
  1477  	jobList := []*K8sMetaEvent{
  1478  		{
  1479  			EventType: "update",
  1480  			Object:    cronjob1,
  1481  		},
  1482  		{
  1483  			EventType: "update",
  1484  			Object:    cronjob2,
  1485  		},
  1486  	}
  1487  	linkGenerator := NewK8sMetaLinkGenerator(map[string]MetaCache{
  1488  		CRONJOB:   cronjobCache,
  1489  		NAMESPACE: namespaceCache,
  1490  	})
  1491  
  1492  	results := linkGenerator.getCronJobNamesapceLink(jobList)
  1493  	assert.Equal(t, 2, len(results))
  1494  	assert.Equal(t, "default", results[0].Object.Raw.(*CronJobNamespace).Namespace.Name)
  1495  	assert.Equal(t, "cronjob1", results[0].Object.Raw.(*CronJobNamespace).CronJob.Name)
  1496  	assert.Equal(t, "kube-system", results[1].Object.Raw.(*CronJobNamespace).Namespace.Name)
  1497  	assert.Equal(t, "cronjob2", results[1].Object.Raw.(*CronJobNamespace).CronJob.Name)
  1498  	assert.Equal(t, CRONJOB_NAMESPACE, results[0].Object.ResourceType)
  1499  }
  1500  
  1501  func TestGetPVCNamespaceLink(t *testing.T) {
  1502  	pvcCache := newK8sMetaCache(make(chan struct{}), PERSISTENTVOLUME)
  1503  	namespaceCache := newK8sMetaCache(make(chan struct{}), NAMESPACE)
  1504  	namespaceCache.metaStore.handleAddOrUpdateEvent(&K8sMetaEvent{
  1505  		EventType: "add",
  1506  		Object:    generateMockNamespace("default"),
  1507  	})
  1508  	namespaceCache.metaStore.handleAddOrUpdateEvent(&K8sMetaEvent{
  1509  		EventType: "add",
  1510  		Object:    generateMockNamespace("kube-system"),
  1511  	})
  1512  	pvc1 := &ObjectWrapper{
  1513  		Raw: &corev1.PersistentVolumeClaim{
  1514  			ObjectMeta: metav1.ObjectMeta{
  1515  				Name:      "pvc1",
  1516  				Namespace: "default",
  1517  			},
  1518  		},
  1519  	}
  1520  	pvc2 := &ObjectWrapper{
  1521  		Raw: &corev1.PersistentVolumeClaim{
  1522  			ObjectMeta: metav1.ObjectMeta{
  1523  				Name:      "pvc2",
  1524  				Namespace: "kube-system",
  1525  			},
  1526  		},
  1527  	}
  1528  	pvcCache.metaStore.handleAddOrUpdateEvent(&K8sMetaEvent{
  1529  		EventType: "add",
  1530  		Object:    pvc1,
  1531  	})
  1532  	pvcCache.metaStore.handleAddOrUpdateEvent(&K8sMetaEvent{
  1533  		EventType: "add",
  1534  		Object:    pvc2,
  1535  	})
  1536  
  1537  	jobList := []*K8sMetaEvent{
  1538  		{
  1539  			EventType: "update",
  1540  			Object:    pvc1,
  1541  		},
  1542  		{
  1543  			EventType: "update",
  1544  			Object:    pvc2,
  1545  		},
  1546  	}
  1547  	linkGenerator := NewK8sMetaLinkGenerator(map[string]MetaCache{
  1548  		PERSISTENTVOLUMECLAIM: pvcCache,
  1549  		NAMESPACE:             namespaceCache,
  1550  	})
  1551  
  1552  	results := linkGenerator.getPVCNamesapceLink(jobList)
  1553  	assert.Equal(t, 2, len(results))
  1554  	assert.Equal(t, "default", results[0].Object.Raw.(*PersistentVolumeClaimNamespace).Namespace.Name)
  1555  	assert.Equal(t, "pvc1", results[0].Object.Raw.(*PersistentVolumeClaimNamespace).PersistentVolumeClaim.Name)
  1556  	assert.Equal(t, "kube-system", results[1].Object.Raw.(*PersistentVolumeClaimNamespace).Namespace.Name)
  1557  	assert.Equal(t, "pvc2", results[1].Object.Raw.(*PersistentVolumeClaimNamespace).PersistentVolumeClaim.Name)
  1558  	assert.Equal(t, PERSISTENTVOLUMECLAIM_NAMESPACE, results[0].Object.ResourceType)
  1559  }
  1560  
  1561  func TestGetIngressNamespaceLink(t *testing.T) {
  1562  	ingressCache := newK8sMetaCache(make(chan struct{}), INGRESS)
  1563  	namespaceCache := newK8sMetaCache(make(chan struct{}), NAMESPACE)
  1564  	namespaceCache.metaStore.handleAddOrUpdateEvent(&K8sMetaEvent{
  1565  		EventType: "add",
  1566  		Object:    generateMockNamespace("default"),
  1567  	})
  1568  	namespaceCache.metaStore.handleAddOrUpdateEvent(&K8sMetaEvent{
  1569  		EventType: "add",
  1570  		Object:    generateMockNamespace("kube-system"),
  1571  	})
  1572  	ingress1 := &ObjectWrapper{
  1573  		Raw: &networking.Ingress{
  1574  			ObjectMeta: metav1.ObjectMeta{
  1575  				Name:      "ingress1",
  1576  				Namespace: "default",
  1577  			},
  1578  		},
  1579  	}
  1580  	ingress2 := &ObjectWrapper{
  1581  		Raw: &networking.Ingress{
  1582  			ObjectMeta: metav1.ObjectMeta{
  1583  				Name:      "ingress2",
  1584  				Namespace: "kube-system",
  1585  			},
  1586  		},
  1587  	}
  1588  	ingressCache.metaStore.handleAddOrUpdateEvent(&K8sMetaEvent{
  1589  		EventType: "add",
  1590  		Object:    ingress1,
  1591  	})
  1592  	ingressCache.metaStore.handleAddOrUpdateEvent(&K8sMetaEvent{
  1593  		EventType: "add",
  1594  		Object:    ingress2,
  1595  	})
  1596  
  1597  	jobList := []*K8sMetaEvent{
  1598  		{
  1599  			EventType: "update",
  1600  			Object:    ingress1,
  1601  		},
  1602  		{
  1603  			EventType: "update",
  1604  			Object:    ingress2,
  1605  		},
  1606  	}
  1607  	linkGenerator := NewK8sMetaLinkGenerator(map[string]MetaCache{
  1608  		INGRESS:   ingressCache,
  1609  		NAMESPACE: namespaceCache,
  1610  	})
  1611  
  1612  	results := linkGenerator.getIngressNamesapceLink(jobList)
  1613  	assert.Equal(t, 2, len(results))
  1614  	assert.Equal(t, "default", results[0].Object.Raw.(*IngressNamespace).Namespace.Name)
  1615  	assert.Equal(t, "ingress1", results[0].Object.Raw.(*IngressNamespace).Ingress.Name)
  1616  	assert.Equal(t, "kube-system", results[1].Object.Raw.(*IngressNamespace).Namespace.Name)
  1617  	assert.Equal(t, "ingress2", results[1].Object.Raw.(*IngressNamespace).Ingress.Name)
  1618  	assert.Equal(t, INGRESS_NAMESPACE, results[0].Object.ResourceType)
  1619  }
  1620  
  1621  func generateMockNamespace(namespaceName string) *ObjectWrapper {
  1622  	return &ObjectWrapper{
  1623  		Raw: &corev1.Namespace{
  1624  			ObjectMeta: metav1.ObjectMeta{
  1625  				Name:      namespaceName,
  1626  				Namespace: "", // namesapce itself without namesapce
  1627  			},
  1628  		},
  1629  	}
  1630  }
  1631  
  1632  func generateMockPod(index string) *ObjectWrapper {
  1633  	return &ObjectWrapper{
  1634  		Raw: &corev1.Pod{
  1635  			ObjectMeta: metav1.ObjectMeta{
  1636  				Name:      "pod" + index,
  1637  				Namespace: "default",
  1638  			},
  1639  			Spec: corev1.PodSpec{
  1640  				Containers: []corev1.Container{
  1641  					{
  1642  						Name:  "test" + index,
  1643  						Image: "test" + index,
  1644  					},
  1645  				},
  1646  			},
  1647  		},
  1648  	}
  1649  }