//go:build unix package hostbox import ( "context" "errors" "os" "path/filepath" "testing" "time" "github.com/carlosframework/platform/internal/hostclaim" "github.com/carlosframework/platform/internal/hostguard" "github.com/carlosframework/platform/internal/hostwrite" "github.com/carlosframework/platform/internal/provision" "github.com/carlosframework/platform/internal/registry" "github.com/carlosframework/platform/internal/release" ) // The production adapter, driven by the real reconcile passes, hands the // RecordSelection it derived to the record check. That check aborts the // install, so nothing is written; what it saw is the layout the claim // inventory would have been stamped with. func TestAdapterSelectionLayoutFollowsRoutePaths(t *testing.T) { stop := errors.New("selection captured") for _, tc := range []struct { name string sidecar bool mode string want string }{ {"instance minted nested", false, release.LayoutModeNested, "nested"}, {"instance minted flat", false, release.LayoutModeFlat, "flat"}, {"sidecar stays flat on a nested box", true, release.LayoutModeNested, "flat"}, } { t.Run(tc.name, func(t *testing.T) { ctx := t.Context() f := newAdmissionFixture(t, tc.sidecar) reg, err := registry.Open(filepath.Join(t.TempDir(), "registry.db")) if err != nil { t.Fatal(err) } defer reg.Close() inventory, err := OpenStopInventoryDB(filepath.Join(t.TempDir(), "inventory.db")) if err != nil { t.Fatal(err) } defer inventory.Close() var seen []RecordSelection adapter := ReconcileAdapter{ Registry: reg, Inventory: inventory, Box: "box", Enrollment: "en", DirectoryRevision: "1", Reconciler: Reconciler{ Claims: f.store, Box: "box", Region: "ie", Guard: hostguard.Guard{DataDir: f.data, LockDir: t.TempDir(), Claims: hostguard.StoreReader{Store: f.store}}, Writes: hostwrite.Config{Enabled: true}, Now: func() time.Time { return time.Unix(100, 0) }, CheckRecord: func(_ context.Context, s RecordSelection) error { seen = append(seen, s); return stop }, CheckLocal: func(context.Context, hostclaim.Observed, RecordSelection) error { return nil }, }, } cfg := provision.ReconcileConfig{DataDir: f.data, Region: "ie"} cfg.Layout = func(context.Context, release.Store) (string, error) { return tc.mode, nil } adapter.Configure(&cfg) if !cfg.ClaimEnabled { t.Fatal("adapter did not enable claim admission") } if err := f.pass(ctx, f.store, reg, cfg); err != nil { t.Fatal(err) } if len(seen) != 1 { t.Fatalf("record check ran %d times, want 1", len(seen)) } if seen[0].Layout != tc.want || seen[0].Host != f.host || seen[0].Family != f.family { t.Fatalf("selection = %+v, want layout %q for %s %s", seen[0], tc.want, f.family, f.host) } if row, err := reg.Get(f.host); err != nil || row != nil { t.Fatalf("aborted install wrote a route: %v", err) } if _, err := os.Stat(filepath.Join(f.data, "hostguard", f.host+".json")); !errors.Is(err, os.ErrNotExist) { t.Fatalf("aborted install activated the guard: %v", err) } }) } }