package host import ( "context" "os" "testing" "github.com/carlosframework/platform/internal/hostguard" "github.com/carlosframework/platform/internal/release" "github.com/carlosframework/platform/internal/rootparticipation" "github.com/carlosframework/platform/internal/rootstate" ) type heldHostStore struct { rootstate.Store locks int } func (s *heldHostStore) Lock(context.Context, string) (func(), error) { s.locks++ return nil, os.ErrPermission } func TestPlan14LaunchSettingsUnderHostGuard(t *testing.T) { disk := &rollbackMemory{files: map[string][]byte{}} in := hostguard.RootInstallation{Host: "shop.example", Incarnation: "inc", Stamp: 2, Account: "bab", App: "app", Record: "record", Box: "box", Enrollment: "en", Migration: 1, InventoryRevision: 1} if err := hostguard.NewRootAuthority(disk).RetainMigrationDeny(t.Context(), in, 1); err != nil { t.Fatal(err) } held := &heldHostStore{Store: disk} source := rootRestartRequestSource{state: held, census: func() (rootparticipation.Census, error) { return rootparticipation.Census{Complete: true, Box: "box", Enrollment: "en", Migration: 1}, nil }} b := release.GenerationBinding{Binding: release.HistoryBinding{Host: in.Host, Account: in.Account, App: in.App}, Target: release.GenerationOwner{Host: in.Host, Incarnation: in.Incarnation, Stamp: in.Stamp, Box: in.Box, Enrollment: in.Enrollment}, Installation: rootHistoryInstallation(in), Record: in.Record} if got, err := source.launchInstallation(t.Context(), in.Host, b); err != nil || got.Host != in.Host || held.locks != 0 { t.Fatal("nested lock or wrong installation", err, held.locks) } for _, field := range []string{"host", "stamp", "installation", "account", "record", "box", "enrollment"} { bad := b switch field { case "host": bad.Target.Host = "other.example" case "stamp": bad.Target.Stamp++ case "installation": bad.Installation = "foreign" case "account": bad.Binding.Account = "foreign" case "record": bad.Record = "foreign" case "box": bad.Target.Box = "foreign" case "enrollment": bad.Target.Enrollment = "foreign" } if _, err := source.launchInstallation(t.Context(), in.Host, bad); err == nil { t.Fatal("accepted changed", field) } } if _, err := source.installation(t.Context(), in.Host); err == nil || held.locks == 0 { t.Fatal("ordinary lookup stopped taking the host lock", err) } }