Add storage conformance suite - #110
Conversation
|
Warning Review limit reached
Next review available in: 20 minutes You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (8)
📝 WalkthroughWalkthroughThe change adds a framework-neutral storage conformance catalog, capability detection, provider fixtures, shared queue/recurring/graph/fair-queue/replica cases, provider fixes, and migrated storage tests. ChangesStorage contracts and conformance API
Estimated code review effort: 4 (Complex) | ~60 minutes Sequence Diagram(s)sequenceDiagram
participant TestRunner
participant JobStorageConformanceSuite
participant IServiceProvider
participant StorageProvider
participant ConformanceCase
TestRunner->>JobStorageConformanceSuite: GetCases(capabilities)
JobStorageConformanceSuite->>TestRunner: Return required cases
TestRunner->>IServiceProvider: Build isolated provider
TestRunner->>ConformanceCase: RunAsync(provider, cancellation)
ConformanceCase->>IServiceProvider: Resolve storage
ConformanceCase->>StorageProvider: Verify capabilities and run scenario
StorageProvider->>ConformanceCase: Return persisted state and results
Possibly related PRs
Suggested reviewers: 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches 💡 1📝 Generate docstrings 💡
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 5
🧹 Nitpick comments (8)
src/Immediate.Jobs.Testing/Storage/QueueStorageConformance.cs (2)
114-118: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueAlign the method name with the case name.
The case constant is
Queue.Acquisition.ExcludesFutureJobs, and the body enqueues only a due record and a future record. The method nameExcludesFutureAndParkedAsyncimplies parked-state coverage that the case does not exercise.♻️ Proposed rename
- private static async ValueTask ExcludesFutureAndParkedAsync( + private static async ValueTask ExcludesFutureJobsAsync(Update the reference on line 33 as well:
- new(DueName, StorageCapabilities.Queue, ExcludesFutureAndParkedAsync), + new(DueName, StorageCapabilities.Queue, ExcludesFutureJobsAsync),🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/Immediate.Jobs.Testing/Storage/QueueStorageConformance.cs` around lines 114 - 118, Rename ExcludesFutureAndParkedAsync to ExcludesFutureJobsAsync to match the Queue.Acquisition.ExcludesFutureJobs case and its covered records, and update the reference to this method at the existing call site.
458-468: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winDocument that this case disposes the container-owned storage.
DisposesIdempotentlyAsynccallsDisposeAsyncon theIJobStorageinstance that the service provider owns and will dispose again. Every host in this PR builds a fresh provider per case, so the suite passes today. If a provider author reuses one service provider for all cases, the disposal case leaves a disposed singleton for later cases, and failures depend on case order.State this requirement in the provider-author documentation, or resolve a dedicated storage instance for this case.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/Immediate.Jobs.Testing/Storage/QueueStorageConformance.cs` around lines 458 - 468, Document in the provider-author guidance that DisposesIdempotentlyAsync disposes the service-provider-owned IJobStorage instance and therefore requires a provider created specifically for this case; alternatively, change the test to resolve a dedicated storage instance before disposing it. Preserve the idempotent disposal assertions.src/Immediate.Jobs.Testing/Storage/RecurringStorageConformance.cs (1)
425-430: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winUse
GetServiceso a missingTimeProviderproduces a conformance message.
QueueStorageConformance.GetClock(lines 500-508) callsGetService<TimeProvider>()and letsConformanceAssert.IsAssignableFromreport the missing registration with the case name. This helper callsGetRequiredService<TimeProvider>(), so a provider author who forgets the registration gets anInvalidOperationExceptionthat the runner wraps as an unexpected scenario failure. Align both catalogs on the clearer diagnostic.♻️ Proposed change
private static FakeTimeProvider Clock(IServiceProvider serviceProvider, string caseName) => ConformanceAssert.IsAssignableFrom<FakeTimeProvider>( - serviceProvider.GetRequiredService<TimeProvider>(), + serviceProvider.GetService<TimeProvider>(), caseName, "time-dependent conformance cases require the registered TimeProvider to be a FakeTimeProvider" );🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/Immediate.Jobs.Testing/Storage/RecurringStorageConformance.cs` around lines 425 - 430, Update the Clock helper to resolve TimeProvider with GetService rather than GetRequiredService, allowing ConformanceAssert.IsAssignableFrom to handle missing registrations and report the case name consistently with QueueStorageConformance.GetClock.tests/Immediate.Jobs.StorageTests/StorageConformanceTests.cs (1)
29-63: 🚀 Performance & Scalability | 🔵 Trivial | ⚖️ Poor tradeoffConsider sharing one fixture per provider combination.
RelationalStorageConformscreates a fixture for every theory row. The row count is 3 databases × 2 adapters × the full conformance case count, and each row creates and drops a schema, or creates and deletes a SQLite file. This multiplies container round trips and CI time.Per-case isolation is the safest default, so this is a trade-off rather than a defect. If the suite runtime becomes a problem, group cases by provider combination and reset only the data between cases.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@tests/Immediate.Jobs.StorageTests/StorageConformanceTests.cs` around lines 29 - 63, Consider refactoring RelationalStorageConforms to reuse one RelationalConformanceFixture for each database and adapter combination, while resetting only test data between JobStorageConformanceTestCase executions. Preserve per-case isolation and ensure each provider fixture is disposed after all its cases complete.src/Immediate.Jobs.Testing/Storage/GraphStorageConformance.cs (2)
475-476: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winAssert the setup acquisition before you complete the job.
The code discards the acquisition result. If
AcquireDueJobsAsyncreturns no job, the laterCompleteWithContinuationsAsynccall fails with an unrelated message, which hides the real cause. Assert the acquired job and reuse itsAttemptvalue.♻️ Proposed refactor
- _ = await graph.AcquireDueJobsAsync(CreateRequest("dynamic-worker", current.JobName), cancellationToken) - .ConfigureAwait(false); + var acquiredCurrent = ConformanceAssert.NotNull( + (await graph.AcquireDueJobsAsync(CreateRequest("dynamic-worker", current.JobName), cancellationToken) + .ConfigureAwait(false)).SingleOrDefault(), + DynamicName, + "the dynamic batch root must be acquirable" + ); var inserted = CreateJob("dynamic-inserted", batchId: "dynamic-batch"); await graph.CompleteWithContinuationsAsync( current.Id, - 1, + acquiredCurrent.Attempt, "dynamic-worker",🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/Immediate.Jobs.Testing/Storage/GraphStorageConformance.cs` around lines 475 - 476, Update the setup acquisition in the conformance test to capture and assert the result of AcquireDueJobsAsync before completing the job, then reuse the asserted acquired job’s Attempt value in CompleteWithContinuationsAsync instead of relying on the existing current job state.
587-595: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueShare one default-queue-name helper instead of duplicating the dummy
JobRecordprobe. Both catalogs construct a throwawayJobRecordonly to read its computedQueueName. Extract this into a single internal helper in the conformance package, then use it in both files. If a public accessor for the default queue name already exists, prefer it over the probe.
src/Immediate.Jobs.Testing/Storage/GraphStorageConformance.cs#L587-L595: replace the inline probe with the shared helper, and stop rebuilding the record on everyCreateRequestcall.src/Immediate.Jobs.Testing/Storage/FairQueueStorageConformance.cs#L448-L456: delete the localDefaultQueueNameprobe and reference the shared helper.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/Immediate.Jobs.Testing/Storage/GraphStorageConformance.cs` around lines 587 - 595, Create one internal default-queue-name helper in the conformance package, or reuse an existing public accessor if available, instead of constructing dummy JobRecord probes. In src/Immediate.Jobs.Testing/Storage/GraphStorageConformance.cs lines 587-595, replace the inline probe with the shared helper so it is not rebuilt for each CreateRequest call; in src/Immediate.Jobs.Testing/Storage/FairQueueStorageConformance.cs lines 448-456, remove the local DefaultQueueName probe and reference the same helper.src/Immediate.Jobs.Testing/Storage/FairQueueStorageConformance.cs (1)
431-440: 🗄️ Data Integrity & Integration | 🔵 Trivial | ⚡ Quick winDocument the acquisition ordering contract.
Queue acquisition orders jobs by
DueAt, thenCreatedAt, thenId; fair acquisition uses theCreatedAttie-breaker before comparing candidate fairness. Add this contract to the storage/provider conformance docs so new providers do not implement another deterministic order.Also mention that enqueue records can have
CreatedAtafterDueAtfor queued delayed jobs, since providers may inspect that field.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/Immediate.Jobs.Testing/Storage/FairQueueStorageConformance.cs` around lines 431 - 440, Update the storage/provider conformance documentation around the enqueue fixture to explicitly define acquisition ordering: sort by DueAt, then CreatedAt, then Id; for fair acquisition, apply CreatedAt as the tie-breaker before comparing candidate fairness. Also document that queued delayed jobs may have CreatedAt later than DueAt, and providers must inspect and preserve this field.src/Immediate.Jobs.Testing/Storage/ReplicaStorageConformance.cs (1)
465-465: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueMake the expected attempt a parameter of
AssertAcquired.The message says "must increment the attempt", but the assertion requires the absolute value
1. The single current caller acquires the job once, so the check passes today. A later caller that asserts a reclaimed acquisition would get a misleading failure.♻️ Proposed refactor
private static void AssertAcquired( JobRecord expected, JobRecord actual, string workerId, DateTimeOffset leaseExpiresAt, - string caseName + string caseName, + int expectedAttempt = 1 ) {- ConformanceAssert.Equal(1, actual.Attempt, caseName, "exact acquisition must increment the attempt"); + ConformanceAssert.Equal(expectedAttempt, actual.Attempt, caseName, "exact acquisition must increment the attempt");🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/Immediate.Jobs.Testing/Storage/ReplicaStorageConformance.cs` at line 465, Update AssertAcquired to accept an expected attempt parameter and compare actual.Attempt against it instead of hardcoding 1. Pass the appropriate expected attempt from each caller, including the existing single-acquisition case, while preserving the current assertion message and behavior.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/Immediate.Jobs.EntityFrameworkCore/EntityFrameworkCoreJobStorage.cs`:
- Around line 15-18: Restore public accessibility for
EntityFrameworkCoreJobStorage<TContext> in
src/Immediate.Jobs.EntityFrameworkCore/EntityFrameworkCoreJobStorage.cs:15-18,
LinqToDBJobStorage in src/Immediate.Jobs.LinqToDB/LinqToDBJobStorage.cs:14, and
RedisJobStorage in src/Immediate.Jobs.Redis/RedisJobStorage.cs:16 so existing
consumers and public factory methods retain access to these storage
implementations.
In `@src/Immediate.Jobs.Testing/Storage/FairQueueStorageConformance.cs`:
- Around line 375-383: Update the concurrent acquisition assertions in the test
around Task.WhenAll: remove the requirement that the two parallel claims
immediately return exactly 12 IDs, while retaining the invariant that IDs are
distinct. Then either drain remaining eligible jobs after the concurrent calls
and verify all 12 are eventually claimed, or assert the collected ID count does
not exceed 12.
In `@src/Immediate.Jobs.Testing/Storage/JobStorageConformanceTestCase.cs`:
- Line 61: Update the setup in the conformance test case to resolve all
registrations through GetServices<IJobStorage>() and require exactly one result
before assigning the storage used by the scenario. Replace the current
GetRequiredService<IJobStorage>() resolution while preserving the existing
failure behavior for invalid service configuration.
In `@src/Immediate.Jobs.Testing/Storage/ReplicaStorageConformance.cs`:
- Around line 258-268: Update the clock advancement immediately before the
second AcquireJobsAsync call in the stale-worker lease test to move beyond the
first lease’s expiry instant, rather than exactly one minute. Preserve the
existing reclaimability assertion and use a small additional duration sufficient
to avoid provider-specific expiry-boundary behavior.
In `@tests/Immediate.Jobs.StorageTests/StorageConformanceTests.cs`:
- Around line 199-241: Update the fixture-construction method containing
ConformanceDbContextFactory and serviceCollection so schema creation and
BuildServiceProvider occur inside a try/catch after constructing the fixture. On
any failure from CreateImmediateJobsSchemaAsync, ExecuteSqlRawAsync, or provider
validation, call the fixture’s DisposeAsync cleanup before rethrowing, matching
the existing MatrixFixture pattern in RelationalStorageMatrixTests.
---
Nitpick comments:
In `@src/Immediate.Jobs.Testing/Storage/FairQueueStorageConformance.cs`:
- Around line 431-440: Update the storage/provider conformance documentation
around the enqueue fixture to explicitly define acquisition ordering: sort by
DueAt, then CreatedAt, then Id; for fair acquisition, apply CreatedAt as the
tie-breaker before comparing candidate fairness. Also document that queued
delayed jobs may have CreatedAt later than DueAt, and providers must inspect and
preserve this field.
In `@src/Immediate.Jobs.Testing/Storage/GraphStorageConformance.cs`:
- Around line 475-476: Update the setup acquisition in the conformance test to
capture and assert the result of AcquireDueJobsAsync before completing the job,
then reuse the asserted acquired job’s Attempt value in
CompleteWithContinuationsAsync instead of relying on the existing current job
state.
- Around line 587-595: Create one internal default-queue-name helper in the
conformance package, or reuse an existing public accessor if available, instead
of constructing dummy JobRecord probes. In
src/Immediate.Jobs.Testing/Storage/GraphStorageConformance.cs lines 587-595,
replace the inline probe with the shared helper so it is not rebuilt for each
CreateRequest call; in
src/Immediate.Jobs.Testing/Storage/FairQueueStorageConformance.cs lines 448-456,
remove the local DefaultQueueName probe and reference the same helper.
In `@src/Immediate.Jobs.Testing/Storage/QueueStorageConformance.cs`:
- Around line 114-118: Rename ExcludesFutureAndParkedAsync to
ExcludesFutureJobsAsync to match the Queue.Acquisition.ExcludesFutureJobs case
and its covered records, and update the reference to this method at the existing
call site.
- Around line 458-468: Document in the provider-author guidance that
DisposesIdempotentlyAsync disposes the service-provider-owned IJobStorage
instance and therefore requires a provider created specifically for this case;
alternatively, change the test to resolve a dedicated storage instance before
disposing it. Preserve the idempotent disposal assertions.
In `@src/Immediate.Jobs.Testing/Storage/RecurringStorageConformance.cs`:
- Around line 425-430: Update the Clock helper to resolve TimeProvider with
GetService rather than GetRequiredService, allowing
ConformanceAssert.IsAssignableFrom to handle missing registrations and report
the case name consistently with QueueStorageConformance.GetClock.
In `@src/Immediate.Jobs.Testing/Storage/ReplicaStorageConformance.cs`:
- Line 465: Update AssertAcquired to accept an expected attempt parameter and
compare actual.Attempt against it instead of hardcoding 1. Pass the appropriate
expected attempt from each caller, including the existing single-acquisition
case, while preserving the current assertion message and behavior.
In `@tests/Immediate.Jobs.StorageTests/StorageConformanceTests.cs`:
- Around line 29-63: Consider refactoring RelationalStorageConforms to reuse one
RelationalConformanceFixture for each database and adapter combination, while
resetting only test data between JobStorageConformanceTestCase executions.
Preserve per-case isolation and ensure each provider fixture is disposed after
all its cases complete.
🪄 Autofix
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro Plus
Run ID: defcebd9-1028-4f5f-8eb0-5ffaa227cba4
📒 Files selected for processing (38)
docs/storage-tests.mdreadme.mdsrc/Immediate.Jobs.EntityFrameworkCore/EntityFrameworkCoreJobStorage.cssrc/Immediate.Jobs.EntityFrameworkCore/Immediate.Jobs.EntityFrameworkCore.csprojsrc/Immediate.Jobs.EntityFrameworkCore/ImmediateJobsModelBuilderExtensions.cssrc/Immediate.Jobs.LinqToDB/Immediate.Jobs.LinqToDB.csprojsrc/Immediate.Jobs.LinqToDB/LinqToDBJobStorage.cssrc/Immediate.Jobs.Redis/Immediate.Jobs.Redis.csprojsrc/Immediate.Jobs.Redis/RedisJobStorage.cssrc/Immediate.Jobs.Shared/Immediate.Jobs.Shared.csprojsrc/Immediate.Jobs.Shared/Storage/IFairQueueStorage.cssrc/Immediate.Jobs.Shared/Storage/InMemoryJobStorage.cssrc/Immediate.Jobs.Shared/Storage/SingleServerJobStorage.cssrc/Immediate.Jobs.Shared/Storage/StorageCapabilities.cssrc/Immediate.Jobs.Testing/Immediate.Jobs.Testing.csprojsrc/Immediate.Jobs.Testing/Storage/ConformanceAssert.cssrc/Immediate.Jobs.Testing/Storage/FairQueueStorageConformance.cssrc/Immediate.Jobs.Testing/Storage/GraphStorageConformance.cssrc/Immediate.Jobs.Testing/Storage/JobStorageConformanceScenario.cssrc/Immediate.Jobs.Testing/Storage/JobStorageConformanceSuite.cssrc/Immediate.Jobs.Testing/Storage/JobStorageConformanceTestCase.cssrc/Immediate.Jobs.Testing/Storage/QueueStorageConformance.cssrc/Immediate.Jobs.Testing/Storage/RecurringStorageConformance.cssrc/Immediate.Jobs.Testing/Storage/ReplicaStorageConformance.cstests/Immediate.Jobs.FunctionalTests/Packages/InMemoryStorageConformanceTests.cstests/Immediate.Jobs.FunctionalTests/Packages/StorageConformanceInfrastructureTests.cstests/Immediate.Jobs.FunctionalTests/Storage/EntityFrameworkCoreJobStorageTests.cstests/Immediate.Jobs.FunctionalTests/Storage/InMemoryFairQueueTests.cstests/Immediate.Jobs.FunctionalTests/Storage/InMemoryJobStorageBatchTests.cstests/Immediate.Jobs.FunctionalTests/Storage/JobExecutionStorageTests.cstests/Immediate.Jobs.FunctionalTests/Storage/QueueStorageTests.cstests/Immediate.Jobs.FunctionalTests/Storage/SingleServerJobStorageTests.cstests/Immediate.Jobs.FunctionalTests/StorageCapabilityTests.cstests/Immediate.Jobs.StorageTests/Immediate.Jobs.StorageTests.csprojtests/Immediate.Jobs.StorageTests/LinqToDBSqliteStorageTests.cstests/Immediate.Jobs.StorageTests/RedisStorageTests.cstests/Immediate.Jobs.StorageTests/RelationalStorageMatrixTests.cstests/Immediate.Jobs.StorageTests/StorageConformanceTests.cs
💤 Files with no reviewable changes (6)
- tests/Immediate.Jobs.FunctionalTests/Storage/InMemoryJobStorageBatchTests.cs
- tests/Immediate.Jobs.FunctionalTests/Storage/QueueStorageTests.cs
- tests/Immediate.Jobs.FunctionalTests/Storage/InMemoryFairQueueTests.cs
- tests/Immediate.Jobs.FunctionalTests/Storage/JobExecutionStorageTests.cs
- tests/Immediate.Jobs.StorageTests/RedisStorageTests.cs
- tests/Immediate.Jobs.StorageTests/LinqToDBSqliteStorageTests.cs
Coverage Report for CI Build 31316266018Coverage increased (+6.6%) to 90.508%Details
Uncovered Changes
Coverage Regressions11 previously-covered lines in 4 files lost coverage.
Coverage Stats
💛 - Coveralls |
f35fced to
71f7024
Compare
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@tests/Immediate.Jobs.StorageTests/JobExecutionStorageTests.cs`:
- Around line 15-16: Update the legacy job fixture in JobExecutionStorageTests
so CreateJob’s CreatedAt value is at least two minutes earlier than completedAt,
while preserving the existing execution timestamps and test flow.
🪄 Autofix
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro Plus
Run ID: 0f0be227-01e1-4896-b298-2873df8fac28
📒 Files selected for processing (15)
src/Immediate.Jobs.Testing/Storage/FairQueueStorageConformance.cssrc/Immediate.Jobs.Testing/Storage/JobStorageConformanceTestCase.cstests/Immediate.Jobs.FunctionalTests/BatchesAndContinuationsTests.cstests/Immediate.Jobs.FunctionalTests/ControllableJobStorageProxy.cstests/Immediate.Jobs.FunctionalTests/JobSchedulingServiceTests.cstests/Immediate.Jobs.StorageTests/EntityFrameworkCoreJobStorageTests.cstests/Immediate.Jobs.StorageTests/InMemoryJobStorageBatchTests.cstests/Immediate.Jobs.StorageTests/InMemoryStorageConformanceTests.cstests/Immediate.Jobs.StorageTests/JobExecutionStorageTests.cstests/Immediate.Jobs.StorageTests/LinqToDBSqliteStorageTests.cstests/Immediate.Jobs.StorageTests/RedisStorageTests.cstests/Immediate.Jobs.StorageTests/RelationalStorageMatrixTests.cstests/Immediate.Jobs.StorageTests/SingleServerJobStorageTests.cstests/Immediate.Jobs.StorageTests/StorageConformanceInfrastructureTests.cstests/Immediate.Jobs.StorageTests/StorageConformanceTests.cs
💤 Files with no reviewable changes (2)
- tests/Immediate.Jobs.StorageTests/RedisStorageTests.cs
- tests/Immediate.Jobs.StorageTests/LinqToDBSqliteStorageTests.cs
🚧 Files skipped from review as they are similar to previous changes (11)
- tests/Immediate.Jobs.StorageTests/InMemoryStorageConformanceTests.cs
- tests/Immediate.Jobs.FunctionalTests/JobSchedulingServiceTests.cs
- src/Immediate.Jobs.Testing/Storage/FairQueueStorageConformance.cs
- src/Immediate.Jobs.Testing/Storage/JobStorageConformanceTestCase.cs
- tests/Immediate.Jobs.StorageTests/EntityFrameworkCoreJobStorageTests.cs
- tests/Immediate.Jobs.StorageTests/StorageConformanceTests.cs
- tests/Immediate.Jobs.StorageTests/StorageConformanceInfrastructureTests.cs
- tests/Immediate.Jobs.FunctionalTests/BatchesAndContinuationsTests.cs
- tests/Immediate.Jobs.StorageTests/SingleServerJobStorageTests.cs
- tests/Immediate.Jobs.StorageTests/InMemoryJobStorageBatchTests.cs
- tests/Immediate.Jobs.StorageTests/RelationalStorageMatrixTests.cs
Summary
This PR is stacked on #109 and targets refactor/internalize-storage-providers.
Testing
InternalsVisibleTo follow-up
The conformance suite itself no longer requires InternalsVisibleTo: it uses public registration APIs, receives an IServiceProvider, and resolves IJobStorage from the built container.
Some existing friendships remain because the surviving provider-specific white-box tests directly instantiate internal RedisJobStorage, LinqToDBJobStorage, EntityFrameworkCoreJobStorage, InMemoryJobStorage, and SingleServerJobStorage implementations. Those tests cover cross-instance races, recovery, corruption, transaction behavior, and single-server internals that are deliberately outside the portable conformance contract.
Fully removing those test friendships is possible as a separate refactoring: the remaining fixtures would need to resolve public storage interfaces from independently built containers, and the single-server tests need a public composition seam for custom durable stores and proxies. The Immediate.Jobs.Shared friendship with Immediate.Jobs.Benchmarks is unrelated to storage conformance.
Summary by CodeRabbit
New Features
Bug Fixes
Documentation
Tests