Skip to content

Commit b1e2d6c

Browse files
committed
Add unit tests for the new events API
Signed-off-by: Borja Clemente <[email protected]>
1 parent 907a6de commit b1e2d6c

File tree

5 files changed

+98
-24
lines changed

5 files changed

+98
-24
lines changed

pkg/cluster/cluster_test.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,12 @@ var _ = Describe("cluster.Cluster", func() {
155155
})
156156

157157
It("should provide a function to get the EventRecorder", func() {
158+
c, err := New(cfg)
159+
Expect(err).NotTo(HaveOccurred())
160+
Expect(c.GetEventRecorder("test")).NotTo(BeNil())
161+
})
162+
163+
It("should provide a function to get the deprecated EventRecorder", func() {
158164
c, err := New(cfg)
159165
Expect(err).NotTo(HaveOccurred())
160166
Expect(c.GetEventRecorderFor("test")).NotTo(BeNil()) //nolint:staticcheck

pkg/internal/recorder/recorder.go

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -104,16 +104,12 @@ func (p *Provider) getBroadcaster() (record.EventBroadcaster, events.EventBroadc
104104
p.broadcasterOnce.Do(func() {
105105
p.deprecatedBroadcaster, p.broadcaster, p.stopBroadcaster = p.makeBroadcaster()
106106

107-
// init old broadcaster
107+
// init deprecated broadcaster (new broadcaster does not need to be initialised)
108108
p.deprecatedBroadcaster.StartRecordingToSink(&corev1client.EventSinkImpl{Interface: p.evtClient})
109109
p.deprecatedBroadcaster.StartEventWatcher(
110110
func(e *corev1.Event) {
111111
p.logger.V(1).Info(e.Message, "type", e.Type, "object", e.InvolvedObject, "reason", e.Reason)
112112
})
113-
114-
// init new broadcaster
115-
// TODO(clebs): figure out how to manage the context/channel that StartRecordingToSink needs inside the provider.
116-
_ = p.broadcaster.StartRecordingToSinkWithContext(context.TODO())
117113
})
118114

119115
return p.deprecatedBroadcaster, p.broadcaster

pkg/internal/recorder/recorder_test.go

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -28,16 +28,9 @@ import (
2828
)
2929

3030
var _ = Describe("recorder.Provider", func() {
31-
evtCl, err := eventsv1client.NewForConfigAndClient(cfg, httpClient)
32-
Expect(err).NotTo(HaveOccurred())
33-
34-
makeBroadcaster := func() (record.EventBroadcaster, events.EventBroadcaster, bool) {
35-
return record.NewBroadcaster(), events.NewBroadcaster(&events.EventSinkImpl{Interface: evtCl}), true
36-
}
37-
3831
Describe("NewProvider", func() {
3932
It("should return a provider instance and a nil error.", func() {
40-
provider, err := recorder.NewProvider(cfg, httpClient, scheme.Scheme, logr.Discard(), makeBroadcaster)
33+
provider, err := recorder.NewProvider(cfg, httpClient, scheme.Scheme, logr.Discard(), makeBroadcaster())
4134
Expect(provider).NotTo(BeNil())
4235
Expect(err).NotTo(HaveOccurred())
4336
})
@@ -46,18 +39,36 @@ var _ = Describe("recorder.Provider", func() {
4639
// Invalid the config
4740
cfg1 := *cfg
4841
cfg1.Host = "invalid host"
49-
_, err := recorder.NewProvider(&cfg1, httpClient, scheme.Scheme, logr.Discard(), makeBroadcaster)
42+
_, err := recorder.NewProvider(&cfg1, httpClient, scheme.Scheme, logr.Discard(), makeBroadcaster())
5043
Expect(err).To(HaveOccurred())
5144
Expect(err.Error()).To(ContainSubstring("failed to init client"))
5245
})
5346
})
5447
Describe("GetEventRecorderFor", func() {
55-
It("should return a recorder instance.", func() {
56-
provider, err := recorder.NewProvider(cfg, httpClient, scheme.Scheme, logr.Discard(), makeBroadcaster)
48+
It("should return a deprecated recorder instance.", func() {
49+
provider, err := recorder.NewProvider(cfg, httpClient, scheme.Scheme, logr.Discard(), makeBroadcaster())
5750
Expect(err).NotTo(HaveOccurred())
5851

5952
recorder := provider.GetEventRecorderFor("test")
6053
Expect(recorder).NotTo(BeNil())
6154
})
6255
})
56+
Describe("GetEventRecorder", func() {
57+
It("should return a recorder instance.", func() {
58+
provider, err := recorder.NewProvider(cfg, httpClient, scheme.Scheme, logr.Discard(), makeBroadcaster())
59+
Expect(err).NotTo(HaveOccurred())
60+
61+
recorder := provider.GetEventRecorder("test")
62+
Expect(recorder).NotTo(BeNil())
63+
})
64+
})
6365
})
66+
67+
func makeBroadcaster() func() (record.EventBroadcaster, events.EventBroadcaster, bool) {
68+
evtCl, err := eventsv1client.NewForConfigAndClient(cfg, httpClient)
69+
Expect(err).NotTo(HaveOccurred())
70+
71+
return func() (record.EventBroadcaster, events.EventBroadcaster, bool) {
72+
return record.NewBroadcaster(), events.NewBroadcaster(&events.EventSinkImpl{Interface: evtCl}), true
73+
}
74+
}

pkg/manager/manager_test.go

Lines changed: 55 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1804,7 +1804,7 @@ var _ = Describe("manger.Manager", func() {
18041804
Eventually(func() error { return goleak.Find(currentGRs) }).Should(Succeed())
18051805
})
18061806

1807-
It("should not leak goroutines if the default event broadcaster is used & events are emitted", func(specCtx SpecContext) {
1807+
It("should not leak goroutines if the deprecated event broadcaster is used & events are emitted", func(specCtx SpecContext) {
18081808
currentGRs := goleak.IgnoreCurrent()
18091809

18101810
m, err := New(cfg, Options{ /* implicit: default setting for EventBroadcaster */ })
@@ -1852,6 +1852,54 @@ var _ = Describe("manger.Manager", func() {
18521852
Eventually(func() error { return goleak.Find(currentGRs) }).Should(Succeed())
18531853
})
18541854

1855+
It("should not leak goroutines if the default event broadcaster is used & events are emitted", func(specCtx SpecContext) {
1856+
currentGRs := goleak.IgnoreCurrent()
1857+
1858+
m, err := New(cfg, Options{ /* implicit: default setting for EventBroadcaster */ })
1859+
Expect(err).NotTo(HaveOccurred())
1860+
1861+
By("adding a runnable that emits an event")
1862+
ns := corev1.Namespace{}
1863+
ns.Name = "default"
1864+
1865+
recorder := m.GetEventRecorder("rock-and-roll")
1866+
Expect(m.Add(RunnableFunc(func(_ context.Context) error {
1867+
recorder.Eventf(&ns, nil, "Warning", "BallroomBlitz", "dance action", "yeah, yeah, yeah-yeah-yeah")
1868+
return nil
1869+
}))).To(Succeed())
1870+
1871+
By("starting the manager & waiting till we've sent our event")
1872+
ctx, cancel := context.WithCancel(specCtx)
1873+
doneCh := make(chan struct{})
1874+
go func() {
1875+
defer GinkgoRecover()
1876+
defer close(doneCh)
1877+
Expect(m.Start(ctx)).To(Succeed())
1878+
}()
1879+
<-m.Elected()
1880+
1881+
Eventually(func() *corev1.Event {
1882+
evts, err := clientset.CoreV1().Events("").SearchWithContext(ctx, m.GetScheme(), &ns)
1883+
Expect(err).NotTo(HaveOccurred())
1884+
1885+
for i, evt := range evts.Items {
1886+
if evt.Reason == "BallroomBlitz" {
1887+
return &evts.Items[i]
1888+
}
1889+
}
1890+
return nil
1891+
}).ShouldNot(BeNil())
1892+
1893+
By("making sure there's no extra go routines still running after we stop")
1894+
cancel()
1895+
<-doneCh
1896+
1897+
// force-close keep-alive connections. These'll time anyway (after
1898+
// like 30s or so) but force it to speed up the tests.
1899+
clientTransport.CloseIdleConnections()
1900+
Eventually(func() error { return goleak.Find(currentGRs) }).Should(Succeed())
1901+
})
1902+
18551903
It("should not leak goroutines when a runnable returns error slowly after being signaled to stop", func(specCtx SpecContext) {
18561904
// This test reproduces the race condition where the manager's Start method
18571905
// exits due to context cancellation, leaving no one to drain errChan
@@ -1932,11 +1980,16 @@ var _ = Describe("manger.Manager", func() {
19321980
Expect(m.GetFieldIndexer()).To(Equal(mgr.cluster.GetFieldIndexer()))
19331981
})
19341982

1935-
It("should provide a function to get the EventRecorder", func() {
1983+
It("should provide a function to get the deprecated EventRecorder", func() {
19361984
m, err := New(cfg, Options{})
19371985
Expect(err).NotTo(HaveOccurred())
19381986
Expect(m.GetEventRecorderFor("test")).NotTo(BeNil()) //nolint:staticcheck
19391987
})
1988+
It("should provide a function to get the EventRecorder", func() {
1989+
m, err := New(cfg, Options{})
1990+
Expect(err).NotTo(HaveOccurred())
1991+
Expect(m.GetEventRecorder("test")).NotTo(BeNil())
1992+
})
19401993
It("should provide a function to get the APIReader", func() {
19411994
m, err := New(cfg, Options{})
19421995
Expect(err).NotTo(HaveOccurred())

pkg/recorder/example_test.go

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,31 +18,39 @@ package recorder_test
1818

1919
import (
2020
corev1 "k8s.io/api/core/v1"
21+
"k8s.io/apimachinery/pkg/runtime"
2122

2223
_ "github.com/onsi/ginkgo/v2"
2324
"sigs.k8s.io/controller-runtime/pkg/recorder"
2425
)
2526

2627
var (
27-
recorderProvider recorder.Provider
28-
somePod *corev1.Pod // the object you're reconciling, for example
28+
recorderProvider recorder.Provider
29+
somePod *corev1.Pod // the object you're reconciling, for example
30+
someRelatedObject runtime.Object // another object related to the reconciled object and the event.
2931
)
3032

3133
func Example_event() {
3234
// recorderProvider is a recorder.Provider
33-
recorder := recorderProvider.GetEventRecorderFor("my-controller")
35+
deprecatedRecorder := recorderProvider.GetEventRecorderFor("my-controller")
3436

3537
// emit an event with a fixed message
36-
recorder.Event(somePod, corev1.EventTypeWarning,
38+
deprecatedRecorder.Event(somePod, corev1.EventTypeWarning,
3739
"WrongTrousers", "It's the wrong trousers, Gromit!")
3840
}
3941

4042
func Example_eventf() {
4143
// recorderProvider is a recorder.Provider
42-
recorder := recorderProvider.GetEventRecorderFor("my-controller")
44+
deprecatedRecorder := recorderProvider.GetEventRecorderFor("my-controller")
4345

4446
// emit an event with a variable message
4547
mildCheese := "Wensleydale"
46-
recorder.Eventf(somePod, corev1.EventTypeNormal,
48+
deprecatedRecorder.Eventf(somePod, corev1.EventTypeNormal,
4749
"DislikesCheese", "Not even %s?", mildCheese)
50+
51+
recorder := recorderProvider.GetEventRecorder("my-controller")
52+
53+
// emit an event with a fixed message
54+
recorder.Eventf(somePod, someRelatedObject, corev1.EventTypeWarning,
55+
"WrongTrousers", "getting dressed", "It's the wrong trousers, Gromit!")
4856
}

0 commit comments

Comments
 (0)