/// <summary> /// Asynchronously gets package dependencies. /// </summary> /// <param name="libraryIdentity">A library identity.</param> /// <param name="targetFramework">A target framework.</param> /// <param name="cacheContext">A source cache context.</param> /// <param name="logger">A logger.</param> /// <param name="cancellationToken">A cancellation token.</param> /// <returns>A task that represents the asynchronous operation. /// The task result (<see cref="Task{TResult}.Result" />) returns a <see cref="LibraryDependencyInfo" /> /// instance.</returns> /// <exception cref="ArgumentNullException">Thrown if <paramref name="libraryIdentity" /> /// is either <c>null</c> or empty.</exception> /// <exception cref="ArgumentNullException">Thrown if <paramref name="targetFramework" /> /// is either <c>null</c> or empty.</exception> public Task <LibraryDependencyInfo> GetDependenciesAsync( LibraryIdentity libraryIdentity, NuGetFramework targetFramework, SourceCacheContext cacheContext, ILogger logger, CancellationToken cancellationToken) { if (libraryIdentity == null) { throw new ArgumentNullException(nameof(libraryIdentity)); } if (targetFramework == null) { throw new ArgumentNullException(nameof(targetFramework)); } var library = _dependencyProvider.GetLibrary(libraryIdentity, targetFramework); var dependencyInfo = LibraryDependencyInfo.Create( library.Identity, targetFramework, library.Dependencies); return(Task.FromResult(dependencyInfo)); }
public Task <LibraryDependencyInfo> GetDependenciesAsync( LibraryIdentity match, NuGetFramework targetFramework, SourceCacheContext cacheContext, ILogger logger, CancellationToken cancellationToken) { return(Task.FromResult(LibraryDependencyInfo.Create(match, targetFramework, Enumerable.Empty <LibraryDependency>()))); }
private async Task <LibraryDependencyInfo> GetDependenciesCoreAsync( LibraryIdentity match, NuGetFramework targetFramework, SourceCacheContext cacheContext, ILogger logger, CancellationToken cancellationToken) { await EnsureResource(); FindPackageByIdDependencyInfo packageInfo = null; try { if (_throttle != null) { await _throttle.WaitAsync(); } // Read package info, this will download the package if needed. packageInfo = await _findPackagesByIdResource.GetDependencyInfoAsync( match.Name, match.Version, cacheContext, logger, cancellationToken); } catch (FatalProtocolException e) when(_ignoreFailedSources && !(e is InvalidCacheProtocolException)) { if (!_ignoreWarning) { await _logger.LogAsync(RestoreLogMessage.CreateWarning(NuGetLogCode.NU1801, e.Message, match.Name)); } } finally { _throttle?.Release(); } if (packageInfo == null) { // Package was not found return(LibraryDependencyInfo.CreateUnresolved(match, targetFramework)); } else { // Package found var originalIdentity = new LibraryIdentity( packageInfo.PackageIdentity.Id, packageInfo.PackageIdentity.Version, match.Type); var dependencies = GetDependencies(packageInfo, targetFramework); return(LibraryDependencyInfo.Create(originalIdentity, targetFramework, dependencies)); } }
public async Task FindLibraryEntryAsync_LogsOnlyPackages(LibraryDependencyTarget libraryDependencyTarget) { // Arrange const string packageX = "x", version = "1.0.0-beta.1", source = "source"; var range = new LibraryRange(packageX, VersionRange.Parse(version), libraryDependencyTarget); var cacheContext = new SourceCacheContext(); var testLogger = new TestLogger(); var framework = NuGetFramework.Parse("net45"); var token = CancellationToken.None; var edge = new GraphEdge <RemoteResolveResult>(null, null, null); var actualIdentity = new LibraryIdentity(packageX, NuGetVersion.Parse(version), LibraryType.Package); var dependencies = new[] { new LibraryDependency() { LibraryRange = new LibraryRange("y", VersionRange.All, LibraryDependencyTarget.Package) } }; var dependencyInfo = LibraryDependencyInfo.Create(actualIdentity, framework, dependencies); //package source mapping configuration Dictionary <string, IReadOnlyList <string> > patterns = new(); patterns.Add(source, new List <string>() { packageX }); PackageSourceMapping sourceMappingConfiguration = new(patterns); var context = new RemoteWalkContext(cacheContext, sourceMappingConfiguration, testLogger); var remoteProvider = new Mock <IRemoteDependencyProvider>(); remoteProvider.Setup(e => e.FindLibraryAsync(range, It.IsAny <NuGetFramework>(), It.IsAny <SourceCacheContext>(), testLogger, token)) .ReturnsAsync(actualIdentity); remoteProvider.SetupGet(e => e.IsHttp).Returns(true); remoteProvider.SetupGet(e => e.Source).Returns(new PackageSource(source)); remoteProvider.Setup(e => e.GetDependenciesAsync(It.IsAny <LibraryIdentity>(), It.IsAny <NuGetFramework>(), It.IsAny <SourceCacheContext>(), testLogger, token)) .ReturnsAsync(dependencyInfo); context.RemoteLibraryProviders.Add(remoteProvider.Object); // Act var result = await ResolverUtility.FindLibraryEntryAsync(range, framework, null, context, token); // Assert Assert.Equal(0, testLogger.Errors); testLogger.DebugMessages.TryPeek(out string message); if (libraryDependencyTarget == LibraryDependencyTarget.Package) { Assert.Equal($"Package source mapping matches found for package ID '{packageX}' are: '{source}'.", message); Assert.Equal(version, result.Key.Version.ToString()); Assert.Equal(source, result.Data.Match.Provider.Source.Name); } else { Assert.Equal(message, null); } }
public async Task FindPackage_VerifyFloatingPackageIsRequiredOnlyFromASingleSource() { // Arrange var range = new LibraryRange("x", VersionRange.Parse("1.0.0-*"), LibraryDependencyTarget.Package); var cacheContext = new SourceCacheContext(); var testLogger = new TestLogger(); var framework = NuGetFramework.Parse("net45"); var context = new RemoteWalkContext(cacheContext, testLogger); var token = CancellationToken.None; var edge = new GraphEdge <RemoteResolveResult>(null, null, null); var actualIdentity = new LibraryIdentity("x", NuGetVersion.Parse("1.0.0-beta.1"), LibraryType.Package); var higherIdentity = new LibraryIdentity("x", NuGetVersion.Parse("1.0.0-beta.2"), LibraryType.Package); var dependencies = new[] { new LibraryDependency() { LibraryRange = new LibraryRange("y", VersionRange.All, LibraryDependencyTarget.Package) } }; var dependencyInfo = LibraryDependencyInfo.Create(actualIdentity, framework, dependencies); var dependencyInfo2 = LibraryDependencyInfo.Create(higherIdentity, framework, dependencies); var downloadCount = 0; // Source1 returns 1.0.0-beta.1 var remoteProvider = new Mock <IRemoteDependencyProvider>(); remoteProvider.Setup(e => e.FindLibraryAsync(range, It.IsAny <NuGetFramework>(), It.IsAny <SourceCacheContext>(), testLogger, token)) .ReturnsAsync(actualIdentity); remoteProvider.SetupGet(e => e.IsHttp).Returns(true); remoteProvider.SetupGet(e => e.Source).Returns(new PackageSource("test")); remoteProvider.Setup(e => e.GetDependenciesAsync(It.IsAny <LibraryIdentity>(), It.IsAny <NuGetFramework>(), It.IsAny <SourceCacheContext>(), testLogger, token)) .ReturnsAsync(dependencyInfo) .Callback(() => ++ downloadCount); context.RemoteLibraryProviders.Add(remoteProvider.Object); // Source2 returns 1.0.0-beta.2 var remoteProvider2 = new Mock <IRemoteDependencyProvider>(); remoteProvider2.Setup(e => e.FindLibraryAsync(range, It.IsAny <NuGetFramework>(), It.IsAny <SourceCacheContext>(), testLogger, token)) .ReturnsAsync(higherIdentity); remoteProvider2.SetupGet(e => e.IsHttp).Returns(true); remoteProvider2.SetupGet(e => e.Source).Returns(new PackageSource("test")); remoteProvider2.Setup(e => e.GetDependenciesAsync(It.IsAny <LibraryIdentity>(), It.IsAny <NuGetFramework>(), It.IsAny <SourceCacheContext>(), testLogger, token)) .ReturnsAsync(dependencyInfo2) .Callback(() => ++ downloadCount); context.RemoteLibraryProviders.Add(remoteProvider2.Object); // Act var result = await ResolverUtility.FindLibraryEntryAsync(range, framework, null, edge, context, token); // Assert // Verify only one download happened Assert.Equal(1, downloadCount); Assert.Equal("1.0.0-beta.2", result.Key.Version.ToString()); }
public Task <LibraryDependencyInfo> GetDependenciesAsync( LibraryIdentity library, NuGetFramework targetFramework, SourceCacheContext cacheContext, ILogger logger, CancellationToken cancellationToken) { var description = _dependencyProvider.GetLibrary(library, targetFramework); var dependencyInfo = LibraryDependencyInfo.Create( description.Identity, targetFramework, description.Dependencies); return(Task.FromResult(dependencyInfo)); }
private static async Task <GraphItem <RemoteResolveResult> > CreateGraphItemAsync( RemoteMatch match, NuGetFramework framework, SourceCacheContext cacheContext, ILogger logger, CancellationToken cancellationToken) { LibraryDependencyInfo dependencies; // For local matches such as projects get the dependencies from the LocalLibrary property. var localMatch = match as LocalMatch; if (localMatch != null) { dependencies = LibraryDependencyInfo.Create( localMatch.LocalLibrary.Identity, framework, localMatch.LocalLibrary.Dependencies); } else { // Look up the dependencies from the source, this will download the package if needed. dependencies = await match.Provider.GetDependenciesAsync( match.Library, framework, cacheContext, logger, cancellationToken); } // Copy the original identity to the remote match. // This ensures that the correct casing is used for // the id/version. match.Library = dependencies.Library; return(new GraphItem <RemoteResolveResult>(match.Library) { Data = new RemoteResolveResult { Match = match, Dependencies = dependencies.Dependencies.ToList() }, }); }
public async Task FindPackage_VerifyMissingListedPackageSucceedsOnRetry() { // Arrange var range = new LibraryRange("x", VersionRange.Parse("1.0.0-beta"), LibraryDependencyTarget.Package); var cacheContext = new SourceCacheContext(); var testLogger = new TestLogger(); var framework = NuGetFramework.Parse("net45"); var context = new RemoteWalkContext(cacheContext, testLogger); var token = CancellationToken.None; var edge = new GraphEdge <RemoteResolveResult>(null, null, null); var actualIdentity = new LibraryIdentity("x", NuGetVersion.Parse("1.0.0-beta"), LibraryType.Package); var dependencies = new[] { new LibraryDependency() { LibraryRange = new LibraryRange("y", VersionRange.All, LibraryDependencyTarget.Package) } }; var dependencyInfo = LibraryDependencyInfo.Create(actualIdentity, framework, dependencies); var remoteProvider = new Mock <IRemoteDependencyProvider>(); remoteProvider.Setup(e => e.FindLibraryAsync(range, framework, It.IsAny <SourceCacheContext>(), testLogger, token)) .ReturnsAsync(actualIdentity); remoteProvider.SetupGet(e => e.IsHttp).Returns(true); remoteProvider.SetupGet(e => e.Source).Returns(new PackageSource("test")); var hitCount = 0; remoteProvider.Setup(e => e.GetDependenciesAsync(actualIdentity, framework, cacheContext, testLogger, token)) .ThrowsAsync(new PackageNotFoundProtocolException(new PackageIdentity(actualIdentity.Name, actualIdentity.Version))) .Callback(() => ++ hitCount); remoteProvider.Setup(e => e.GetDependenciesAsync(actualIdentity, framework, It.IsAny <SourceCacheContext>(), testLogger, token)) .ReturnsAsync(dependencyInfo) .Callback(() => ++ hitCount); context.RemoteLibraryProviders.Add(remoteProvider.Object); // Act var result = await ResolverUtility.FindLibraryEntryAsync(range, framework, null, edge, context, token); // Assert Assert.Equal(1, hitCount); Assert.Equal("x", result.Key.Name); }
public async Task <LibraryDependencyInfo> GetDependenciesAsync( LibraryIdentity match, NuGetFramework targetFramework, SourceCacheContext cacheContext, ILogger logger, CancellationToken cancellationToken) { List <LibraryDependency> dependencies; // Yield the task to help uncovering concurrency issues in tests await Task.Yield(); if (_graph.TryGetValue(match, out dependencies)) { return(LibraryDependencyInfo.Create(match, targetFramework, dependencies)); } return(LibraryDependencyInfo.Create(match, targetFramework, Enumerable.Empty <LibraryDependency>())); }
public async Task FindPackage_VerifyFindLibraryEntryReturnsOriginalCase() { // Arrange var range = new LibraryRange("x", VersionRange.Parse("1.0.0-beta"), LibraryDependencyTarget.Package); var cacheContext = new SourceCacheContext(); var testLogger = new TestLogger(); var framework = NuGetFramework.Parse("net45"); var context = new RemoteWalkContext(cacheContext, testLogger); var token = CancellationToken.None; var edge = new GraphEdge <RemoteResolveResult>(null, null, null); var actualIdentity = new LibraryIdentity("X", NuGetVersion.Parse("1.0.0-bEta"), LibraryType.Package); var dependencies = new[] { new LibraryDependency() { LibraryRange = new LibraryRange("y", VersionRange.All, LibraryDependencyTarget.Package) } }; var dependencyInfo = LibraryDependencyInfo.Create(actualIdentity, framework, dependencies); var remoteProvider = new Mock <IRemoteDependencyProvider>(); remoteProvider.Setup(e => e.FindLibraryAsync(range, framework, cacheContext, testLogger, token)) .ReturnsAsync(actualIdentity); remoteProvider.Setup(e => e.GetDependenciesAsync(actualIdentity, framework, cacheContext, testLogger, token)) .ReturnsAsync(dependencyInfo); context.RemoteLibraryProviders.Add(remoteProvider.Object); // Act var result = await ResolverUtility.FindLibraryEntryAsync(range, framework, null, edge, context, token); // Assert Assert.Equal(LibraryType.Package, result.Data.Match.Library.Type); Assert.Equal("X", result.Data.Match.Library.Name); Assert.Equal("1.0.0-bEta", result.Data.Match.Library.Version.ToString()); Assert.Equal("y", result.Data.Dependencies.Single().Name); }
public async Task FindPackage_WhenNoPackageSourceMappingIsEnabledForAPackage_Fails() { // Arrange const string packageX = "x", version = "1.0.0-beta.1"; var range = new LibraryRange(packageX, VersionRange.Parse(version), LibraryDependencyTarget.Package); var cacheContext = new SourceCacheContext(); var testLogger = new TestLogger(); var framework = NuGetFramework.Parse("net45"); var token = CancellationToken.None; var edge = new GraphEdge <RemoteResolveResult>(null, null, null); var actualIdentity = new LibraryIdentity(packageX, NuGetVersion.Parse(version), LibraryType.Package); var dependencies = new[] { new LibraryDependency() { LibraryRange = new LibraryRange("y", VersionRange.All, LibraryDependencyTarget.Package) } }; var dependencyInfo = LibraryDependencyInfo.Create(actualIdentity, framework, dependencies); var downloadCount = 0; //package source mapping configuration Dictionary <string, IReadOnlyList <string> > patterns = new(); patterns.Add("source2", new List <string>() { "z" }); patterns.Add("source1", new List <string>() { "y" }); PackageSourceMapping sourceMappingConfiguration = new(patterns); var context = new RemoteWalkContext(cacheContext, sourceMappingConfiguration, testLogger); // Source1 returns 1.0.0-beta.1 var remoteProvider = new Mock <IRemoteDependencyProvider>(); remoteProvider.Setup(e => e.FindLibraryAsync(range, It.IsAny <NuGetFramework>(), It.IsAny <SourceCacheContext>(), testLogger, token)) .ReturnsAsync(actualIdentity); remoteProvider.SetupGet(e => e.IsHttp).Returns(true); remoteProvider.SetupGet(e => e.Source).Returns(new PackageSource("source1")); remoteProvider.Setup(e => e.GetDependenciesAsync(It.IsAny <LibraryIdentity>(), It.IsAny <NuGetFramework>(), It.IsAny <SourceCacheContext>(), testLogger, token)) .ReturnsAsync(dependencyInfo) .Callback(() => ++ downloadCount); context.RemoteLibraryProviders.Add(remoteProvider.Object); // Source2 returns 1.0.0-beta.1 var remoteProvider2 = new Mock <IRemoteDependencyProvider>(); remoteProvider2.Setup(e => e.FindLibraryAsync(range, It.IsAny <NuGetFramework>(), It.IsAny <SourceCacheContext>(), testLogger, token)) .ReturnsAsync(actualIdentity); remoteProvider2.SetupGet(e => e.IsHttp).Returns(true); remoteProvider2.SetupGet(e => e.Source).Returns(new PackageSource("source2")); remoteProvider2.Setup(e => e.GetDependenciesAsync(It.IsAny <LibraryIdentity>(), It.IsAny <NuGetFramework>(), It.IsAny <SourceCacheContext>(), testLogger, token)) .ReturnsAsync(dependencyInfo) .Callback(() => ++ downloadCount); context.RemoteLibraryProviders.Add(remoteProvider2.Object); // Act var result = await ResolverUtility.FindLibraryEntryAsync(range, framework, null, context, token); Assert.Equal(0, downloadCount); Assert.Equal(0, testLogger.Errors); Assert.Equal(1, testLogger.DebugMessages.Count); testLogger.DebugMessages.TryPeek(out string message); Assert.Equal($"Package source mapping match not found for package ID '{packageX}'.", message); }
public async Task FindPackage_VerifyPackageSourcesAreFilteredWhenPackageSourceMappingIsEnabled_Success() { // Arrange const string packageX = "x", packageY = "y", version = "1.0.0-beta.1", source1 = "source1", source2 = "source2"; var range = new LibraryRange(packageX, VersionRange.Parse(version), LibraryDependencyTarget.Package); var cacheContext = new SourceCacheContext(); var testLogger = new TestLogger(); var framework = NuGetFramework.Parse("net45"); var token = CancellationToken.None; var edge = new GraphEdge <RemoteResolveResult>(null, null, null); var actualIdentity = new LibraryIdentity(packageX, NuGetVersion.Parse(version), LibraryType.Package); var dependencies = new[] { new LibraryDependency() { LibraryRange = new LibraryRange(packageY, VersionRange.All, LibraryDependencyTarget.Package) } }; var dependencyInfo = LibraryDependencyInfo.Create(actualIdentity, framework, dependencies); var downloadCount = 0; //package source mapping configuration Dictionary <string, IReadOnlyList <string> > patterns = new(); patterns.Add(source2, new List <string>() { packageX }); patterns.Add(source1, new List <string>() { packageY }); PackageSourceMapping sourceMappingConfiguration = new(patterns); var context = new RemoteWalkContext(cacheContext, sourceMappingConfiguration, testLogger); // Source1 returns 1.0.0-beta.1 var remoteProvider = new Mock <IRemoteDependencyProvider>(); remoteProvider.Setup(e => e.FindLibraryAsync(range, It.IsAny <NuGetFramework>(), It.IsAny <SourceCacheContext>(), testLogger, token)) .ReturnsAsync(actualIdentity); remoteProvider.SetupGet(e => e.IsHttp).Returns(true); remoteProvider.SetupGet(e => e.Source).Returns(new PackageSource(source1)); remoteProvider.Setup(e => e.GetDependenciesAsync(It.IsAny <LibraryIdentity>(), It.IsAny <NuGetFramework>(), It.IsAny <SourceCacheContext>(), testLogger, token)) .ReturnsAsync(dependencyInfo) .Callback(() => ++ downloadCount); context.RemoteLibraryProviders.Add(remoteProvider.Object); // Source2 returns 1.0.0-beta.1 var remoteProvider2 = new Mock <IRemoteDependencyProvider>(); remoteProvider2.Setup(e => e.FindLibraryAsync(range, It.IsAny <NuGetFramework>(), It.IsAny <SourceCacheContext>(), testLogger, token)) .ReturnsAsync(actualIdentity); remoteProvider2.SetupGet(e => e.IsHttp).Returns(true); remoteProvider2.SetupGet(e => e.Source).Returns(new PackageSource(source2)); remoteProvider2.Setup(e => e.GetDependenciesAsync(It.IsAny <LibraryIdentity>(), It.IsAny <NuGetFramework>(), It.IsAny <SourceCacheContext>(), testLogger, token)) .ReturnsAsync(dependencyInfo) .Callback(() => ++ downloadCount); context.RemoteLibraryProviders.Add(remoteProvider2.Object); // Act var result = await ResolverUtility.FindLibraryEntryAsync(range, framework, null, context, token); // Assert // Verify only one download happened from the expected source i.e. source2 Assert.Equal(1, downloadCount); Assert.Equal(1, testLogger.DebugMessages.Count); testLogger.DebugMessages.TryPeek(out string message); Assert.Equal($"Package source mapping matches found for package ID '{packageX}' are: '{source2}'.", message); Assert.Equal(version, result.Key.Version.ToString()); Assert.Equal(source2, result.Data.Match.Provider.Source.Name); }
private async Task <LibraryDependencyInfo> GetDependenciesCoreAsync( LibraryIdentity match, NuGetFramework targetFramework, SourceCacheContext cacheContext, ILogger logger, CancellationToken cancellationToken) { FindPackageByIdDependencyInfo packageInfo = null; try { await EnsureResource(); if (_throttle != null) { await _throttle.WaitAsync(); } // Read package info, this will download the package if needed. packageInfo = await _findPackagesByIdResource.GetDependencyInfoAsync( match.Name, match.Version, cacheContext, logger, cancellationToken); } catch (FatalProtocolException e) when(e is not InvalidCacheProtocolException) { if (_ignoreFailedSources) { await LogWarningAsync(logger, match.Name, e); } else { await LogErrorAsync(logger, match.Name, e); throw; } } finally { _throttle?.Release(); } if (packageInfo == null) { // Package was not found return(LibraryDependencyInfo.CreateUnresolved(match, targetFramework)); } else { // Package found var originalIdentity = new LibraryIdentity( packageInfo.PackageIdentity.Id, packageInfo.PackageIdentity.Version, match.Type); IEnumerable <LibraryDependency> dependencyGroup = GetDependencies(packageInfo, targetFramework); return(LibraryDependencyInfo.Create(originalIdentity, targetFramework, dependencies: dependencyGroup)); } }