package host import ( "context" "os" "strings" "testing" "github.com/carlosframework/platform/internal/instancectl" "github.com/carlosframework/platform/internal/rootstate" ) func TestPlan14UnitStartupIsolation(t *testing.T) { b, in, shape := plan14UnitBindingFixture(t, "console.service", "", "") shape.Program = strings.Repeat("a", 64) b.canonical = func(context.Context, string) (claimUnitShape, error) { return shape, nil } if _, err := b.establish(t.Context(), in.Host); err != nil { t.Fatal(err) } d := claimUnitDispatch{bindings: b, shapes: func() (map[string]claimUnitShape, error) { return nil, os.ErrPermission }} if unit, _, err := d.Placement("sibling.example"); err != nil || unit != instancectl.UnitName(instancectl.RoleRun, "sibling.example") { t.Fatal("config corruption blocked ordinary cleanup", unit, err) } if _, err := d.forStart(t.Context(), in.Host); err == nil { t.Fatal("corrupt config launched named unit") } if _, err := d.forStart(t.Context(), "sibling.example"); err == nil { t.Fatal("corrupt config allowed an unverified ordinary launch") } d.shapes = func() (map[string]claimUnitShape, error) { return map[string]claimUnitShape{}, nil } checked := false d.effective = func(context.Context, claimUnitShape) error { checked = true; return nil } if _, err := d.forStart(t.Context(), "sibling.example"); err != nil || !checked { t.Fatal("verified ordinary launch refused", err, checked) } } func TestPlan14ProductionUnitStartupIsolation(t *testing.T) { for _, corrupt := range []bool{false, true} { t.Run(map[bool]string{false: "bad-program", true: "corrupt-config"}[corrupt], func(t *testing.T) { f, _, _ := generationLaunchFixture(t) b, in, shape := plan14UnitBindingFixture(t, "console.service", "", "") if _, err := b.establish(t.Context(), in.Host); err != nil { t.Fatal(err) } oldOpen, oldMaterials, oldShapes := openClaimUnitBindings, openClaimUnitMaterializations, productionClaimUnitShapes defer func() { openClaimUnitBindings, openClaimUnitMaterializations, productionClaimUnitShapes = oldOpen, oldMaterials, oldShapes }() openClaimUnitBindings = func() (rootstate.Store, error) { return b.state, nil } openClaimUnitMaterializations = func() (rootstate.Store, error) { return &rollbackDisk{dir: t.TempDir()}, nil } productionClaimUnitShapes = func() (map[string]claimUnitShape, error) { if corrupt { return nil, os.ErrPermission } return map[string]claimUnitShape{in.Host: shape}, nil } base := instancectl.ClaimUnits{Systemctl: func(_ context.Context, args ...string) (string, error) { if len(args) != 1 || args[0] != "daemon-reload" { t.Fatal("startup touched a unit", args) } return "", nil }} f.root.Units = base wrapped := ClaimRootWithLaunch{Launch: f.root} wrapped.Root.Stop.Coordinator.Kernel = claimUnitStopKernel{Units: base} a := &ClaimAssembly{} if err := bindProductionClaimUnits(t.Context(), &wrapped, a); err != nil { t.Fatal("one unit killed root startup", err) } defer a.Close(t.Context()) for _, units := range []ClaimLaunchUnits{wrapped.Launch.Units, wrapped.Root.Stop.Coordinator.Kernel.(claimUnitStopKernel).Units} { p := units.(interface { Placement(string) (string, string, error) }) if unit, _, err := p.Placement("ordinary.example"); err != nil || unit != instancectl.UnitName(instancectl.RoleRun, "ordinary.example") { t.Fatal("ordinary host blocked", unit, err) } if unit, _, err := p.Placement(in.Host); err != nil || unit != shape.Unit { t.Fatal("retained cleanup placement lost", unit, err) } } }) } }