Skip to content

test: Fix flaky MultiDbConnectionProviderTest caused by shared test key pollution - #4644

Merged
ggivo merged 10 commits into
masterfrom
topic/ggivo/fix-flaky-multidb-test-keys
Jul 24, 2026
Merged

ggivo merged 10 commits into
masterfrom
topic/ggivo/fix-flaky-multidb-test-keys

Conversation

@ggivo

@ggivo ggivo commented Jul 24, 2026 •

Copy link
Copy Markdown
Collaborator

What

Fix sporadic WRONGTYPE failures in MultiDbConnectionProviderTest caused by test-key pollution on the shared Redis endpoints, and add a reusable TestKeyRegistry utility to prevent this class of flakiness.

Why

MultiDbConnectionProviderTest reads the well-known key foo on the shared standalone0/standalone1 endpoints. JedisCommandsTestBase subclasses flush only in @BeforeEach, so the last test of each class leaks its keys β€” e.g. TupleSortedSetTest leaves foo as a zset, and a later GET foo fails with WRONGTYPE depending on class execution order.

Fixes #4643

Changes

  • TestKeyRegistry (new test utility): generates unique, human-readable keys namespaced by ClassName.methodName; every key is auto-registered and deletable via cleanup() with a per-slot DEL fallback on cluster CROSSSLOT errors.
    • Class-level scope: a registry created in @BeforeAll derives a ClassName identifier, so class-level keys survive between tests and are cleaned once in @AfterAll.
    • Binary keys: bKey(pattern) mirrors key(pattern) via SafeEncoder; keys are stored internally as bytes so string- and binary-created keys share one entry and cleanup is a single binary DEL.
  • MultiDbConnectionProviderTest: migrated the three tests using "foo" to registry-generated per-test keys.
  • JedisCommandsTestBase: also flushAll() in @AfterEach, so no subclass leaks keys to the rest of the suite.

Verified by planting foo as a zset on both endpoints: the unmodified test reproduces the exact CI failure; with this change all tests pass.


Note

Low Risk
Test-only changes (new utility, integration test keys, and teardown flush); no production client behavior is modified.

Overview
Addresses sporadic WRONGTYPE failures when integration tests reuse shared Redis endpoints and collide on keys like "foo".

Introduces TestKeyRegistry, a test helper that builds per-test namespaced keys (ClassName.methodName:…), tracks them, and deletes them via cleanup() (with per-slot DEL when cluster clients reject cross-slot multi-key deletes). MultiDbConnectionProviderTest switches its failover scenarios from "foo" to registry keys and tears them down through dedicated control Jedis clients on both standalones.

JedisCommandsTestBase also runs flushAll() in @AfterEach (errors ignored) so subclasses are less likely to leave data on the shared endpoint after a class finishes.

Reviewed by Cursor Bugbot for commit 4cb571b. Bugbot is set up for automated code reviews on this repo. Configure here.

ggivo added 5 commits July 24, 2026 13:20
The test read key "foo" on the shared standalone0/standalone1
endpoints without cleanup. Earlier suites (e.g. TupleSortedSetTest)
leave "foo" holding a non-string type, so GET sporadically failed
with WRONGTYPE in CI. Use a unique per-test key (test name + short
random id) instead.
Generalizes the per-test key helper from MultiDbConnectionProviderTest
into a reusable utility so any test can avoid key collisions on the
shared Redis endpoints. Keys are namespaced by ClassName.methodName,
auto-registered, and deletable via cleanup() with a per-slot DEL
fallback on cluster CROSSSLOT errors.
A registry created in @BeforeAll now derives a class-scoped identifier
(ClassName, no method suffix), so keys shared across a class's tests
survive between tests and are cleaned once in @afterall. Scope is a
property of where the registry is created and cleaned; the two scopes
cannot collide since method keys always contain ".methodName".
bKey(pattern) mirrors key(pattern) for byte[] command overloads,
encoding via SafeEncoder. Keys are now stored internally as bytes
(ByteBuffer for content equality), so string- and binary-created keys
share one registry entry and cleanup stays a single binary DEL.
register(byte[]) stores a copy so caller mutation cannot break cleanup.
flushAll() ran only in @beforeeach, so the last test of each subclass
left its keys on the shared endpoints, breaking later tests that read
well-known key names (WRONGTYPE). Flush in @AfterEach as well so no
subclass leaks keys to the rest of the suite.
@github-actions

github-actions Bot commented Jul 24, 2026 •

Copy link
Copy Markdown

Test Results

β€‡β€ˆ206 files  ± 0β€‚β€ƒβ€‡β€ˆ206 suites  Β±0   10m 24s ⏱️ +31s
7β€ˆ849 tests +12  7β€ˆ779 βœ… +939  70 πŸ’€  -β€Š927  0 ❌ Β±0 
7β€ˆ869 runsβ€Š +24  7β€ˆ799 βœ… +959  70 πŸ’€  -β€Š935  0 ❌ Β±0 

Results for commit 4cb571b. ± Comparison against base commit 7aef6e8.

This pull request removes 2 and adds 14 tests. Note that renamed tests count towards both.
redis.clients.jedis.commands.unified.search.FTHybridCommandsTestBase$SupportedScorersTest ‑ testScorer(Scorer, double, double)[1]
redis.clients.jedis.commands.unified.search.FTHybridCommandsTestBase$SupportedScorersTest ‑ testScorer(Scorer, double, double)[2]
redis.clients.jedis.commands.unified.search.FTHybridCommandsTestBase$SupportedScorersTest[1] ‑ testScorer(Scorer, double, double)[1][1]
redis.clients.jedis.commands.unified.search.FTHybridCommandsTestBase$SupportedScorersTest[1] ‑ testScorer(Scorer, double, double)[1][2]
redis.clients.jedis.commands.unified.search.FTHybridCommandsTestBase$SupportedScorersTest[1] ‑ testScorer(Scorer, double, double)[1][3]
redis.clients.jedis.commands.unified.search.FTHybridCommandsTestBase$SupportedScorersTest[1] ‑ testScorer(Scorer, double, double)[1][4]
redis.clients.jedis.commands.unified.search.FTHybridCommandsTestBase$SupportedScorersTest[1] ‑ testScorer(Scorer, double, double)[1][5]
redis.clients.jedis.commands.unified.search.FTHybridCommandsTestBase$SupportedScorersTest[1] ‑ testScorer(Scorer, double, double)[1][6]
redis.clients.jedis.commands.unified.search.FTHybridCommandsTestBase$SupportedScorersTest[1] ‑ testScorer(Scorer, double, double)[1][7]
redis.clients.jedis.commands.unified.search.FTHybridCommandsTestBase$SupportedScorersTest[2] ‑ testScorer(Scorer, double, double)[2][1]
redis.clients.jedis.commands.unified.search.FTHybridCommandsTestBase$SupportedScorersTest[2] ‑ testScorer(Scorer, double, double)[2][2]
redis.clients.jedis.commands.unified.search.FTHybridCommandsTestBase$SupportedScorersTest[2] ‑ testScorer(Scorer, double, double)[2][3]
…

♻️ This comment has been updated with latest results.

@ggivo ggivo added the testing label Jul 24, 2026
@ggivo
ggivo requested review from atakavci and uglide July 24, 2026 11:59
The formatter plugin validates only explicitly listed files;
TestKeyRegistry was missing, failing formatter:validate in CI.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

πŸ’‘ Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 49eea46ff6

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with πŸ‘.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

TestKeyRegistry.cleanup() now accepts KeyBinaryCommands so any Jedis
client type can perform cleanup. MultiDbConnectionProviderTest holds
control Jedis clients for both endpoints (opened in @BeforeAll,
released in @afterall) and deletes each test's keys in @AfterEach.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

πŸ’‘ Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: a1d446fb01

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with πŸ‘.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.

There are 2 total unresolved issues (including 1 from previous review).

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, have a team admin enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit a1d446f. Configure here.

ggivo added 3 commits July 24, 2026 16:32
- Flush on a fresh connection, best-effort:
- Fall back to per-slot DEL on JedisClusterOperationException
- Null-guard @afterall control-client release

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

πŸ’‘ Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 4cb571b485

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with πŸ‘.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

@atakavci atakavci left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

@ggivo
ggivo merged commit 567b7bb into master Jul 24, 2026
17 of 18 checks passed
@ggivo
ggivo deleted the topic/ggivo/fix-flaky-multidb-test-keys branch July 31, 2026 09:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

test: Flaky MultiDbConnectionProviderTest β€” WRONGTYPE failures caused by shared test key pollution

2 participants