package main import ( "context" "fmt" "os" "path/filepath" "strings" "testing" "time" "github.com/carlosframework/platform/internal/release" ) // manifestCountingStore is the production store shape in miniature — a bare // DirStore, ListMod and all (struct embedding keeps the method) — counting // manifest reads specifically, so the tag reads ListTags does don't muddy // the assertion. type manifestCountingStore struct { *release.DirStore manifestGets int } func (c *manifestCountingStore) Get(ctx context.Context, key string) ([]byte, string, error) { if strings.HasSuffix(key, "/manifest.json") { c.manifestGets++ } return c.DirStore.Get(ctx, key) } // TestLocalReleasesBoundsManifestReads: `carlos releases` direct mode reads // only the manifests it will print, chosen by manifest mod time exactly as // the console does (release.VersionCandidates is shared) — version names // here are numbered AGAINST recency so a name-ranked selection fails, and a // fetch-everything regression fails the read count. func TestLocalReleasesBoundsManifestReads(t *testing.T) { dir := t.TempDir() store := &manifestCountingStore{DirStore: release.NewDirStore(dir)} ctx := context.Background() base := time.Date(2026, 8, 1, 10, 0, 0, 0, time.UTC) const shipped = releasesCap + 5 for i := 1; i <= shipped; i++ { v := fmt.Sprintf("v%02d", i) mod := base.Add(time.Duration(shipped-i) * time.Minute) // v01 newest m := release.Manifest{ Schema: 1, App: "kass", Version: v, Kind: "binary", BuiltAt: mod.Format(time.RFC3339), Artifacts: map[string]release.Artifact{"linux-amd64": {File: "kass"}}, } if err := release.Ship(ctx, store, release.OpsAccount, m, map[string][]byte{"linux-amd64": []byte("bin " + v)}); err != nil { t.Fatal(err) } key := release.ManifestKey(release.OpsAccount, "kass", v) if err := os.Chtimes(filepath.Join(dir, filepath.FromSlash(key)), mod, mod); err != nil { t.Fatal(err) } } store.manifestGets = 0 // Ship reads during setup don't count rows, err := localReleases(ctx, store, release.OpsAccount, "kass") if err != nil { t.Fatal(err) } if len(rows) != releasesCap { t.Fatalf("len = %d, want releasesCap %d", len(rows), releasesCap) } for i := 0; i < releasesCap; i++ { want := fmt.Sprintf("v%02d", i+1) if rows[i].Version != want { t.Fatalf("rows[%d] = %s, want %s (rank by mod time, not name)", i, rows[i].Version, want) } } if rows[0].Kind != "binary" || rows[0].Err != "" { t.Fatalf("rows[0] = %+v, want a rendered release row", rows[0]) } if store.manifestGets != releasesCap { t.Fatalf("read %d manifests for %d shipped versions, want %d", store.manifestGets, shipped, releasesCap) } }