Artifact d232ad3e0625264e255acd09b572ea65256c55d649829d17ba40a31277018f7b:
- File
internal/ingest/ingest_test.go
— part of check-in
[83db19e8c7]
at
2026-08-15 10:52:57
on branch trunk
— phase 1 tracer (minus NATS): index, watcher, timeline op + page
SQLite fold via ncruces driver; ingest.Sync with cursor-loss rebuild; serve --repo; harness wipe is now a real rm -rf + re-ingest. (user: dmestas, size: 2956) [annotate] [blame] [check-ins using]
package ingest import ( "os" "os/exec" "path/filepath" "strings" "testing" "craftdesign.group/quarry/internal/index" "craftdesign.group/quarry/internal/zitcli" ) func run(t *testing.T, dir string, args ...string) { t.Helper() cmd := exec.Command("zit", args...) cmd.Dir = dir if out, err := cmd.CombinedOutput(); err != nil { t.Fatalf("zit %v: %v\n%s", args, err, out) } } func commitFile(t *testing.T, repo, name, body, msg string) { t.Helper() if err := os.WriteFile(filepath.Join(repo, name), []byte(body), 0o644); err != nil { t.Fatal(err) } run(t, repo, "add", name) run(t, repo, "commit", "-m", msg) } func testSetup(t *testing.T) (*zitcli.Client, *index.Index, string) { t.Helper() if _, err := exec.LookPath("zit"); err != nil { t.Skip("zit not on PATH") } repo := t.TempDir() run(t, repo, "init") commitFile(t, repo, "a.txt", "alpha\n", "add a") commitFile(t, repo, "b.txt", "beta\n", "add b") ix, err := index.Open(filepath.Join(t.TempDir(), "index.db")) if err != nil { t.Fatal(err) } t.Cleanup(func() { ix.Close() }) return zitcli.New(repo), ix, repo } func TestSyncBootstrapAndIncremental(t *testing.T) { cli, ix, repo := testSetup(t) n, err := Sync(cli, ix) if err != nil { t.Fatal(err) } if n == 0 { t.Fatal("bootstrap folded nothing") } tl, err := ix.Timeline(10) if err != nil { t.Fatal(err) } // zit init creates no initial check-in; two commits, two entries. // Same-second commits tie on date, so assert membership, not wall // order — the ordering guarantee under test is determinism (date // then hash), which the disposability harness covers. if len(tl) != 2 { t.Fatalf("timeline has %d entries: %+v", len(tl), tl) } comments := map[string]bool{tl[0].Comment: true, tl[1].Comment: true} if !comments["add a"] || !comments["add b"] { t.Fatalf("timeline contents: %+v", tl) } // Current cursor: no-op. if n, err = Sync(cli, ix); err != nil || n != 0 { t.Fatalf("idle sync: n=%d err=%v", n, err) } // Append converges. commitFile(t, repo, "c.txt", "gamma\n", "add c") if n, err = Sync(cli, ix); err != nil || n == 0 { t.Fatalf("incremental sync: n=%d err=%v", n, err) } tl, _ = ix.Timeline(10) if len(tl) != 3 { t.Fatalf("timeline after append: %+v", tl) } } func TestSyncRecoversFromStoreRewrite(t *testing.T) { cli, ix, repo := testSetup(t) if _, err := Sync(cli, ix); err != nil { t.Fatal(err) } before, _ := ix.Timeline(10) // Rewrite the store under the cursor: shun a blob and reclaim. head, err := exec.Command("zit", "ls", "-R", repo, "tip").Output() if err != nil { t.Fatal(err) } blob := strings.Fields(string(head))[0] run(t, repo, "shun", blob, "--force") if _, err := Sync(cli, ix); err != nil { t.Fatalf("sync after rewrite should reset and rebuild, got %v", err) } after, _ := ix.Timeline(10) if len(after) != len(before) { t.Fatalf("rebuild diverged: %d vs %d check-ins", len(after), len(before)) } }