@@ -286,6 +286,133 @@ func TestScaleToZero_Start(t *testing.T) {
286286
287287 wantErr : nil ,
288288 },
289+ {
290+ name : "cluster with scale to zero enabled and inactive cluster with ongoing backup, no hibernation triggered until complete" ,
291+ client : func (done chan struct {}) * mockClusterClient {
292+ return & mockClusterClient {
293+ getClusterFunc : func (ctx context.Context , forceUpdate bool ) (* cnpgv1.Cluster , error ) {
294+ return & cnpgv1.Cluster {
295+ Status : cnpgv1.ClusterStatus {
296+ Phase : healthyClusterStatus ,
297+ CurrentPrimary : "test-pod-1" ,
298+ },
299+ ObjectMeta : metav1.ObjectMeta {
300+ Annotations : map [string ]string {
301+ scaleToZeroEnabledAnnotation : "true" ,
302+ inactivityMinutesAnnotation : "5" ,
303+ },
304+ },
305+ }, nil
306+ },
307+ updateClusterFunc : func (ctx context.Context , cluster * cnpgv1.Cluster ) error {
308+ defer func () { done <- struct {}{} }()
309+ require .NotNil (t , cluster )
310+ require .Equal (t , "on" , cluster .Annotations [hibernationAnnotation ])
311+ return nil
312+ },
313+ getClusterScheduledBackupFunc : func (ctx context.Context ) (* cnpgv1.ScheduledBackup , error ) {
314+ return nil , fmt .Errorf ("scheduledbackups.postgresql.cnpg.io \" test-cluster\" not found" )
315+ },
316+ getClusterBackupsFunc : func (ctx context.Context , i uint ) ([]cnpgv1.Backup , error ) {
317+ backup := func (status cnpgv1.BackupPhase ) cnpgv1.Backup {
318+ return cnpgv1.Backup {
319+ Spec : cnpgv1.BackupSpec {
320+ Cluster : cnpgv1.LocalObjectReference {
321+ Name : "test-cluster" ,
322+ },
323+ },
324+ Status : cnpgv1.BackupStatus {
325+ Phase : status ,
326+ },
327+ }
328+ }
329+ switch i {
330+ case 1 :
331+ return []cnpgv1.Backup {
332+ backup (cnpgv1 .BackupPhaseRunning ),
333+ }, nil
334+ case 2 :
335+ return []cnpgv1.Backup {
336+ backup (cnpgv1 .BackupPhaseCompleted ),
337+ }, nil
338+ default :
339+ return nil , fmt .Errorf ("unexpected call to getClusterBackups with index %d" , i )
340+ }
341+ },
342+ }
343+ },
344+
345+ querier : func (_ chan struct {}) * mockQuerier {
346+ return & mockQuerier {
347+ queryFunc : func (ctx context.Context , query string , args ... any ) (postgres.Row , error ) {
348+ return & mockRow {
349+ scanFn : func (dest ... any ) error {
350+ require .Len (t , dest , 1 )
351+ count , ok := dest [0 ].(* int )
352+ require .True (t , ok )
353+ * count = 0 // Simulate an inactive cluster
354+ return nil
355+ },
356+ }, nil
357+ },
358+ }
359+ },
360+ lastActive : time .Now ().Add (- time .Minute * 10 ), // Simulate inactivity
361+
362+ wantErr : nil ,
363+ },
364+ {
365+ name : "cluster with scale to zero enabled and inactive cluster with unknown backups, hibernation triggered" ,
366+ client : func (done chan struct {}) * mockClusterClient {
367+ return & mockClusterClient {
368+ getClusterFunc : func (ctx context.Context , forceUpdate bool ) (* cnpgv1.Cluster , error ) {
369+ return & cnpgv1.Cluster {
370+ Status : cnpgv1.ClusterStatus {
371+ Phase : healthyClusterStatus ,
372+ CurrentPrimary : "test-pod-1" ,
373+ },
374+ ObjectMeta : metav1.ObjectMeta {
375+ Annotations : map [string ]string {
376+ scaleToZeroEnabledAnnotation : "true" ,
377+ inactivityMinutesAnnotation : "5" ,
378+ },
379+ },
380+ }, nil
381+ },
382+ updateClusterFunc : func (ctx context.Context , cluster * cnpgv1.Cluster ) error {
383+ defer func () { done <- struct {}{} }()
384+ require .NotNil (t , cluster )
385+ require .Equal (t , "on" , cluster .Annotations [hibernationAnnotation ])
386+ return nil
387+ },
388+ getClusterScheduledBackupFunc : func (ctx context.Context ) (* cnpgv1.ScheduledBackup , error ) {
389+ return nil , fmt .Errorf ("scheduledbackups.postgresql.cnpg.io \" test-cluster\" not found" )
390+ },
391+ getClusterBackupsFunc : func (ctx context.Context , i uint ) ([]cnpgv1.Backup , error ) {
392+ return nil , errTest
393+ },
394+ }
395+ },
396+
397+ querier : func (_ chan struct {}) * mockQuerier {
398+ return & mockQuerier {
399+ queryFunc : func (ctx context.Context , query string , args ... any ) (postgres.Row , error ) {
400+ return & mockRow {
401+ scanFn : func (dest ... any ) error {
402+ require .Len (t , dest , 1 )
403+ count , ok := dest [0 ].(* int )
404+ require .True (t , ok )
405+ * count = 0 // Simulate an inactive cluster
406+ return nil
407+ },
408+ }, nil
409+ },
410+ }
411+ },
412+ lastActive : time .Now ().Add (- time .Minute * 10 ), // Simulate inactivity
413+
414+ wantErr : nil ,
415+ },
289416 {
290417 name : "cluster with scale to zero enabled and inactive cluster, hibernation triggered, scheduled backup get error ignored" ,
291418 client : func (done chan struct {}) * mockClusterClient {
0 commit comments