- 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")
50 lines
1.4 KiB
Go
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)
|
|
})
|
|
}
|