Skip to content

Commit

Permalink
Add tests cover using statement difference between mcs and csc.
Browse files Browse the repository at this point in the history
Add new [KeptReferencesInAssembly] attribute for asserting the expected
references in an assembly
  • Loading branch information
mrvoorhe authored and marek-safar committed Feb 1, 2019
1 parent 9c67ee6 commit 1195fea
Show file tree
Hide file tree
Showing 8 changed files with 103 additions and 0 deletions.
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 @@ -298,6 +298,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

0 comments on commit 1195fea

Please sign in to comment.