|
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using System.IO;
using Microsoft.Build.Framework;
using Microsoft.Build.Tasks;
using Microsoft.Build.Utilities;
using Xunit;
using Xunit.Abstractions;
#nullable disable
namespace Microsoft.Build.UnitTests.ResolveAssemblyReference_Tests
{
/// <summary>
/// Unit test the cases where we need to determine if the target framework is greater than the current target framework through the use of the target framework attribute
/// </summary>
public sealed class VerifyTargetFrameworkAttribute : ResolveAssemblyReferenceTestFixture
{
public VerifyTargetFrameworkAttribute(ITestOutputHelper output) : base(output)
{
}
/// <summary>
/// Verify there are no warnings if the target framework identifier passed to rar and the target framework identifier in the dll do not match.
/// </summary>
[Fact]
public void FrameworksDoNotMatch()
{
MockEngine e = new MockEngine(_output);
ITaskItem[] items = new ITaskItem[]
{
new TaskItem("DependsOnFoo4Framework"),
};
ResolveAssemblyReference t = new ResolveAssemblyReference();
t.BuildEngine = e;
t.Assemblies = items;
t.TargetFrameworkMoniker = "BAR, Version=4.0";
t.TargetFrameworkMonikerDisplayName = "BAR";
t.SearchPaths = new string[] { s_frameworksPath + Path.DirectorySeparatorChar };
Execute(t);
Assert.Equal(0, e.Warnings); // "No warnings expected in this scenario."
Assert.Equal(0, e.Errors); // "No errors expected in this scenario."
Assert.Single(t.ResolvedFiles);
Assert.True(ContainsItem(t.ResolvedFiles, Path.Combine(s_frameworksPath, "DependsOnFoo4Framework.dll"))); // "Expected to find assembly, but didn't."
}
/// <summary>
/// Verify there are no warnings if it is the same framework but we are a lower version. With a primary reference in the project.
/// </summary>
[Fact]
public void LowerVersionSameFrameworkDirect()
{
MockEngine e = new MockEngine(_output);
ITaskItem[] items = new ITaskItem[]
{
new TaskItem("DependsOnFoo35Framework"),
};
ResolveAssemblyReference t = new ResolveAssemblyReference();
t.BuildEngine = e;
t.Assemblies = items;
t.TargetFrameworkMoniker = "Foo, Version=v4.0";
t.TargetFrameworkMonikerDisplayName = "Foo";
t.SearchPaths = new string[] { s_frameworksPath + Path.DirectorySeparatorChar };
Execute(t);
Assert.Equal(0, e.Warnings); // "No warnings expected in this scenario."
Assert.Equal(0, e.Errors); // "No errors expected in this scenario."
Assert.Single(t.ResolvedFiles);
Assert.True(ContainsItem(t.ResolvedFiles, Path.Combine(s_frameworksPath, "DependsOnFoo35Framework.dll"))); // "Expected to find assembly, but didn't."
}
/// <summary>
/// Verify there are no warnings if it is the same framework and the same version and a direct reference
/// </summary>
[Fact]
public void SameVersionSameFrameworkDirect()
{
MockEngine e = new MockEngine(_output);
ITaskItem[] items = new ITaskItem[]
{
new TaskItem("DependsOnFoo4Framework"),
};
ResolveAssemblyReference t = new ResolveAssemblyReference();
t.BuildEngine = e;
t.Assemblies = items;
t.TargetFrameworkMoniker = "Foo, Version=4.0";
t.TargetFrameworkMonikerDisplayName = "Foo";
t.SearchPaths = new string[] { s_frameworksPath + Path.DirectorySeparatorChar };
Execute(t);
Assert.Equal(0, e.Warnings); // "No warnings expected in this scenario."
Assert.Equal(0, e.Errors); // "No errors expected in this scenario."
Assert.Single(t.ResolvedFiles);
Assert.True(ContainsItem(t.ResolvedFiles, Path.Combine(s_frameworksPath, "DependsOnFoo4Framework.dll"))); // "Expected to find assembly, but didn't."
}
/// <summary>
/// Verify there are no warnings if the reference was built for a higher framework but specific version is true
/// </summary>
[Fact]
public void HigherVersionButSpecificVersionDirect()
{
MockEngine e = new MockEngine(_output);
TaskItem item = new TaskItem("DependsOnFoo45Framework, Version=4.5.0.0, PublicKeyToken=null, Culture=Neutral");
item.SetMetadata("SpecificVersion", "true");
ITaskItem[] items = new ITaskItem[]
{
item
};
ResolveAssemblyReference t = new ResolveAssemblyReference();
t.BuildEngine = e;
t.Assemblies = items;
t.TargetFrameworkMoniker = "Foo, Version=4.0";
t.TargetFrameworkMonikerDisplayName = "Foo";
t.SearchPaths = new string[] { s_frameworksPath + Path.DirectorySeparatorChar };
Execute(t);
Assert.Equal(0, e.Warnings); // "No warnings expected in this scenario."
Assert.Equal(0, e.Errors); // "No errors expected in this scenario."
Assert.Single(t.ResolvedFiles);
Assert.True(ContainsItem(t.ResolvedFiles, Path.Combine(s_frameworksPath, "DependsOnFoo45Framework.dll"))); // "Expected to find assembly, but didn't."
}
/// <summary>
/// Verify there are no warnings if it is the same framework but we are a lower version.
/// </summary>
[Fact]
public void LowerVersionSameFrameworkInDirect()
{
MockEngine e = new MockEngine(_output);
ITaskItem[] items = new ITaskItem[]
{
new TaskItem("IndirectDependsOnFoo35Framework"),
};
ResolveAssemblyReference t = new ResolveAssemblyReference();
t.BuildEngine = e;
t.Assemblies = items;
t.TargetFrameworkMoniker = "Foo, Version=v4.0";
t.TargetFrameworkMonikerDisplayName = "Foo";
t.SearchPaths = new string[] { s_frameworksPath + Path.DirectorySeparatorChar };
Execute(t);
Assert.Equal(0, e.Warnings); // "No warnings expected in this scenario."
Assert.Equal(0, e.Errors); // "No errors expected in this scenario."
Assert.Single(t.ResolvedFiles);
Assert.Single(t.ResolvedDependencyFiles);
Assert.True(ContainsItem(t.ResolvedFiles, Path.Combine(s_frameworksPath, "IndirectDependsOnFoo35Framework.dll"))); // "Expected to find assembly, but didn't."
Assert.True(ContainsItem(t.ResolvedDependencyFiles, Path.Combine(s_frameworksPath, "DependsOnFoo35Framework.dll"))); // "Expected to find assembly, but didn't."
}
/// <summary>
/// Verify there are no warnings if it is the same framework and the same version.
/// </summary>
[Fact]
public void SameVersionSameFrameworkInDirect()
{
MockEngine e = new MockEngine(_output);
ITaskItem[] items = new ITaskItem[]
{
new TaskItem("IndirectDependsOnFoo4Framework"),
};
ResolveAssemblyReference t = new ResolveAssemblyReference();
t.BuildEngine = e;
t.Assemblies = items;
t.TargetFrameworkMoniker = "Foo, Version=4.0";
t.TargetFrameworkMonikerDisplayName = "Foo";
t.SearchPaths = new string[] { s_frameworksPath + Path.DirectorySeparatorChar };
Execute(t);
Assert.Equal(0, e.Warnings); // "No warnings expected in this scenario."
Assert.Equal(0, e.Errors); // "No errors expected in this scenario."
Assert.Single(t.ResolvedFiles);
Assert.Single(t.ResolvedDependencyFiles);
Assert.True(ContainsItem(t.ResolvedFiles, Path.Combine(s_frameworksPath, "IndirectDependsOnFoo4Framework.dll"))); // "Expected to find assembly, but didn't."
Assert.True(ContainsItem(t.ResolvedDependencyFiles, Path.Combine(s_frameworksPath, "DependsOnFoo4Framework.dll"))); // "Expected to find assembly, but didn't."
}
/// <summary>
/// Verify there are no warnings if it is the same framework and a higher version but specific version is true.
/// </summary>
[Fact]
public void HigherVersionButSpecificVersionInDirect()
{
MockEngine e = new MockEngine(_output);
TaskItem item = new TaskItem("IndirectDependsOnFoo45Framework, Version=0.0.0.0, PublicKeyToken=null, Culture=Neutral");
item.SetMetadata("SpecificVersion", "true");
ITaskItem[] items = new ITaskItem[]
{
item
};
ResolveAssemblyReference t = new ResolveAssemblyReference();
t.BuildEngine = e;
t.Assemblies = items;
t.TargetFrameworkMoniker = "Foo, Version=4.0";
t.TargetFrameworkMonikerDisplayName = "Foo";
t.SearchPaths = new string[] { s_frameworksPath + Path.DirectorySeparatorChar };
Execute(t);
Assert.Equal(0, e.Warnings); // "No warnings expected in this scenario."
Assert.Equal(0, e.Errors); // "No errors expected in this scenario."
Assert.Single(t.ResolvedFiles);
Assert.Single(t.ResolvedDependencyFiles);
Assert.True(ContainsItem(t.ResolvedFiles, Path.Combine(s_frameworksPath, "IndirectDependsOnFoo45Framework.dll"))); // "Expected to find assembly, but didn't."
Assert.True(ContainsItem(t.ResolvedDependencyFiles, Path.Combine(s_frameworksPath, "DependsOnFoo45Framework.dll"))); // "Expected to find assembly, but didn't."
}
/// <summary>
/// Verify there are warnings if there is an indirect reference to a dll that is higher that what the current target framework is.
/// </summary>
[Fact]
public void HigherVersionInDirect()
{
MockEngine e = new MockEngine(_output);
TaskItem item = new TaskItem("IndirectDependsOnFoo45Framework, Version=0.0.0.0, PublicKeyToken=null, Culture=Neutral");
ITaskItem[] items = new ITaskItem[]
{
item
};
ResolveAssemblyReference t = new ResolveAssemblyReference();
t.BuildEngine = e;
t.Assemblies = items;
t.TargetFrameworkMoniker = "Foo, Version=4.0";
t.TargetFrameworkMonikerDisplayName = "Foo";
t.SearchPaths = new string[] { s_frameworksPath + Path.DirectorySeparatorChar };
Execute(t, false);
Assert.Equal(1, e.Warnings); // "One warning expected in this scenario."
e.AssertLogContains("MSB3275");
Assert.Equal(0, e.Errors); // "No errors expected in this scenario."
Assert.Empty(t.ResolvedFiles);
Assert.Empty(t.ResolvedDependencyFiles);
}
/// <summary>
/// Verify there are no warnings if there is an indirect reference to a dll that is higher that what the current target framework is but IgnoreFrameworkAttributeVersionMismatch is true.
/// </summary>
[Fact]
public void HigherVersionInDirectIgnoreMismatch()
{
MockEngine e = new MockEngine(_output);
TaskItem item = new TaskItem("IndirectDependsOnFoo45Framework, Version=0.0.0.0, PublicKeyToken=null, Culture=Neutral");
ITaskItem[] items = new ITaskItem[]
{
item
};
ResolveAssemblyReference t = new ResolveAssemblyReference();
t.BuildEngine = e;
t.Assemblies = items;
t.TargetFrameworkMoniker = "Foo, Version=4.0";
t.TargetFrameworkMonikerDisplayName = "Foo";
t.SearchPaths = new string[] { s_frameworksPath + Path.DirectorySeparatorChar };
t.IgnoreTargetFrameworkAttributeVersionMismatch = true;
Execute(t);
Assert.Equal(0, e.Warnings); // "No warnings expected in this scenario."
Assert.Equal(0, e.Errors); // "No errors expected in this scenario."
Assert.Single(t.ResolvedFiles);
Assert.Single(t.ResolvedDependencyFiles);
Assert.True(ContainsItem(t.ResolvedFiles, Path.Combine(s_frameworksPath, "IndirectDependsOnFoo45Framework.dll"))); // "Expected to find assembly, but didn't."
Assert.True(ContainsItem(t.ResolvedDependencyFiles, Path.Combine(s_frameworksPath, "DependsOnFoo45Framework.dll"))); // "Expected to find assembly, but didn't."
}
/// <summary>
/// Verify there are no warnings if there is a direct reference to a dll that is higher that what the current target framework is but the property IgnoreFrameworkAttributeVersionMismatch is true.
/// </summary>
[Fact]
public void HigherVersionDirectIgnoreMismatch()
{
MockEngine e = new MockEngine(_output);
TaskItem item = new TaskItem("DependsOnFoo45Framework");
ITaskItem[] items = new ITaskItem[]
{
item
};
ResolveAssemblyReference t = new ResolveAssemblyReference();
t.BuildEngine = e;
t.Assemblies = items;
t.TargetFrameworkMoniker = "Foo, Version=4.0";
t.TargetFrameworkMonikerDisplayName = "Foo";
t.SearchPaths = new string[] { s_frameworksPath + Path.DirectorySeparatorChar };
t.IgnoreTargetFrameworkAttributeVersionMismatch = true;
Execute(t);
Assert.Equal(0, e.Warnings); // "No warnings expected in this scenario."
Assert.Equal(0, e.Errors); // "No errors expected in this scenario."
Assert.Single(t.ResolvedFiles);
Assert.True(ContainsItem(t.ResolvedFiles, Path.Combine(s_frameworksPath, "DependsOnFoo45Framework.dll"))); // "Expected to find assembly, but didn't."
}
/// <summary>
/// Verify there are warnings if there is a direct reference to a dll that is higher that what the current target framework is.
/// </summary>
[Fact]
public void HigherVersionDirect()
{
MockEngine e = new MockEngine(_output);
TaskItem item = new TaskItem("DependsOnFoo45Framework");
ITaskItem[] items = new ITaskItem[]
{
item
};
ResolveAssemblyReference t = new ResolveAssemblyReference();
t.BuildEngine = e;
t.Assemblies = items;
t.TargetFrameworkMoniker = "Foo, Version=4.0";
t.TargetFrameworkMonikerDisplayName = "Foo";
t.SearchPaths = new string[] { s_frameworksPath + Path.DirectorySeparatorChar };
Execute(t, false);
Assert.Equal(1, e.Warnings); // "One warning expected in this scenario."
e.AssertLogContains("MSB3274");
Assert.Equal(0, e.Errors); // "No errors expected in this scenario."
Assert.Empty(t.ResolvedFiles);
Assert.Empty(t.ResolvedDependencyFiles);
}
/// <summary>
/// Verify there are no warnings if there is a direct reference to a dll that is higher that what the current target framework is but
/// find dependencies is false. This is because we do not want to add an extra read for this attribute during the project load phase.
/// which has dependencies set to false. A regular build or design time build has this set to true so we do the correct check.
/// </summary>
[Fact]
public void HigherVersionDirectDependenciesFalse()
{
MockEngine e = new MockEngine(_output);
TaskItem item = new TaskItem("DependsOnFoo45Framework");
ITaskItem[] items = new ITaskItem[]
{
item
};
ResolveAssemblyReference t = new ResolveAssemblyReference();
t.BuildEngine = e;
t.Assemblies = items;
t.FindDependencies = false;
t.TargetFrameworkMoniker = "Foo, Version=4.0";
t.TargetFrameworkMonikerDisplayName = "Foo";
t.SearchPaths = new string[] { @"c:\Frameworks\" };
Assert.True(
t.Execute(
fileExists,
directoryExists,
getDirectories,
getAssemblyName,
getAssemblyMetadata,
#if FEATURE_WIN32_REGISTRY
getRegistrySubKeyNames,
getRegistrySubKeyDefaultValue,
#endif
getLastWriteTime,
getRuntimeVersion,
#if FEATURE_WIN32_REGISTRY
openBaseKey,
#endif
checkIfAssemblyIsInGac,
isWinMDFile,
readMachineTypeFromPEHeader));
Assert.Equal(0, e.Warnings); // "No warning expected in this scenario."
Assert.Equal(0, e.Errors); // "No errors expected in this scenario."
Assert.Single(t.ResolvedFiles);
Assert.Empty(t.ResolvedDependencyFiles);
Assert.True(ContainsItem(t.ResolvedFiles, Path.Combine(s_frameworksPath, "DependsOnFoo45Framework.dll"))); // "Expected to find assembly, but didn't."
}
}
}
|