package park import ( "context" "github.com/carlosframework/platform/internal/hostclaim" "testing" ) func TestPlan13ObserveRemoteBinding(t *testing.T) { f := newFixture(t) o, err := hostclaim.Read(t.Context(), f.e.Claims, f.w.Host) if err != nil { t.Fatal(err) } _, err = hostclaim.Update(t.Context(), f.e.Claims, o, func(c *hostclaim.Claim) error { c.Op.Intent = map[string]string{"home_region": "ie"}; return nil }) if err != nil { t.Fatal(err) } f.e.Region = "uk" f.e.View = func(_ context.Context, o hostclaim.Observed) (View, error) { return View{Region: "uk", HomeRegion: "ie", ClaimETag: o.ETag}, nil } _, v, err := f.e.observe(t.Context(), f.w, f.held, f.ob) if err != nil { t.Fatal(err) } if v.HomeRegion != "ie" || f.e.OwnsRegion(HomeRegion) { t.Fatal("history binding lost or ownership widened") } c := &hostclaim.Claim{Holder: &hostclaim.Holder{Location: f.ob.Park.Location, Generation: "new", Admissions: []hostclaim.AdmissionRecord{{Generation: "new", Predecessor: "old", Region: "ie", PredecessorRegion: HomeRegion, Mode: "cold"}}}, Op: hostclaim.Op{Kind: hostclaim.KindServing}} v.GenerationOf = func(Ref) (string, bool) { return "old", true } v.Region = HomeRegion v.AuthoritativeRegion = HomeRegion v.MarkerKnown = true v.MarkerGeneration = "old" live, err := LiveGenerations(c, v, c.Holder.Location) if err != nil || !live["old"] || !live["new"] { t.Fatal(live, err) } } func TestPlan13CompletedHomeParkCoversNamedPredecessor(t *testing.T) { f := newFixture(t) f.e.HomeRegion = "ie" f.e.Region = HomeRegion o, err := hostclaim.Read(t.Context(), f.e.Claims, f.w.Host) if err != nil { t.Fatal(err) } _, err = hostclaim.Update(t.Context(), f.e.Claims, o, func(c *hostclaim.Claim) error { c.Obligations[0].Region = HomeRegion c.Obligations[0].Owner = "region:" + HomeRegion c.Holder.Generation = "next" c.Holder.Admissions = []hostclaim.AdmissionRecord{{Generation: "next", Predecessor: "old", Region: "uk", PredecessorRegion: "ie", Mode: "cold"}, {Generation: "foreign", Predecessor: "old", Region: "fr", PredecessorRegion: "fr", Mode: "cold"}} return nil }) if err != nil { t.Fatal(err) } f.e.View = func(_ context.Context, o hostclaim.Observed) (View, error) { return View{Region: HomeRegion, ClaimETag: o.ETag, AuthoritativeRegion: "uk", GenerationOf: func(Ref) (string, bool) { return "old", true }}, nil } f.b.Put("data", f.ob.Park.Location+"/g-old/0000/a", []byte("old")) if err := f.e.Run(t.Context(), f.w); err != nil { t.Fatal(err) } done, err := hostclaim.Read(t.Context(), f.e.Claims, f.w.Host) if err != nil { t.Fatal(err) } if len(done.Claim.Obligations) != 0 || !done.Claim.Holder.Admissions[0].Covered || done.Claim.Holder.Admissions[1].Covered { t.Fatalf("coverage: %+v", done.Claim.Holder.Admissions) } } func TestPlan13SweepRejectsConflictingHome(t *testing.T) { f := newFixture(t) f.e.HomeRegion = "ie" o, err := hostclaim.Read(t.Context(), f.e.Claims, f.w.Host) if err != nil { t.Fatal(err) } _, err = hostclaim.Update(t.Context(), f.e.Claims, o, func(c *hostclaim.Claim) error { c.Op.Intent = map[string]string{"home_region": "uk"}; return nil }) if err != nil { t.Fatal(err) } if _, err = f.e.Sweep(t.Context(), f.w.Host, "", f.e.Now(), f.ob.Park.RequestLimit); err == nil { t.Fatal("conflicting home binding accepted") } } func TestPlan13SweepAbsentClaimRefuses(t *testing.T) { f := newFixture(t) f.e.View = func(context.Context, hostclaim.Observed) (View, error) { return View{}, nil } if _, err := f.e.Sweep(t.Context(), "absent.example", "", f.e.Now(), f.ob.Park.RequestLimit); err == nil { t.Fatal("absent claim accepted") } } func TestPlan13ReturningWriterEmptyHomePark(t *testing.T) { f := newFixture(t) choreIn(t, f, HomeRegion) f.e.HomeRegion = "ie" engineIn(f, HomeRegion, HomeRegion) o, err := hostclaim.Read(t.Context(), f.e.Claims, f.w.Host) if err != nil { t.Fatal(err) } o, err = hostclaim.Update(t.Context(), f.e.Claims, o, func(c *hostclaim.Claim) error { c.Op = hostclaim.Op{ID: "op", Kind: hostclaim.KindRestoring, Phase: hostclaim.PhaseClaimed, Exec: "returner", Intent: map[string]string{"home_region": "ie"}} c.Holder.Generation, c.Holder.Session, c.Holder.WriterBox = "old", 1, "target" c.Holder.Admissions = []hostclaim.AdmissionRecord{{Generation: "old", Region: "ie", Session: 1, Box: "target", Mode: "cold"}} return nil }) if err != nil { t.Fatal(err) } o, err = hostclaim.Update(t.Context(), f.e.Claims, o, hostclaim.AdmitWriter(hostclaim.Admission{ObservedOpID: "op", ObservedPhase: hostclaim.PhaseClaimed, ObservedSession: 1, ObservedGeneration: "old", Region: "uk", Box: "returner", Mode: "cold", NewGeneration: "return"})) if err != nil { t.Fatal(err) } if !o.Claim.Holder.Admissions[1].Covered { t.Fatal("returning predecessor uncovered") } if err := f.e.Run(t.Context(), f.w); err != nil { t.Fatal(err) } done, err := hostclaim.Read(t.Context(), f.e.Claims, f.w.Host) if err != nil { t.Fatal(err) } if len(done.Claim.Obligations) != 0 || !done.Claim.Holder.Admissions[1].Covered || done.Claim.Holder.Admissions[1].PredecessorRegion != "ie" { t.Fatal(done.Claim) } }