Pulse/internal/monitoring/pbs_convert_test.go
rcourtman 4f824ab148 style: Apply gofmt to 37 files
Standardize code formatting across test files and monitor.go.
No functional changes.
2025-12-02 17:21:48 +00:00

322 lines
8.4 KiB
Go

package monitoring
import (
"testing"
"time"
"github.com/rcourtman/pulse-go-rewrite/pkg/pbs"
)
func TestConvertPBSSnapshots(t *testing.T) {
t.Run("empty input returns empty slice", func(t *testing.T) {
result := convertPBSSnapshots("pbs-1", "backup-store", "ns1", nil)
if len(result) != 0 {
t.Errorf("expected empty slice, got %d items", len(result))
}
result = convertPBSSnapshots("pbs-1", "backup-store", "ns1", []pbs.BackupSnapshot{})
if len(result) != 0 {
t.Errorf("expected empty slice, got %d items", len(result))
}
})
t.Run("basic snapshot conversion", func(t *testing.T) {
backupTime := int64(1700000000)
snapshots := []pbs.BackupSnapshot{
{
BackupType: "vm",
BackupID: "100",
BackupTime: backupTime,
Size: 1024000,
Protected: true,
Comment: "Test backup",
Owner: "root@pam",
},
}
result := convertPBSSnapshots("pbs-prod", "datastore1", "production", snapshots)
if len(result) != 1 {
t.Fatalf("expected 1 backup, got %d", len(result))
}
backup := result[0]
expectedID := "pbs-pbs-prod-datastore1-production-vm-100-1700000000"
if backup.ID != expectedID {
t.Errorf("ID: expected %q, got %q", expectedID, backup.ID)
}
if backup.Instance != "pbs-prod" {
t.Errorf("Instance: expected %q, got %q", "pbs-prod", backup.Instance)
}
if backup.Datastore != "datastore1" {
t.Errorf("Datastore: expected %q, got %q", "datastore1", backup.Datastore)
}
if backup.Namespace != "production" {
t.Errorf("Namespace: expected %q, got %q", "production", backup.Namespace)
}
if backup.BackupType != "vm" {
t.Errorf("BackupType: expected %q, got %q", "vm", backup.BackupType)
}
if backup.VMID != "100" {
t.Errorf("VMID: expected %q, got %q", "100", backup.VMID)
}
expectedTime := time.Unix(backupTime, 0)
if !backup.BackupTime.Equal(expectedTime) {
t.Errorf("BackupTime: expected %v, got %v", expectedTime, backup.BackupTime)
}
if backup.Size != 1024000 {
t.Errorf("Size: expected %d, got %d", 1024000, backup.Size)
}
if !backup.Protected {
t.Error("Protected: expected true")
}
if backup.Verified {
t.Error("Verified: expected false (no verification data)")
}
if backup.Comment != "Test backup" {
t.Errorf("Comment: expected %q, got %q", "Test backup", backup.Comment)
}
if backup.Owner != "root@pam" {
t.Errorf("Owner: expected %q, got %q", "root@pam", backup.Owner)
}
})
t.Run("files as string array", func(t *testing.T) {
snapshots := []pbs.BackupSnapshot{
{
BackupType: "ct",
BackupID: "200",
BackupTime: 1700000000,
Files: []interface{}{"file1.img", "file2.pxar", "file3.conf"},
},
}
result := convertPBSSnapshots("pbs-1", "store", "", snapshots)
if len(result[0].Files) != 3 {
t.Fatalf("expected 3 files, got %d", len(result[0].Files))
}
if result[0].Files[0] != "file1.img" {
t.Errorf("Files[0]: expected %q, got %q", "file1.img", result[0].Files[0])
}
if result[0].Files[1] != "file2.pxar" {
t.Errorf("Files[1]: expected %q, got %q", "file2.pxar", result[0].Files[1])
}
if result[0].Files[2] != "file3.conf" {
t.Errorf("Files[2]: expected %q, got %q", "file3.conf", result[0].Files[2])
}
})
t.Run("files as object array with filename field", func(t *testing.T) {
snapshots := []pbs.BackupSnapshot{
{
BackupType: "vm",
BackupID: "300",
BackupTime: 1700000000,
Files: []interface{}{
map[string]interface{}{"filename": "disk-0.raw", "size": 10737418240},
map[string]interface{}{"filename": "vm.conf", "size": 1024},
},
},
}
result := convertPBSSnapshots("pbs-1", "store", "", snapshots)
if len(result[0].Files) != 2 {
t.Fatalf("expected 2 files, got %d", len(result[0].Files))
}
if result[0].Files[0] != "disk-0.raw" {
t.Errorf("Files[0]: expected %q, got %q", "disk-0.raw", result[0].Files[0])
}
if result[0].Files[1] != "vm.conf" {
t.Errorf("Files[1]: expected %q, got %q", "vm.conf", result[0].Files[1])
}
})
t.Run("files with missing filename field ignored", func(t *testing.T) {
snapshots := []pbs.BackupSnapshot{
{
BackupType: "vm",
BackupID: "400",
BackupTime: 1700000000,
Files: []interface{}{
map[string]interface{}{"filename": "valid.raw"},
map[string]interface{}{"name": "invalid.raw"}, // Wrong field name
map[string]interface{}{}, // Empty object
},
},
}
result := convertPBSSnapshots("pbs-1", "store", "", snapshots)
if len(result[0].Files) != 1 {
t.Fatalf("expected 1 file (only valid one), got %d", len(result[0].Files))
}
if result[0].Files[0] != "valid.raw" {
t.Errorf("Files[0]: expected %q, got %q", "valid.raw", result[0].Files[0])
}
})
t.Run("verification as string ok", func(t *testing.T) {
snapshots := []pbs.BackupSnapshot{
{
BackupType: "vm",
BackupID: "500",
BackupTime: 1700000000,
Verification: "ok",
},
}
result := convertPBSSnapshots("pbs-1", "store", "", snapshots)
if !result[0].Verified {
t.Error("Verified: expected true when verification is 'ok'")
}
})
t.Run("verification as string not ok", func(t *testing.T) {
snapshots := []pbs.BackupSnapshot{
{
BackupType: "vm",
BackupID: "501",
BackupTime: 1700000000,
Verification: "failed",
},
}
result := convertPBSSnapshots("pbs-1", "store", "", snapshots)
if result[0].Verified {
t.Error("Verified: expected false when verification is not 'ok'")
}
})
t.Run("verification as object with state ok", func(t *testing.T) {
snapshots := []pbs.BackupSnapshot{
{
BackupType: "vm",
BackupID: "600",
BackupTime: 1700000000,
Verification: map[string]interface{}{
"state": "ok",
"upid": "UPID:pbs:00001234",
"snapshot": "2023-11-14T12:00:00Z",
},
},
}
result := convertPBSSnapshots("pbs-1", "store", "", snapshots)
if !result[0].Verified {
t.Error("Verified: expected true when verification.state is 'ok'")
}
})
t.Run("verification as object with state failed", func(t *testing.T) {
snapshots := []pbs.BackupSnapshot{
{
BackupType: "vm",
BackupID: "601",
BackupTime: 1700000000,
Verification: map[string]interface{}{
"state": "failed",
"upid": "UPID:pbs:00005678",
},
},
}
result := convertPBSSnapshots("pbs-1", "store", "", snapshots)
if result[0].Verified {
t.Error("Verified: expected false when verification.state is 'failed'")
}
})
t.Run("verification as object without state field", func(t *testing.T) {
snapshots := []pbs.BackupSnapshot{
{
BackupType: "vm",
BackupID: "602",
BackupTime: 1700000000,
Verification: map[string]interface{}{
"upid": "UPID:pbs:00009999",
},
},
}
result := convertPBSSnapshots("pbs-1", "store", "", snapshots)
if result[0].Verified {
t.Error("Verified: expected false when verification object has no state field")
}
})
t.Run("multiple snapshots", func(t *testing.T) {
snapshots := []pbs.BackupSnapshot{
{
BackupType: "vm",
BackupID: "100",
BackupTime: 1700000000,
},
{
BackupType: "ct",
BackupID: "200",
BackupTime: 1700001000,
},
{
BackupType: "vm",
BackupID: "100",
BackupTime: 1700002000, // Same VM, different time
},
}
result := convertPBSSnapshots("pbs-1", "store", "ns", snapshots)
if len(result) != 3 {
t.Fatalf("expected 3 backups, got %d", len(result))
}
// Verify each has unique ID
ids := make(map[string]bool)
for _, backup := range result {
if ids[backup.ID] {
t.Errorf("duplicate ID found: %s", backup.ID)
}
ids[backup.ID] = true
}
})
t.Run("empty namespace in ID", func(t *testing.T) {
snapshots := []pbs.BackupSnapshot{
{
BackupType: "vm",
BackupID: "100",
BackupTime: 1700000000,
},
}
result := convertPBSSnapshots("pbs-1", "store", "", snapshots)
expectedID := "pbs-pbs-1-store--vm-100-1700000000"
if result[0].ID != expectedID {
t.Errorf("ID with empty namespace: expected %q, got %q", expectedID, result[0].ID)
}
})
t.Run("container backup type", func(t *testing.T) {
snapshots := []pbs.BackupSnapshot{
{
BackupType: "ct",
BackupID: "101",
BackupTime: 1700000000,
Size: 512000,
},
}
result := convertPBSSnapshots("pbs-1", "store", "ns", snapshots)
if result[0].BackupType != "ct" {
t.Errorf("BackupType: expected %q, got %q", "ct", result[0].BackupType)
}
})
}