package host import ( "context" "github.com/carlosframework/platform/internal/moves" "github.com/carlosframework/platform/internal/rootstate" "os" "path/filepath" "testing" ) func TestPlan14FloorNoDeadEndCurrentExecutor(t *testing.T) { for _, source := range []string{"root-authorized bound", "agent-written moves", "unpublished seeds"} { t.Run(source, func(t *testing.T) { f := rootMovesFloors{private: &rollbackMemory{files: map[string][]byte{}}, public: &rollbackMemory{files: map[string][]byte{}}, identity: rootFloorIdentity{"d", "b", "e"}} high := &moves.Floor{Min: 1, MinRelease: "v9.0.0"} if source == "root-authorized bound" { if err := f.reconstruct(t.Context(), rootFloorReconstruction{Identity: f.identity, Floor: high, Source: "root observation", Digest: floorTestDigest, Authorization: floorTestAuthorization(t, f)}); err != nil { t.Fatal(err) } } else if err := f.refresh(t.Context(), nil, []*moves.Floor{high}, nil); err != nil { t.Fatal(err) } binary := rootFloorBinary{Version: "v1.0.0", Protocol: 1, Digest: floorTestDigest} if source == "unpublished seeds" { binary = binary.forSeeds() } j := rootFloorJudge{floors: f, current: "current", prev: "prev", binary: func(string) (rootFloorBinary, error) { return binary, nil }} got, err := rootFloorBootCandidate(t.Context(), j, false, nil, nil) if err != nil || got != "current" { t.Fatalf("R6 stranded certified executor: source=%s selected=%q err=%v", source, got, err) } }) } } func TestPlan14FloorNoDeadEndUnknownPrev(t *testing.T) { f := rootMovesFloors{private: &rollbackMemory{files: map[string][]byte{}}, public: &rollbackMemory{files: map[string][]byte{}}, identity: rootFloorIdentity{"d", "b", "e"}} j := rootFloorJudge{floors: f, current: "current", prev: "prev", binary: func(string) (rootFloorBinary, error) { return rootFloorBinary{Version: "v1.0.0", Protocol: 1, Digest: floorTestDigest}, nil }} got, err := rootFloorBootCandidate(t.Context(), j, true, func(context.Context, string) error { return nil }, func(context.Context) error { return nil }) if err != nil || got != "prev" { t.Fatalf("R6 unknown history lost eligible signed prev: selected=%q err=%v", got, err) } } func TestPlan14FloorNoDeadEndNotePrev(t *testing.T) { f := rootMovesFloors{private: &rollbackMemory{files: map[string][]byte{}}, public: &rollbackMemory{files: map[string][]byte{}}, identity: rootFloorIdentity{"d", "b", "e"}} if err := f.refresh(t.Context(), nil, []*moves.Floor{{Min: 1, MinRelease: "v9.0.0"}}, nil); err != nil { t.Fatal(err) } j := rootFloorJudge{floors: f, current: "current", prev: "prev", binary: func(string) (rootFloorBinary, error) { return rootFloorBinary{Version: "v1.0.0", Protocol: 1, Digest: floorTestDigest}, nil }, idle: func(context.Context) error { return nil }} if err := j.judge(t.Context()); err != nil { t.Fatalf("R6 notePrev judge refuses rescue install: %v", err) } } func TestPlan14FloorNoDeadEndLegacyCapAndHealth(t *testing.T) { f := rootMovesFloors{private: &rollbackMemory{files: map[string][]byte{}}, public: &rollbackMemory{files: map[string][]byte{}}, identity: rootFloorIdentity{"d", "b", "e"}} high := &moves.Floor{Min: 9, MinRelease: "v9.0.0"} if err := f.refresh(t.Context(), nil, []*moves.Floor{high}, nil); err != nil { t.Fatal(err) } if b, err := f.localBound(); err != nil || b != nil { t.Fatal("agent initialized floor", b, err) } b := rootFloorBinary{Version: "v2.0.0", Protocol: 2, Digest: floorTestDigest} if err := f.acceptHealthy(t.Context(), b); err != nil { t.Fatal(err) } if _, err := f.projection(); err != nil { t.Fatal("root health did not establish accepted history", err) } _ = f.refresh(t.Context(), nil, []*moves.Floor{high}, nil) got, err := f.localBound() if err != nil || got == nil || got.Min != 2 || got.MinRelease != "v2.0.0" { t.Fatal("agent escaped health cap", got, err) } // A lower healthy recovery cannot erase the highest root observation. b.Version = "v1.0.0" if err := f.acceptHealthy(t.Context(), b); err != nil { t.Fatal(err) } h, err := f.healthy() if err != nil || h.Version != "v2.0.0" { t.Fatal("health cap regressed", h, err) } } type floorOrderStore struct { rootstate.Store held *bool } func (s floorOrderStore) Lock(ctx context.Context, name string) (func(), error) { unlock, err := s.Store.Lock(ctx, name) if err != nil { return nil, err } *s.held = true return func() { *s.held = false; unlock() }, nil } func TestPlan14RootFloorParticipationBeforeFloor(t *testing.T) { held := false f := rootMovesFloors{private: floorOrderStore{Store: &rollbackMemory{files: map[string][]byte{}}, held: &held}, public: &rollbackMemory{files: map[string][]byte{}}, identity: rootFloorIdentity{"d", "b", "e"}} calls := 0 j := rootFloorJudge{floors: f, current: "current", prev: "prev", binary: func(string) (rootFloorBinary, error) { return rootFloorBinary{Version: "v1.0.0", Protocol: 1, Digest: floorTestDigest}, nil }, idle: func(context.Context) error { calls++ if held { t.Fatal("participation acquired under floor lock") } return nil }} if err := j.judge(t.Context()); err != nil { t.Fatal(err) } if calls != 1 { t.Fatal("participation check omitted") } } func TestPlan14FloorAvailableStagedCandidate(t *testing.T) { low := rootFloorBinary{Version: "v1.0.0", Protocol: 1, Digest: floorTestDigest} high := low high.Version = "v9.0.0" opt := t.TempDir() staged := filepath.Join(systemRootDir(opt), "staging", "carlos") present := false j := rootFloorJudge{current: systemBinaryPath(opt), prev: systemPrevPath(opt), binary: func(path string) (rootFloorBinary, error) { if path == staged { if present { return high, nil } return rootFloorBinary{}, os.ErrNotExist } return low, nil }} bound := &moves.Floor{Min: 1, MinRelease: "v9.0.0"} if !j.permits(low, bound) { t.Fatal("no available build must permit recovery") } present = true if j.permits(low, bound) { t.Fatal("staged certified candidate must preserve floor refusal") } }