cachetest

package
v0.0.0-...-8c930d8 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 11, 2026 License: Apache-2.0 Imports: 7 Imported by: 0

Documentation

Overview

Package cachetest provides the conformance suite every types.Cache backend must pass. Each backend declares its capabilities and the suite asserts the contract documented on types.Cache: miss errors, idempotent deletes, ttl semantics and concurrency safety.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Run

func Run(t *testing.T, cache types.Cache[string], caps Capabilities)

Run asserts the types.Cache contract against cache. Backends that honor neither ttl form must reject every Set with ErrTTLNotSupported and are only checked for that plus the read-path contract.

func RunWriteRetention

func RunWriteRetention[T ~string](t *testing.T, cache types.Cache[T], capacity int)

RunWriteRetention asserts that entries written under capacity pressure are still there when a later request comes looking, not merely readable on the next line.

RunWriteVisibility cannot see this. Reading each key immediately after writing it hides any backend that accepts the write and then picks the newcomer as its eviction victim, because the read lands before the eviction does. An admission-weighted policy does exactly that: a fresh key has the lowest frequency estimate in the cache, so it is the first thing evicted once the writes stop. Measured on a warm 100k-entry cache taking 10k new keys, one backend lost none on the immediate read and 44% on a read 200ms later.

Preferring old entries over new ones is a legitimate policy — it is the same mechanism that makes a cache resist scans — but it is incompatible with the ordinary write-now-read-later use of a cache, so the forwarded default has to pass this.

func RunWriteVisibility

func RunWriteVisibility[T ~string](t *testing.T, cache types.Cache[T], capacity int)

RunWriteVisibility asserts the contract's core write guarantee under capacity pressure: a value stored by Set must be readable by the next Get, even when the cache is full and its resident entries are warm.

It is separate from Run because it needs an instance whose capacity it knows and whose contents it owns, so callers pass a freshly created cache — giving the probe its own value type yields its own per-type instance — together with the entry bound that instance was built with.

The warm-up pass is what makes this a real guard rather than a formality. A backend that admits entries by estimated frequency only starts rejecting newcomers once the resident entries have accumulated hits; merely filling the cache to capacity leaves the defect invisible, which is why the rest of this suite passes even on a backend that drops most of its writes.

Types

type Capabilities

type Capabilities struct {
	// PerEntryTTL is true when Set honors ttl > 0 as a per-entry lifetime.
	PerEntryTTL bool

	// NoExpiry is true when Set honors ttl == 0 as "never expires".
	NoExpiry bool

	// TTLGranularity is the coarsest ttl unit the backend can represent; zero
	// means full precision. A backend with a granularity rejects a ttl below
	// it with ErrTTLNotSupported — honoring it would mean silently extending
	// the lifetime — and rounds a ttl above it up to the next unit, since
	// truncating would shorten the promised lifetime. The expiry probe waits
	// accordingly, and the suite asserts the sub-granularity rejection.
	TTLGranularity time.Duration

	// MaxEntries is the backend's entry bound when it has one, and the suite
	// overfills it to prove eviction runs. Zero means the backend is not
	// bounded by entry count — either it evicts by byte budget, which takes
	// too long to fill in a conformance run, or it never evicts at all.
	// Unbounded separates those two, so a backend that quietly stopped
	// enforcing its bound cannot pass as one that never claimed one.
	MaxEntries int

	// Unbounded declares that the backend never evicts, so a caller-influenced
	// key space grows until the process runs out of memory.
	Unbounded bool
}

Capabilities declares which parts of the ttl contract a backend honors.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL
⌂ 换网址