improvement on user management
Build and Push Docker Image / build (push) Failing after 14s

This commit is contained in:
Worph
2026-08-02 21:35:39 +02:00
parent 1f084b817c
commit 55d08e77ed
3 changed files with 111 additions and 6 deletions
+79
View File
@@ -0,0 +1,79 @@
package storage
import (
"testing"
)
// A tombstone must leave the cell in place but drop the cid from the user+key
// index.
//
// The cell has to stay: it *is* the CRDT state, and deleting it would let an
// older write resurrect the value the tombstone retracted. The index entry has
// to go: `active_for_user_key` returns every member of that set, so a set that
// only ever grows means each My List / Continue Watching read carries every
// title the user has ever un-liked or finished — with its full record blob —
// forever. The reader filters them out again, so the cost is invisible until
// the account is old.
func TestUDLUpsert_TombstonePrunesUserKeyIndexButKeepsCell(t *testing.T) {
c, _ := newTestClient(t, "")
const (
uid = "zAlice"
cid = "bagcsaaalocator"
key = "seek"
)
// A live position: indexed, readable.
if ok, err := c.UDLUpsertIfNewer(uid, cid, key, 1, 100, "rec-v1", "", false, false); err != nil || !ok {
t.Fatalf("live upsert: ok=%v err=%v", ok, err)
}
entries, err := c.UDLListUserKey(uid, key)
if err != nil {
t.Fatalf("active_for_user_key: %v", err)
}
if len(entries) != 1 || entries[0].Cid != cid {
t.Fatalf("live position should be indexed, got %+v", entries)
}
// Finishing it tombstones the seek.
if ok, err := c.UDLUpsertIfNewer(uid, cid, key, 2, 200, "rec-v2-tombstone", "", false, true); err != nil || !ok {
t.Fatalf("tombstone upsert: ok=%v err=%v", ok, err)
}
entries, err = c.UDLListUserKey(uid, key)
if err != nil {
t.Fatalf("active_for_user_key after tombstone: %v", err)
}
if len(entries) != 0 {
t.Fatalf("tombstoned cid must leave the user+key index, got %+v", entries)
}
// ...but the cell itself survives, at the tombstone's version.
cell, exists, err := c.UDLGetCell(uid, cid, key)
if err != nil {
t.Fatalf("get cell: %v", err)
}
if !exists {
t.Fatal("tombstone must not delete the cell — an older write could then resurrect the value")
}
if cell.Version != 2 || cell.Record != "rec-v2-tombstone" {
t.Fatalf("cell should hold the tombstone record at v2, got %+v", cell)
}
// And the high-water mark still rejects the superseded write.
if ok, err := c.UDLUpsertIfNewer(uid, cid, key, 1, 300, "rec-v1-replay", "", false, false); err != nil || ok {
t.Fatalf("stale replay must be rejected: ok=%v err=%v", ok, err)
}
// Re-watching re-establishes the cell and puts it back in the index.
if ok, err := c.UDLUpsertIfNewer(uid, cid, key, 3, 400, "rec-v3", "", false, false); err != nil || !ok {
t.Fatalf("re-establish upsert: ok=%v err=%v", ok, err)
}
entries, err = c.UDLListUserKey(uid, key)
if err != nil {
t.Fatalf("active_for_user_key after re-establish: %v", err)
}
if len(entries) != 1 || entries[0].Cid != cid {
t.Fatalf("re-established cid must return to the index, got %+v", entries)
}
}