@@ -13,9 +13,13 @@ import (
1313 "github.com/stretchr/testify/require"
1414 v1 "k8s.io/api/coordination/v1"
1515 corev1 "k8s.io/api/core/v1"
16+ policyv1 "k8s.io/api/policy/v1"
17+ policyv1beta1 "k8s.io/api/policy/v1beta1"
1618 storagev1 "k8s.io/api/storage/v1"
1719 apixfake "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/fake"
1820 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
21+ "k8s.io/apimachinery/pkg/util/intstr"
22+ fakediscovery "k8s.io/client-go/discovery/fake"
1923 testdynamicclient "k8s.io/client-go/dynamic/fake"
2024 "k8s.io/client-go/kubernetes"
2125 testclient "k8s.io/client-go/kubernetes/fake"
@@ -523,3 +527,173 @@ func fromJSON(t *testing.T, dat []byte) troubleshootv1beta2.SupportBundle {
523527 require .Equal (t , 1 , len (sb ))
524528 return sb [0 ]
525529}
530+
531+ func Test_getPodDisruptionBudgets (t * testing.T ) {
532+ tests := []struct {
533+ name string
534+ pdbNames []string
535+ namespaces []string
536+ }{
537+ {
538+ name : "single namespace" ,
539+ pdbNames : []string {"test-pdb" },
540+ namespaces : []string {"default" },
541+ },
542+ {
543+ name : "multiple namespaces" ,
544+ pdbNames : []string {"test-pdb" },
545+ namespaces : []string {"default" , "test" },
546+ },
547+ {
548+ name : "multiple pdbs in different namespaces" ,
549+ pdbNames : []string {"test-pdb" , "another-pdb" },
550+ namespaces : []string {"default" , "test" },
551+ },
552+ }
553+ for _ , tt := range tests {
554+ t .Run (tt .name , func (t * testing.T ) {
555+ client := testclient .NewClientset ()
556+ ctx := context .Background ()
557+ err := createTestPodDisruptionBudgets (client , tt .pdbNames , tt .namespaces )
558+ assert .NoError (t , err )
559+
560+ fakeDiscovery , ok := client .Discovery ().(* fakediscovery.FakeDiscovery )
561+ if ! ok {
562+ t .Fatalf ("could not convert Discovery() to *FakeDiscovery" )
563+ }
564+ fakeDiscovery .Resources = []* metav1.APIResourceList {
565+ {
566+ GroupVersion : "policy/v1" ,
567+ APIResources : []metav1.APIResource {
568+ {
569+ Kind : "PodDisruptionBudget" ,
570+ },
571+ },
572+ },
573+ }
574+
575+ pdbs , errors := getPodDisruptionBudgets (ctx , client , tt .namespaces )
576+ assert .Empty (t , errors )
577+ assert .Equal (t , len (tt .namespaces ), len (pdbs ))
578+
579+ for _ , ns := range tt .namespaces {
580+ assert .NotEmpty (t , pdbs [ns + ".json" ])
581+ var pdbList policyv1.PodDisruptionBudgetList
582+ err := json .Unmarshal (pdbs [ns + ".json" ], & pdbList )
583+ assert .NoError (t , err )
584+ assert .Equal (t , len (tt .pdbNames ), len (pdbList .Items ))
585+ for _ , pdb := range pdbList .Items {
586+ assert .Contains (t , tt .pdbNames , pdb .ObjectMeta .Name )
587+ }
588+ }
589+ })
590+ }
591+ }
592+
593+ func Test_getPodDisruptionBudgets_v1beta1 (t * testing.T ) {
594+ tests := []struct {
595+ name string
596+ pdbNames []string
597+ namespaces []string
598+ }{
599+ {
600+ name : "single namespace v1beta1" ,
601+ pdbNames : []string {"test-pdb-beta" },
602+ namespaces : []string {"default" },
603+ },
604+ {
605+ name : "multiple namespaces v1beta1" ,
606+ pdbNames : []string {"test-pdb-beta" },
607+ namespaces : []string {"default" , "test" },
608+ },
609+ }
610+ for _ , tt := range tests {
611+ t .Run (tt .name , func (t * testing.T ) {
612+ client := testclient .NewClientset ()
613+ ctx := context .Background ()
614+ err := createTestPodDisruptionBudgetsV1beta1 (client , tt .pdbNames , tt .namespaces )
615+ assert .NoError (t , err )
616+
617+ fakeDiscovery , ok := client .Discovery ().(* fakediscovery.FakeDiscovery )
618+ if ! ok {
619+ t .Fatalf ("could not convert Discovery() to *FakeDiscovery" )
620+ }
621+ // Mock discovery to only have v1beta1 PodDisruptionBudget
622+ fakeDiscovery .Resources = []* metav1.APIResourceList {
623+ {
624+ GroupVersion : "policy/v1beta1" ,
625+ APIResources : []metav1.APIResource {
626+ {
627+ Kind : "PodDisruptionBudget" ,
628+ },
629+ },
630+ },
631+ }
632+
633+ pdbs , errors := getPodDisruptionBudgets (ctx , client , tt .namespaces )
634+ assert .Empty (t , errors )
635+ assert .Equal (t , len (tt .namespaces ), len (pdbs ))
636+
637+ for _ , ns := range tt .namespaces {
638+ assert .NotEmpty (t , pdbs [ns + ".json" ])
639+ var pdbList policyv1beta1.PodDisruptionBudgetList
640+ err := json .Unmarshal (pdbs [ns + ".json" ], & pdbList )
641+ assert .NoError (t , err )
642+ assert .Equal (t , len (tt .pdbNames ), len (pdbList .Items ))
643+ for _ , pdb := range pdbList .Items {
644+ assert .Contains (t , tt .pdbNames , pdb .ObjectMeta .Name )
645+ }
646+ }
647+ })
648+ }
649+ }
650+
651+ func createTestPodDisruptionBudgets (client kubernetes.Interface , pdbNames []string , namespaces []string ) error {
652+ for _ , ns := range namespaces {
653+ for _ , pdbName := range pdbNames {
654+ minAvailable := intstr .FromInt32 (1 )
655+ _ , err := client .PolicyV1 ().PodDisruptionBudgets (ns ).Create (context .Background (), & policyv1.PodDisruptionBudget {
656+ ObjectMeta : metav1.ObjectMeta {
657+ Name : pdbName ,
658+ },
659+ Spec : policyv1.PodDisruptionBudgetSpec {
660+ MinAvailable : & minAvailable ,
661+ Selector : & metav1.LabelSelector {
662+ MatchLabels : map [string ]string {
663+ "app" : "test-app" ,
664+ },
665+ },
666+ },
667+ }, metav1.CreateOptions {})
668+ if err != nil {
669+ return err
670+ }
671+ }
672+ }
673+ return nil
674+ }
675+
676+ func createTestPodDisruptionBudgetsV1beta1 (client kubernetes.Interface , pdbNames []string , namespaces []string ) error {
677+ for _ , ns := range namespaces {
678+ for _ , pdbName := range pdbNames {
679+ minAvailable := intstr .FromInt32 (1 )
680+ _ , err := client .PolicyV1beta1 ().PodDisruptionBudgets (ns ).Create (context .Background (), & policyv1beta1.PodDisruptionBudget {
681+ ObjectMeta : metav1.ObjectMeta {
682+ Name : pdbName ,
683+ },
684+ Spec : policyv1beta1.PodDisruptionBudgetSpec {
685+ MinAvailable : & minAvailable ,
686+ Selector : & metav1.LabelSelector {
687+ MatchLabels : map [string ]string {
688+ "app" : "test-app" ,
689+ },
690+ },
691+ },
692+ }, metav1.CreateOptions {})
693+ if err != nil {
694+ return err
695+ }
696+ }
697+ }
698+ return nil
699+ }
0 commit comments