@@ -11,6 +11,10 @@ import (
1111 "github.com/stretchr/testify/assert"
1212 "github.com/stretchr/testify/require"
1313
14+ "gitlab.com/postgres-ai/database-lab/v3/internal/provision/pool"
15+ "gitlab.com/postgres-ai/database-lab/v3/internal/provision/resources"
16+ "gitlab.com/postgres-ai/database-lab/v3/internal/provision/thinclones"
17+ srvCfg "gitlab.com/postgres-ai/database-lab/v3/internal/srv/config"
1418 "gitlab.com/postgres-ai/database-lab/v3/internal/webhooks"
1519 "gitlab.com/postgres-ai/database-lab/v3/pkg/models"
1620)
@@ -282,3 +286,44 @@ func TestMapKeys(t *testing.T) {
282286func timePtr (t time.Time ) * time.Time {
283287 return & t
284288}
289+
290+ // nilRepoFSM is a pool.FSManager whose GetRepo reports no repo data with no error, mirroring
291+ // thin-clone managers without repo support (LVM). It embeds the interface so unimplemented
292+ // methods are absent at compile time. ListProtection and GetProtection are the first FSManager
293+ // calls the sweep makes once it passes the nil-repo guard; they count reaches so a skipped pool
294+ // can be asserted positively, and returning empty (instead of panicking on the nil embedded
295+ // interface) keeps the without-guard failure at the same nil-repo dereference that crashes
296+ // production (branchHeadSet -> repo.Branches).
297+ type nilRepoFSM struct {
298+ pool.FSManager
299+ name string
300+ reached int
301+ }
302+
303+ func (m * nilRepoFSM ) GetRepo () (* models.Repo , error ) {
304+ return nil , nil
305+ }
306+
307+ func (m * nilRepoFSM ) Pool () * resources.Pool {
308+ return & resources.Pool {Name : m .name }
309+ }
310+
311+ func (m * nilRepoFSM ) ListProtection () (map [string ]thinclones.ProtectionProperties , error ) {
312+ m .reached ++
313+
314+ return nil , nil
315+ }
316+
317+ func (m * nilRepoFSM ) GetProtection (string ) (thinclones.ProtectionProperties , error ) {
318+ m .reached ++
319+
320+ return thinclones.ProtectionProperties {}, nil
321+ }
322+
323+ func TestSweepPoolSkipsNilRepo (t * testing.T ) {
324+ sw := & sweep {retention : srvCfg.Retention {UnusedSnapshotMinutes : 1 , UnusedBranchMinutes : 1 }}
325+ fsm := & nilRepoFSM {name : "lvm_pool" }
326+
327+ assert .NotPanics (t , func () { sw .pool (fsm ) })
328+ assert .Zero (t , fsm .reached , "sweep must skip a pool with no repo data, not reconcile it" )
329+ }
0 commit comments