package web import ( "context" "strings" "testing" "gitea.dooplex.hu/admin/felhom-controller/internal/agentapi" "gitea.dooplex.hu/admin/felhom-controller/internal/settings" ) // R-1084 (v0.318.0, felhom.eu architecture/16 §4): the whole-box backup offer promises survival of a DISK failure only // for a drive the agent proves is another disk than the system data. Seen on Tester 1 (a VM): the promise stood next to // build A's „cannot check" notice. func offerHarness(t *testing.T, rel map[string]offerRelation, paths ...string) *Server { t.Helper() var disks []agentapi.DiskInfo for _, p := range paths { disks = append(disks, agentapi.DiskInfo{Name: p, GuestPath: p, MountPath: "/mnt/" + strings.TrimPrefix(p, "/mnt/felhom-drives/"), Role: "user-data"}) } s := absentHarness(t, "local", disks, "") for _, p := range paths { if err := s.settings.AddStoragePath(settings.StoragePath{Path: p, Label: "Meghajtó " + p}); err != nil { t.Fatal(err) } } s.sameDiskFn = func(_ context.Context, drive, sysData string) offerRelation { if sysData != "/mnt/sys_drive" { t.Errorf("the offer must compare against the system data path, got %q", sysData) } return rel[drive] } return s } const drvA, drvB = "/mnt/felhom-drives/hdd_1", "/mnt/felhom-drives/hdd_2" func TestR1084_ProvenDifferentDiskKeepsThePromise(t *testing.T) { s := offerHarness(t, map[string]offerRelation{drvA: offerDifferent}, drvA) v := s.backupTargetView(context.Background(), "hu") if v == nil || v.OfferPath != drvA || v.OfferText != huText(t, backupTargetOfferKey) { t.Fatalf("a proven different disk: want today's offer, got %+v", v) } } func TestR1084_UnprovenDiskIsOfferedWithoutThePromise(t *testing.T) { s := offerHarness(t, map[string]offerRelation{drvA: offerUnknown}, drvA) v := s.backupTargetView(context.Background(), "hu") if v == nil || v.OfferPath != drvA { t.Fatalf("an unproven disk is still offered, got %+v", v) } if strings.Contains(v.OfferText, "így egy lemezhiba után is vissza tudod") || !strings.Contains(v.OfferText, "nem tudja ellenőrizni") { t.Fatalf("an unproven disk must not carry the disk-failure promise; got %q", v.OfferText) } } func TestR1084_SameDiskIsNeverOffered(t *testing.T) { s := offerHarness(t, map[string]offerRelation{drvA: offerSame}, drvA) if v := s.backupTargetView(context.Background(), "hu"); v == nil || v.OfferPath != "" { t.Fatalf("a drive on the system disk must not be offered as the backup place, got %+v", v) } } func TestR1084_AProvenDiskWinsOverAnUnprovenOne(t *testing.T) { s := offerHarness(t, map[string]offerRelation{drvA: offerUnknown, drvB: offerDifferent}, drvA, drvB) if v := s.backupTargetView(context.Background(), "hu"); v == nil || v.OfferPath != drvB || v.OfferText != huText(t, backupTargetOfferKey) { t.Fatalf("the proven different disk must be offered first, got %+v", v) } } // An agent older than 0.157.0 cannot judge: today's offer stays (build A's rule for an older agent). func TestR1084_OlderAgentKeepsTodaysOffer(t *testing.T) { s := offerHarness(t, map[string]offerRelation{drvA: offerLegacy}, drvA) if v := s.backupTargetView(context.Background(), "hu"); v == nil || v.OfferPath != drvA || v.OfferText != huText(t, backupTargetOfferKey) { t.Fatalf("an older agent: want today's offer, got %+v", v) } } // The internal place is never the whole-box backup place (it is the system disk). func TestR1084_InternalPlaceIsNeverOffered(t *testing.T) { s := absentHarness(t, "local", []agentapi.DiskInfo{{Name: "belso", GuestPath: "/mnt/felhom-drives/belso", MountPath: "/mnt/belso", Role: "user-data", Kind: agentapi.PlaceKindInternal}}, "") if err := s.settings.AddStoragePath(settings.StoragePath{Path: "/mnt/felhom-drives/belso", Kind: settings.StorageKindInternal}); err != nil { t.Fatal(err) } s.sameDiskFn = func(context.Context, string, string) offerRelation { return offerLegacy } // even an old judge if v := s.backupTargetView(context.Background(), "hu"); v == nil || v.OfferPath != "" { t.Fatalf("the internal place must not be offered, got %+v", v) } }