Skip to content

redis cache: re-enable scheme/not-installed tests + fix not-installed guard#724

Closed
wbarnha wants to merge 2 commits into
masterfrom
claude/fix-redis-backend-not-installed-guard
Closed

redis cache: re-enable scheme/not-installed tests + fix not-installed guard#724
wbarnha wants to merge 2 commits into
masterfrom
claude/fix-redis-backend-not-installed-guard

Conversation

@wbarnha

@wbarnha wbarnha commented Jul 20, 2026

Copy link
Copy Markdown
Member

Description

Re-enables the skipped redis cache tests and fixes the latent backend bug they surfaced. Independent, off master (consolidates the former #721 + the source fix; #721 is closed in favour of this).

Source fix — faust/web/cache/backends/redis.py

The import guard bound only aredis on failure:

except ImportError:
    aredis = None        # <-- redis left unbound

but the backend guards on if redis is None (on_start, scheme/error setup). With redis genuinely uninstalled, redis stays unbound and the first if redis is None raises NameError at import instead of the intended ImproperlyConfigured. Fixed by binding redis = None, and dropped the dead import redis.asyncio as aredis alias (only ever assigned None, never referenced — its presence is what made the guard look correct).

Tests — tests/functional/web/test_cache.py

  • Test_RedisScheme::test_single_client / test_cluster_client — rewritten for redis-py 8.x: assert against the scheme→client map the backend actually builds (_client_by_scheme); single-node resolves to redis.client.Redis (built for real; connects lazily), cluster to redis.RedisCluster (mocked like the existing mocked_redis fixture, since it connects on construction). Scheme selection and db-stripping run for real.
  • test_redis__is_not_installed (renamed from …aredis_is_not_installed) — patches the redis name the guard reads and asserts ImproperlyConfigured without opening a socket.

Verification

tests/functional/web/test_cache.py32 passed; the guard now raises ImproperlyConfigured (previously NameError), verified directly. flake8/black/isort clean.

Not addressed (separate, larger concern)

The backend maps schemes to sync clients (redis.StrictRedis/RedisCluster) yet awaits them in _get/_set — fine under the mocked tests, likely broken for real async use. Worth a dedicated look.

🤖 Generated with Claude Code

wbarnha and others added 2 commits July 20, 2026 19:11
Both were skipped "Needs fixing" and had drifted against redis-py 8.x and the
current cache backend:

* Test_RedisScheme referenced `redis.StrictRedis`/`aredis.RedisCluster` as the
  backend module's client types, which no longer exist there.  Assert instead
  against the scheme->client-class map the backend actually builds
  (`_client_by_scheme`): single-node resolves to redis-py 8.x's concrete
  `redis.client.Redis`; cluster resolves to `redis.RedisCluster`.  The
  single-node client is built for real (redis-py connects lazily) and its
  `connection_pool.connection_kwargs` are checked; the cluster class -- which
  would connect on construction -- is mocked like the existing `mocked_redis`
  fixture, while scheme selection and db-stripping run for real.
* test_redis__aredis_is_not_installed now patches the `redis` module name the
  backend's on_start guard actually reads (`if redis is None`), so it raises
  ImproperlyConfigured without opening a socket.

Only external redis client classes are mocked; the backend logic runs for real.

NB: the backend imports `redis.asyncio as aredis` but never guards on it -- a
possible latent bug left for a separate source-side change.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HHPL4VFWQRQPpjR1gXSKyL
The redis cache backend's import guard set only `aredis = None` on
ImportError, never `redis`.  But `on_start` (and the module-level scheme/error
guards) key off `if redis is None`, and `redis` stays unbound when the library
isn't installed -- so instead of the intended `ImproperlyConfigured`, importing
the backend raised `NameError: name 'redis' is not defined`.

Bind `redis = None` in the except block so the guard works, and drop the
`import redis.asyncio as aredis` alias, which was dead: `aredis` was never
referenced anywhere in the backend (only assigned None), and the backend's
clients come from the sync `redis` module.

Rename the now-accurate test `test_redis__aredis_is_not_installed` ->
`test_redis__is_not_installed` (it exercises the `redis is None` guard).

Verified: with `redis` patched to None, `on_start` now raises
ImproperlyConfigured (previously NameError); redis cache tests still pass.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HHPL4VFWQRQPpjR1gXSKyL
@wbarnha wbarnha changed the title fix(cache): bind redis=None when the redis library is missing redis cache: re-enable scheme/not-installed tests + fix not-installed guard Jul 20, 2026
@wbarnha
wbarnha changed the base branch from claude/reenable-redis-cache-tests to master July 20, 2026 21:13

wbarnha commented Jul 20, 2026

Copy link
Copy Markdown
Member Author

Superseded by #725. Investigating "can we test redis in CI" revealed the backend is actually broken against a real server (it awaits the sync redis.StrictRedisTypeError), which this PR's mocks were hiding. #725 folds in this guard fix, switches the backend to the redis.asyncio clients so it works for real, updates the scheme tests accordingly, and adds a live-redis CI job. Closing in favour of it — nothing is lost.


Generated by Claude Code

@wbarnha wbarnha closed this Jul 20, 2026
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.

1 participant