@@ -533,6 +533,44 @@ var _ = Describe("controller", func() {
533533 Expect (startCount .Load ()).To (Equal (int32 (1 )), "Source should only be started once even when called multiple times" )
534534 })
535535
536+ It ("should block subsequent calls from returning until the first call to startEventSources has returned" , func () {
537+ ctx , cancel := context .WithCancel (context .Background ())
538+ defer cancel ()
539+ ctrl .CacheSyncTimeout = 5 * time .Second
540+
541+ // finishSourceChan is closed to unblock startEventSources from returning
542+ finishSourceChan := make (chan struct {})
543+
544+ src := source .Func (func (ctx context.Context , _ workqueue.TypedRateLimitingInterface [reconcile.Request ]) error {
545+ <- finishSourceChan
546+ return nil
547+ })
548+ ctrl .startWatches = []source.TypedSource [reconcile.Request ]{src }
549+
550+ By ("Calling startEventSources asynchronously" )
551+ go func () {
552+ defer GinkgoRecover ()
553+ Expect (ctrl .startEventSources (ctx )).To (Succeed ())
554+ }()
555+
556+ By ("Calling startEventSources again" )
557+ var didSubsequentCallComplete atomic.Bool
558+ go func () {
559+ defer GinkgoRecover ()
560+ Expect (ctrl .startEventSources (ctx )).To (Succeed ())
561+ didSubsequentCallComplete .Store (true )
562+ }()
563+
564+ // Assert that second call to startEventSources is blocked while source has not finished
565+ Consistently (didSubsequentCallComplete .Load ).Should (BeFalse ())
566+
567+ By ("Finishing source start + sync" )
568+ finishSourceChan <- struct {}{}
569+
570+ // Assert that second call to startEventSources is now complete
571+ Eventually (didSubsequentCallComplete .Load ).Should (BeTrue (), "startEventSources should complete after source is started and synced" )
572+ })
573+
536574 It ("should reset c.startWatches to nil after returning" , func () {
537575 ctx , cancel := context .WithCancel (context .Background ())
538576 defer cancel ()
0 commit comments