open-cluster-management.io/governance-policy-propagator@v0.13.0/controllers/common/common_test.go (about) 1 package common 2 3 import ( 4 "reflect" 5 "sort" 6 "testing" 7 8 "github.com/google/go-cmp/cmp" 9 "k8s.io/apimachinery/pkg/types" 10 clusterv1beta1 "open-cluster-management.io/api/cluster/v1beta1" 11 "sigs.k8s.io/controller-runtime/pkg/reconcile" 12 13 policiesv1 "open-cluster-management.io/governance-policy-propagator/api/v1" 14 ) 15 16 func TestParseRootPolicyLabel(t *testing.T) { 17 tests := map[string]struct { 18 name string 19 namespace string 20 shouldErr bool 21 }{ 22 "foobar": {"", "", true}, 23 "foo.bar": {"bar", "foo", false}, 24 "fo.ob.ar": {"ob.ar", "fo", false}, 25 } 26 27 for input, expected := range tests { 28 t.Run(input, func(t *testing.T) { 29 name, namespace, err := ParseRootPolicyLabel(input) 30 if (err != nil) != expected.shouldErr { 31 t.Fatal("expected error, got nil") 32 } 33 if name != expected.name { 34 t.Fatalf("expected name '%v', got '%v'", expected.name, name) 35 } 36 if namespace != expected.namespace { 37 t.Fatalf("expected namespace '%v', got '%v'", expected.namespace, namespace) 38 } 39 }) 40 } 41 } 42 43 func TestGetAffectedObjsWithDecision(t *testing.T) { 44 newOjbs := []clusterv1beta1.ClusterDecision{ 45 {ClusterName: "managed1", Reason: "test11"}, 46 {ClusterName: "managed2", Reason: "test11"}, 47 } 48 oldObjs := []clusterv1beta1.ClusterDecision{ 49 {ClusterName: "managed1", Reason: "test11"}, 50 {ClusterName: "managed3", Reason: "test11"}, 51 } 52 expectedResult := []clusterv1beta1.ClusterDecision{ 53 {ClusterName: "managed2", Reason: "test11"}, 54 {ClusterName: "managed3", Reason: "test11"}, 55 } 56 57 result := GetAffectedObjs(newOjbs, oldObjs) 58 sort.SliceStable(result, func(i, j int) bool { 59 return result[i].ClusterName < result[j].ClusterName 60 }) 61 62 if !cmp.Equal(result, expectedResult) { 63 t.Fatalf(`GetAffectedObjs test failed expected: %+v but result is %+v`, expectedResult, result) 64 } 65 } 66 67 func TestGetAffectedObjsWithRequest(t *testing.T) { 68 newOjbs := []reconcile.Request{ 69 {NamespacedName: types.NamespacedName{Namespace: "test1", Name: "test1"}}, 70 {NamespacedName: types.NamespacedName{Namespace: "test2", Name: "test2"}}, 71 } 72 oldOjbs := []reconcile.Request{ 73 {NamespacedName: types.NamespacedName{Namespace: "test1", Name: "test1"}}, 74 {NamespacedName: types.NamespacedName{Namespace: "test3", Name: "test3"}}, 75 } 76 expectedResult := []reconcile.Request{ 77 {NamespacedName: types.NamespacedName{Namespace: "test2", Name: "test2"}}, 78 {NamespacedName: types.NamespacedName{Namespace: "test3", Name: "test3"}}, 79 } 80 81 result := GetAffectedObjs(newOjbs, oldOjbs) 82 sort.SliceStable(result, func(i, j int) bool { 83 return result[i].NamespacedName.Namespace < result[j].NamespacedName.Namespace 84 }) 85 86 if !cmp.Equal(result, expectedResult) { 87 t.Fatalf(`GetAffectedObjs test failed expected: %+v but result is %+v`, expectedResult, result) 88 } 89 } 90 91 func fakeCPCS(name, compliance string) *policiesv1.CompliancePerClusterStatus { 92 return &policiesv1.CompliancePerClusterStatus{ 93 ComplianceState: policiesv1.ComplianceState(compliance), 94 ClusterName: name, 95 ClusterNamespace: name, 96 } 97 } 98 99 func TestCalculateRootCompliance(t *testing.T) { 100 allCompliantList := []*policiesv1.CompliancePerClusterStatus{ 101 fakeCPCS("articuno", "Compliant"), 102 fakeCPCS("zapdos", "Compliant"), 103 fakeCPCS("moltres", "Compliant"), 104 } 105 106 tests := map[string]struct { 107 input []*policiesv1.CompliancePerClusterStatus 108 want policiesv1.ComplianceState 109 }{ 110 "all compliant": { 111 input: allCompliantList, 112 want: policiesv1.Compliant, 113 }, 114 "one noncompliant": { 115 input: append(allCompliantList, fakeCPCS("foo", "NonCompliant")), 116 want: policiesv1.NonCompliant, 117 }, 118 "one pending": { 119 input: append(allCompliantList, fakeCPCS("bar", "Pending")), 120 want: policiesv1.Pending, 121 }, 122 "one empty": { 123 input: append(allCompliantList, fakeCPCS("thud", "")), 124 want: policiesv1.ComplianceState(""), 125 }, 126 "one odd value": { 127 input: append(allCompliantList, fakeCPCS("wibble", "Discombobulated")), 128 want: policiesv1.ComplianceState(""), 129 }, 130 "noncompliant and pending": { 131 input: append(allCompliantList, 132 fakeCPCS("foo", "NonCompliant"), 133 fakeCPCS("bar", "Pending")), 134 want: policiesv1.NonCompliant, 135 }, 136 "pending and unknown": { 137 input: append(allCompliantList, 138 fakeCPCS("bar", "Pending"), 139 fakeCPCS("thud", "")), 140 want: policiesv1.Pending, 141 }, 142 "all states": { 143 input: append(allCompliantList, 144 fakeCPCS("foo", "NonCompliant"), 145 fakeCPCS("bar", "Pending"), 146 fakeCPCS("thud", ""), 147 fakeCPCS("wibble", "Discombobulated")), 148 want: policiesv1.NonCompliant, 149 }, 150 } 151 152 for name, test := range tests { 153 t.Run(name, func(t *testing.T) { 154 got := CalculateRootCompliance(test.input) 155 if !reflect.DeepEqual(test.want, got) { 156 t.Fatalf("expected: %v, got: %v", test.want, got) 157 } 158 }) 159 } 160 }