Skip to content

Commit 3228060

Browse files
committed
Add tests for SetControllerReference
1 parent f06d7fa commit 3228060

File tree

2 files changed

+57
-2
lines changed

2 files changed

+57
-2
lines changed

pkg/controller/controllerutil/controllerutil.go

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@ import (
2828
// SetControllerReference sets owner as a Controller OwnerReference on owned.
2929
// This is used for garbage collection of the owned object and for
3030
// reconciling the owner object on changes to owned (with a Watch + EnqueueRequestForOwner).
31+
// Since only one OwnerRecerence can be a controller, it returns an error if
32+
// there is another OwnerReference with Controller flag set.
3133
func SetControllerReference(owner, object v1.Object, scheme *runtime.Scheme) error {
3234
ro, ok := owner.(runtime.Object)
3335
if !ok {
@@ -50,9 +52,10 @@ func SetControllerReference(owner, object v1.Object, scheme *runtime.Scheme) err
5052
existingRefs := object.GetOwnerReferences()
5153
fi := -1
5254
for i, r := range existingRefs {
53-
if r.Kind == gvk.Kind && r.Name == owner.GetName() {
55+
if r.Kind == gvk.Kind && r.Name == owner.GetName() && r.UID == owner.GetUID() {
5456
fi = i
55-
break
57+
} else if r.Controller != nil && *r.Controller {
58+
return fmt.Errorf("Object %s/%s is already owned by another %s controller %s", object.GetNamespace(), object.GetName(), r.Kind, r.Name)
5659
}
5760
}
5861
if fi == -1 {

pkg/controller/controllerutil/controllerutil_test.go

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,58 @@ var _ = Describe("Controllerutil", func() {
4343
rs := &appsv1.ReplicaSet{}
4444
Expect(controllerutil.SetControllerReference(&errMetaObj{}, rs, scheme.Scheme)).To(HaveOccurred())
4545
})
46+
47+
It("should return an error if object and owner are not in the same namespace", func() {
48+
rs := &appsv1.ReplicaSet{ObjectMeta: metav1.ObjectMeta{Name: "foo", Namespace: "one"}}
49+
dep := &extensionsv1beta1.Deployment{ObjectMeta: metav1.ObjectMeta{Name: "foo", Namespace: "two"}}
50+
51+
Expect(controllerutil.SetControllerReference(dep, rs, scheme.Scheme)).To(HaveOccurred())
52+
})
53+
54+
It("should return an error if object is already owned by another controller", func() {
55+
t := true
56+
rsOwners := []metav1.OwnerReference{
57+
metav1.OwnerReference{
58+
Name: "foo",
59+
Kind: "Deployment",
60+
APIVersion: "extensions/v1beta1",
61+
UID: "bar-uid",
62+
Controller: &t,
63+
BlockOwnerDeletion: &t,
64+
},
65+
}
66+
rs := &appsv1.ReplicaSet{ObjectMeta: metav1.ObjectMeta{Name: "foo", Namespace: "default", OwnerReferences: rsOwners}}
67+
dep := &extensionsv1beta1.Deployment{ObjectMeta: metav1.ObjectMeta{Name: "foo", Namespace: "default", UID: "foo-uid"}}
68+
69+
Expect(controllerutil.SetControllerReference(dep, rs, scheme.Scheme)).To(HaveOccurred())
70+
})
71+
72+
It("should not duplicate existing owner reference", func() {
73+
f := false
74+
t := true
75+
rsOwners := []metav1.OwnerReference{
76+
metav1.OwnerReference{
77+
Name: "foo",
78+
Kind: "Deployment",
79+
APIVersion: "extensions/v1beta1",
80+
UID: "foo-uid",
81+
Controller: &f,
82+
BlockOwnerDeletion: &t,
83+
},
84+
}
85+
rs := &appsv1.ReplicaSet{ObjectMeta: metav1.ObjectMeta{Name: "foo", Namespace: "default", OwnerReferences: rsOwners}}
86+
dep := &extensionsv1beta1.Deployment{ObjectMeta: metav1.ObjectMeta{Name: "foo", Namespace: "default", UID: "foo-uid"}}
87+
88+
Expect(controllerutil.SetControllerReference(dep, rs, scheme.Scheme)).NotTo(HaveOccurred())
89+
Expect(rs.OwnerReferences).To(ConsistOf(metav1.OwnerReference{
90+
Name: "foo",
91+
Kind: "Deployment",
92+
APIVersion: "extensions/v1beta1",
93+
UID: "foo-uid",
94+
Controller: &t,
95+
BlockOwnerDeletion: &t,
96+
}))
97+
})
4698
})
4799
})
48100

0 commit comments

Comments
 (0)