Documentation
¶
Overview ¶
Package testutil provides common test helper utilities for the Dingo project. It replaces ad-hoc time.Sleep patterns with deterministic synchronization helpers that make tests faster and more reliable.
Index ¶
- Constants
- func BadgerBlobConfig() map[string]any
- func BuildDecodableConwayBlockBytes(t *testing.T, slot, blockNumber uint64) []byte
- func ConwayEmptyBodyHash(t testing.TB) lcommon.Blake2b256
- func ExtendConwayHeaderBody(t *testing.T, standardRaw []byte, extraFields ...cbor.RawMessage) []byte
- func ExtendConwayHeaderWithLeios(t *testing.T, standardRaw []byte) []byte
- func FreePort(t *testing.T) string
- func GenerateTestTLSCertKey(t *testing.T) (certPath, keyPath string)
- func InsecureHTTPClient() *http.Client
- func MakeDirectoryUnwritable(t testing.TB, path string)
- func RequireNoReceive[T any](t *testing.T, ch <-chan T, duration time.Duration, msg string)
- func RequireReceive[T any](t *testing.T, ch <-chan T, timeout time.Duration, msg string) T
- func RestrictFileToCurrentUser(t testing.TB, path string)
- func WaitForCondition(t *testing.T, condition func() bool, timeout time.Duration, msg string)
- func WaitForConditionWithInterval(t *testing.T, condition func() bool, timeout time.Duration, ...)
- type MockInput
- type ValidatedConwayBlock
Constants ¶
const ( // TestBadgerValueLogFileSize and TestBadgerMemTableSize are the file // sizes a test's badger blob store should ask for, well below the // production defaults (1 GiB and 128 MiB). // // badger sizes both files up front when it opens an on-disk store: the // value log is truncated to ValueLogFileSize and the memtable WAL to // MemTableSize. On Linux and macOS those are sparse, so the space is // only charged as it is written and the production sizes cost a test // nothing. On Windows the space is really reserved the moment the // store opens -- and badger maps the value log at twice // ValueLogFileSize so the last entry always fits (badger/v4 // value.go:536), making that 2 GiB per store at the default rather // than 1 -- so enough concurrent stores fill a CI runner's disk. // badger then fails every open with "There is not enough space on the // disk" out of valueLog.open, and the affected t.TempDir cleanup fails // behind it because the mapping is still held. // // A test writes kilobytes to a few megabytes, so it asks for files it // can actually fill. Anything larger only reserves space. TestBadgerValueLogFileSize = 16 * 1024 * 1024 TestBadgerMemTableSize = 8 * 1024 * 1024 )
const AsyncWait = 2 * time.Minute
AsyncWait is the deadline a test should give a wait on asynchronous progress -- a goroutine the code under test started, a background manager reacting to an event, a commit draining its after-commit callbacks -- when the test has no way to observe that work other than polling for its result.
It is a failure deadline, not a delay. WaitForCondition and RequireReceive return the moment the condition holds, so a larger value costs a passing run nothing; it only changes how long a genuinely stuck test takes to report, and the per-package -timeout still backstops that.
The value is deliberately far above the time the work takes on an idle machine, because that time is not what the deadline has to cover. `go test` defaults -parallel to GOMAXPROCS, so on a large host dozens of race-instrumented tests run at once, each with its own SQLite database, and a wait that completes in milliseconds standalone takes tens of seconds under that load. Slow single-core runners produce the same effect for the opposite reason.
Use one value rather than a per-site guess: a spread of 1s/2s/5s deadlines across a package encodes no information about the work being waited on, and the short end of the spread is where the flakes are.
const BindAttempts = 8
BindAttempts bounds how many ports a test tries before giving up when racing another process for a loopback port (see FreePort). Shared by every built-in API provider's TLS test suite (Blockfrost, Mesh, UTxO RPC).
Variables ¶
This section is empty.
Functions ¶
func BadgerBlobConfig ¶ added in v0.70.8
BadgerBlobConfig returns the badger blob provider config a test should use, sized by TestBadgerValueLogFileSize and TestBadgerMemTableSize. Pass it as the provider config to plugin.Resolve wherever a test opens an on-disk badger store; dbtest.NewDatabase applies it for you.
func BuildDecodableConwayBlockBytes ¶ added in v0.70.0
BuildDecodableConwayBlockBytes constructs a minimal, valid (10-field header), individually decodable Conway block with a correct block body hash and empty transaction components, for the given slot and block number. It is shared by tests across packages (database/models, ledger) that need a cheap, uniquely-identifiable, real Conway block rather than a hand-rolled mock.
func ConwayEmptyBodyHash ¶ added in v0.70.9
func ConwayEmptyBodyHash(t testing.TB) lcommon.Blake2b256
ConwayEmptyBodyHash returns the block body hash for a Conway block with empty transaction components (bodies, witness sets, metadata set, invalid transactions), which is independent of the header. Computed once via the same technique as BuildDecodableConwayBlockBytes (blake2b256 over the concatenation of the per-component blake2b256 hashes). Exported so callers building their own Conway headers with genuine crypto (e.g. a package-local competing-fork generator) share this computation instead of duplicating it, which would let the two drift apart.
func ExtendConwayHeaderBody ¶ added in v0.70.8
func ExtendConwayHeaderBody( t *testing.T, standardRaw []byte, extraFields ...cbor.RawMessage, ) []byte
ExtendConwayHeaderBody rewrites a standard (10-field header) Conway block so its header body carries extraFields appended after the 10 standard Babbage fields, for constructing malformed-extension fixtures (a field count other than the real 12-field Musashi/Leios extension) as well as the genuine extension itself.
func ExtendConwayHeaderWithLeios ¶ added in v0.70.8
ExtendConwayHeaderWithLeios rewrites a standard (10-field header) Conway block so its header body carries the two trailing Musashi/Leios fields (leios_certified = false, leios_announcement = nil), producing a 12-field header body. The transaction components (and therefore the block body hash) are left untouched.
func FreePort ¶ added in v0.70.0
FreePort reserves a loopback port and releases it, returning the bound address ("host:port"). The port is not guaranteed to still be free when the caller binds it -- retry up to BindAttempts times instead of treating one bind failure as a test failure.
func GenerateTestTLSCertKey ¶ added in v0.70.0
GenerateTestTLSCertKey generates a throwaway self-signed certificate/key pair valid for 127.0.0.1 and writes them as PEM files under a fresh t.TempDir(), returning their paths. Used to exercise a listener's TLS startup path (Blockfrost, Mesh, UTxORPC, Bark) without depending on any fixed certificate checked into the repo.
func InsecureHTTPClient ¶ added in v0.70.0
InsecureHTTPClient returns an *http.Client that skips TLS certificate verification, for exercising a listener's throwaway self-signed test certificate (see GenerateTestTLSCertKey).
func MakeDirectoryUnwritable ¶ added in v0.70.1
MakeDirectoryUnwritable removes write permission from a test directory and restores it before the test's temporary-directory cleanup runs.
Both modes are derived from what the directory already has rather than written literally: t.TempDir() creates 0o700, so restoring a fixed 0o755 would hand the caller a more permissive directory than it passed in, and clearing to a fixed 0o555 would do the same for anything created stricter.
func RequireNoReceive ¶
RequireNoReceive verifies that no value is received on the given channel within the specified duration. This replaces the pattern of time.Sleep followed by a non-blocking channel read to confirm that nothing was sent.
func RequireReceive ¶
RequireReceive waits for a value on the given channel or fails the test if the timeout expires. This replaces the common pattern of time.Sleep followed by reading a channel.
func RestrictFileToCurrentUser ¶ added in v0.70.0
RestrictFileToCurrentUser makes a test fixture acceptable to secret-key permission checks on Unix.
func WaitForCondition ¶
WaitForCondition polls the given condition function until it returns true or the timeout expires. This replaces the common pattern of time.Sleep followed by an assertion check.
Types ¶
type MockInput ¶ added in v0.37.0
MockInput is a reusable transaction input for database tests.
func NewMockInput ¶ added in v0.37.0
func (*MockInput) Id ¶ added in v0.37.0
func (m *MockInput) Id() lcommon.Blake2b256
func (*MockInput) ToPlutusData ¶ added in v0.37.0
func (m *MockInput) ToPlutusData() pdata.PlutusData
type ValidatedConwayBlock ¶ added in v0.70.1
type ValidatedConwayBlock struct {
Cbor []byte
Hash []byte
Slot uint64
BlockNumber uint64
EpochNonceHex string
SlotsPerKesPeriod uint64
}
ValidatedConwayBlock holds a genuinely VRF/KES-valid Conway block's raw CBOR alongside the parameters a caller needs to independently re-verify it (e.g. via gouroboros' ledger.VerifyBlock or pipeline.ValidateStage).
func BuildValidatedConwayBlockBytes ¶ added in v0.70.1
func BuildValidatedConwayBlockBytes( t *testing.T, seed [32]byte, nonceSeed byte, slotRangeStart uint64, blockNumber uint64, ) ValidatedConwayBlock
BuildValidatedConwayBlockBytes generates real VRF, KES, and cold keys, searches slots in [slotRangeStart, slotRangeStart+199] for one where the generated VRF key wins leadership (99% active slot coefficient, pool stake == total stake), and returns a genuinely decodable, VRF/KES-valid Conway block at that slot with an empty transaction body.
Unlike BuildDecodableConwayBlockBytes (which zeroes out the VRF/KES/OpCert fields for tests that only need a decodable block), this is for tests that need actual cryptographic validation -- gouroboros' pipeline.ValidateStage / ledger.VerifyBlock -- to genuinely pass, not merely decode. seed must be 32 bytes and should differ between blocks needing distinct producer keys; nonceSeed derives the epoch nonce the block is proven against (use the same nonceSeed for blocks meant to share an epoch).
func BuildValidatedConwayBlockBytesWithInvalidOpCert ¶ added in v0.70.1
func BuildValidatedConwayBlockBytesWithInvalidOpCert( t *testing.T, seed [32]byte, nonceSeed byte, slotRangeStart uint64, blockNumber uint64, ) ValidatedConwayBlock
BuildValidatedConwayBlockBytesWithInvalidOpCert generates a block whose VRF proof and KES signature are genuine but whose operational certificate was signed by an unrelated cold key. The KES signature is computed after substituting the unrelated signature, so rejecting this block specifically exercises the cold-key OpCert check rather than failing KES verification.