Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add tests cover using statement difference between mcs and csc. #399

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
using System;

namespace Mono.Linker.Tests.Cases.Expectations.Assertions {
[AttributeUsage (AttributeTargets.Class, AllowMultiple = true, Inherited = false)]
public class KeptReferencesInAssemblyAttribute : BaseInAssemblyAttribute {
public KeptReferencesInAssemblyAttribute (string assemblyFileName, string [] expectedReferenceAssemblyNames)
{
if (string.IsNullOrEmpty (assemblyFileName))
throw new ArgumentNullException (nameof (assemblyFileName));

if (expectedReferenceAssemblyNames == null)
throw new ArgumentNullException (nameof (expectedReferenceAssemblyNames));
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@
<Compile Include="Assertions\KeptMemberAttribute.cs" />
<Compile Include="Assertions\KeptMemberInAssemblyAttribute.cs" />
<Compile Include="Assertions\KeptReferenceAttribute.cs" />
<Compile Include="Assertions\KeptReferencesInAssemblyAttribute.cs" />
<Compile Include="Assertions\KeptResourceAttribute.cs" />
<Compile Include="Assertions\KeptResourceInAssemblyAttribute.cs" />
<Compile Include="Assertions\KeptSecurityAttribute.cs" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -297,6 +297,10 @@
<Compile Include="PreserveDependencies\PreserveDependencyOnUnusedMethodInNonReferencedAssembly.cs" />
<Compile Include="PreserveDependencies\PreserveDependencyOnUnusedMethodInNonReferencedAssemblyWithCopyUsedAction.cs" />
<Compile Include="PreserveDependencies\PreserveDependencyOnUnusedMethodInNonReferencedAssemblyWithEmbeddedXml.cs" />
<Compile Include="References\AssemblyOnlyUsedByUsingWithCsc.cs" />
<Compile Include="References\AssemblyOnlyUsedByUsingWithMcs.cs" />
<Compile Include="References\Dependencies\AssemblyOnlyUsedByUsing_Copied.cs" />
<Compile Include="References\Dependencies\AssemblyOnlyUsedByUsing_Lib.cs" />
<Compile Include="References\Individual\CanSkipUnresolved.cs" />
<Compile Include="References\Individual\Dependencies\CanSkipUnresolved_Library.cs" />
<Compile Include="References\Dependencies\UserAssembliesAreLinkedByDefault_Library1.cs" />
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
using Mono.Linker.Tests.Cases.Expectations.Assertions;
using Mono.Linker.Tests.Cases.Expectations.Metadata;
using Mono.Linker.Tests.Cases.References.Dependencies;

namespace Mono.Linker.Tests.Cases.References {
/// <summary>
/// We can't detect the using usage in the assembly. As a result, nothing in `library` is going to be marked and that assembly will be deleted.
/// Because of that, `copied` needs to have it's reference to `library` removed even though we specified an assembly action of `copy`
/// </summary>
[SetupLinkerAction ("copy", "copied")]
[SetupCompileBefore ("library.dll", new [] {"Dependencies/AssemblyOnlyUsedByUsing_Lib.cs"})]

// When csc is used, `copied.dll` will have a reference to `library.dll`
[SetupCompileBefore ("copied.dll", new [] {"Dependencies/AssemblyOnlyUsedByUsing_Copied.cs"}, new [] {"library.dll"}, compilerToUse: "csc")]

// Here to assert that the test is setup correctly to copy the copied assembly. This is an important aspect of the bug
[KeptMemberInAssembly ("copied.dll", typeof (AssemblyOnlyUsedByUsing_Copied), "Unused()")]

// We library should be gone. The `using` statement leaves no traces in the IL so nothing in `library` will be marked
[RemovedAssembly ("library.dll")]
[KeptReferencesInAssembly ("copied.dll", new [] {"mscorlib"})]
public class AssemblyOnlyUsedByUsingWithCsc {
public static void Main ()
{
// Use something to keep the reference at compile time
AssemblyOnlyUsedByUsing_Copied.UsedToKeepReference ();
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
using Mono.Linker.Tests.Cases.Expectations.Assertions;
using Mono.Linker.Tests.Cases.Expectations.Metadata;
using Mono.Linker.Tests.Cases.References.Dependencies;

namespace Mono.Linker.Tests.Cases.References {
[SetupLinkerAction ("copy", "copied")]
[SetupCompileBefore ("library.dll", new [] {"Dependencies/AssemblyOnlyUsedByUsing_Lib.cs"})]

// When mcs is used, `copied.dll` will not have a reference to `library.dll`
[SetupCompileBefore ("copied.dll", new [] {"Dependencies/AssemblyOnlyUsedByUsing_Copied.cs"}, new [] {"library.dll"}, compilerToUse: "mcs")]

// Here to assert that the test is setup correctly to copy the copied assembly. This is an important aspect of the bug
[KeptMemberInAssembly ("copied.dll", typeof (AssemblyOnlyUsedByUsing_Copied), "Unused()")]

[RemovedAssembly ("library.dll")]
[KeptReferencesInAssembly ("copied.dll", new [] {"mscorlib"})]
public class AssemblyOnlyUsedByUsingWithMcs {
public static void Main ()
{
// Use something to keep the reference at compile time
AssemblyOnlyUsedByUsing_Copied.UsedToKeepReference ();
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@

// This is what triggers the behavior difference between Roslyn and mcs. Roslyn will keep the reference
// to this assembly because of this whereas mcs will not
using ImportantForBug = Mono.Linker.Tests.Cases.References.Dependencies.AssemblyOnlyUsedByUsing_Lib;

namespace Mono.Linker.Tests.Cases.References.Dependencies {
public class AssemblyOnlyUsedByUsing_Copied {
public static void UsedToKeepReference ()
{
}

private static void Unused ()
{
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
namespace Mono.Linker.Tests.Cases.References.Dependencies {
public class AssemblyOnlyUsedByUsing_Lib {
}
}
10 changes: 10 additions & 0 deletions linker/Tests/TestCasesRunner/ResultChecker.cs
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,9 @@ void VerifyLinkingOfOtherAssemblies (AssemblyDefinition original)
case nameof (RemovedResourceInAssemblyAttribute):
VerifyRemovedResourceInAssembly (checkAttrInAssembly);
break;
case nameof (KeptReferencesInAssemblyAttribute):
VerifyKeptReferencesInAssembly (checkAttrInAssembly);
break;
default:
UnhandledOtherAssemblyAssertion (expectedTypeName, checkAttrInAssembly, linkedType);
break;
Expand Down Expand Up @@ -506,6 +509,13 @@ protected virtual bool TryVerifyKeptMemberInAssemblyAsMethod (string memberName,
return false;
}

void VerifyKeptReferencesInAssembly (CustomAttribute inAssemblyAttribute)
{
var assembly = ResolveLinkedAssembly (inAssemblyAttribute.ConstructorArguments [0].Value.ToString ());
var expectedReferenceNames = ((CustomAttributeArgument []) inAssemblyAttribute.ConstructorArguments [1].Value).Select (attr => (string) attr.Value);
Assert.That (assembly.MainModule.AssemblyReferences.Select (asm => asm.Name), Is.EquivalentTo (expectedReferenceNames));
}

void VerifyKeptResourceInAssembly (CustomAttribute inAssemblyAttribute)
{
var assembly = ResolveLinkedAssembly (inAssemblyAttribute.ConstructorArguments [0].Value.ToString ());
Expand Down