@@ -2,6 +2,7 @@ package controller
22
33import (
44 "context"
5+ "fmt"
56 "slices"
67 "sync"
78 "testing"
@@ -40,7 +41,7 @@ func (m *mockRecordPoster) getRecords() []*deploymentrecord.DeploymentRecord {
4041 return slices .Clone (m .records )
4142}
4243
43- func setup (t * testing.T , namespace string ) (* kubernetes.Clientset , * mockRecordPoster ) {
44+ func setup (t * testing.T , namespace string , onlyNamepsace string , excludeNamespaces string ) (* kubernetes.Clientset , * mockRecordPoster ) {
4445 t .Helper ()
4546 testEnv := & envtest.Environment {}
4647
@@ -76,8 +77,8 @@ func setup(t *testing.T, namespace string) (*kubernetes.Clientset, *mockRecordPo
7677 ctrl , err := New (
7778 clientset ,
7879 metadataAggregator ,
79- "" ,
80- "" ,
80+ onlyNamepsace ,
81+ excludeNamespaces ,
8182 & Config {
8283 "{{namespace}}/{{deploymentName}}/{{containerName}}" ,
8384 "test-logical-env" ,
@@ -271,8 +272,9 @@ func TestControllerIntegration_KubernetesDeployment(t *testing.T) {
271272 if testing .Short () {
272273 t .Skip ("skipping integration test in short mode" )
273274 }
274- namespace := "test-namespace"
275- clientset , mock := setup (t , namespace )
275+ t .Parallel ()
276+ namespace := "test-controller-ns"
277+ clientset , mock := setup (t , namespace , "" , "" )
276278
277279 // Create deployment, replicaset, and pod; expect 1 record
278280 deployment := makeDeployment (t , clientset , []metav1.OwnerReference {}, namespace , "test-deployment" )
@@ -331,8 +333,9 @@ func TestControllerIntegration_InitContainers(t *testing.T) {
331333 if testing .Short () {
332334 t .Skip ("skipping integration test in short mode" )
333335 }
334- namespace := "test-init-containers"
335- clientset , mock := setup (t , namespace )
336+ t .Parallel ()
337+ namespace := "test-controller-ns"
338+ clientset , mock := setup (t , namespace , "" , "" )
336339
337340 // Create deployment, replicaset, and pod with an init container; expect 2 records (one per container)
338341 deployment := makeDeployment (t , clientset , []metav1.OwnerReference {}, namespace , "init-deployment" )
@@ -361,8 +364,8 @@ func TestControllerIntegration_InitContainers(t *testing.T) {
361364 assert .Equal (t , deploymentrecord .StatusDeployed , r .Status )
362365 deploymentNames [i ] = r .DeploymentName
363366 }
364- assert .Contains (t , deploymentNames , "test-init-containers /init-deployment/app" )
365- assert .Contains (t , deploymentNames , "test-init-containers /init-deployment/init" )
367+ assert .Contains (t , deploymentNames , fmt . Sprintf ( "%s /init-deployment/app", namespace ) )
368+ assert .Contains (t , deploymentNames , fmt . Sprintf ( "%s /init-deployment/init", namespace ) )
366369
367370 // Delete deployment, replicaset, and pod; expect 2 more decommissioned records (one per container)
368371 deleteDeployment (t , clientset , namespace , "init-deployment" )
@@ -380,6 +383,142 @@ func TestControllerIntegration_InitContainers(t *testing.T) {
380383 assert .Equal (t , deploymentrecord .StatusDecommissioned , r .Status )
381384 decommissionedNames = append (decommissionedNames , r .DeploymentName )
382385 }
383- assert .Contains (t , decommissionedNames , "test-init-containers/init-deployment/app" )
384- assert .Contains (t , decommissionedNames , "test-init-containers/init-deployment/init" )
386+ assert .Contains (t , decommissionedNames , fmt .Sprintf ("%s/init-deployment/app" , namespace ))
387+ assert .Contains (t , decommissionedNames , fmt .Sprintf ("%s/init-deployment/init" , namespace ))
388+ }
389+
390+ func TestControllerIntegration_OnlyWatchOneNamespace (t * testing.T ) {
391+ if testing .Short () {
392+ t .Skip ("skipping integration test in short mode" )
393+ }
394+ t .Parallel ()
395+ namespace1 := "namespace1"
396+ namespace2 := "namespace2"
397+ clientset , mock := setup (t , "test-controller-ns" , namespace1 , "" )
398+
399+ ns1 := & corev1.Namespace {ObjectMeta : metav1.ObjectMeta {Name : namespace1 }}
400+ _ , err := clientset .CoreV1 ().Namespaces ().Create (context .Background (), ns1 , metav1.CreateOptions {})
401+ if err != nil {
402+ t .Fatalf ("failed to create namespace: %v" , err )
403+ }
404+ ns2 := & corev1.Namespace {ObjectMeta : metav1.ObjectMeta {Name : namespace2 }}
405+ _ , err = clientset .CoreV1 ().Namespaces ().Create (context .Background (), ns2 , metav1.CreateOptions {})
406+ if err != nil {
407+ t .Fatalf ("failed to create namespace: %v" , err )
408+ }
409+
410+ // Make new deployment in namespace1; expect 1 record
411+ deployment1 := makeDeployment (t , clientset , []metav1.OwnerReference {}, namespace1 , "init-deployment" )
412+ replicaSet1 := makeReplicaSet (t , clientset , []metav1.OwnerReference {{
413+ APIVersion : "apps/v1" ,
414+ Kind : "Deployment" ,
415+ Name : deployment1 .Name ,
416+ UID : deployment1 .UID ,
417+ }}, namespace1 , "init-deployment-abc123" )
418+ _ = makePod (t , clientset , []metav1.OwnerReference {{
419+ APIVersion : "apps/v1" ,
420+ Kind : "ReplicaSet" ,
421+ Name : replicaSet1 .Name ,
422+ UID : replicaSet1 .UID ,
423+ }}, namespace1 , "init-deployment-abc123-1" )
424+ require .Eventually (t , func () bool {
425+ return len (mock .getRecords ()) == 1
426+ }, 3 * time .Second , 100 * time .Millisecond )
427+
428+ // Make new deployment in namespace2; expect no new records
429+ deployment2 := makeDeployment (t , clientset , []metav1.OwnerReference {}, namespace2 , "init-deployment" )
430+ replicaSet2 := makeReplicaSet (t , clientset , []metav1.OwnerReference {{
431+ APIVersion : "apps/v1" ,
432+ Kind : "Deployment" ,
433+ Name : deployment2 .Name ,
434+ UID : deployment2 .UID ,
435+ }}, namespace2 , "init-deployment-abc123" )
436+ _ = makePod (t , clientset , []metav1.OwnerReference {{
437+ APIVersion : "apps/v1" ,
438+ Kind : "ReplicaSet" ,
439+ Name : replicaSet2 .Name ,
440+ UID : replicaSet2 .UID ,
441+ }}, namespace2 , "init-deployment-abc123-1" )
442+ require .Never (t , func () bool {
443+ return len (mock .getRecords ()) != 1
444+ }, 3 * time .Second , 100 * time .Millisecond )
445+ }
446+
447+ func TestControllerIntegration_ExcludeNamespaces (t * testing.T ) {
448+ if testing .Short () {
449+ t .Skip ("skipping integration test in short mode" )
450+ }
451+ t .Parallel ()
452+ namespace1 := "namespace1"
453+ namespace2 := "namespace2"
454+ namespace3 := "namespace3"
455+ clientset , mock := setup (t , "test-controller-ns" , "" , fmt .Sprintf ("%s,%s" , namespace2 , namespace3 ))
456+
457+ ns1 := & corev1.Namespace {ObjectMeta : metav1.ObjectMeta {Name : namespace1 }}
458+ _ , err := clientset .CoreV1 ().Namespaces ().Create (context .Background (), ns1 , metav1.CreateOptions {})
459+ if err != nil {
460+ t .Fatalf ("failed to create namespace: %v" , err )
461+ }
462+ ns2 := & corev1.Namespace {ObjectMeta : metav1.ObjectMeta {Name : namespace2 }}
463+ _ , err = clientset .CoreV1 ().Namespaces ().Create (context .Background (), ns2 , metav1.CreateOptions {})
464+ if err != nil {
465+ t .Fatalf ("failed to create namespace: %v" , err )
466+ }
467+ ns3 := & corev1.Namespace {ObjectMeta : metav1.ObjectMeta {Name : namespace3 }}
468+ _ , err = clientset .CoreV1 ().Namespaces ().Create (context .Background (), ns3 , metav1.CreateOptions {})
469+ if err != nil {
470+ t .Fatalf ("failed to create namespace: %v" , err )
471+ }
472+
473+ // Make new deployment in namespace1; expect 1 record
474+ deployment1 := makeDeployment (t , clientset , []metav1.OwnerReference {}, namespace1 , "init-deployment" )
475+ replicaSet1 := makeReplicaSet (t , clientset , []metav1.OwnerReference {{
476+ APIVersion : "apps/v1" ,
477+ Kind : "Deployment" ,
478+ Name : deployment1 .Name ,
479+ UID : deployment1 .UID ,
480+ }}, namespace1 , "init-deployment-abc123" )
481+ _ = makePod (t , clientset , []metav1.OwnerReference {{
482+ APIVersion : "apps/v1" ,
483+ Kind : "ReplicaSet" ,
484+ Name : replicaSet1 .Name ,
485+ UID : replicaSet1 .UID ,
486+ }}, namespace1 , "init-deployment-abc123-1" )
487+ require .Eventually (t , func () bool {
488+ return len (mock .getRecords ()) == 1
489+ }, 3 * time .Second , 100 * time .Millisecond )
490+
491+ // Make new deployment in namespace2; expect no new records
492+ deployment2 := makeDeployment (t , clientset , []metav1.OwnerReference {}, namespace2 , "init-deployment" )
493+ replicaSet2 := makeReplicaSet (t , clientset , []metav1.OwnerReference {{
494+ APIVersion : "apps/v1" ,
495+ Kind : "Deployment" ,
496+ Name : deployment2 .Name ,
497+ UID : deployment2 .UID ,
498+ }}, namespace2 , "init-deployment-abc123" )
499+ _ = makePod (t , clientset , []metav1.OwnerReference {{
500+ APIVersion : "apps/v1" ,
501+ Kind : "ReplicaSet" ,
502+ Name : replicaSet2 .Name ,
503+ UID : replicaSet2 .UID ,
504+ }}, namespace2 , "init-deployment-abc123-1" )
505+
506+ // Make new deployment in namespace 3; expect no new records
507+ deployment3 := makeDeployment (t , clientset , []metav1.OwnerReference {}, namespace3 , "init-deployment" )
508+ replicaSet3 := makeReplicaSet (t , clientset , []metav1.OwnerReference {{
509+ APIVersion : "apps/v1" ,
510+ Kind : "Deployment" ,
511+ Name : deployment3 .Name ,
512+ UID : deployment3 .UID ,
513+ }}, namespace3 , "init-deployment-abc123" )
514+ _ = makePod (t , clientset , []metav1.OwnerReference {{
515+ APIVersion : "apps/v1" ,
516+ Kind : "ReplicaSet" ,
517+ Name : replicaSet3 .Name ,
518+ UID : replicaSet3 .UID ,
519+ }}, namespace3 , "init-deployment-abc123-1" )
520+
521+ require .Never (t , func () bool {
522+ return len (mock .getRecords ()) != 1
523+ }, 3 * time .Second , 100 * time .Millisecond )
385524}
0 commit comments