Artifact 09843923be615c96a40034d24fe6e97eb9ffc77f0580ba9cf723078cd0b60b8d:
- File
internal/sync/sparse_prepared_lifecycle_test.go
— part of check-in
[63e0b940eb]
at
2026-10-21 00:05:34
on branch feat/submanifest-reader
— feat(sync): prototype internal prepared sparse serving lifecycle
Separate immutable cone-independent raw facts from request-local classification. Validate the observer connection, database generation and post-preparation file identity under a bound transaction. Unsupported, stale and mutating requests use dense fallback without cold cone discovery while preserving sparse-origin refusal.
Exercise real clone and pull over excluded candidates, same-request writes, observer lifecycle and durable cluster advertisements across restart. Classification and inventory remain whole-store work; this does not close sparse per-round resource bounds or expose a public lifecycle API. (user: [email protected], size: 4807) [annotate] [blame] [check-ins using] [more...]
package sync import ( "context" "strings" "testing" "github.com/danmestas/go-libfossil/db" "github.com/danmestas/go-libfossil/internal/blob" "github.com/danmestas/go-libfossil/internal/cone" "github.com/danmestas/go-libfossil/internal/content" "github.com/danmestas/go-libfossil/internal/deck" "github.com/danmestas/go-libfossil/internal/hash" "github.com/danmestas/go-libfossil/internal/manifest" "github.com/danmestas/go-libfossil/internal/repo" "github.com/danmestas/go-libfossil/internal/xfer" ) func TestPreparedSparseServiceSameRequestMutation(t *testing.T) { r := setupSyncTestRepo(t) if _, err := r.DB().Exec("UPDATE user SET cap='goix' WHERE login='nobody'"); err != nil { t.Fatal(err) } service, err := prepareSparseService(context.Background(), r, HandleOpts{}) if err != nil { t.Fatal(err) } defer service.Close() data := []byte("new artifact within the same request") uuid := hash.SHA1(data) cards := preparedCloneCards()[:3] cards = append(cards, &xfer.PushCard{ServerCode: "test", ProjectCode: testPC}, &xfer.FileCard{UUID: uuid, Content: data}, &xfer.CloneCard{Version: 3, SeqNo: 1, SeqNoIsDecimal: true}) resp, applied, err := service.handle(context.Background(), &xfer.Message{Cards: cards}) if err != nil || applied { t.Fatalf("mutating response: applied=%v err=%v", applied, err) } if !preparedHasFile(resp, uuid) { for _, card := range resp.Cards { t.Logf("reply %T: %+v", card, card) } t.Fatal("same-request newly stored artifact missing from dense clone") } if _, exists := blob.Exists(r.DB(), uuid); !exists { t.Fatal("fallback did not commit accepted file") } } func TestPreparedSparseServiceFallbackPreservesOriginRefusal(t *testing.T) { r := setupSyncTestRepo(t) c, err := cone.New([]string{"src"}, nil) if err != nil { t.Fatal(err) } if err := content.SetStoreCone(r.DB(), c); err != nil { t.Fatal(err) } service, err := prepareSparseService(context.Background(), r, HandleOpts{}) if err != nil { t.Fatal(err) } defer service.Close() storeTestBlob(t, r, []byte("invalidate prepared snapshot")) cards := preparedCloneCards() cards[2] = &xfer.PragmaCard{Name: "cone", Values: []string{"zzz"}} resp, applied, err := service.handle(context.Background(), &xfer.Message{Cards: cards}) if err != nil || applied { t.Fatalf("fallback: applied=%v err=%v", applied, err) } for _, card := range resp.Cards { if c, ok := card.(*xfer.ErrorCard); ok && strings.Contains(c.Message, "Sparse cone does not cover requested clone") { return } } t.Fatal("dense fallback removed the request cone and bypassed origin coverage") } func TestPreparedSparseServiceAdvertisedClusterSurvivesRestart(t *testing.T) { r := setupSyncTestRepo(t) member := storeTestBlob(t, r, []byte("durable prepared cluster member")) cluster := &deck.Deck{M: []string{member}} data, err := cluster.Marshal() if err != nil { t.Fatal(err) } var uuid string if err := r.WithTx(func(tx *db.Tx) error { rid, name, err := blob.Store(tx, data) if err != nil { return err } uuid = name return manifest.CrosslinkCluster(tx, rid, cluster) }); err != nil { t.Fatal(err) } service, err := prepareSparseService(context.Background(), r, HandleOpts{}) if err != nil { t.Fatal(err) } transport := &preparedSparseTransport{service: service} cards := preparedCloneCards()[:3] cards = append(cards, &xfer.PullCard{ServerCode: "test", ProjectCode: testPC}) resp, err := transport.Exchange(context.Background(), &xfer.Message{Cards: cards}) if err != nil { t.Fatal(err) } announced := false for _, card := range resp.Cards { if c, ok := card.(*xfer.IGotCard); ok && c.UUID == uuid { announced = true } } if !announced || transport.applied != 1 { t.Fatalf("prepared pull announced=%v prepared=%d", announced, transport.applied) } storeTestBlob(t, r, []byte("generation after advertisement")) if err := service.Close(); err != nil { t.Fatal(err) } path := r.Path() if err := r.Close(); err != nil { t.Fatal(err) } reopened, err := repo.Open(path) if err != nil { t.Fatal(err) } defer reopened.Close() service, err = prepareSparseService(context.Background(), reopened, HandleOpts{}) if err != nil { t.Fatal(err) } defer service.Close() transport = &preparedSparseTransport{service: service} cards = append(cards, &xfer.GimmeCard{UUID: uuid}) resp, err = transport.Exchange(context.Background(), &xfer.Message{Cards: cards}) if err != nil { t.Fatal(err) } for _, card := range resp.Cards { if c, ok := card.(*xfer.FileCard); ok && c.UUID == uuid { if string(c.Content) != string(data) || hash.SHA3(c.Content) != uuid { t.Fatal("advertised cluster changed across refresh/restart") } return } } t.Fatal("advertised cluster unavailable after refresh/restart") }