Skip to content

Commit 895c0ac

Browse files
committed
Move utility functions around, update tests
Signed-off-by: Anish Asthana <anishasthana1@gmail.com>
1 parent d16ca1f commit 895c0ac

File tree

9 files changed

+260
-50
lines changed

9 files changed

+260
-50
lines changed

config/internal/mcad/rolebinding_custom-metrics-auth-reader.yaml.tmpl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ apiVersion: rbac.authorization.k8s.io/v1
22
kind: RoleBinding
33
metadata:
44
name: {{.Name}}-custom-metrics-auth-reader
5-
namespace: {{.Namespace}}
5+
namespace: kube-system
66
roleRef:
77
apiGroup: rbac.authorization.k8s.io
88
kind: Role

controllers/mcad_controller_test.go

Lines changed: 8 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,14 @@ import (
77
. "github.com/onsi/ginkgo/v2"
88
. "github.com/onsi/gomega"
99
codeflarev1alpha1 "github.com/project-codeflare/codeflare-operator/api/v1alpha1"
10-
"github.com/project-codeflare/codeflare-operator/controllers/testutil"
11-
12-
v1 "k8s.io/api/core/v1"
13-
"k8s.io/apimachinery/pkg/types"
1410
)
1511

1612
const (
17-
mcadCRCase1 = "./testdata/mcad_test_cases/case_1.yaml"
18-
mcadConfigMap1 = "./testdata/mcad_test_results/case_1/configmap.yaml"
13+
mcadCRCase1 = "./testdata/mcad_test_cases/case_1.yaml"
14+
mcadConfigMap1 = "./testdata/mcad_test_results/case_1/configmap.yaml"
15+
mcadRolebinding1 = "./testdata/mcad_test_results/case_1/rolebinding.yaml"
16+
mcadService1 = "./testdata/mcad_test_results/case_1/service.yaml"
17+
mcadServiceAccount1 = "./testdata/mcad_test_results/case_1/serviceaccount.yaml"
1918
)
2019

2120
func deployMCAD(ctx context.Context, path string, opts mf.Option) {
@@ -25,20 +24,6 @@ func deployMCAD(ctx context.Context, path string, opts mf.Option) {
2524
Expect(k8sClient.Create(ctx, mcad)).Should(Succeed())
2625
}
2726

28-
func compareConfigMaps(path string, opts mf.Option) {
29-
expectedConfigMap := &v1.ConfigMap{}
30-
Expect(convertToStructuredResource(path, expectedConfigMap, opts)).NotTo(HaveOccurred())
31-
32-
actualConfigMap := &v1.ConfigMap{}
33-
Eventually(func() error {
34-
namespacedNamed := types.NamespacedName{Name: expectedConfigMap.Name, Namespace: WorkingNamespace}
35-
return k8sClient.Get(ctx, namespacedNamed, actualConfigMap)
36-
}, timeout, interval).ShouldNot(HaveOccurred())
37-
38-
Expect(testutil.ConfigMapsAreEqual(*expectedConfigMap, *actualConfigMap)).Should(BeTrue())
39-
40-
}
41-
4227
var _ = Describe("The MCAD Controller", func() {
4328
client := mfc.NewClient(k8sClient)
4429
opts := mf.UseClient(client)
@@ -49,6 +34,9 @@ var _ = Describe("The MCAD Controller", func() {
4934
It("It should create a configmap", func() {
5035
deployMCAD(ctx, mcadCRCase1, opts)
5136
compareConfigMaps(mcadConfigMap1, opts)
37+
compareRoleBindings(mcadRolebinding1, opts)
38+
compareServiceAccounts(mcadServiceAccount1, opts)
39+
compareServices(mcadService1, opts)
5240
})
5341
})
5442

controllers/multi_cluster_app_dispatcher.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ var multiClusterAppDispatcherTemplates = []string{
1111
"mcad/service.yaml.tmpl",
1212
"mcad/serviceaccount.yaml.tmpl",
1313
"mcad/service.yaml.tmpl",
14-
"mcad/rolebinding_custom-metrics-auth-reader.yaml.tmpl",
14+
"mcad/rolebinding_custom-metrics-auth-reader.yaml.tmpl", //Confirm is this rolebinding is actually required by MCAD
1515
}
1616

1717
func (r *MCADReconciler) ReconcileMCAD(ctx context.Context, mcad *codeflarev1alpha1.MCAD, req ctrl.Request, params *MCADParams) error {

controllers/suite_test.go

Lines changed: 61 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,11 @@ package controllers
1818

1919
import (
2020
"context"
21+
"github.com/project-codeflare/codeflare-operator/controllers/util"
2122
"go.uber.org/zap/zapcore"
23+
corev1 "k8s.io/api/core/v1"
24+
k8srbacv1 "k8s.io/api/rbac/v1"
25+
"k8s.io/apimachinery/pkg/types"
2226
"path/filepath"
2327
"testing"
2428
"time"
@@ -52,7 +56,7 @@ var (
5256
)
5357

5458
const (
55-
WorkingNamespace = "default"
59+
workingNamespace = "default"
5660
timeout = time.Second * 30
5761
interval = time.Millisecond * 10
5862
)
@@ -132,7 +136,7 @@ var _ = AfterSuite(func() {
132136

133137
// Cleanup resources to not contaminate between tests
134138
var _ = AfterEach(func() {
135-
inNamespace := client.InNamespace(WorkingNamespace)
139+
inNamespace := client.InNamespace(workingNamespace)
136140
Expect(k8sClient.DeleteAllOf(context.TODO(), &codeflarev1alpha1.MCAD{}, inNamespace)).ToNot(HaveOccurred())
137141

138142
})
@@ -142,7 +146,7 @@ func convertToStructuredResource(path string, out interface{}, opts mf.Option) e
142146
if err != nil {
143147
return err
144148
}
145-
m, err = m.Transform(mf.InjectNamespace(WorkingNamespace))
149+
m, err = m.Transform(mf.InjectNamespace(workingNamespace))
146150
if err != nil {
147151
return err
148152
}
@@ -155,3 +159,57 @@ func convertToStructuredResource(path string, out interface{}, opts mf.Option) e
155159
}
156160
return nil
157161
}
162+
163+
func compareConfigMaps(path string, opts mf.Option) {
164+
expectedConfigMap := &corev1.ConfigMap{}
165+
Expect(convertToStructuredResource(path, expectedConfigMap, opts)).NotTo(HaveOccurred())
166+
167+
actualConfigMap := &corev1.ConfigMap{}
168+
Eventually(func() error {
169+
namespacedNamed := types.NamespacedName{Name: expectedConfigMap.Name, Namespace: workingNamespace}
170+
return k8sClient.Get(ctx, namespacedNamed, actualConfigMap)
171+
}, timeout, interval).ShouldNot(HaveOccurred())
172+
173+
Expect(util.ConfigMapsAreEqual(*expectedConfigMap, *actualConfigMap)).Should(BeTrue())
174+
}
175+
176+
func compareRoleBindings(path string, opts mf.Option) {
177+
expectedRB := &k8srbacv1.RoleBinding{}
178+
Expect(convertToStructuredResource(path, expectedRB, opts)).NotTo(HaveOccurred())
179+
expectedRB.Subjects[0].Namespace = workingNamespace
180+
181+
actualRB := &k8srbacv1.RoleBinding{}
182+
Eventually(func() error {
183+
namespacedNamed := types.NamespacedName{Name: expectedRB.Name, Namespace: workingNamespace}
184+
return k8sClient.Get(ctx, namespacedNamed, actualRB)
185+
}, timeout, interval).ShouldNot(HaveOccurred())
186+
187+
Expect(util.RoleBindingsAreEqual(*expectedRB, *actualRB)).Should(BeTrue())
188+
}
189+
190+
func compareServiceAccounts(path string, opts mf.Option) {
191+
expectedSA := &corev1.ServiceAccount{}
192+
Expect(convertToStructuredResource(path, expectedSA, opts)).NotTo(HaveOccurred())
193+
expectedSA.Namespace = workingNamespace
194+
195+
actualSA := &corev1.ServiceAccount{}
196+
Eventually(func() error {
197+
namespacedNamed := types.NamespacedName{Name: expectedSA.Name, Namespace: workingNamespace}
198+
return k8sClient.Get(ctx, namespacedNamed, actualSA)
199+
}, timeout, interval).ShouldNot(HaveOccurred())
200+
201+
Expect(util.ServiceAccountsAreEqual(*expectedSA, *actualSA)).Should(BeTrue())
202+
}
203+
204+
func compareServices(path string, opts mf.Option) {
205+
expectedService := &corev1.Service{}
206+
Expect(convertToStructuredResource(path, expectedService, opts)).NotTo(HaveOccurred())
207+
208+
actualService := &corev1.Service{}
209+
Eventually(func() error {
210+
namespacedNamed := types.NamespacedName{Name: expectedService.Name, Namespace: workingNamespace}
211+
return k8sClient.Get(ctx, namespacedNamed, actualService)
212+
}, timeout, interval).ShouldNot(HaveOccurred())
213+
214+
Expect(util.ServicesAreEqual(*expectedService, *actualService)).Should(BeTrue())
215+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
kind: RoleBinding
2+
apiVersion: rbac.authorization.k8s.io/v1
3+
metadata:
4+
name: blank-custom-resource-custom-metrics-auth-reader
5+
namespace: default
6+
subjects:
7+
- kind: ServiceAccount
8+
name: mcad-controller-blank-custom-resource
9+
namespace: default
10+
roleRef:
11+
apiGroup: rbac.authorization.k8s.io
12+
kind: Role
13+
name: extension-apiserver-authentication-reader
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
kind: Service
2+
apiVersion: v1
3+
metadata:
4+
name: mcad-blank-custom-resource-metrics
5+
namespace: default
6+
spec:
7+
clusterIP: 172.31.181.101
8+
ipFamilies:
9+
- IPv4
10+
ports:
11+
- name: https
12+
protocol: TCP
13+
port: 443
14+
targetPort: 6443
15+
- name: http
16+
protocol: TCP
17+
port: 80
18+
targetPort: 8080
19+
internalTrafficPolicy: Cluster
20+
clusterIPs:
21+
- 172.31.181.101
22+
type: ClusterIP
23+
ipFamilyPolicy: SingleStack
24+
sessionAffinity: None
25+
selector:
26+
app: mcad-blank-custom-resource
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
kind: ServiceAccount
2+
apiVersion: v1
3+
metadata:
4+
name: mcad-controller-blank-custom-resource
5+
namespace: default

controllers/testutil/utils.go

Lines changed: 0 additions & 25 deletions
This file was deleted.

controllers/util/util.go

Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
package util
2+
3+
import (
4+
"fmt"
5+
appsv1 "k8s.io/api/apps/v1"
6+
corev1 "k8s.io/api/core/v1"
7+
k8srbacv1 "k8s.io/api/rbac/v1"
8+
"reflect"
9+
)
10+
11+
func notEqualMsg(value string) {
12+
print(fmt.Sprintf("%s are not equal.", value))
13+
}
14+
15+
func ConfigMapsAreEqual(expected corev1.ConfigMap, actual corev1.ConfigMap) bool {
16+
if expected.Name != actual.Name {
17+
notEqualMsg("Configmap Names")
18+
return false
19+
}
20+
21+
if !reflect.DeepEqual(expected.Data, actual.Data) {
22+
notEqualMsg("Configmap Data values")
23+
return false
24+
}
25+
return true
26+
}
27+
28+
func RoleBindingsAreEqual(rb1 k8srbacv1.RoleBinding, rb2 k8srbacv1.RoleBinding) bool {
29+
30+
if !reflect.DeepEqual(rb1.ObjectMeta.Labels, rb2.ObjectMeta.Labels) {
31+
notEqualMsg("Rolebinding labels")
32+
return false
33+
}
34+
if !reflect.DeepEqual(rb1.Subjects, rb2.Subjects) {
35+
notEqualMsg("Rolebinding subjects")
36+
return false
37+
}
38+
if !reflect.DeepEqual(rb1.RoleRef, rb2.RoleRef) {
39+
notEqualMsg("Rolebinding role references")
40+
return false
41+
}
42+
return true
43+
}
44+
45+
func ServiceAccountsAreEqual(sa1 corev1.ServiceAccount, sa2 corev1.ServiceAccount) bool {
46+
if !reflect.DeepEqual(sa1.ObjectMeta.Labels, sa2.ObjectMeta.Labels) {
47+
notEqualMsg("ServiceAccount labels")
48+
return false
49+
}
50+
if !reflect.DeepEqual(sa1.Name, sa2.Name) {
51+
notEqualMsg("ServiceAccount names")
52+
return false
53+
}
54+
if !reflect.DeepEqual(sa1.Namespace, sa2.Namespace) {
55+
notEqualMsg("ServiceAccount namespaces")
56+
return false
57+
}
58+
return true
59+
}
60+
61+
func ServicesAreEqual(service1 corev1.Service, service2 corev1.Service) bool {
62+
if !reflect.DeepEqual(service1.ObjectMeta.Labels, service2.ObjectMeta.Labels) {
63+
notEqualMsg("Service labels")
64+
return false
65+
}
66+
if !reflect.DeepEqual(service1.Name, service2.Name) {
67+
notEqualMsg("Service Names")
68+
return false
69+
}
70+
if !reflect.DeepEqual(service1.Namespace, service2.Namespace) {
71+
notEqualMsg("Service namespaces")
72+
return false
73+
}
74+
if !reflect.DeepEqual(service1.Spec.Selector, service2.Spec.Selector) {
75+
notEqualMsg("Service Selectors")
76+
return false
77+
}
78+
if !reflect.DeepEqual(service1.Spec.Ports, service2.Spec.Ports) {
79+
notEqualMsg("Service Ports")
80+
return false
81+
}
82+
return true
83+
}
84+
85+
func DeploymentsAreEqual(dp1 appsv1.Deployment, dp2 appsv1.Deployment) bool {
86+
87+
if !reflect.DeepEqual(dp1.ObjectMeta.Labels, dp2.ObjectMeta.Labels) {
88+
notEqualMsg("labels")
89+
return false
90+
}
91+
92+
if !reflect.DeepEqual(dp1.Spec.Selector, dp2.Spec.Selector) {
93+
notEqualMsg("selector")
94+
return false
95+
}
96+
97+
if !reflect.DeepEqual(dp1.Spec.Template.ObjectMeta, dp2.Spec.Template.ObjectMeta) {
98+
notEqualMsg("selector")
99+
return false
100+
}
101+
102+
if !reflect.DeepEqual(dp1.Spec.Template.Spec.Volumes, dp2.Spec.Template.Spec.Volumes) {
103+
notEqualMsg("Volumes")
104+
return false
105+
}
106+
107+
if len(dp1.Spec.Template.Spec.Containers) != len(dp2.Spec.Template.Spec.Containers) {
108+
notEqualMsg("Containers")
109+
return false
110+
}
111+
for i := range dp1.Spec.Template.Spec.Containers {
112+
c1 := dp1.Spec.Template.Spec.Containers[i]
113+
c2 := dp2.Spec.Template.Spec.Containers[i]
114+
if !reflect.DeepEqual(c1.Env, c2.Env) {
115+
notEqualMsg("Container Env")
116+
return false
117+
}
118+
if !reflect.DeepEqual(c1.Ports, c2.Ports) {
119+
notEqualMsg("Container Ports")
120+
return false
121+
}
122+
if !reflect.DeepEqual(c1.Resources, c2.Resources) {
123+
notEqualMsg("Container Resources")
124+
return false
125+
}
126+
if !reflect.DeepEqual(c1.VolumeMounts, c2.VolumeMounts) {
127+
notEqualMsg("Container VolumeMounts")
128+
return false
129+
}
130+
if !reflect.DeepEqual(c1.Args, c2.Args) {
131+
notEqualMsg("Container Args")
132+
return false
133+
}
134+
if c1.Name != c2.Name {
135+
notEqualMsg("Container Name")
136+
return false
137+
}
138+
if c1.Image != c2.Image {
139+
notEqualMsg("Container Image")
140+
return false
141+
}
142+
}
143+
144+
return true
145+
}

0 commit comments

Comments
 (0)