hunt

package
v0.0.0-...-2e4c5eb Latest Latest
Warning

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

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

Documentation

Overview

Package hunt is a brute-force, seed-driven bug hunter for the record layer.

It drives a randomized save/overwrite/delete/deleteAll workload — under a seed-derived commit-fault schedule (commit_unknown / not_committed / transaction_too_old, via the Buggify points SimFDB's commit reads) — over SimFDB, the deterministic in-memory FDB backend, and after every batch checks the store against a chaos.StoreModel with chaos.Verify (the same 14-invariant oracle the fixed-seed chaos suite uses over real FDB).

The point is throughput: SimFDB runs in-process with no Docker, so one core replays tens of thousands of independent seeds per second. That turns bug hunting into a loop — FuzzHunt (coverage-guided) and TestBruteHunt (time-budgeted) sweep an enormous permutation space "until a bug drops out", the brute-force complement to chaos.RunRandom (one fixed seed, real FDB, Docker). A found bug is a single uint64: Run(seed) replays it exactly and Shrink minimizes it. This is RFC-199 Tier 2.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func CountSumMetadata

func CountSumMetadata() *recordlayer.RecordMetaData

CountSumMetadata: a COUNT (grouped by price) + a SUM (ungrouped) index — the aggregate maintainers whose removeCommon* retry optimizations are the classic non-idempotency risk.

func CoveringMetadata

func CoveringMetadata() *recordlayer.RecordMetaData

CoveringMetadata: a VALUE + a covering (KeyWithValue) index — the covering payload must stay in lockstep with the record it mirrors.

func FaultDependent

func FaultDependent(seed uint64, cfg Config) bool

FaultDependent reports whether a failing seed needs the commit-fault schedule to fail: true = it passes with faults disabled (a retry/idempotency defect — the common case), false = it still fails on the happy path (a plain logic bug, and a more serious one). Only meaningful for a seed that already failed under cfg.

func Fingerprint

func Fingerprint(db *recordlayer.FDBDatabase) string

Fingerprint hashes db's entire persisted keyspace — the determinism probe (same seed ⇒ same fingerprint) that any workload can use to assert byte-identical replay. The read is read-only (no commit), so it draws no fault and never perturbs the run.

func KitchenSinkMetadata

func KitchenSinkMetadata() *recordlayer.RecordMetaData

KitchenSinkMetadata builds the Order schema with all seven index types active at once (VALUE + COUNT + SUM + RANK + MAX_EVER + VERSION + COVERING) plus record counting and record versions — the maximal-coverage schema, so a single run exercises every index maintainer's fault/retry path and Verify has teeth on all of them.

func MaxEverMetadata

func MaxEverMetadata() *recordlayer.RecordMetaData

MaxEverMetadata: a MAX_EVER (ungrouped, long) index — monotone aggregate that must never regress even when the record carrying the max is deleted then a retry re-derives.

func NewSimEnv

func NewSimEnv(seed uint64, faultProb float64) *dst.Env

NewSimEnv builds the seeded simulation environment a workload runs under: deterministic clock + RNG, and Buggify set to faultProb (activation and fire). faultProb <= 0 disables faults. A workload that needs a clean setup phase can pass the built env, run setup, then raise the probability — but for a one-phase workload this is the whole story.

func PermutedMetadata

func PermutedMetadata() *recordlayer.RecordMetaData

PermutedMetadata: PERMUTED_MAX + PERMUTED_MIN over (group=price, value=quantity). The permuted subspace must always reflect the current per-group extremum.

func RankMetadata

func RankMetadata() *recordlayer.RecordMetaData

RankMetadata: a VALUE + RANK index. RANK has dual-subspace state (B-tree + RankedSet) that can drift under retry — the deepest maintainer to keep consistent.

func Shrink

func Shrink(seed uint64, cfg Config) (Config, *Report)

Shrink minimizes a failing seed to the smallest reproducer: the fewest operations that still trip the oracle, verified at every op so the failure pins to the exact offending operation. It returns the shrunk Config and its Report. If the seed does not reproduce under per-op verification (e.g. it was a flaky artifact — which cannot happen here since Run is fully deterministic, but the guard keeps Shrink honest), the original Config and Report come back.

A minimized (seed, NumOps) pair is the whole bug report: hand it to Run and the failure reproduces instantly, no cluster, no Docker.

func ValueMetadata

func ValueMetadata() *recordlayer.RecordMetaData

ValueMetadata: record counting + a single VALUE index on price.

func VersionMetadata

func VersionMetadata() *recordlayer.RecordMetaData

VersionMetadata: record versions on + a VERSION index. Exercises the versionstamp path (the one that surfaced the API-version fidelity gap) and its cleanup/recreate on retry.

Types

type Config

type Config struct {
	NumOps      int     // operations per run (default 300)
	MaxPKs      int64   // primary-key range [0,MaxPKs); smaller = more overwrite/conflict (default 30)
	VerifyEvery int     // run the oracle every N ops, plus once at the end (default 25)
	FaultProb   float64 // Buggify activation+fire probability for the commit faults (default 0.25; 0 = fault-free)

	// Workload is the surface under test — record layer, SQL, or a future one. Nil selects the
	// record-layer workload over Metadata (or the kitchen-sink schema). This is the extension
	// point: implement Workload, drop it in a Config, and the whole loop-until-bug machinery
	// (seed sweep, fault schedule, shrink, findings recording) works unchanged.
	Workload Workload

	// Metadata builds the schema + indexes for the DEFAULT record-layer workload. Nil uses the
	// kitchen-sink schema (VALUE + COUNT + SUM + RANK + MAX_EVER + VERSION + COVERING) so every
	// maintainer is exercised and Verify has maximal teeth. Ignored when Workload is set.
	Metadata func() *recordlayer.RecordMetaData
}

Config parameterizes a single Run. The zero value is valid: withDefaults fills a sensible brute-force profile (a small keyspace so overwrites and conflicts are frequent, the full kitchen-sink index set, faults at FDB's 0.25 Buggify rate).

type Profile

type Profile struct {
	Name string
	Cfg  Config
}

A Profile is a named hunting configuration: a schema + workload shape. Rotating profiles widens coverage — the kitchen sink stresses all maintainers together, the single-index profiles isolate one maintainer at higher throughput (so a per-maintainer bug surfaces without the others' noise), and the *-dense profiles shrink the keyspace so overwrite/ delete/retry churn on a few hot keys is relentless.

func Profiles

func Profiles() []Profile

Profiles is the overnight-sweep matrix: every index maintainer in isolation and together, across normal and conflict-dense keyspaces. The runner cycles through these per seed so a long sweep covers the whole matrix uniformly.

type Report

type Report struct {
	Seed        uint64
	Ops         int      // operations executed before the run stopped
	FaultsFired int      // commit faults actually injected (0 = happy-path-only this seed)
	Violations  []string // oracle violations found (a store/model divergence)
	Err         string   // an unexpected harness error (an op that should never have failed)
	Fingerprint string   // sha256 of the final persisted keyspace (determinism probe); empty on failure
}

Report is the outcome of one Run: clean, or a reproducible failure keyed by Seed.

func Run

func Run(seed uint64, cfg Config) *Report

Run replays seed deterministically under cfg's workload and returns its Report. Never panics on a found bug — it captures the divergence in the Report so a driver (fuzzer / brute loop) can decide how to surface it. Same (seed, cfg) always yields the same Report.

func (*Report) Failed

func (r *Report) Failed() bool

Failed reports whether this run found a bug — an oracle violation or an unexpected error.

func (*Report) String

func (r *Report) String() string

type Workload

type Workload interface {
	Name() string
	Run(seed uint64, cfg Config) *Report
}

Workload is one kind of seeded, fault-injected exercise of the stack over SimFDB. The hunter treats it as a black box: Run(seed, cfg) must be deterministic in (seed, cfg) and return a Report capturing any oracle violation (never panic on a found bug — record it in the Report). Add a Workload to hunt a new surface; the seed loop, shrink, and recording are shared.

Directories

Path Synopsis
Package atomicops is a DST driver that differentials FoundationDB's ten atomic mutation types (Add / And / Or / Xor / Max / Min / ByteMax / ByteMin / AppendIfFits / CompareAndClear) end-to-end through the SimFDB backend against an INDEPENDENT Go reference model.
Package atomicops is a DST driver that differentials FoundationDB's ten atomic mutation types (Add / And / Or / Xor / Max / Min / ByteMax / ByteMin / AppendIfFits / CompareAndClear) end-to-end through the SimFDB backend against an INDEPENDENT Go reference model.
Package continuation is RFC-199 Tier 2's continuation-under-fault replay driver.
Package continuation is RFC-199 Tier 2's continuation-under-fault replay driver.
Package golden is a characterization ("golden master") harness for the SQL engine over SimFDB.
Package golden is a characterization ("golden master") harness for the SQL engine over SimFDB.
Package interleave is RFC-199 Tier 2's concurrent-open-transaction interleaving driver.
Package interleave is RFC-199 Tier 2's concurrent-open-transaction interleaving driver.
Package metamorphic is the WRONG-catching SQL oracle for the DST harness (RFC-199 Tier 2).
Package metamorphic is the WRONG-catching SQL oracle for the DST harness (RFC-199 Tier 2).
Package rangeconflict is RFC-199 Tier 2's range-conflict interleaving driver.
Package rangeconflict is RFC-199 Tier 2's range-conflict interleaving driver.
This file adds a SECOND SQL workload to the DST bug hunter, focused on SECONDARY-INDEX maintenance under the commit-fault schedule (commit_unknown / not_committed / too_old retry).
This file adds a SECOND SQL workload to the DST bug hunter, focused on SECONDARY-INDEX maintenance under the commit-fault schedule (commit_unknown / not_committed / too_old retry).
Package sqlpage is RFC-199 Tier 2's SQL-query pagination oracle.
Package sqlpage is RFC-199 Tier 2's SQL-query pagination oracle.

Jump to

Keyboard shortcuts

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