Documentation
¶
Overview ¶
Package txbudgetcensus finds test transactions that carry an unstated assumption about FDB's five-second MVCC window.
THE CONDITION IT LOOKS FOR. An explicit SQL transaction pins one FDB read version, and that version dies five seconds after it opened in WALL CLOCK — whether the client was working or merely queued behind other load. The driver pre-empts at four with a typed 40001 carrying api.TransactionTimeLimitError. So a test that opens a transaction against a REAL FoundationDB and issues more than one statement on it is asserting, without saying so, that all of them finish inside four seconds. Under a full-parallel suite run against one containerised FDB that assertion is reachable: one such test was measured at 5.34s against 0.08s standalone.
A transaction meeting all three of — real FDB, two or more statements, no time-limit handling — is EXPOSED. The fix is never to widen a timeout; it is to retry the WHOLE transaction on the typed marker, which is what api.IsTransactionTimeLimit and the retryTx helper in the sqldriver tests do.
WHY AN AST WALK AND NOT A GREP. The two ways a naive tally goes wrong are both invisible to text matching, they point in OPPOSITE directions, and both were observed in this repo's own suite:
- OVER-COUNT: two SEQUENTIAL one-statement transactions in one test function read as a single two-statement transaction. Counting per function rather than per transaction reports an exposure that does not exist, because each window closes before the next opens.
- UNDER-COUNT: several subtests each rebinding the same name `tx` collapse into one tally, hiding which of them is actually exposed. This one is the dangerous direction — it reports FEWER exposures than exist.
Both are pinned as unit tests on synthetic sources, because they are properties of the INSTRUMENT and must not depend on the corpus continuing to contain an example.
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Site ¶
type Site struct {
File string
Line int
Func string
TxVar string
Direct int // statements issued directly on the transaction
Helper int // statements a helper issues, detected by the tx being passed in
RealFDB bool
Sim bool
Handles bool
}
Site is one explicit transaction — one BeginTx/Begin call — with everything needed to classify it.
func Handled ¶
Handled filters to transactions that DO handle the time limit. Watched for collapse: if this population empties while the corpus still holds transactions, the marker detection has broken and every converted test would silently re-enter the exposed set.
func ScanDirs ¶
ScanDirs classifies every explicit transaction in the *_test.go files of the given directories, and reports how many files it actually read.
The file count is returned rather than discarded because it is the only thing that distinguishes "no exposed transactions" from "no files" — and under Bazel a test runs in a runfiles tree containing only its declared inputs, so an undeclared corpus produces a perfect, meaningless zero.
func ScanSource ¶
ScanSource classifies every explicit transaction in one Go source file.
func (Site) Statements ¶
Statements is the lower bound on how many statements this transaction issues. A LOWER bound on purpose: a helper receiving the transaction may issue several and is counted once, which is how a converted test scored 2 while really issuing 3. Under-counting can only make the census miss an exposure, never invent one.