diff --git a/src/NuGet.Core/NuGet.Commands/RestoreCommand/SourceRepositoryDependencyProvider.cs b/src/NuGet.Core/NuGet.Commands/RestoreCommand/SourceRepositoryDependencyProvider.cs index faa19f1c4a3..17eb6647aa4 100644 --- a/src/NuGet.Core/NuGet.Commands/RestoreCommand/SourceRepositoryDependencyProvider.cs +++ b/src/NuGet.Core/NuGet.Commands/RestoreCommand/SourceRepositoryDependencyProvider.cs @@ -361,13 +361,13 @@ private async Task GetDependenciesCoreAsync( FindPackageByIdDependencyInfo packageInfo = null; try { - await EnsureResource(cancellationToken); - if (_throttle != null) { await _throttle.WaitAsync(cancellationToken); } + await EnsureResource(cancellationToken); + // Read package info, this will download the package if needed. packageInfo = await _findPackagesByIdResource.GetDependencyInfoAsync( match.Name, @@ -459,13 +459,13 @@ public async Task GetPackageDownloaderAsync( try { - await EnsureResource(cancellationToken); - if (_throttle != null) { await _throttle.WaitAsync(cancellationToken); } + await EnsureResource(cancellationToken); + cancellationToken.ThrowIfCancellationRequested(); var packageDownloader = await _findPackagesByIdResource.GetPackageDownloaderAsync( @@ -634,10 +634,9 @@ internal async Task> GetAllVersionsInternalAsync( { await _throttle.WaitAsync(cancellationToken); } - if (_findPackagesByIdResource == null) - { - return null; - } + + await EnsureResource(cancellationToken); + return await _findPackagesByIdResource.GetAllVersionsAsync( id, cacheContext, diff --git a/test/NuGet.Core.Tests/NuGet.Commands.Test/SourceRepositoryDependencyProviderTests.cs b/test/NuGet.Core.Tests/NuGet.Commands.Test/SourceRepositoryDependencyProviderTests.cs index dece8f6b3cb..61d9fabf260 100644 --- a/test/NuGet.Core.Tests/NuGet.Commands.Test/SourceRepositoryDependencyProviderTests.cs +++ b/test/NuGet.Core.Tests/NuGet.Commands.Test/SourceRepositoryDependencyProviderTests.cs @@ -661,6 +661,56 @@ public async Task GetPackageDownloaderAsync_ReturnsPackageDownloader() } } + [Fact] + public async Task GetAllVersionsAsync_EnsuresResourceIsInitialized_ReturnsVersions() + { + // Arrange + // This test verifies that GetAllVersionsAsync properly calls EnsureResource + // to initialize _findPackagesByIdResource. Previously, EnsureResource was not called + // and GetAllVersionsInternalAsync would see _findPackagesByIdResource as null, + // silently returning null instead of the actual versions. + var testLogger = new TestLogger(); + var cacheContext = new SourceCacheContext(); + var expectedVersions = new[] { NuGetVersion.Parse("1.0.0"), NuGetVersion.Parse("2.0.0") }; + + var findResource = new Mock(); + findResource.Setup(s => s.GetAllVersionsAsync( + It.IsAny(), + It.IsAny(), + It.IsAny(), + It.IsAny())) + .ReturnsAsync(expectedVersions); + + var source = new Mock(); + source.Setup(s => s.GetResourceAsync(CancellationToken.None)) + .ReturnsAsync(findResource.Object); + source.SetupGet(s => s.PackageSource) + .Returns(new PackageSource("http://test/index.json")); + + var provider = new SourceRepositoryDependencyProvider( + source.Object, + testLogger, + cacheContext, + ignoreFailedSources: true, + ignoreWarning: true); + + // Act + var versions = await provider.GetAllVersionsAsync( + "x", + cacheContext, + testLogger, + CancellationToken.None); + + // Assert + versions.Should().BeEquivalentTo(expectedVersions); + source.Verify(s => s.GetResourceAsync(CancellationToken.None), Times.Once); + findResource.Verify(s => s.GetAllVersionsAsync( + "x", + It.IsAny(), + It.IsAny(), + It.IsAny()), Times.Once); + } + [Fact] public async Task FindLibraryAsync_WhenASourceIsInaccessible_AndFailuresAreNotIgnored_EveryCallLogsAnErrorMessage() {