Skip to content

Commit

Permalink
restrict when we add binding redirects (#10833)
Browse files Browse the repository at this point in the history
* add binding redirect tests
* only add binding redirects for assemblies from the updated package
  • Loading branch information
brettfo authored Oct 31, 2024
1 parent 1175b5a commit 1c08936
Show file tree
Hide file tree
Showing 5 changed files with 366 additions and 12 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,225 @@
using Xunit;

namespace NuGetUpdater.Core.Test.Update;

public class BindingRedirectsTests
{
[Fact]
public async Task SimpleBindingRedirectIsPerformed()
{
await VerifyBindingRedirectsAsync(
projectContents: """
<Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
</PropertyGroup>
<ItemGroup>
<None Include="app.config" />
</ItemGroup>
<ItemGroup>
<Reference Include="Some.Package, Version=2.0.0.0, Culture=neutral, PublicKeyToken=null">
<HintPath>packages\Some.Package.2.0.0\lib\net45\Some.Package.dll</HintPath>
<Private>True</Private>
</Reference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>
""",
configContents: """
<configuration>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="Some.Package" publicKeyToken="null" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-1.0.0.0" newVersion="1.0.0.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>
""",
updatedPackageName: "Some.Package",
updatedPackageVersion: "2.0.0",
expectedConfigContents: """
<configuration>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="Some.Package" publicKeyToken="null" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-2.0.0.0" newVersion="2.0.0.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>
"""
);
}

[Fact]
public async Task ConfigFileIndentationIsPreserved()
{
await VerifyBindingRedirectsAsync(
projectContents: """
<Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
</PropertyGroup>
<ItemGroup>
<None Include="app.config" />
</ItemGroup>
<ItemGroup>
<Reference Include="Some.Package, Version=2.0.0.0, Culture=neutral, PublicKeyToken=null">
<HintPath>packages\Some.Package.2.0.0\lib\net45\Some.Package.dll</HintPath>
<Private>True</Private>
</Reference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>
""",
configContents: """
<configuration>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="Some.Package" publicKeyToken="null" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-1.0.0.0" newVersion="1.0.0.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>
""",
updatedPackageName: "Some.Package",
updatedPackageVersion: "2.0.0",
expectedConfigContents: """
<configuration>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="Some.Package" publicKeyToken="null" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-2.0.0.0" newVersion="2.0.0.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>
"""
);
}

[Fact]
public async Task NoExtraBindingsAreAdded()
{
await VerifyBindingRedirectsAsync(
projectContents: """
<Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
</PropertyGroup>
<ItemGroup>
<None Include="app.config" />
</ItemGroup>
<ItemGroup>
<Reference Include="Some.Package, Version=2.0.0.0, Culture=neutral, PublicKeyToken=null">
<HintPath>packages\Some.Package.2.0.0\lib\net45\Some.Package.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Some.Unrelated.Package, Version=3.0.0.0, Culture=neutral, PublicKeyToken=null">
<HintPath>packages\Some.Unrelated.Package.3.0.0\lib\net45\Some.Package.dll</HintPath>
<Private>True</Private>
</Reference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>
""",
configContents: """
<configuration>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="Some.Package" publicKeyToken="null" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-1.0.0.0" newVersion="1.0.0.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>
""",
updatedPackageName: "Some.Package",
updatedPackageVersion: "2.0.0",
expectedConfigContents: """
<configuration>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="Some.Package" publicKeyToken="null" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-2.0.0.0" newVersion="2.0.0.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>
"""
);
}

[Fact]
public async Task NewBindingIsAdded()
{
await VerifyBindingRedirectsAsync(
projectContents: """
<Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
</PropertyGroup>
<ItemGroup>
<None Include="app.config" />
</ItemGroup>
<ItemGroup>
<Reference Include="Some.Package, Version=2.0.0.0, Culture=neutral, PublicKeyToken=null">
<HintPath>packages\Some.Package.2.0.0\lib\net45\Some.Package.dll</HintPath>
<Private>True</Private>
</Reference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>
""",
configContents: """
<configuration>
<runtime />
</configuration>
""",
updatedPackageName: "Some.Package",
updatedPackageVersion: "2.0.0",
expectedConfigContents: """
<configuration>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="Some.Package" publicKeyToken="null" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-2.0.0.0" newVersion="2.0.0.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>
"""
);
}

private static async Task VerifyBindingRedirectsAsync(string projectContents, string configContents, string expectedConfigContents, string updatedPackageName, string updatedPackageVersion, string configFileName = "app.config")
{
using var tempDir = new TemporaryDirectory();
var projectFileName = "project.csproj";
var projectFilePath = Path.Combine(tempDir.DirectoryPath, projectFileName);
var configFilePath = Path.Combine(tempDir.DirectoryPath, configFileName);

await File.WriteAllTextAsync(projectFilePath, projectContents);
await File.WriteAllTextAsync(configFilePath, configContents);

var projectBuildFile = ProjectBuildFile.Open(tempDir.DirectoryPath, projectFilePath);
await BindingRedirectManager.UpdateBindingRedirectsAsync(projectBuildFile, updatedPackageName, updatedPackageVersion);

var actualConfigContents = (await File.ReadAllTextAsync(configFilePath)).Replace("\r", "");
expectedConfigContents = expectedConfigContents.Replace("\r", "");
Assert.Equal(expectedConfigContents, actualConfigContents);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -594,6 +594,7 @@ await TestUpdateForProject("Some.Package", "7.0.1", "13.0.1",
[
MockNuGetPackage.CreatePackageWithAssembly("Some.Package", "7.0.1", "net45", "7.0.0.0"),
MockNuGetPackage.CreatePackageWithAssembly("Some.Package", "13.0.1", "net45", "13.0.0.0"),
MockNuGetPackage.CreatePackageWithAssembly("Unrelated.Package", "1.2.3", "net45","1.2.0.0"),
],
projectContents: """
<Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
Expand All @@ -612,6 +613,10 @@ await TestUpdateForProject("Some.Package", "7.0.1", "13.0.1",
<HintPath>packages\Some.Package.7.0.1\lib\net45\Some.Package.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Unrelated.Package, Version=1.2.0.0, Culture=neutral, PublicKeyToken=null">
<HintPath>packages\Unrelated.Package.1.2.3\lib\net45\Unrelated.Package.dll</HintPath>
<Private>True</Private>
</Reference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>
Expand Down Expand Up @@ -653,6 +658,107 @@ await TestUpdateForProject("Some.Package", "7.0.1", "13.0.1",
<HintPath>packages\Some.Package.13.0.1\lib\net45\Some.Package.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Unrelated.Package, Version=1.2.0.0, Culture=neutral, PublicKeyToken=null">
<HintPath>packages\Unrelated.Package.1.2.3\lib\net45\Unrelated.Package.dll</HintPath>
<Private>True</Private>
</Reference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>
""",
expectedPackagesConfigContents: """
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Some.Package" version="13.0.1" targetFramework="net45" />
</packages>
""",
additionalFilesExpected:
[
("app.config", """
<configuration>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="Some.Package" publicKeyToken="null" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-13.0.0.0" newVersion="13.0.0.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>
""")
]
);
}

[Fact]
public async Task BindingRedirectIsAddedForUpdatedPackage()
{
await TestUpdateForProject("Some.Package", "7.0.1", "13.0.1",
packages:
[
MockNuGetPackage.CreatePackageWithAssembly("Some.Package", "7.0.1", "net45", "7.0.0.0"),
MockNuGetPackage.CreatePackageWithAssembly("Some.Package", "13.0.1", "net45", "13.0.0.0"),
MockNuGetPackage.CreatePackageWithAssembly("Unrelated.Package", "1.2.3", "net45","1.2.0.0"),
],
projectContents: """
<Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
</PropertyGroup>
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
<ItemGroup>
<None Include="app.config" />
</ItemGroup>
<ItemGroup>
<Reference Include="Some.Package, Version=7.0.0.0, Culture=neutral, PublicKeyToken=null">
<HintPath>packages\Some.Package.7.0.1\lib\net45\Some.Package.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Unrelated.Package, Version=1.2.0.0, Culture=neutral, PublicKeyToken=null">
<HintPath>packages\Unrelated.Package.1.2.3\lib\net45\Unrelated.Package.dll</HintPath>
<Private>True</Private>
</Reference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>
""",
packagesConfigContents: """
<packages>
<package id="Some.Package" version="7.0.1" targetFramework="net45" />
</packages>
""",
additionalFiles:
[
("app.config", """
<configuration>
<runtime />
</configuration>
""")
],
expectedProjectContents: """
<Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
</PropertyGroup>
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
<ItemGroup>
<None Include="app.config" />
</ItemGroup>
<ItemGroup>
<Reference Include="Some.Package, Version=13.0.0.0, Culture=neutral, PublicKeyToken=null">
<HintPath>packages\Some.Package.13.0.1\lib\net45\Some.Package.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Unrelated.Package, Version=1.2.0.0, Culture=neutral, PublicKeyToken=null">
<HintPath>packages\Unrelated.Package.1.2.3\lib\net45\Unrelated.Package.dll</HintPath>
<Private>True</Private>
</Reference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>
Expand Down
Loading

0 comments on commit 1c08936

Please sign in to comment.