Skip to content

test(redis): add live e2e guards for StackExchange.Redis internal reflection - #82

Merged
cosmin-staicu merged 1 commit into
mainfrom
test/redis-reflection-e2e-guards
Jul 16, 2026
Merged

test(redis): add live e2e guards for StackExchange.Redis internal reflection#82
cosmin-staicu merged 1 commit into
mainfrom
test/redis-reflection-e2e-guards

Conversation

@cosmin-staicu

Copy link
Copy Markdown
Member

Summary

Adds live end-to-end tests that guard the two places where the library reflects into StackExchange.Redis private internals. Both fail silently, so unit tests (which mock the Redis interfaces) can't detect them degrading — this lands the guards before the upcoming StackExchange.Redis 2.1x and 3.0 upgrades so those bumps have a real runtime tripwire.

Changes

  • New ProfiledCommandExtensionsIntegrationTests — runs a keyed command against live Redis and asserts GetStatement() carries the key. That only holds when the ProfiledCommand.MessageMessage.CommandAndKey reflection resolves; on a silent miss it falls back to the bare command name and the test fails.
  • Strengthened GetMasterPhysicalConnectionMetrics test — was a bare NotBeNull; now also asserts the reflected endpoint and a sane AwaitingResponseCount, so a wrong-but-present field bind returning garbage is caught, not just a null.

Both are gated behind RUN_REDIS_INTEGRATION_TESTS=1 (no change to the default test run).

Context: 3.0 is an internal IO-core rewrite touching exactly the PhysicalConnection/PhysicalBridge internals the hang-detection reflection reads. All 7 reflected members still exist at tag 3.0.17, but only a live test proves the runtime values still resolve.

Test plan

  • Unit tests added/updated
  • Integration tests pass locally (dotnet test)
  • CHANGELOG.md updated

Verified against a live Redis on net8.0 and net10.0 at the current 2.10.1 baseline (all 9 integration tests pass). Also mutation-proved the profiling guard: forcing the reflection to miss drops the key from GetStatement() and the test fails as intended.

Linked issues

Fixes #

Contributor declaration

  • I signed off my commits per the DCO (git commit -s).
  • I am contributing on behalf of my employer, or in the course of employment / using employer resources.

🤖 Generated with Claude Code

…lection

Two reflection sites reach into StackExchange.Redis private internals and
fail silently, so unit tests (which mock the Redis interfaces) cannot detect
them degrading — a risk ahead of the upcoming 2.1x and 3.0 upgrades.

- Add ProfiledCommandExtensionsIntegrationTests: runs a keyed command against
  live Redis and asserts GetStatement() carries the key, which only holds when
  the ProfiledCommand.Message -> Message.CommandAndKey reflection resolves.
- Strengthen the existing GetMasterPhysicalConnectionMetrics test to also check
  the reflected endpoint and a sane AwaitingResponseCount, catching a
  wrong-but-present field bind, not just a null.

Both gated by RUN_REDIS_INTEGRATION_TESTS=1. Verified against live Redis on
net8.0 and net10.0 at the current 2.10.1 baseline.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Cosmin Staicu <cosmin.staicu@uipath.com>
@sonarqubecloud

Copy link
Copy Markdown

@cosmin-staicu
cosmin-staicu merged commit d91bf46 into main Jul 16, 2026
9 checks passed
@cosmin-staicu
cosmin-staicu deleted the test/redis-reflection-e2e-guards branch July 16, 2026 18:26
cosmin-staicu added a commit that referenced this pull request Jul 16, 2026
First step of the staged StackExchange.Redis upgrade toward 3.0. 2.13.17 is
the latest 2.x and shares 3.0's public API, so it de-risks the major bump.

No public API or runtime behavior change. The only breakage was a test
fixture: SE.Redis 2.13.17 grew the internal StreamInfo constructor from 7 to
16 parameters, and RedisStreamHealthMaintainerTests fabricates StreamInfo via
reflection with a hardcoded positional arg list. The old 7-arg call no longer
bound, the fixture threw, and the maintainer's try/catch swallowed it —
surfacing as "received no matching calls" on the downstream mocks. Production
is unaffected (it gets real StreamInfo objects from SE.Redis deserialization,
never this reflection). GenerateStreamInfo now fills by the ctor's actual
parameter list and sets only the fields the maintainer reads, so it survives
this bump and the upcoming 3.0 one.

Verified: full suite green on net8.0 and net10.0 (1174/1174 each), including
the live-Redis reflection guards from #82.

Signed-off-by: Cosmin Staicu <cosmin.staicu@uipath.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
cosmin-staicu added a commit that referenced this pull request Jul 17, 2026
Final step of the staged StackExchange.Redis upgrade. 3.0 is an internal
IO-core rewrite that mirrors 2.13.17's public API, so there is no public API
change. Stacked on the Logging.Abstractions bump (that package is a hard
transitive prerequisite for 3.0).

3.0 removed SocketManager (its new IO core no longer uses one), so
ConfigurationOptions.SocketManager is obsolete. Dropped the now-dead
assignment in RedisConfigurationOptionsProvider and marked the backing option
RedisConnectionOptions.ThreadPoolSocketManager [Obsolete] (no-op, non-breaking
signature) so consumers get a signal rather than a silent no-op.

The two silent-failing reflection paths were the upgrade's main risk. Verified
against live Redis on both TFMs via the guards added in #82: hang-detection
metrics (GetMasterPhysicalConnectionMetrics) still resolve real values, and
the profiling GetStatement still carries the command key. Benchmarks' admin
FLUSHALL is unaffected (the runner already sets allowAdmin=true). The Azure
Entra/RESP3 path is covered by build + configurator unit tests only (no live
Azure endpoint); its runtime behavior is unverified in this PR.

Full suite green on net8.0 and net10.0 (1174/1174 each) with
RUN_REDIS_INTEGRATION_TESTS=1.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Cosmin Staicu <cosmin.staicu@uipath.com>
cosmin-staicu added a commit that referenced this pull request Jul 17, 2026
Final step of the staged StackExchange.Redis upgrade. 3.0 is an internal
IO-core rewrite that mirrors 2.13.17's public API, so there is no public API
change. Stacked on the Logging.Abstractions bump (that package is a hard
transitive prerequisite for 3.0).

3.0 removed SocketManager (its new IO core no longer uses one), so
ConfigurationOptions.SocketManager is obsolete. Dropped the now-dead
assignment in RedisConfigurationOptionsProvider and marked the backing option
RedisConnectionOptions.ThreadPoolSocketManager [Obsolete] (no-op, non-breaking
signature) so consumers get a signal rather than a silent no-op.

The two silent-failing reflection paths were the upgrade's main risk. Verified
against live Redis on both TFMs via the guards added in #82: hang-detection
metrics (GetMasterPhysicalConnectionMetrics) still resolve real values, and
the profiling GetStatement still carries the command key. Benchmarks' admin
FLUSHALL is unaffected (the runner already sets allowAdmin=true). The Azure
Entra/RESP3 path is covered by build + configurator unit tests only (no live
Azure endpoint); its runtime behavior is unverified in this PR.

Full suite green on net8.0 and net10.0 (1174/1174 each) with
RUN_REDIS_INTEGRATION_TESTS=1.

Signed-off-by: Cosmin Staicu <cosmin.staicu@uipath.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
cosmin-staicu added a commit that referenced this pull request Jul 17, 2026
Final step of the staged StackExchange.Redis upgrade. 3.0 is an internal
IO-core rewrite that mirrors 2.13.17's public API, so there is no public API
change. Stacked on the Logging.Abstractions bump (that package is a hard
transitive prerequisite for 3.0).

3.0 removed SocketManager (its new IO core no longer uses one), so
ConfigurationOptions.SocketManager is obsolete. Dropped the now-dead
assignment in RedisConfigurationOptionsProvider and marked the backing option
RedisConnectionOptions.ThreadPoolSocketManager [Obsolete] (no-op, non-breaking
signature) so consumers get a signal rather than a silent no-op.

The two silent-failing reflection paths were the upgrade's main risk. Verified
against live Redis on both TFMs via the guards added in #82: hang-detection
metrics (GetMasterPhysicalConnectionMetrics) still resolve real values, and
the profiling GetStatement still carries the command key. Benchmarks' admin
FLUSHALL is unaffected (the runner already sets allowAdmin=true). The Azure
Entra/RESP3 path is covered by build + configurator unit tests only (no live
Azure endpoint); its runtime behavior is unverified in this PR.

Full suite green on net8.0 and net10.0 (1174/1174 each) with
RUN_REDIS_INTEGRATION_TESTS=1.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Cosmin Staicu <cosmin.staicu@uipath.com>
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