- storageNamesForNode: 83.3%→100% (8 cases for filtering logic) - GetDockerHost: 75%→100% (5 cases for lookup and whitespace handling) - SchedulerHealth: 85.3%→89.1% (13 cases for nil handling, breaker key parsing)
199 lines
5.2 KiB
Go
199 lines
5.2 KiB
Go
package monitoring
|
|
|
|
import (
|
|
"slices"
|
|
"testing"
|
|
|
|
"github.com/rcourtman/pulse-go-rewrite/internal/models"
|
|
)
|
|
|
|
func TestPreserveFailedStorageBackups(t *testing.T) {
|
|
instance := "pve01"
|
|
current := []models.StorageBackup{
|
|
{
|
|
ID: "pve01-volid-new",
|
|
Instance: instance,
|
|
Storage: "local-lvm",
|
|
Volid: "local-lvm:backup/new.vma.zst",
|
|
},
|
|
}
|
|
snapshot := models.StateSnapshot{
|
|
PVEBackups: models.PVEBackups{
|
|
StorageBackups: []models.StorageBackup{
|
|
{
|
|
ID: "pve01-volid-old",
|
|
Instance: instance,
|
|
Storage: "nas-share",
|
|
Volid: "nas-share:backup/old.vma.zst",
|
|
},
|
|
{
|
|
ID: "pve01-volid-new",
|
|
Instance: instance,
|
|
Storage: "local-lvm",
|
|
Volid: "local-lvm:backup/new.vma.zst",
|
|
},
|
|
},
|
|
},
|
|
}
|
|
toPreserve := map[string]struct{}{
|
|
"nas-share": {},
|
|
}
|
|
|
|
merged, storages := preserveFailedStorageBackups(instance, snapshot, toPreserve, current)
|
|
|
|
if len(merged) != 2 {
|
|
t.Fatalf("expected 2 backups after merge, got %d", len(merged))
|
|
}
|
|
|
|
if !slices.Contains(storages, "nas-share") {
|
|
t.Fatalf("expected nas-share to be reported as preserved, got %v", storages)
|
|
}
|
|
|
|
if !slices.ContainsFunc(merged, func(b models.StorageBackup) bool {
|
|
return b.Storage == "nas-share"
|
|
}) {
|
|
t.Fatalf("expected preserved backup for nas-share to be present")
|
|
}
|
|
}
|
|
|
|
func TestPreserveFailedStorageBackupsSkipsDuplicates(t *testing.T) {
|
|
instance := "pve01"
|
|
current := []models.StorageBackup{
|
|
{
|
|
ID: "pve01-volid-old",
|
|
Instance: instance,
|
|
Storage: "nas-share",
|
|
Volid: "nas-share:backup/old.vma.zst",
|
|
},
|
|
}
|
|
snapshot := models.StateSnapshot{
|
|
PVEBackups: models.PVEBackups{
|
|
StorageBackups: []models.StorageBackup{
|
|
{
|
|
ID: "pve01-volid-old",
|
|
Instance: instance,
|
|
Storage: "nas-share",
|
|
Volid: "nas-share:backup/old.vma.zst",
|
|
},
|
|
},
|
|
},
|
|
}
|
|
toPreserve := map[string]struct{}{
|
|
"nas-share": {},
|
|
}
|
|
|
|
merged, storages := preserveFailedStorageBackups(instance, snapshot, toPreserve, current)
|
|
|
|
if len(merged) != 1 {
|
|
t.Fatalf("expected duplicate backup to be ignored, got %d entries", len(merged))
|
|
}
|
|
if len(storages) != 0 {
|
|
t.Fatalf("expected no storages to be reported because nothing new was preserved, got %v", storages)
|
|
}
|
|
}
|
|
|
|
func TestStorageNamesForNode(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
instanceName string
|
|
nodeName string
|
|
snapshot models.StateSnapshot
|
|
want []string
|
|
}{
|
|
{
|
|
name: "empty nodeName returns nil",
|
|
instanceName: "pve1",
|
|
nodeName: "",
|
|
snapshot: models.StateSnapshot{
|
|
Storage: []models.Storage{
|
|
{Instance: "pve1", Name: "local-backup", Node: "node1", Content: "backup"},
|
|
},
|
|
},
|
|
want: nil,
|
|
},
|
|
{
|
|
name: "empty snapshot returns nil",
|
|
instanceName: "pve1",
|
|
nodeName: "node1",
|
|
snapshot: models.StateSnapshot{},
|
|
want: nil,
|
|
},
|
|
{
|
|
name: "storage with wrong instance is skipped",
|
|
instanceName: "pve1",
|
|
nodeName: "node1",
|
|
snapshot: models.StateSnapshot{
|
|
Storage: []models.Storage{
|
|
{Instance: "pve2", Name: "local-backup", Node: "node1", Content: "backup"},
|
|
},
|
|
},
|
|
want: nil,
|
|
},
|
|
{
|
|
name: "storage with empty name is skipped",
|
|
instanceName: "pve1",
|
|
nodeName: "node1",
|
|
snapshot: models.StateSnapshot{
|
|
Storage: []models.Storage{
|
|
{Instance: "pve1", Name: "", Node: "node1", Content: "backup"},
|
|
},
|
|
},
|
|
want: nil,
|
|
},
|
|
{
|
|
name: "storage without backup in Content is skipped",
|
|
instanceName: "pve1",
|
|
nodeName: "node1",
|
|
snapshot: models.StateSnapshot{
|
|
Storage: []models.Storage{
|
|
{Instance: "pve1", Name: "local", Node: "node1", Content: "images,rootdir"},
|
|
},
|
|
},
|
|
want: nil,
|
|
},
|
|
{
|
|
name: "storage where Node matches nodeName is included",
|
|
instanceName: "pve1",
|
|
nodeName: "node1",
|
|
snapshot: models.StateSnapshot{
|
|
Storage: []models.Storage{
|
|
{Instance: "pve1", Name: "backup-storage", Node: "node1", Content: "backup"},
|
|
},
|
|
},
|
|
want: []string{"backup-storage"},
|
|
},
|
|
{
|
|
name: "storage where nodeName is in Nodes slice is included",
|
|
instanceName: "pve1",
|
|
nodeName: "node2",
|
|
snapshot: models.StateSnapshot{
|
|
Storage: []models.Storage{
|
|
{Instance: "pve1", Name: "shared-backup", Node: "node1", Nodes: []string{"node1", "node2", "node3"}, Content: "backup"},
|
|
},
|
|
},
|
|
want: []string{"shared-backup"},
|
|
},
|
|
{
|
|
name: "multiple matching storages are returned",
|
|
instanceName: "pve1",
|
|
nodeName: "node1",
|
|
snapshot: models.StateSnapshot{
|
|
Storage: []models.Storage{
|
|
{Instance: "pve1", Name: "local-backup", Node: "node1", Content: "backup"},
|
|
{Instance: "pve1", Name: "nfs-backup", Node: "node1", Content: "backup,images"},
|
|
{Instance: "pve1", Name: "shared-backup", Node: "node2", Nodes: []string{"node1", "node2"}, Content: "backup"},
|
|
},
|
|
},
|
|
want: []string{"local-backup", "nfs-backup", "shared-backup"},
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
got := storageNamesForNode(tt.instanceName, tt.nodeName, tt.snapshot)
|
|
if !slices.Equal(got, tt.want) {
|
|
t.Errorf("storageNamesForNode() = %v, want %v", got, tt.want)
|
|
}
|
|
})
|
|
}
|
|
}
|