Skip to content

Commit 66e3be4

Browse files
committed
Add UT that verifies WaitForWarmupComplete blocking / non-blocking behavior.
1 parent 667bb03 commit 66e3be4

File tree

1 file changed

+53
-1
lines changed

1 file changed

+53
-1
lines changed

pkg/internal/controller/controller_test.go

Lines changed: 53 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1064,7 +1064,7 @@ var _ = Describe("controller", func() {
10641064
Expect(result).To(BeFalse())
10651065
})
10661066

1067-
It("should return true if context is cancelled", func() {
1067+
It("should return true if context is cancelled while waiting for source to start", func() {
10681068
// Setup controller with sources that complete with error
10691069
ctx, cancel := context.WithCancel(context.Background())
10701070
defer cancel()
@@ -1198,6 +1198,58 @@ var _ = Describe("controller", func() {
11981198
Eventually(isSourceStarted.Load).Should(BeTrue())
11991199
})
12001200
})
1201+
1202+
Describe("WaitForWarmupComplete", func() {
1203+
It("should short circuit without blocking if warmup is disabled", func() {
1204+
ctrl.NeedWarmup = ptr.To(false)
1205+
1206+
ctx, cancel := context.WithCancel(context.Background())
1207+
defer cancel()
1208+
1209+
// Call WaitForWarmupComplete and expect it to return immediately
1210+
result := ctrl.WaitForWarmupComplete(ctx)
1211+
Expect(result).To(BeTrue())
1212+
})
1213+
1214+
It("should block until warmup is complete if warmup is enabled", func() {
1215+
ctrl.NeedWarmup = ptr.To(true)
1216+
// Setup controller with sources that complete successfully
1217+
ctx, cancel := context.WithCancel(context.Background())
1218+
defer cancel()
1219+
1220+
// Close the channel to signal watch completion
1221+
shouldWatchCompleteChan := make(chan struct{})
1222+
1223+
ctrl.CacheSyncTimeout = time.Second
1224+
ctrl.startWatches = []source.TypedSource[reconcile.Request]{
1225+
source.Func(func(ctx context.Context, _ workqueue.TypedRateLimitingInterface[reconcile.Request]) error {
1226+
<-shouldWatchCompleteChan
1227+
return nil
1228+
}),
1229+
}
1230+
1231+
By("Starting a blocking warmup")
1232+
1233+
go func() {
1234+
defer GinkgoRecover()
1235+
Expect(ctrl.Warmup(ctx)).To(Succeed())
1236+
}()
1237+
1238+
// didWaitForWarmupCompleteReturn is true when the call to WaitForWarmupComplete returns
1239+
didWaitForWarmupCompleteReturn := atomic.Bool{}
1240+
go func() {
1241+
// Verify WaitForWarmupComplete returns true for successful sync
1242+
Expect(ctrl.WaitForWarmupComplete(ctx)).To(BeTrue())
1243+
didWaitForWarmupCompleteReturn.Store(true)
1244+
}()
1245+
Consistently(didWaitForWarmupCompleteReturn.Load).Should(BeFalse())
1246+
1247+
By("Unblocking the watch to simulate initial sync completion")
1248+
close(shouldWatchCompleteChan)
1249+
Eventually(didWaitForWarmupCompleteReturn.Load).Should(BeTrue())
1250+
})
1251+
1252+
})
12011253
})
12021254

12031255
var _ = Describe("ReconcileIDFromContext function", func() {

0 commit comments

Comments
 (0)