package storage import ( "testing" "gitea.dooplex.hu/admin/felhom-agent/internal/proxmox" ) // durable_id is the DR-load-bearing field — the hub re-attaches the RIGHT physical target // by it. Each type must derive deterministically; the false-id failure mode is // re-attaching the WRONG disk, so this table pins the per-type shape. func TestDeriveDurableID(t *testing.T) { cases := []struct { name string typ string s proxmox.Storage backingDevice string uuid string want string }{ { name: "usb by fs-uuid", typ: hubTypeUSB, s: proxmox.Storage{Storage: "usb-backup", Path: "/mnt/usb-backup"}, uuid: "0fc6-abcd", want: "uuid:0fc6-abcd", }, { name: "local-dir by fs-uuid", typ: hubTypeLocalDir, s: proxmox.Storage{Storage: "extra"}, uuid: "dead-beef", want: "uuid:dead-beef", }, { name: "usb falls back to device when uuid unresolved", typ: hubTypeUSB, s: proxmox.Storage{Storage: "usb-backup"}, backingDevice: "/dev/sdb1", want: "dev:/dev/sdb1", }, { name: "nfs server:export", typ: hubTypeNFS, s: proxmox.Storage{Storage: "nfs-arch", Server: "10.0.0.5", Export: "/export/b"}, want: "10.0.0.5:/export/b", }, { name: "cifs server:share", typ: hubTypeCIFS, s: proxmox.Storage{Storage: "cifs", Server: "nas.local", Share: "backups"}, want: "nas.local:backups", }, { name: "pbs repo + fingerprint (lowercased)", typ: hubTypePBS, s: proxmox.Storage{Storage: "pbs", Server: "pbs.local", Datastore: "store1", Fingerprint: "AB:CD:EF"}, want: "pbs.local:store1#ab:cd:ef", }, { name: "pbs without fingerprint", typ: hubTypePBS, s: proxmox.Storage{Storage: "pbs", Server: "pbs.local", Datastore: "store1"}, want: "pbs.local:store1", }, { name: "lvmthin vg/pool", typ: hubTypeLVMThin, s: proxmox.Storage{Storage: "local-lvm", VGName: "pve", ThinPool: "data"}, want: "pve/data", }, { name: "lvm (thick) vg only", typ: "lvm", s: proxmox.Storage{Storage: "vg0", VGName: "vg0"}, want: "vg0", }, { name: "local builtin by path when no uuid", typ: hubTypeLocal, s: proxmox.Storage{Storage: "local", Path: "/var/lib/vz"}, want: "path:/var/lib/vz", }, { name: "unknown/unresolvable falls back to store name (never empty)", typ: hubTypeNFS, s: proxmox.Storage{Storage: "broken-nfs"}, // missing server/export want: "store:broken-nfs", }, } for _, c := range cases { t.Run(c.name, func(t *testing.T) { got := deriveDurableID(c.typ, c.s, c.backingDevice, c.uuid) if got != c.want { t.Errorf("deriveDurableID = %q, want %q", got, c.want) } if got == "" { t.Error("durable_id must never be empty") } }) } }