public async Task DeepCycleCheck() { var context = new TestRemoteWalkContext(); var provider = new DependencyProvider(); provider.Package("A", "1.0") .DependsOn("B", "2.0"); provider.Package("B", "2.0") .DependsOn("C", "2.0"); provider.Package("C", "2.0") .DependsOn("D", "1.0") .DependsOn("E", "1.0"); provider.Package("D", "1.0"); provider.Package("E", "1.0") .DependsOn("A", "1.0"); context.LocalLibraryProviders.Add(provider); var walker = new RemoteDependencyWalker(context); var node = await DoWalkAsync(walker, "A"); var result = node.Analyze(); Assert.Equal(1, result.Cycles.Count); var cycle = result.Cycles[0]; AssertPath(cycle, "A 1.0", "B 2.0", "C 2.0", "E 1.0", "A 1.0"); }
public async Task DowngradeThenUpgradeThenDowngrade() { var context = new TestRemoteWalkContext(); var provider = new DependencyProvider(); provider.Package("A", "1.0") .DependsOn("B", "1.0") .DependsOn("C", "1.0"); provider.Package("B", "1.0"); provider.Package("C", "1.0") .DependsOn("B", "2.0") .DependsOn("D", "1.0"); provider.Package("B", "2.0"); provider.Package("D", "1.0") .DependsOn("B", "1.0"); context.LocalLibraryProviders.Add(provider); var walker = new RemoteDependencyWalker(context); var node = await DoWalkAsync(walker, "A"); var result = node.Analyze(); Assert.Equal(1, result.Downgrades.Count); var downgraded = result.Downgrades[0].DowngradedFrom; var downgradedBy = result.Downgrades[0].DowngradedTo; AssertPath(downgraded, "A 1.0", "C 1.0", "B 2.0"); AssertPath(downgradedBy, "A 1.0", "B 1.0"); }
public async Task UpgradeThenDowngradeThenEqual() { var context = new TestRemoteWalkContext(); var provider = new DependencyProvider(); provider.Package("A", "1.0") .DependsOn("B", "2.0") .DependsOn("C", "1.0"); provider.Package("B", "1.0"); provider.Package("C", "1.0") .DependsOn("B", "1.0") .DependsOn("D", "1.0"); provider.Package("B", "2.0"); provider.Package("D", "1.0") .DependsOn("B", "2.0"); context.LocalLibraryProviders.Add(provider); var walker = new RemoteDependencyWalker(context); var node = await DoWalkAsync(walker, "A"); var result = node.Analyze(); Assert.Equal(0, result.Downgrades.Count); }
public async Task StrictDependenciesButNoConflict() { var context = new TestRemoteWalkContext(); var provider = new DependencyProvider(); provider.Package("A", "1.0") .DependsOn("B", "2.0") .DependsOn("C", "2.0"); provider.Package("B", "2.0") .DependsOn("D", "[2.0]"); provider.Package("C", "2.0") .DependsOn("D", "[1.0, 3.0]"); provider.Package("D", "1.0"); provider.Package("D", "2.0"); context.LocalLibraryProviders.Add(provider); var walker = new RemoteDependencyWalker(context); var node = await DoWalkAsync(walker, "A"); var result = node.Analyze(); Assert.Equal(0, result.VersionConflicts.Count); }
public async Task NearestWinsOverridesStrictDependencyButDowngradeWarns() { var context = new TestRemoteWalkContext(); var provider = new DependencyProvider(); provider.Package("A", "1.0") .DependsOn("B", "2.0") .DependsOn("C", "2.0") .DependsOn("D", "1.0"); provider.Package("B", "2.0") .DependsOn("D", "[2.0]"); provider.Package("C", "2.0") .DependsOn("D", "[1.0]"); provider.Package("D", "1.0"); provider.Package("D", "2.0"); provider.Package("D", "3.0"); context.LocalLibraryProviders.Add(provider); var walker = new RemoteDependencyWalker(context); var node = await DoWalkAsync(walker, "A"); var result = node.Analyze(); Assert.Equal(0, result.VersionConflicts.Count); Assert.Equal(1, result.Downgrades.Count); var downgraded = result.Downgrades[0].DowngradedFrom; var downgradedBy = result.Downgrades[0].DowngradedTo; AssertPath(downgraded, "A 1.0", "B 2.0", "D 2.0"); AssertPath(downgradedBy, "A 1.0", "D 1.0"); }
public async Task TryResolveConflicts_ThrowsIfPackageConstraintCannotBeResolved() { var context = new TestRemoteWalkContext(); var provider = new DependencyProvider(); provider.Package("Root", "1.0") .DependsOn("A", "1.0") .DependsOn("B", "2.0"); provider.Package("A", "1.0") .DependsOn("C", "(1.0, 1.4]"); provider.Package("B", "2.0") .DependsOn("C", "1.8"); provider.Package("C", "1.3.8"); provider.Package("C", "1.8"); context.LocalLibraryProviders.Add(provider); var walker = new RemoteDependencyWalker(context); var node = await DoWalkAsync(walker, "Root"); var result = node.Analyze(); Assert.Equal(1, result.VersionConflicts.Count); var conflict = result.VersionConflicts[0]; var c1 = conflict.Selected; var c2 = conflict.Conflicting; AssertPath(c1, "Root 1.0", "B 2.0", "C 1.8"); AssertPath(c2, "Root 1.0", "A 1.0", "C 1.3.8"); }
public async Task AllowPreleaseVersionNoConflict() { var context = new TestRemoteWalkContext(); var provider = new DependencyProvider(); provider.Package("A", "1.0-beta") .DependsOn("B", "1.0") .DependsOn("C", "1.0-beta") .DependsOn("E", "1.0"); provider.Package("B", "1.0") .DependsOn("D", "1.0"); provider.Package("C", "1.0-beta") .DependsOn("D", "1.1-beta"); provider.Package("E", "1.0") .DependsOn("D", "0.1"); context.LocalLibraryProviders.Add(provider); var walker = new RemoteDependencyWalker(context); var node = await DoWalkAsync(walker, "A"); var result = node.Analyze(); Assert.Equal(0, result.VersionConflicts.Count); }
public async Task SingleConflictWhereConflictingDependenyIsUnresolved() { var context = new TestRemoteWalkContext(); var provider = new DependencyProvider(); provider.Package("A", "1.0") .DependsOn("B", "2.0") .DependsOn("C", "2.0"); provider.Package("B", "2.0") .DependsOn("D", "[2.0]"); provider.Package("C", "2.0") .DependsOn("D", "[1.0]"); provider.Package("D", "2.0"); context.LocalLibraryProviders.Add(provider); var walker = new RemoteDependencyWalker(context); var node = await DoWalkAsync(walker, "A"); var result = node.Analyze(); Assert.Equal(1, result.VersionConflicts.Count); var conflict = result.VersionConflicts[0]; var c1 = conflict.Selected; var c2 = conflict.Conflicting; AssertPath(c1, "A 1.0", "B 2.0", "D 2.0"); AssertPath(c2, "A 1.0", "C 2.0", "D 1.0"); }
public async Task AllowProjectOverridePackageNoConflict() { var context = new TestRemoteWalkContext(); var packageProvider = new DependencyProvider(); var projectProvider = new DependencyProvider(); projectProvider.Package("A", "1.0", LibraryType.Project) .DependsOn("B", "2.0", LibraryDependencyTarget.Project) .DependsOn("C", "2.0"); projectProvider.Package("B", "2.0", LibraryType.Project) .DependsOn("D", "[2.0]", LibraryDependencyTarget.Project); packageProvider.Package("C", "2.0") .DependsOn("D", "[1.0]"); packageProvider.Package("D", "1.0"); projectProvider.Package("D", "2.0", LibraryType.Project); context.LocalLibraryProviders.Add(packageProvider); context.ProjectLibraryProviders.Add(projectProvider); var walker = new RemoteDependencyWalker(context); var node = await DoWalkAsync(walker, "A"); var result = node.Analyze(); Assert.Equal(0, result.VersionConflicts.Count); }
public void IsDependencyValidForGraphTest(LibraryDependencyReferenceType referenceType, bool versionCentrallyManaged) { var centralPackageName = "D"; var context = new TestRemoteWalkContext(); var centralPackageVersion = new CentralPackageVersion(centralPackageName, VersionRange.Parse("2.0.0")); var centralPackageVersionDependecy_VersionCentrallyManaged = new LibraryDependency() { LibraryRange = new LibraryRange(centralPackageVersion.Name, centralPackageVersion.VersionRange, LibraryDependencyTarget.Package), VersionCentrallyManaged = versionCentrallyManaged, ReferenceType = referenceType, }; var walker = new RemoteDependencyWalker(context); // Act var expectedResult = walker.IsDependencyValidForGraph(centralPackageVersionDependecy_VersionCentrallyManaged); // Assert if (referenceType != LibraryDependencyReferenceType.None) { Assert.True(expectedResult); } else { Assert.False(expectedResult); } }
public async Task WalkAsyncDowngradesBecauseOfCentralDependecy() { var centralPackageName = "D"; var centralPackageVersion = "2.0.0"; var otherVersion = "3.0.0"; var framework = NuGetFramework.Parse("net45"); var context = new TestRemoteWalkContext(); var provider = new DependencyProvider(); // D is a transitive dependency for package A through package B -> C -> D // D is defined as a Central Package Version // In this context Package D with version centralPackageVersion will be added as inner node of Node A, next to B // Picture: // A -> B -> C -> D (version 1.0.0 or 2.0.0 as defined by "otherVersion" argument. // A ~> D (the version 2.0.0 or as defined by "centralPackageVersion" argument // the dependency is not direct, // it simulates the fact that there is a centrally defined "D" package // the information is added to the provider) provider.Package("A", otherVersion) .DependsOn("B", otherVersion); provider.Package("B", otherVersion) .DependsOn("C", otherVersion); provider.Package("C", otherVersion) .DependsOn(centralPackageName, otherVersion); // Simulates the existence of a D centrally defined package that is not direct dependency provider.Package("A", otherVersion) .DependsOn(centralPackageName, centralPackageVersion, LibraryDependencyTarget.Package, versionCentrallyManaged: true); // Add central package to the source with multiple versions provider.Package(centralPackageName, "1.0.0"); provider.Package(centralPackageName, centralPackageVersion); provider.Package(centralPackageName, "3.0.0"); context.LocalLibraryProviders.Add(provider); var walker = new RemoteDependencyWalker(context); // Act var rootNode = await DoWalkAsync(walker, "A", framework); var analyzeResult = rootNode.Analyze(); // Assert Assert.Equal(1, analyzeResult.Downgrades.Count); var downgrade = analyzeResult.Downgrades.First(); Assert.Equal(centralPackageName, downgrade.DowngradedFrom.Key.Name); Assert.Equal("[3.0.0, )", downgrade.DowngradedFrom.Key.VersionRange.ToNormalizedString()); Assert.Equal(centralPackageName, downgrade.DowngradedTo.Key.Name); Assert.Equal("[2.0.0, )", downgrade.DowngradedTo.Key.VersionRange.ToNormalizedString()); }
public async Task DoubleDowngrade() { var context = new TestRemoteWalkContext(); var provider = new DependencyProvider(); provider.Package("A", "1.0") .DependsOn("B", "0.7") .DependsOn("C", "1.0"); provider.Package("B", "0.7"); provider.Package("C", "1.0") .DependsOn("B", "0.8") .DependsOn("D", "1.0"); provider.Package("B", "0.8"); provider.Package("D", "1.0") .DependsOn("B", "1.0"); provider.Package("B", "1.0"); context.LocalLibraryProviders.Add(provider); var walker = new RemoteDependencyWalker(context); var node = await DoWalkAsync(walker, "A"); var downgrades = new List <Tuple <GraphNode <RemoteResolveResult>, GraphNode <RemoteResolveResult> > >(); var cycles = new List <GraphNode <RemoteResolveResult> >(); var result = node.Analyze(); Assert.Equal(2, result.Downgrades.Count); var d0 = result.Downgrades[0]; var d0To = d0.DowngradedFrom; var d0By = d0.DowngradedTo; AssertPath(d0To, "A 1.0", "C 1.0", "B 0.8"); AssertPath(d0By, "A 1.0", "B 0.7"); var d1 = result.Downgrades[1]; var d1To = d1.DowngradedFrom; var d1By = d1.DowngradedTo; AssertPath(d1To, "A 1.0", "C 1.0", "D 1.0", "B 1.0"); AssertPath(d1By, "A 1.0", "B 0.7"); }
public async Task WalkAsync_CentralTransitiveDependencyList_DoesNotHaveDuplicates() { var framework = NuGetFramework.Parse("net45"); var context = new TestRemoteWalkContext(); var provider = new DependencyProvider(); // A -> centralPackage1 // -> centralPackage2 -> centralPackage1 provider.Package("A", "1.0.0") .DependsOn("centralPackage1", "1.0.0", target: LibraryDependencyTarget.Package, versionCentrallyManaged: true); provider.Package("A", "1.0.0") .DependsOn("centralPackage2", "1.0.0", target: LibraryDependencyTarget.Package, versionCentrallyManaged: true); provider.Package("centralPackage2", "1.0.0") .DependsOn("centralPackage1", "1.0.0"); // A -> projectB -> projectC -> centralPackage1 provider.Package("A", "1.0.0") .DependsOn("B", "1.0.0"); provider.Package("B", "1.0.0") .DependsOn("C", "1.0.0"); provider.Package("C", "1.0.0") .DependsOn("centralPackage1", "1.0.0", target: LibraryDependencyTarget.Package, versionCentrallyManaged: true); // B ~> centralPackage1 provider.Package("B", "1.0.0") .DependsOn("centralPackage1", "1.0.0", target: LibraryDependencyTarget.Package, versionCentrallyManaged: true, libraryDependencyReferenceType: LibraryDependencyReferenceType.None); provider.Package("centralPackage1", "1.0.0"); provider.Package("centralPackage2", "1.0.0"); context.LocalLibraryProviders.Add(provider); var walker = new RemoteDependencyWalker(context); // Act var rootNode = await DoWalkAsync(walker, "A", framework); // Assert Assert.Equal(3, rootNode.InnerNodes.Count); }
public async Task TryResolveConflicts_WorksWhenVersionRangeIsNotSpecified() { var context = new TestRemoteWalkContext(); var provider = new DependencyProvider(); provider.Package("Root", "1.0") .DependsOn("A", "1.0") .DependsOn("B", "2.0"); provider.Package("A", "1.0") .DependsOn("C"); provider.Package("B", "2.0") .DependsOn("C", "1.8"); provider.Package("C", "1.8"); provider.Package("C", "2.0"); context.LocalLibraryProviders.Add(provider); var walker = new RemoteDependencyWalker(context); var node = await DoWalkAsync(walker, "Root"); // Restore doesn't actually support null versions so fake a resolved dependency var cNode = node.Path("A", "C"); cNode.Key.TypeConstraint = LibraryDependencyTarget.Package; cNode.Item = new GraphItem <RemoteResolveResult>(new LibraryIdentity { Name = "C", Version = new NuGetVersion("2.0") }); var result = node.Analyze(); Assert.Empty(result.VersionConflicts); Assert.Equal(Disposition.Accepted, cNode.Disposition); Assert.Equal(Disposition.Rejected, node.Path("B", "C").Disposition); }
public async Task CyclesAreDetectedIf2VersionsOfTheSamePackageId() { var context = new TestRemoteWalkContext(); var provider = new DependencyProvider(); provider.Package("A", "1.0") .DependsOn("B", "2.0"); provider.Package("B", "2.0") .DependsOn("A", "5.0"); context.LocalLibraryProviders.Add(provider); var walker = new RemoteDependencyWalker(context); var node = await DoWalkAsync(walker, "A"); var result = node.Analyze(); Assert.Equal(1, result.Cycles.Count); var cycle = result.Cycles[0]; AssertPath(cycle, "A 1.0", "B 2.0", "A 5.0"); }
public async Task WalkAsyncAddsTransitiveCentralDependency(string centralPackageVersion, string otherVersion) { var centralPackageName = "D"; var framework = NuGetFramework.Parse("net45"); var context = new TestRemoteWalkContext(); var provider = new DependencyProvider(); // D is a transitive dependency for package A through package B -> C -> D // D is defined as a Central Package Version // In this context Package D with version centralPackageVersion will be added as inner node of Node A, next to B // Input // A -> B (version = otherVersion) -> C (version = otherVersion) -> D (version = otherVersion) // A ~> D (the version 2.0.0 or as defined by "centralPackageVersion" argument // the dependency is not direct, // it simulates the fact that there is a centrally defined "D" package // the information is added to the provider) // The expected output graph // -> B (version = otherVersion) -> C (version = otherVersion) // A // -> D (version = 2.0.0) provider.Package("A", otherVersion) .DependsOn("B", otherVersion); provider.Package("B", otherVersion) .DependsOn("C", otherVersion); provider.Package("C", otherVersion) .DependsOn(centralPackageName, otherVersion); // Simulates the existence of a D centrally defined package that is not direct dependency provider.Package("A", otherVersion) .DependsOn(centralPackageName, centralPackageVersion, LibraryDependencyTarget.Package, versionCentrallyManaged: true, libraryDependencyReferenceType: LibraryDependencyReferenceType.None); // Add central package to the source with multiple versions provider.Package(centralPackageName, "1.0.0"); provider.Package(centralPackageName, centralPackageVersion); provider.Package(centralPackageName, "3.0.0"); context.LocalLibraryProviders.Add(provider); var walker = new RemoteDependencyWalker(context); // Act var rootNode = await DoWalkAsync(walker, "A", framework); // Assert Assert.Equal(2, rootNode.InnerNodes.Count); var centralVersionInGraphNode = rootNode.InnerNodes.Where(n => n.Item.Key.Name == centralPackageName).FirstOrDefault(); Assert.NotNull(centralVersionInGraphNode); Assert.Equal(centralPackageVersion, centralVersionInGraphNode.Item.Key.Version.ToNormalizedString()); Assert.True(centralVersionInGraphNode.Item.IsCentralTransitive); var BNode = rootNode.InnerNodes.Where(n => n.Item.Key.Name == "B").FirstOrDefault(); Assert.NotNull(BNode); Assert.Equal(1, BNode.InnerNodes.Count); Assert.Equal(otherVersion, BNode.Item.Key.Version.ToNormalizedString()); Assert.False(BNode.Item.IsCentralTransitive); var CNode = BNode.InnerNodes.Where(n => n.Item.Key.Name == "C").FirstOrDefault(); Assert.NotNull(CNode); Assert.Equal(otherVersion, CNode.Item.Key.Version.ToNormalizedString()); Assert.Equal(0, CNode.InnerNodes.Count); Assert.False(CNode.Item.IsCentralTransitive); }