Skip to content

test: run the lock store contract against the documented stores - #49

Merged
kamilmysliwiec merged 1 commit into
nestjs:masterfrom
sadatsajid:test/contract-on-documented-stores
Oct 29, 2026
Merged

kamilmysliwiec merged 1 commit into
nestjs:masterfrom
sadatsajid:test/contract-on-documented-stores

Conversation

@sadatsajid

@sadatsajid sadatsajid commented Oct 29, 2026 •

Copy link
Copy Markdown
Contributor

PR Checklist

Please check if your PR fulfills the following requirements:

PR Type

What kind of change does this PR introduce?

  • Bugfix
  • Feature
  • Code style update (formatting, local variables)
  • Refactoring (no functional changes, no api changes)
  • Build related changes
  • CI related changes
  • Other... Please describe: tests only, no change to lib/

What is the current behavior?

The docs give the DrizzleLockStore and RedisLockStore recipes for applications to copy, and tell them to check a store with lockStoreContract(). The repo runs the contract only against InMemoryLockStore. The recipes go through the stores integration spec (several instances, jobs, elections), but not through the contract's cases: expiry measured on the server's clock, tokens across releases and expiries, keys kept apart, and the concurrency races.

Issue Number: N/A

What is the new behavior?

The stores integration spec also runs lockStoreContract(..., { concurrent: true }) against each recipe, on the servers it already opens:

  • DrizzleLockStore on PGlite
  • DrizzleLockStore on PostgreSQL, over the backend's pg.Pool
  • RedisLockStore on Redis, over 8 connections, so the concurrency cases race for real

A server that isn't available skips its cases with the reason, as the instances do. StoreBackend gets an optional contractStore(); the in-memory backend has none, since in-memory-store.spec.ts already runs the contract on a ManualLockClock.

All 16 cases pass on each of the three: the full e2e suite is 335 passed, with PostgreSQL 18.6 and Redis 8.10 local, on Node 25.

Does this PR introduce a breaking change?

  • Yes
  • No

Other information

The cases sit in the integration spec rather than a file of their own: files run in parallel, and on CI's shared Redis service the FLUSHALL between the integration tests could empty the store under a contract case. In one file they run after the instances.

The expiry cases wait in real time, so the e2e run goes from about 20s to about 75s.

The docs give the DrizzleLockStore and RedisLockStore recipes for applications to copy and
check with lockStoreContract(), but the suite only ran the contract against InMemoryLockStore.
Run it with concurrent: true against both recipes, on the PGlite, PostgreSQL and Redis servers
the integration spec already opens, over a pool of connections where the server takes them.

The cases live in the integration spec so that its FLUSHALL between tests can't empty a shared
Redis server under a contract case. The expiry cases wait in real time, which adds about a
minute to the e2e run.
@sadatsajid
sadatsajid force-pushed the test/contract-on-documented-stores branch from c166f73 to 7034a0b Compare October 29, 2026 08:13
@kamilmysliwiec
kamilmysliwiec merged commit 21b3fc6 into nestjs:master Oct 29, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants