Skip to content

C#: Re-factor FeedManager to allow better unit testing. - #22468

Merged
michaelnebel merged 8 commits into
github:mainfrom
michaelnebel:csharp/refactorfeedmanager
Sep 1, 2026
Merged

C#: Re-factor FeedManager to allow better unit testing.#22468
michaelnebel merged 8 commits into
github:mainfrom
michaelnebel:csharp/refactorfeedmanager

Conversation

@michaelnebel

@michaelnebel michaelnebel commented Aug 31, 2026

Copy link
Copy Markdown
Contributor

In this PR we

  • Re-factor the FeedManager to enable unit testing.
  • Add some unit tests.

This is in preparation for using feeds configured via the dependabot proxy as "base" feed(s) (instead of the current hardcoded public nuget.org feed).

@github-actions github-actions Bot added the C# label Aug 31, 2026
@michaelnebel
michaelnebel force-pushed the csharp/refactorfeedmanager branch from 08d2f0e to b31ae61 Compare August 31, 2026 11:24
@michaelnebel
michaelnebel force-pushed the csharp/refactorfeedmanager branch from 98f0019 to 446e52e Compare August 31, 2026 13:21
@michaelnebel
michaelnebel force-pushed the csharp/refactorfeedmanager branch from 446e52e to b76f793 Compare August 31, 2026 13:23
@michaelnebel michaelnebel added the no-change-note-required This PR does not need a change note label Aug 31, 2026
@michaelnebel
michaelnebel requested a review from hvitved September 1, 2026 06:52
@michaelnebel
michaelnebel marked this pull request as ready for review September 1, 2026 06:52
@michaelnebel
michaelnebel requested a review from a team as a code owner September 1, 2026 06:52
Copilot AI balanced review requested due to automatic review settings September 1, 2026 06:52

Copilot AI 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.

Copilot review overview

🟡 Changes recommended

The new tests compare unordered sets using order-sensitive assertions, making them unreliable.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Review tier: Balanced
Findings: 1 Medium severity

New issues introduced by this change (1)
Severity Finding
Medium severity csharp/​extractor/​Semmle.Extraction.Tests/​FeedManager.csExplicitFeeds is a set, but Assert.Equal compares these enumerables in iteration order.…
What changed in this PR

Refactors C# dependency-feed handling behind injectable interfaces and adds FeedManager unit tests.

Changes:

  • Introduces abstractions for file, proxy, and feed I/O dependencies.
  • Separates raw feed selection from CLI argument construction.
  • Adds FeedManager and restore-source tests.
File Description
csharp/​extractor/​Semmle.Extraction.Tests/​Runtime.cs Uses the shared DotNetStub.
csharp/​extractor/​Semmle.Extraction.Tests/​FeedManager.cs Adds FeedManager unit tests and stubs.
csharp/​extractor/​Semmle.Extraction.Tests/​DotNetStub.cs Adds reusable .NET CLI stub behavior.
csharp/​extractor/​Semmle.Extraction.Tests/​DotNet.cs Tests source argument generation.
csharp/​extractor/​Semmle.Extraction.CSharp.DependencyFetching/​SourceGenerators/​ResxGenerator.cs Accepts the file-provider interface.
csharp/​extractor/​Semmle.Extraction.CSharp.DependencyFetching/​SourceGenerators/​RazorGenerator.cs Accepts the file-provider interface.
csharp/​extractor/​Semmle.Extraction.CSharp.DependencyFetching/​SourceGenerators/​DotnetSourceGeneratorBase.cs Stores the file-provider abstraction.
csharp/​extractor/​Semmle.Extraction.CSharp.DependencyFetching/​PackagesConfigRestorer.cs Converts selected feeds into NuGet arguments.
csharp/​extractor/​Semmle.Extraction.CSharp.DependencyFetching/​NugetPackageRestorer.cs Uses abstract dependencies and raw feeds.
csharp/​extractor/​Semmle.Extraction.CSharp.DependencyFetching/​IFileProvider.cs Defines file-discovery operations.
csharp/​extractor/​Semmle.Extraction.CSharp.DependencyFetching/​IFeedManagerIO.cs Defines feed-related I/O operations.
csharp/​extractor/​Semmle.Extraction.CSharp.DependencyFetching/​IDependabotProxy.cs Defines proxy configuration access.
csharp/​extractor/​Semmle.Extraction.CSharp.DependencyFetching/​FileProvider.cs Implements IFileProvider.
csharp/​extractor/​Semmle.Extraction.CSharp.DependencyFetching/​FeedManagerIO.cs Extracts filesystem and reachability logic.
csharp/​extractor/​Semmle.Extraction.CSharp.DependencyFetching/​FeedManager.cs Supports injected dependencies and raw feed selection.
csharp/​extractor/​Semmle.Extraction.CSharp.DependencyFetching/​DotNetCliInvoker.cs Uses the proxy interface.
csharp/​extractor/​Semmle.Extraction.CSharp.DependencyFetching/​DotNet.cs Builds source flags from raw feed URLs.
csharp/​extractor/​Semmle.Extraction.CSharp.DependencyFetching/​DependencyManager.cs Stores abstract dependency types.
csharp/​extractor/​Semmle.Extraction.CSharp.DependencyFetching/​DependabotProxy.cs Implements IDependabotProxy.
Suppressed comments (6)

csharp/extractor/Semmle.Extraction.Tests/FeedManager.cs:96

  • InheritedFeeds is a set, but Assert.Equal makes this assertion depend on its unspecified iteration order. Compare the members without imposing sequence order.
            Assert.Equal([

csharp/extractor/Semmle.Extraction.Tests/FeedManager.cs:112

  • AllFeeds is an ImmutableHashSet, so its iteration order is not part of the contract. This sequence comparison can fail for a correct set; use strict unordered equivalence.
            Assert.Equal([

csharp/extractor/Semmle.Extraction.Tests/FeedManager.cs:131

  • ReachableFeeds is set-valued, but Assert.Equal compares enumeration order. The hash-set order can vary independently of behavior, making this assertion flaky; compare unordered members.
            Assert.Equal([

csharp/extractor/Semmle.Extraction.Tests/FeedManager.cs:148

  • ReachableExplicitFeeds is an ImmutableHashSet; asserting sequence equality relies on an order the property does not guarantee. Use strict unordered equivalence.
            Assert.Equal([

csharp/extractor/Semmle.Extraction.Tests/FeedManager.cs:164

  • ReachableFallbackFeeds is set-valued, so this sequence assertion can fail solely because hash iteration order differs. Compare the set contents without ordering them.
            Assert.Equal([

csharp/extractor/Semmle.Extraction.Tests/FeedManager.cs:181

  • feedsToUse is explicitly converted to a HashSet, then compared as an ordered enumerable. Its iteration order is unspecified, so this can reject the correct members; use strict unordered equivalence.
            Assert.Equal([

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment on lines +79 to +83
Assert.Equal([
"https://example.com/registry1",
"https://example.com/registry2",
"https://feed.from/config"
], actualFeeds);

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

According to the documentation seen hereAssert.Equals uses SetEquals under the hood for hash-sets - so I believe that the current implementation is correct.

@hvitved hvitved 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.

Nice!

@michaelnebel michaelnebel changed the title C#: Re-factor to allow better unit testing. C#: Re-factor FeedManager to allow better unit testing. Sep 1, 2026
@michaelnebel
michaelnebel merged commit c550c51 into github:main Sep 1, 2026
16 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

C# no-change-note-required This PR does not need a change note

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants