package host import ( "context" "github.com/carlosframework/platform/internal/hostbox" "github.com/carlosframework/platform/internal/hostclaim" "github.com/carlosframework/platform/internal/lease" "github.com/carlosframework/platform/internal/park" "github.com/carlosframework/platform/internal/provision" "github.com/carlosframework/platform/internal/release" "testing" ) func TestPlan13ProductionRemoteHomeView(t *testing.T) { t.Parallel() f := newVwFixture(t) f.rec.Region = "" f.rec.Move = &provision.MoveState{ID: vwMove, Incarnation: f.inc, From: "", To: "uk", State: provision.MoveLanding} h := f.holder("src", "src@ie") o := hostclaim.Observed{Host: vwHost, ETag: "tag", Claim: &hostclaim.Claim{Host: vwHost, Holder: h, Op: hostclaim.Op{ID: vwMove, Kind: hostclaim.KindLanding, Phase: "installing", Intent: map[string]string{"home_region": "ie"}}}} identity := handoverRecoveryIdentity(t, hostbox.Actor{Box: "box", Enrollment: "enrolled", Region: "uk", FleetHomeRegion: "ie", ControlBucket: "control", Revision: 1, Binding: "1"}) p := productionClaimRegional{Identity: identity, Local: &productionClaimLocal{legacyParticipation: true, Identity: identity, Resources: ClaimRuntimeResources{Mode: "agent", DataDir: t.TempDir()}, assembly: &ClaimAssembly{}, lifetime: t.Context()}, Parks: &claimMoveParkSources{View: f.view("uk")}} if _, err := p.View(t.Context(), hostclaim.Observed{}); err == nil { t.Fatal("missing claim accepted") } v, err := p.View(t.Context(), o) if err != nil { t.Fatal(err) } if v.AuthoritativeRegion != park.HomeRegion || v.Region != "uk" || v.HomeRegion != "ie" { t.Fatalf("view: %+v", v) } if h.Admissions[0].Region != "ie" { t.Fatal("history rewritten") } ob := hostclaim.Obligation{ID: "persisted", Kind: "park-generation", Op: vwMove, Owner: "region:uk", Region: "uk", Generation: "old", Retirement: "retirement"} store := release.NewDirStore(t.TempDir()) op := o.Claim.Op o, err = hostclaim.Update(t.Context(), store, hostclaim.Observed{Host: vwHost, Absent: true}, func(c *hostclaim.Claim) error { c.Holder = h c.Op = op c.Obligations = []hostclaim.Obligation{ob} return nil }) if err != nil { t.Fatal(err) } o, err = hostclaim.Read(t.Context(), store, vwHost) if err != nil { t.Fatal(err) } if err := p.Authorize(t.Context(), o, ob); err != nil { t.Fatal("authorized control", err) } ob.Owner, ob.Region = "region:@home", park.HomeRegion o, err = hostclaim.Update(t.Context(), store, o, func(c *hostclaim.Claim) error { c.Obligations = []hostclaim.Obligation{ob}; return nil }) if err != nil { t.Fatal(err) } o, err = hostclaim.Read(t.Context(), store, vwHost) if err != nil { t.Fatal(err) } if err := p.Authorize(t.Context(), o, ob); err == nil { t.Fatal("named worker owns home") } } func TestPlan13MovesEngineBindings(t *testing.T) { withMovesWakeSource(t, true) for _, home := range []string{"ie", ""} { region := "uk" if home != "" { region = "ie" } e := park.Engine{HomeRegion: home, Region: region, Bucket: "data", Leases: claimParkLeases(&fakeParkLeases{}), View: func(context.Context, hostclaim.Observed) (park.View, error) { return park.View{}, nil }, Authorize: allowParkAuthorize} providers := ClaimProviders{moveParks: &claimMoveParks{engine: e, leases: hostbox.ReplicaParkLeaseSet, local: func(context.Context, *hostclaim.Claim, hostclaim.Obligation) error { return nil }, check: func(context.Context) error { return nil }}} cfg := moveCfg{Region: region, OwnBucket: "data"} if home != "" { cfg.Region = "" } if err := armMovesParks(t.Context(), &cfg, providers); err != nil { t.Fatal(err) } w := &movesWorker{cfg: cfg} engines := []park.Engine{(&installRun{w: w}).engine(nil), (&sourceFinal{w: w}).engine(nil), (&rollbackRun{w: w}).engine(nil)} for _, got := range engines { if got.HomeRegion != home || !got.OwnsRegion(park.PlacementRegion(cfg.Region)) { t.Fatalf("binding lost: %+v", got) } } } } func TestPlan13HomeLaneEngineBinding(t *testing.T) { withMovesWakeSource(t, true) h := newAbortHarness(t) h.abort(t) h.pass(t) chore := h.laneChore(t) if chore == nil { t.Fatal("no chore") } h.pastHorizon(t, chore) cfg := h.laneCfg() cfg.Region = "" engine := park.Engine{Region: "uk", HomeRegion: "uk", Bucket: cfg.OwnBucket, Leases: cfg.ParkLeases, Authorize: allowParkAuthorize, View: func(_ context.Context, o hostclaim.Observed) (park.View, error) { return park.View{Region: park.HomeRegion, ClaimETag: o.ETag, AuthoritativeRegion: "ie"}, nil }} p := ClaimProviders{moveParks: &claimMoveParks{engine: engine, leases: hostbox.ReplicaParkLeaseSet, local: func(context.Context, *hostclaim.Claim, hostclaim.Obligation) error { return nil }, check: func(context.Context) error { return nil }}} if err := armMovesParks(t.Context(), &cfg, p); err != nil { t.Fatal(err) } o, err := hostclaim.Read(t.Context(), h.s, p1Host) if err != nil { t.Fatal(err) } if _, err = hostclaim.Update(t.Context(), h.s, o, func(c *hostclaim.Claim) error { c.Op.Intent["home_region"] = "uk"; return nil }); err != nil { t.Fatal(err) } rec := h.read(t, p1Host) rec.Move.To = "" worker := &movesWorker{cfg: cfg, mirrors: map[string]lease.MirrorStore{}} if err := worker.laneParkTarget(t.Context(), h.s, rec, hostclaim.KindMoving, hostclaim.PhaseAborting); err != nil { t.Fatal(err) } if h.laneChore(t) != nil { t.Fatal("named home chore was not acknowledged") } } func TestPlan13MovesViewMapsAllHomePlacements(t *testing.T) { for _, moving := range []bool{false, true} { f := newVwFixture(t) f.rec.Region = "" h := f.holder("") op := hostclaim.Op{Kind: hostclaim.KindServing} if moving { h = f.holder("src", "src@ie") op = hostclaim.Op{Kind: hostclaim.KindMoving, ID: vwMove, Intent: map[string]string{"home_region": "ie"}} f.rec.Move = &provision.MoveState{ID: vwMove, Incarnation: f.inc, From: "", To: "uk", State: provision.MoveCutting} } v, err := f.view(park.HomeRegion)(t.Context(), vwObs(&hostclaim.Claim{Holder: h, Op: op})) if !moving { if err == nil { t.Fatal("unbound legacy home accepted") } continue } if err != nil || v.AuthoritativeRegion != park.HomeRegion || !v.MarkerKnown { t.Fatal(moving, v, err) } } }