storetest

package
v0.5.0 Latest Latest
Warning

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

Go to latest
Published: Aug 29, 2026 License: Apache-2.0 Imports: 13 Imported by: 0

Documentation

Overview

Package storetest provides backend-conformance suites for the five storage primitives — Ledger, Leaser, KV, Blobs, and OrderedIndex. A backend's own _test.go calls the relevant Test* function with a factory that returns a fresh, empty primitive; the suite drives every contract behavior shared by all backends and classifies failures with errors.As against the storage-canonical typed errors — never by string.

The suites live in regular (non-_test.go) files and take an extra newBackend parameter, so `go test` never auto-runs them and `go vet`'s test-signature check (which inspects only _test.go files) never flags them — the same pattern the standard library uses for testing/fstest.TestFS. Importing "testing" from a regular file is idiomatic for this conformance-suite shape.

Backend-specific behavior — cursor internals, cross-process lease reclaim, and ctx-honoring — is deliberately out of scope and stays in each backend's own tests. The shared OrderedIndex suite does cover its public copy-in/copy-out ownership guarantees. The separate Leaser lifecycle suite uses a provider-supplied, test-only harness to cover deterministic renewal and expiry without expanding the production Leaser interface. For the same reason the OrderedIndex suite takes malformed and unknown-version cursor tokens from a required OrderedCursorProbe parameter: cursor bytes are opaque, so a literal token here would pin one provider's grammar as the contract, and making the probe a parameter turns "this provider owes the suite two tokens" into a compile error rather than a runtime failure.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func TestBlobs

func TestBlobs(t *testing.T, newBackend func(t *testing.T) storage.Blobs)

TestBlobs runs the Blobs conformance suite. newBackend must return a fresh, empty Blobs; register any cleanup via t.Cleanup inside newBackend.

func TestKV

func TestKV(t *testing.T, newBackend func(t *testing.T) storage.KV)

TestKV runs the KV conformance suite. newBackend must return a fresh, empty KV; register any cleanup via t.Cleanup inside newBackend.

func TestLeaser

func TestLeaser(t *testing.T, newBackend func(t *testing.T) storage.Leaser)

TestLeaser runs the baseline Leaser conformance suite. newBackend must return a fresh, empty Leaser; register any cleanup via t.Cleanup inside newBackend. Every provider also supplies a deterministic LeaserLifecycleHarness and runs TestLeaserLifecycle to cover renewal and expiry.

Cross-process reclaim (a dead holder's lease being reclaimed by the backend's native mechanism) is "where testable" and left to each backend's own tests.

func TestLeaserLifecycle added in v0.5.0

func TestLeaserLifecycle(t *testing.T, newHarness LeaserLifecycleFactory)

TestLeaserLifecycle runs conformance checks for renewable, monotonic epoch ownership. Run it alongside TestLeaser for every provider with a deterministic lifecycle harness.

func TestLedger

func TestLedger(t *testing.T, newBackend func(t *testing.T) storage.Ledger)

TestLedger runs the Ledger conformance suite. newBackend must return a fresh, empty Ledger; register any cleanup via t.Cleanup inside newBackend.

func TestOrderedIndex added in v0.5.0

func TestOrderedIndex(t *testing.T, newBackend OrderedIndexFactory, probe OrderedCursorProbe, counters ...OrderedIndexCounters)

TestOrderedIndex runs the provider-neutral OrderedIndex conformance suite.

newBackend must return a fresh, empty provider and may register cleanup with t.Cleanup. Every test receives a bounded context and reports record identity on failures so remote providers can use the same suite safely.

probe is REQUIRED. Malformed and unknown-version cursor tokens are the two fail-closed inputs the suite cannot invent, because cursor bytes are opaque and each provider owns its encoding; a provider supplies them through OrderedCursorProbe. It is a parameter rather than an optional interface the provider might also implement so that omitting it is a compile error at the conformance test rather than a failure from inside one subtest.

counters is optional and, when provided, runs one provider-defined bounded-work check on another fresh provider.

func TestOrderedIndexRevisionConflicts added in v0.5.0

func TestOrderedIndexRevisionConflicts(t *testing.T, newBackend OrderedIndexFactory)

TestOrderedIndexRevisionConflicts runs only the CAS-conflict conformance case. It exists for the provider adapter that varies one narrow reporting choice the contract leaves open — whether *OrderedRevisionConflictError discloses ActualRevision or reports the zero sentinel — so verifying that branch costs one subtest instead of a second full suite run. It needs no cursor probe because it never lists.

Types

type LeaserLifecycleClient added in v0.5.0

type LeaserLifecycleClient struct {
	Leaser storage.Leaser
	ViewID uint64
}

LeaserLifecycleClient identifies one test-only client view over a Leaser. ViewID is an opaque nonzero identity supplied by the harness and must differ for distinct views; it never expands the production storage interfaces.

type LeaserLifecycleFactory added in v0.5.0

type LeaserLifecycleFactory func(t *testing.T) LeaserLifecycleHarness

LeaserLifecycleFactory returns a fresh lifecycle harness for one conformance subtest. It may register cleanup with t.Cleanup.

type LeaserLifecycleHarness added in v0.5.0

type LeaserLifecycleHarness struct {
	Primary         storage.Leaser
	PrimaryViewID   uint64
	OpenIndependent func(t *testing.T) LeaserLifecycleClient
	Renew           func(t *testing.T, lease storage.Lease)
	Expire          func(t *testing.T, lease storage.Lease)
}

LeaserLifecycleHarness provides test-only, deterministic controls for a renewable Leaser implementation. Every LeaserLifecycleFactory call must return a fresh harness. Primary and each client returned by OpenIndependent must share the same backing state but be separate client views, so the suite can prove no operation depends on retaining one database connection or session. PrimaryViewID and each independent ViewID identify those test-only views. Renew must keep a live grant at its existing epoch; Expire must make that grant lose ownership and close Lost.

These controls are intentionally not part of storage.Leaser or storage.Lease: providers choose their own renewal/expiry mechanism. External providers must supply their own deterministic harness when they run TestLeaserLifecycle.

type OrderedCursorProbe added in v0.5.0

type OrderedCursorProbe interface {
	// MalformedCursor returns a nonempty token the provider must reject for
	// kind with OrderedCursorMalformed. It must be a token the provider could
	// never have issued.
	MalformedCursor(t *testing.T, kind storage.OrderedCursorKind) string

	// UnknownVersionCursor returns a nonempty token that is well formed for the
	// provider's encoding but carries a token version it does not support, and
	// which it must therefore reject for kind with
	// OrderedCursorUnknownVersion.
	UnknownVersionCursor(t *testing.T, kind storage.OrderedCursorKind) string
}

OrderedCursorProbe supplies the fail-closed cursor inputs this suite cannot invent for itself. Cursor bytes are opaque and versioned, and each provider owns its own encoding, so a literal token written here would test one provider's grammar rather than the contract: a provider whose cursors are a signed blob or a stream sequence tuple would fail a test about its own format. A factory returns a provider that also implements this interface, usually by wrapping its OrderedIndex in its own conformance test.

The remaining fail-closed rules need no probe: cross-query and cross-kind inputs are derived from real cursors the provider just issued.

type OrderedIndexCounterFunc added in v0.5.0

type OrderedIndexCounterFunc func(t *testing.T, ctx context.Context, index storage.OrderedIndex)

OrderedIndexCounterFunc adapts an assertion function for OrderedIndexCounters, so a provider can keep its instrumentation seam local to its conformance test.

func (OrderedIndexCounterFunc) Assert added in v0.5.0

Assert invokes f as an OrderedIndexCounters assertion.

type OrderedIndexCounters added in v0.5.0

type OrderedIndexCounters interface {
	Assert(t *testing.T, ctx context.Context, index storage.OrderedIndex)
}

OrderedIndexCounters optionally asserts provider-specific query-work counters against a fresh OrderedIndex under the suite's bounded context. The concrete measurements are intentionally provider-owned: semantic conformance must not prescribe a filesystem walk, a JetStream scan, or a database buffer-read unit.

type OrderedIndexFactory added in v0.5.0

type OrderedIndexFactory func(t *testing.T) storage.OrderedIndex

OrderedIndexFactory returns a fresh, empty OrderedIndex for one conformance subtest.

Jump to

Keyboard shortcuts

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