Documentation
¶
Overview ¶
Package drivertest is the conformance suite every hopper driver must pass.
A driver's tests call Run with a Fixture that hands out isolated, migrated databases and implements the few engine-specific hooks the suite needs to set up situations (an expired lease, a stuck job) that no queue operation produces on its own.
func TestConformance(t *testing.T) {
drivertest.Run(t, pgxFixture{})
}
The suite covers inserting (including unique keys and replace), claiming (order, ownership, expiry, SKIP LOCKED), every finalize transition and its fencing to the claim (also inside a caller's transaction), snooze reasons, leases, leader election, rescue candidates, cancel, retry, TTL expiry, listing, queues, periodic slots, stats, notifications and history maintenance. What depends on whether the engine locks rows or runs one writer at a time (driver.Capabilities.SingleWriter) is tested either way. Engine-specific behavior, such as how partitions are managed, belongs in the driver's own tests; RunPostgres has the tests of what hopper's Postgres drivers share.
Index ¶
- func ReattachRevalidates(exec func(query string), queryText func(query string) string) bool
- func Run[TTx any](t *testing.T, f Fixture[TTx])
- func RunPostgres[TTx any](t *testing.T, f PostgresFixture[TTx])
- type Fixture
- type Postgres
- func (p Postgres[TTx]) AgeAttempt(ctx context.Context, t *testing.T, d driver.Driver[TTx], id driver.JobID, ...)
- func (p Postgres[TTx]) CountEdges(ctx context.Context, t *testing.T, d driver.Driver[TTx]) int
- func (p Postgres[TTx]) CountHistory(ctx context.Context, t *testing.T, d driver.Driver[TTx]) int
- func (p Postgres[TTx]) CountLive(ctx context.Context, t *testing.T, d driver.Driver[TTx]) int
- func (p Postgres[TTx]) Exec(ctx context.Context, t *testing.T, d driver.Driver[TTx], query string, ...)
- func (p Postgres[TTx]) ExpireJob(ctx context.Context, t *testing.T, d driver.Driver[TTx], id driver.JobID)
- func (p Postgres[TTx]) ExpireLeader(ctx context.Context, t *testing.T, d driver.Driver[TTx])
- func (p Postgres[TTx]) ExpireLease(ctx context.Context, t *testing.T, d driver.Driver[TTx], clientID int64)
- func (p Postgres[TTx]) MakeClaimable(ctx context.Context, t *testing.T, d driver.Driver[TTx], id driver.JobID)
- func (p Postgres[TTx]) MakePending(ctx context.Context, t *testing.T, d driver.Driver[TTx], id driver.JobID)
- func (p Postgres[TTx]) QueryText(ctx context.Context, t *testing.T, d driver.Driver[TTx], query string, ...) string
- func (p Postgres[TTx]) SetProgress(ctx context.Context, t *testing.T, d driver.Driver[TTx], id driver.JobID, ...)
- func (p Postgres[TTx]) SetSnoozeReason(ctx context.Context, t *testing.T, d driver.Driver[TTx], id driver.JobID, ...)
- func (p Postgres[TTx]) SnoozeReason(ctx context.Context, t *testing.T, d driver.Driver[TTx], id driver.JobID) string
- func (p Postgres[TTx]) StaleWake(ctx context.Context, t *testing.T, d driver.Driver[TTx], id driver.JobID)
- func (p Postgres[TTx]) WaitForLockWait(ctx context.Context, t *testing.T, d driver.Driver[TTx])
- type PostgresFixture
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func ReattachRevalidates ¶ added in v0.8.0
ReattachRevalidates reports whether attaching a partition's index again marks its parent valid, as Postgres does from the May 2026 releases (18.4, 17.10, 16.14, 15.18, 14.23) on, which decides whether HistoryIndex can repair an outcome table's index or reports it in HistoryIndexResult.Invalid. It runs the driver's own probe: the parent's index left invalid by dropping the one partition without an index, then attached again. exec runs a statement and queryText returns the single text value a query selects, both on a Postgres database a test owns.
func RunPostgres ¶ added in v0.8.0
func RunPostgres[TTx any](t *testing.T, f PostgresFixture[TTx])
RunPostgres runs the tests of what hopper's Postgres drivers share, which a Postgres driver passes besides Run's.
Types ¶
type Fixture ¶
type Fixture[TTx any] interface { // NewDriver returns a driver on a fresh database with hopper's schema // installed, torn down when the test ends. NewDriver(t *testing.T) driver.Driver[TTx] // Begin starts a transaction. The suite calls commit or rollback. Begin(ctx context.Context, t *testing.T, d driver.Driver[TTx]) (tx TTx, commit, rollback func() error) // ExpireLease makes a client's lease expired, as a partition or a long // pause would. ExpireLease(ctx context.Context, t *testing.T, d driver.Driver[TTx], clientID int64) // ExpireLeader makes the leader lease expired. ExpireLeader(ctx context.Context, t *testing.T, d driver.Driver[TTx]) // MakeClaimable moves a job's scheduled time to now. MakeClaimable(ctx context.Context, t *testing.T, d driver.Driver[TTx], id driver.JobID) // AgeAttempt backdates a running job's attempted time by age. AgeAttempt(ctx context.Context, t *testing.T, d driver.Driver[TTx], id driver.JobID, age time.Duration) // CountLive and CountHistory count jobs in the live table and in history. CountLive(ctx context.Context, t *testing.T, d driver.Driver[TTx]) int CountHistory(ctx context.Context, t *testing.T, d driver.Driver[TTx]) int // ExpireJob moves a live job's TTL deadline a second into the past. ExpireJob(ctx context.Context, t *testing.T, d driver.Driver[TTx], id driver.JobID) // StaleWake marks a running job as woken by JobRetryOrderingKey a second // before its attempt began, as a wake during an earlier attempt would. StaleWake(ctx context.Context, t *testing.T, d driver.Driver[TTx], id driver.JobID) // MakePending puts a live job back in the pending state, as a client // that stopped before promoting it would leave it. MakePending(ctx context.Context, t *testing.T, d driver.Driver[TTx], id driver.JobID) // SnoozeReason reads a live job's stored snooze reason, or "" for none, // which the driver's reads show only for a scheduled job. The suite // calls it from any goroutine. SetSnoozeReason stores one, as a client // of an earlier release, which cleared it neither on claim nor on // finalize, can leave it on a job that is not snoozed. SnoozeReason(ctx context.Context, t *testing.T, d driver.Driver[TTx], id driver.JobID) string SetSnoozeReason(ctx context.Context, t *testing.T, d driver.Driver[TTx], id driver.JobID, reason string) // SetProgress stores a JSON value as a live job's progress as it is, as // a direct SQL write could. SetProgress(ctx context.Context, t *testing.T, d driver.Driver[TTx], id driver.JobID, value string) // CountEdges counts the dependency edges the engine keeps for workflow // jobs that have not finished. CountEdges(ctx context.Context, t *testing.T, d driver.Driver[TTx]) int // WaitForLockWait waits until a statement on the driver's database // waits for a lock another transaction holds, so that a test knows its // competing statement is blocked rather than not yet started. WaitForLockWait(ctx context.Context, t *testing.T, d driver.Driver[TTx]) }
Fixture gives the suite a database per test and the hooks it needs. The hooks report a failure with t.Error rather than t.Fatal when the suite may call them from another goroutine, as SnoozeReason says.
type Postgres ¶ added in v0.8.0
type Postgres[TTx any] struct { // SQL runs statements on a driver's database, as PostgresFixture's Exec // and QueryText describe. SQL interface { Exec(ctx context.Context, t *testing.T, d driver.Driver[TTx], query string, args ...any) QueryText(ctx context.Context, t *testing.T, d driver.Driver[TTx], query string, args ...any) string } }
Postgres implements a PostgresFixture's hooks that are statements on hopper's Postgres schema, for the fixtures of hopper's Postgres drivers to embed, which then implement only NewDriver, Begin and SQL.
func (Postgres[TTx]) AgeAttempt ¶ added in v0.8.0
func (p Postgres[TTx]) AgeAttempt(ctx context.Context, t *testing.T, d driver.Driver[TTx], id driver.JobID, age time.Duration)
AgeAttempt implements Fixture.
func (Postgres[TTx]) CountEdges ¶ added in v0.8.0
CountEdges implements Fixture.
func (Postgres[TTx]) CountHistory ¶ added in v0.8.0
CountHistory implements Fixture.
func (Postgres[TTx]) Exec ¶ added in v0.8.0
func (p Postgres[TTx]) Exec(ctx context.Context, t *testing.T, d driver.Driver[TTx], query string, args ...any)
Exec implements PostgresFixture.
func (Postgres[TTx]) ExpireJob ¶ added in v0.8.0
func (p Postgres[TTx]) ExpireJob(ctx context.Context, t *testing.T, d driver.Driver[TTx], id driver.JobID)
ExpireJob implements Fixture.
func (Postgres[TTx]) ExpireLeader ¶ added in v0.8.0
ExpireLeader implements Fixture.
func (Postgres[TTx]) ExpireLease ¶ added in v0.8.0
func (p Postgres[TTx]) ExpireLease(ctx context.Context, t *testing.T, d driver.Driver[TTx], clientID int64)
ExpireLease implements Fixture.
func (Postgres[TTx]) MakeClaimable ¶ added in v0.8.0
func (p Postgres[TTx]) MakeClaimable(ctx context.Context, t *testing.T, d driver.Driver[TTx], id driver.JobID)
MakeClaimable implements Fixture.
func (Postgres[TTx]) MakePending ¶ added in v0.8.0
func (p Postgres[TTx]) MakePending(ctx context.Context, t *testing.T, d driver.Driver[TTx], id driver.JobID)
MakePending implements Fixture.
func (Postgres[TTx]) QueryText ¶ added in v0.8.0
func (p Postgres[TTx]) QueryText(ctx context.Context, t *testing.T, d driver.Driver[TTx], query string, args ...any) string
QueryText implements PostgresFixture.
func (Postgres[TTx]) SetProgress ¶ added in v0.8.0
func (p Postgres[TTx]) SetProgress(ctx context.Context, t *testing.T, d driver.Driver[TTx], id driver.JobID, value string)
SetProgress implements Fixture.
func (Postgres[TTx]) SetSnoozeReason ¶ added in v0.8.0
func (p Postgres[TTx]) SetSnoozeReason(ctx context.Context, t *testing.T, d driver.Driver[TTx], id driver.JobID, reason string)
SetSnoozeReason implements Fixture.
func (Postgres[TTx]) SnoozeReason ¶ added in v0.8.0
func (p Postgres[TTx]) SnoozeReason(ctx context.Context, t *testing.T, d driver.Driver[TTx], id driver.JobID) string
SnoozeReason implements Fixture.
type PostgresFixture ¶ added in v0.8.0
type PostgresFixture[TTx any] interface { Fixture[TTx] // Exec runs a SQL statement with hopper's tables on the search path, for // rows the suite writes directly, such as those a client of the previous // release leaves behind. QueryText returns the single text value a query // selects, for what the driver's reads do not show. Both report a // failure with t.Error rather than t.Fatal, so the suite may call them // from any goroutine. Exec(ctx context.Context, t *testing.T, d driver.Driver[TTx], query string, args ...any) QueryText(ctx context.Context, t *testing.T, d driver.Driver[TTx], query string, args ...any) string }
PostgresFixture is the Fixture of one of hopper's Postgres drivers, which can also run SQL on hopper's schema. RunPostgres runs, with it, the tests of what those drivers share beyond the driver interface: history's partitions and their indexes, the tags tables and their triggers, the rows clients of earlier releases leave, and the planner statistics the leader keeps.