Files
summercms/modules/cooler/pull_smoke_test.go
Jakub Zych 5e0a04e4da feat(cooler): Cache.Pull returns and removes a value atomically
- Cache.Pull(ctx, key) ([]byte, bool, error), Laravel's Cache::pull
- Redis driver runs GETDEL (Redis 6.2+); memory driver uses otter Compute
  with InvalidateOp under the per-key lock; expired keys report not found
- TestPullSmoke over the memory driver and miniredis, ExampleCache_Pull
- README and docs/services/caching.md ("One-time values")
2026-10-20 22:58:44 +02:00

50 lines
1.4 KiB
Go

package cooler
import (
"testing"
"time"
)
// TestPullSmoke takes a value exactly once through Pull on both drivers, and
// reports an expired value as not found.
func TestPullSmoke(t *testing.T) {
run := func(t *testing.T, c Cache, advance func(time.Duration)) {
t.Helper()
ctx := t.Context()
if err := c.Set(ctx, "code", []byte("v"), 0); err != nil {
t.Fatal(err)
}
if v, ok, err := c.Pull(ctx, "code"); err != nil || !ok || string(v) != "v" {
t.Fatalf("first Pull = %q %v %v, want \"v\" true nil", v, ok, err)
}
if v, ok, err := c.Pull(ctx, "code"); err != nil || ok || v != nil {
t.Fatalf("second Pull = %q %v %v, want nil false nil", v, ok, err)
}
if v, ok, err := c.Get(ctx, "code"); err != nil || ok || v != nil {
t.Fatalf("Get after Pull = %q %v %v, want nil false nil", v, ok, err)
}
if err := c.Set(ctx, "short", []byte("x"), 50*time.Millisecond); err != nil {
t.Fatal(err)
}
advance(100 * time.Millisecond)
if v, ok, err := c.Pull(ctx, "short"); err != nil || ok || v != nil {
t.Fatalf("Pull of an expired key = %q %v %v, want nil false nil", v, ok, err)
}
}
t.Run("memory", func(t *testing.T) {
c, err := NewMemoryCache("acme:", 100)
if err != nil {
t.Fatal(err)
}
run(t, c, func(time.Duration) { time.Sleep(80 * time.Millisecond) })
})
t.Run("redis", func(t *testing.T) {
mr, client := miniClient(t)
run(t, NewRedisCache(client, "acme:"), mr.FastForward)
})
}