Skip to content

fix(odata): handle mixed annotation cache key collisions - #909

Merged
Gavin Barron (gavinbarron) merged 1 commit into
mainfrom
gavinbarron-odata-annotation-cache-collision
Oct 13, 2026
Merged

Gavin Barron (gavinbarron) merged 1 commit into
mainfrom
gavinbarron-odata-annotation-cache-collision

Conversation

@gavinbarron

Copy link
Copy Markdown
Contributor

Summary

Fix the heterogeneous annotation cache in GetOrAddCached without changing annotation readers, locking, model invalidation, dependencies or publishing configuration.

  • Compare EdmTargetPath keys by ordinal Path value and use matching ordinal hashes.
  • Reject path/nonpath equality in both directions, avoiding the dependency's unsafe cross-type EdmTargetPath.Equals call when hashes collide.
  • Retain EqualityComparer<IEdmVocabularyAnnotatable>.Default equality and hashing for nonpath keys.
  • Add seven deterministic regression cases covering mixed hash collisions in both insertion orders, equivalent/case-distinct paths, nonpath value/reference equality and invalidation for both key kinds. Isolate cache-sensitive tests from parallel model changes.

Addresses the genuine main CI failure at ec43631ab6c2502a24b9fd25c5b354228ef803bb: run 38455900148, where Graph path generation and link generation failed in EdmTargetPath.Equals → Dictionary.FindValue → GetOrAddCached.

Validation

Before the production fix, both forced-collision cases reproduced that exact NullReferenceException stack; the other 10 annotation cases passed. After the fix:

  • Release focused run: 14/14 passed, including all annotation tests and the exact ODataPathProviderTests.GetPathsForGraphBetaModelReturnsAllPaths and OpenApiLinkGeneratorTests.CreateLinksForEntities tests.
  • Complete Release OData suite: 1286/1286 passed (1279 existing + 7 new), no skipped tests.
  • Separate Release Hidi Microsoft.Testing.Platform suite: 107/107 passed, no skipped tests.

OData was run with its project-specific dotnet test runner; Hidi separately with dotnet run --project .\test\Microsoft.OpenApi.Hidi.Tests\Microsoft.OpenApi.Hidi.Tests.csproj -c Release --no-restore -- --minimum-expected-tests 1. No mixed-runner solution command.

Scope

Two files only; no pipeline, assertion-count, dependency, version, tag or release changes. This is a fresh branch from main, not the closed publishing branch.

Read-only review of support/v2 at 92e4df6cf3c4deb53c3b4a1d1c45fe2320adaaa1 confirms the same default heterogeneous cache and the same unsafe EdmTargetPath.Equals implementation in its Microsoft.OData.Edm 8.3.0 dependency. v2 is also affected, but remains unchanged and requires a separate correction.

Compare EdmTargetPath keys by ordinal path value without calling their unsafe cross-type Equals override. Preserve default nonpath equality and hashing, cache locking and model invalidation. Add deterministic mixed-key collision and cache semantics regressions.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 278c98ec-426d-4542-9536-6fa5bf6a821f
@sonarqubecloud

Copy link
Copy Markdown

@gavinbarron
Gavin Barron (gavinbarron) merged commit 3c7ef7d into main Oct 13, 2026
45 checks passed
@gavinbarron
Gavin Barron (gavinbarron) deleted the gavinbarron-odata-annotation-cache-collision branch October 13, 2026 21:47
Gavin Barron (gavinbarron) added a commit that referenced this pull request Oct 13, 2026
Port the private annotation target comparer and seven regression cases from #909. Preserve ordinal path comparison and default nonpath equality without changing cache locking or model invalidation.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 6c249d37-7577-48ae-9e5c-07451849bc7d
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