Skip to content

Commit 56685ca

Browse files
committed
Add unit tests for shardlease controller
1 parent eb5b79c commit 56685ca

File tree

2 files changed

+149
-0
lines changed

2 files changed

+149
-0
lines changed
Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
/*
2+
Copyright 2025 Tim Ebert.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package shardlease_test
18+
19+
import (
20+
"time"
21+
22+
. "github.com/onsi/ginkgo/v2"
23+
. "github.com/onsi/gomega"
24+
coordinationv1 "k8s.io/api/coordination/v1"
25+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
26+
"k8s.io/utils/clock/testing"
27+
"k8s.io/utils/ptr"
28+
"sigs.k8s.io/controller-runtime/pkg/event"
29+
"sigs.k8s.io/controller-runtime/pkg/predicate"
30+
31+
. "github.com/timebertt/kubernetes-controller-sharding/pkg/controller/shardlease"
32+
"github.com/timebertt/kubernetes-controller-sharding/pkg/sharding/leases"
33+
)
34+
35+
var _ = Describe("Reconciler", func() {
36+
var r *Reconciler
37+
38+
BeforeEach(func() {
39+
r = &Reconciler{}
40+
})
41+
42+
Describe("#LeasePredicate", func() {
43+
var (
44+
p predicate.Predicate
45+
obj, objOld *coordinationv1.Lease
46+
47+
fakeClock *testing.FakePassiveClock
48+
)
49+
50+
BeforeEach(func() {
51+
fakeClock = testing.NewFakePassiveClock(time.Now())
52+
r.Clock = fakeClock
53+
54+
p = r.LeasePredicate()
55+
56+
obj = &coordinationv1.Lease{
57+
ObjectMeta: metav1.ObjectMeta{
58+
Name: "foo-0",
59+
},
60+
Spec: coordinationv1.LeaseSpec{
61+
HolderIdentity: ptr.To("foo-0"),
62+
LeaseDurationSeconds: ptr.To[int32](10),
63+
AcquireTime: ptr.To(metav1.NewMicroTime(fakeClock.Now().Add(-5 * time.Minute))),
64+
RenewTime: ptr.To(metav1.NewMicroTime(fakeClock.Now().Add(-2 * time.Second))),
65+
},
66+
}
67+
metav1.SetMetaDataLabel(&obj.ObjectMeta, "alpha.sharding.timebertt.dev/controllerring", "foo")
68+
objOld = obj.DeepCopy()
69+
})
70+
71+
It("should ignore leases with empty label", func() {
72+
metav1.SetMetaDataLabel(&obj.ObjectMeta, "alpha.sharding.timebertt.dev/controllerring", "")
73+
objOld = obj.DeepCopy()
74+
75+
Expect(p.Create(event.CreateEvent{Object: obj})).To(BeFalse())
76+
Expect(p.Update(event.UpdateEvent{ObjectOld: objOld, ObjectNew: obj})).To(BeFalse())
77+
Expect(p.Delete(event.DeleteEvent{Object: obj})).To(BeFalse())
78+
})
79+
80+
It("should react on create events for unavailable leases", func() {
81+
obj.Spec.HolderIdentity = nil
82+
Expect(p.Create(event.CreateEvent{Object: obj})).To(BeTrue())
83+
})
84+
85+
It("should react on create events for available leases", func() {
86+
Expect(p.Create(event.CreateEvent{Object: obj})).To(BeTrue())
87+
})
88+
89+
It("should react when shard state changed to available", func() {
90+
objOld.Spec.HolderIdentity = nil
91+
Expect(p.Update(event.UpdateEvent{ObjectOld: objOld, ObjectNew: obj})).To(BeTrue())
92+
})
93+
94+
It("should react when shard state changed to unavailable", func() {
95+
obj.Spec.HolderIdentity = nil
96+
Expect(p.Update(event.UpdateEvent{ObjectOld: objOld, ObjectNew: obj})).To(BeTrue())
97+
})
98+
99+
It("should react when shard state changed while still being available", func() {
100+
obj.Spec.RenewTime = ptr.To(metav1.NewMicroTime(fakeClock.Now().Add(-time.Duration(*obj.Spec.LeaseDurationSeconds+1) * time.Second)))
101+
102+
Expect(leases.ToState(objOld, fakeClock.Now())).To(Equal(leases.Ready))
103+
Expect(leases.ToState(obj, fakeClock.Now())).To(Equal(leases.Expired))
104+
105+
Expect(p.Update(event.UpdateEvent{ObjectOld: objOld, ObjectNew: obj})).To(BeTrue())
106+
})
107+
108+
It("should ignore when shard state hasn't changed", func() {
109+
Expect(p.Update(event.UpdateEvent{ObjectOld: objOld, ObjectNew: obj})).To(BeFalse())
110+
111+
obj.Spec.HolderIdentity = nil
112+
objOld.Spec.HolderIdentity = nil
113+
Expect(p.Update(event.UpdateEvent{ObjectOld: objOld, ObjectNew: obj})).To(BeFalse())
114+
})
115+
116+
It("should ignore delete events", func() {
117+
Expect(p.Delete(event.DeleteEvent{Object: obj})).To(BeFalse())
118+
})
119+
})
120+
})
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
/*
2+
Copyright 2025 Tim Ebert.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package shardlease_test
18+
19+
import (
20+
"testing"
21+
22+
. "github.com/onsi/ginkgo/v2"
23+
. "github.com/onsi/gomega"
24+
)
25+
26+
func TestShardLease(t *testing.T) {
27+
RegisterFailHandler(Fail)
28+
RunSpecs(t, "Shard Lease Controller Suite")
29+
}

0 commit comments

Comments
 (0)