Skip to content
quarry Artifact [9267ccce57]
Login

Artifact [9267ccce57]

Artifact 9267ccce57d2adbf91daa26acbb93c89f7891817da381e57a271b9ce5179ab7a:


package index

import (
	"errors"
	"testing"
)

// A check-in that arrives after the watermark but carries an older
// date is still new: the cursor is arrival order, not check-in date.
func TestCheckinsAfterSeesAnOlderDatedArrival(t *testing.T) {
	ix := openIndex(t)
	ci(t, ix, "c1", "trunk", "2026-01-01T00:00:00", "first")
	ci(t, ix, "c3", "trunk", "2026-01-03T00:00:00", "newer", "c1")
	ci(t, ix, "c2", "side", "2026-01-02T00:00:00", "older, arrived late", "c1")
	got, err := ix.CheckinsAfter("c3", 10)
	if err != nil {
		t.Fatal(err)
	}
	if len(got) != 1 || got[0].Hash != "c2" {
		t.Fatalf("FAIL: CheckinsAfter(c3) = %v, want c2", got)
	}
}

// Two check-ins with the same date are both seen; a strict date
// comparison would drop the second.
func TestCheckinsAfterSeesASameDateArrival(t *testing.T) {
	ix := openIndex(t)
	ci(t, ix, "a", "trunk", "2026-01-01T00:00:00", "a")
	ci(t, ix, "b", "side", "2026-01-01T00:00:00", "b")
	got, err := ix.CheckinsAfter("a", 10)
	if err != nil || len(got) != 1 || got[0].Hash != "b" {
		t.Fatalf("FAIL: CheckinsAfter(a) = %v, %v", got, err)
	}
}

// A watermark the index does not hold is an explicit error the caller
// waits on, never "only the newest arrival", which skipped everything
// in between during a reindex.
func TestCheckinsAfterRefusesAnUnknownWatermark(t *testing.T) {
	ix := openIndex(t)
	ci(t, ix, "a", "trunk", "2026-01-01T00:00:00", "a")
	if _, err := ix.CheckinsAfter("gone", 10); !errors.Is(err, ErrUnknownWatermark) {
		t.Fatalf("FAIL: CheckinsAfter(gone) err = %v, want ErrUnknownWatermark", err)
	}
}

// A rebuild folds check-ins in the store's arrival order, so a
// watermark lands where it was and nothing before it reads as new.
func TestAWatermarkSurvivesARebuild(t *testing.T) {
	ix := openIndex(t)
	fold := func() {
		ci(t, ix, "c1", "trunk", "2026-01-01T00:00:00", "first")
		ci(t, ix, "c3", "trunk", "2026-01-03T00:00:00", "newer", "c1")
		ci(t, ix, "c2", "side", "2026-01-02T00:00:00", "older", "c1")
	}
	fold()
	if err := ix.Reset(); err != nil {
		t.Fatal(err)
	}
	fold()
	got, err := ix.CheckinsAfter("c3", 10)
	if err != nil || len(got) != 1 || got[0].Hash != "c2" {
		t.Fatalf("FAIL: after rebuild CheckinsAfter(c3) = %v, %v; want only c2", got, err)
	}
}