package registry import ( "errors" "path/filepath" "testing" ) func TestClaimHoldCannotClearReplacementOrChangeProjection(t *testing.T) { r, err := Open(filepath.Join(t.TempDir(), "registry.db")) if err != nil { t.Fatal(err) } defer r.Close() owner := ClaimOwnership{"inc", 1, "owner", "row"} rt := Route{Host: "shop.example", Status: "failed", ClaimOwnership: owner} if err = r.Upsert(rt); err != nil { t.Fatal(err) } if err = r.SetClaimHold(t.Context(), rt.Host, owner, "", "op1"); err != nil { t.Fatal(err) } if err = r.SetClaimHold(t.Context(), rt.Host, owner, "op1", "op2"); err != nil { t.Fatal(err) } if err = r.SetClaimHold(t.Context(), rt.Host, owner, "op1", ""); !errors.Is(err, ErrClaimOwnership) { t.Fatalf("cleared replacement: %v", err) } if err = r.Upsert(rt); err != nil { t.Fatal(err) } got, err := r.Get(rt.Host) if err != nil || got.HoldOp != "op2" || got.Status != "failed" { t.Fatalf("projection erased hold: %+v %v", got, err) } successor := owner successor.ClaimStamp++ if err = r.SetClaimHold(t.Context(), rt.Host, successor, "op2", ""); !errors.Is(err, ErrClaimOwnership) { t.Fatalf("wrong owner: %v", err) } if err = r.SetClaimHold(t.Context(), rt.Host, owner, "op2", ""); err != nil { t.Fatal(err) } got, err = r.Get(rt.Host) if err != nil || got.HoldOp != "" || got.Status != "failed" { t.Fatalf("reset projection: %+v %v", got, err) } }