test(diagnostics): add InMemory/Sqlite StructuredLog store conformance - #8151
Merged
Merged
Conversation
sfmskywalker
marked this pull request as ready for review
September 14, 2026 07:12
Contributor
|
Cover the later IStructuredLogStore order stages independently so a SourceId-only assertion cannot hide Sequence or Id regressions. Co-authored-by: Sipke Schoorstra <sipkeschoorstra@outlook.com>
Use IDs that sort opposite Sequence so a skip-Sequence, order-by-Id implementation cannot pass the shared matrix. Co-authored-by: Sipke Schoorstra <sipkeschoorstra@outlook.com>
sfmskywalker
commented
Sep 14, 2026
sfmskywalker
left a comment
Member
Author
There was a problem hiding this comment.
Code Review — Round 1/4 @ 124d27e → main
Verdict: APPROVE + HIGH (formal event COMMENT — own-PR APPROVE blocked for sfmskywalker)
What changed (fixes #8118)
Shared InMemory / Sqlite conformance suite for IStructuredLogStore (Labels/Alterations/Secrets pattern):
- Take: null →
MaxRecentLogQuerySize, oversize clamp, negative Take / negative max → empty - Order: SourceId, then Sequence, then Id (each stage isolates preceding ties; Sequence/Id seeds cannot pass via the other key)
- ListSources: registry metadata +
SourceHeartbeatTimeout→Stale - Filters: exact-case equality, category prefix, text, level, time range before Take
- DroppedEvents: InMemory ring count vs Relational QueryAsync
0— intentional split, locked both ways - README documents non-portable case/
=collation and SourceId sort case (lowercase seeds)
Scenario fixture flushes Sqlite write buffer, validates DI scopes, cleans temp DB + pool.
Soft steers (non-blocking)
- No dedicated ReceivedAt-only tie-break case (Timestamp tied, ReceivedAt differs) — optional follow-up; SourceId/Sequence/Id stages are solid.
- Sqlite path sets
RecentLogCapacityin the ring-overflow test but Relational ignores it for QueryAsync — intentional viaReportsRingDroppedEvents.
Merge gates
- Code Review: APPROVE + HIGH @
124d27e - Greptile: tip 5/5 ✓
- CI: green on tip ✓
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #8118
Purpose
Add a shared InMemory / Relational (Sqlite) conformance matrix for
IStructuredLogStoreso Take clamp, SourceId tie-break, ListSources heartbeat, DroppedEvents, and portable filters cannot drift independently again.Scope
Description
Problem
Diagnostics StructuredLogs ship parallel InMemory and Relational
IStructuredLogStoreimplementations. Filter/order/Take/ListSources/DroppedEvents invariants lived in separate unit vs Sqlite suites, so one path could regress without the other failing. Companion PRs already aligned production behavior (#8147 Take clamp, #8148 SourceId sort + ListSources registry/heartbeat).Solution
New
Elsa.Diagnostics.StructuredLogs.Persistence.ConformanceTestsproject follows the recent Labels/Alterations/Secrets pattern: shared scenarios + InMemory and Sqlite fixtures.Locked shared contracts:
Takeand oversizeTakeuseStructuredLogsOptions.MaxRecentLogQuerySize; negative ceiling orTakereturns emptySourceId, thenSequence, thenId(each stage asserted with preceding fields tied; Sequence IDs sort opposite Sequence so Id-only order cannot pass)ListSourcesprefers in-process registry metadata and marks sourcesStaleafterSourceHeartbeatTimeoutTakeDocumented store-specific contracts (not chased into a false shared equality):
QueryAsync.DroppedEventsis the InMemory ring overflow count; Relational QueryAsync stays0(write-queue drops live on storage diagnostics)=/ Sqlite BINARY) vs InMemoryOrdinalIgnoreCase— tests seed exact-case valuesNo production store changes: #8147/#8148 already aligned the shared contracts; conformance did not expose remaining drift that needed a prod fix.
Verification
Steps:
dotnet test test/integration/Elsa.Diagnostics.StructuredLogs.Persistence.ConformanceTests/Elsa.Diagnostics.StructuredLogs.Persistence.ConformanceTests.csprojExpected outcome: the new matrix is green on both providers; Take / SourceId / Sequence / Id / ListSources / DroppedEvents / portable filters stay locked.
Local results:
Elsa.Diagnostics.StructuredLogs.Persistence.ConformanceTests(net10.0): 22 passed (11 shared scenarios × InMemory + Sqlite)Tip:
124d27e3eoncursor/structured-logs-conformance-b0d0Checklist