From df72dcfc27e27735c84c68507426a568799b66e9 Mon Sep 17 00:00:00 2001 From: Mateo Torres-Ruiz Date: Tue, 12 May 2020 23:58:58 -0700 Subject: Use MessageContainer for logging errors (#1155) * Log errors via MessageContainer * Use LinkerErrorExceptions for all throws. Don't stop linker on first error found. * Move FoundErrors to LinkContext and clean exceptions. * Use same code for errors with same message. * Fix test and whitespace formatting * Update exit message Co-authored-by: Marek Safar * Add error for unexpected scenarios. * Print all inner exceptions. * Update FeatureSubstitutionsInvalid test. * Update docs/error-codes.md Co-authored-by: Sven Boemer * Print all inner exceptions in LinkerFatalErrorException * Whitespace formatting Co-authored-by: Marek Safar Co-authored-by: Sven Boemer --- .../Assertions/NoLinkedOutputAttribute.cs | 9 ++++++ test/Mono.Linker.Tests.Cases/Logging/CommonLogs.cs | 6 ++-- .../Substitutions/FeatureSubstitutionsInvalid.cs | 15 +++++----- .../TestCasesRunner/ResultChecker.cs | 35 ++++++++++++++-------- .../Tests/MessageContainerTests.cs | 4 +-- 5 files changed, 45 insertions(+), 24 deletions(-) create mode 100644 test/Mono.Linker.Tests.Cases.Expectations/Assertions/NoLinkedOutputAttribute.cs (limited to 'test') diff --git a/test/Mono.Linker.Tests.Cases.Expectations/Assertions/NoLinkedOutputAttribute.cs b/test/Mono.Linker.Tests.Cases.Expectations/Assertions/NoLinkedOutputAttribute.cs new file mode 100644 index 000000000..0537a62e1 --- /dev/null +++ b/test/Mono.Linker.Tests.Cases.Expectations/Assertions/NoLinkedOutputAttribute.cs @@ -0,0 +1,9 @@ +using System; + +namespace Mono.Linker.Tests.Cases.Expectations.Assertions +{ + public class NoLinkedOutputAttribute : Attribute + { + public NoLinkedOutputAttribute () { } + } +} diff --git a/test/Mono.Linker.Tests.Cases/Logging/CommonLogs.cs b/test/Mono.Linker.Tests.Cases/Logging/CommonLogs.cs index d27cb48e6..b34bf11fa 100644 --- a/test/Mono.Linker.Tests.Cases/Logging/CommonLogs.cs +++ b/test/Mono.Linker.Tests.Cases/Logging/CommonLogs.cs @@ -11,10 +11,10 @@ namespace Mono.Linker.Tests.Cases.Logging #endif [SetupLinkerArgument ("--custom-step", "Log.LogStep,LogStep.dll")] - [LogContains ("illinker: error IL1004: Error")] + [LogContains ("ILlinker: error IL1004: Error")] [LogContains ("logtest(1,1): warning IL2001: Warning")] - [LogContains ("illinker: Info")] - [LogContains ("illinker: Diagnostics")] + [LogContains ("ILlinker: Info")] + [LogContains ("ILlinker: Diagnostics")] public class CommonLogs { public static void Main () diff --git a/test/Mono.Linker.Tests.Cases/Substitutions/FeatureSubstitutionsInvalid.cs b/test/Mono.Linker.Tests.Cases/Substitutions/FeatureSubstitutionsInvalid.cs index dc4e99d59..b1fb16d43 100644 --- a/test/Mono.Linker.Tests.Cases/Substitutions/FeatureSubstitutionsInvalid.cs +++ b/test/Mono.Linker.Tests.Cases/Substitutions/FeatureSubstitutionsInvalid.cs @@ -3,15 +3,16 @@ using Mono.Linker.Tests.Cases.Expectations.Metadata; namespace Mono.Linker.Tests.Cases.Substitutions { + [NoLinkedOutput] [SetupLinkerSubstitutionFile ("FeatureSubstitutionsInvalid.xml")] [SetupLinkerArgument ("--feature", "NoValueFeature", "true")] - [LogContains ("Feature NoValueFeature does not specify a \"featurevalue\" attribute")] - [LogContains ("illinker: warning IL2016: Could not find field 'NonExistentField' in type 'Mono.Linker.Tests.Cases.Substitutions.FeatureSubstitutionsInvalid/Foo'")] - [LogContains ("illinker: warning IL2017: Could not find method 'NonExistentMethod' in type 'Mono.Linker.Tests.Cases.Substitutions.FeatureSubstitutionsInvalid/Foo'")] - [LogContains ("illinker: warning IL2018: Could not find event 'NonExistentEvent' in type 'Mono.Linker.Tests.Cases.Substitutions.FeatureSubstitutionsInvalid/Foo'")] - [LogContains ("illinker: warning IL2019: Could not find property 'NonExistentProperty' in type 'Mono.Linker.Tests.Cases.Substitutions.FeatureSubstitutionsInvalid/Foo'")] - [LogContains ("illinker: warning IL2020: Could not find the get accessor of property 'NoGetter' in type 'Mono.Linker.Tests.Cases.Substitutions.FeatureSubstitutionsInvalid/Foo'")] - [LogContains ("illinker: warning IL2021: Could not find the set accessor of property 'NoSetter' in type 'Mono.Linker.Tests.Cases.Substitutions.FeatureSubstitutionsInvalid/Foo'")] + [LogContains ("Feature NoValueFeature does not specify a 'featurevalue' attribute")] + [LogContains ("ILlinker: warning IL2016: Could not find field 'NonExistentField' in type 'Mono.Linker.Tests.Cases.Substitutions.FeatureSubstitutionsInvalid/Foo'")] + [LogContains ("ILlinker: warning IL2017: Could not find method 'NonExistentMethod' in type 'Mono.Linker.Tests.Cases.Substitutions.FeatureSubstitutionsInvalid/Foo'")] + [LogContains ("ILlinker: warning IL2018: Could not find event 'NonExistentEvent' in type 'Mono.Linker.Tests.Cases.Substitutions.FeatureSubstitutionsInvalid/Foo'")] + [LogContains ("ILlinker: warning IL2019: Could not find property 'NonExistentProperty' in type 'Mono.Linker.Tests.Cases.Substitutions.FeatureSubstitutionsInvalid/Foo'")] + [LogContains ("ILlinker: warning IL2020: Could not find the get accessor of property 'NoGetter' in type 'Mono.Linker.Tests.Cases.Substitutions.FeatureSubstitutionsInvalid/Foo'")] + [LogContains ("ILlinker: warning IL2021: Could not find the set accessor of property 'NoSetter' in type 'Mono.Linker.Tests.Cases.Substitutions.FeatureSubstitutionsInvalid/Foo'")] public class FeatureSubstitutionsInvalid { public static void Main () diff --git a/test/Mono.Linker.Tests/TestCasesRunner/ResultChecker.cs b/test/Mono.Linker.Tests/TestCasesRunner/ResultChecker.cs index 0fa22b3b1..bd5ec176d 100644 --- a/test/Mono.Linker.Tests/TestCasesRunner/ResultChecker.cs +++ b/test/Mono.Linker.Tests/TestCasesRunner/ResultChecker.cs @@ -42,27 +42,26 @@ namespace Mono.Linker.Tests.TestCasesRunner public virtual void Check (LinkedTestCaseResult linkResult) { - Assert.IsTrue (linkResult.OutputAssemblyPath.FileExists (), $"The linked output assembly was not found. Expected at {linkResult.OutputAssemblyPath}"); - InitializeResolvers (linkResult); try { var original = ResolveOriginalsAssembly (linkResult.ExpectationsAssemblyPath.FileNameWithoutExtension); - var linked = ResolveLinkedAssembly (linkResult.OutputAssemblyPath.FileNameWithoutExtension); + if (!HasAttribute (original, nameof (NoLinkedOutputAttribute))) { + Assert.IsTrue (linkResult.OutputAssemblyPath.FileExists (), $"The linked output assembly was not found. Expected at {linkResult.OutputAssemblyPath}"); + var linked = ResolveLinkedAssembly (linkResult.OutputAssemblyPath.FileNameWithoutExtension); - InitialChecking (linkResult, original, linked); + InitialChecking (linkResult, original, linked); - PerformOutputAssemblyChecks (original, linkResult.OutputAssemblyPath.Parent); - PerformOutputSymbolChecks (original, linkResult.OutputAssemblyPath.Parent); + PerformOutputAssemblyChecks (original, linkResult.OutputAssemblyPath.Parent); + PerformOutputSymbolChecks (original, linkResult.OutputAssemblyPath.Parent); - if (!original.MainModule.GetType (linkResult.TestCase.ReconstructedFullTypeName).CustomAttributes - .Any (attr => attr.AttributeType.Name == nameof (SkipKeptItemsValidationAttribute))) { - CreateAssemblyChecker (original, linked).Verify (); + if (!HasAttribute (original.MainModule.GetType (linkResult.TestCase.ReconstructedFullTypeName), nameof (SkipKeptItemsValidationAttribute))) { + CreateAssemblyChecker (original, linked).Verify (); + } } VerifyLinkingOfOtherAssemblies (original); - - AdditionalChecking (linkResult, original, linked); + AdditionalChecking (linkResult, original); } finally { _originalsResolver.Dispose (); _linkedResolver.Dispose (); @@ -162,7 +161,7 @@ namespace Mono.Linker.Tests.TestCasesRunner } } - protected virtual void AdditionalChecking (LinkedTestCaseResult linkResult, AssemblyDefinition original, AssemblyDefinition linked) + protected virtual void AdditionalChecking (LinkedTestCaseResult linkResult, AssemblyDefinition original) { VerifyLoggedMessages (original, linkResult.Logger); VerifyRecordedDependencies (original, linkResult.Customizations.DependencyRecorder); @@ -904,5 +903,17 @@ namespace Mono.Linker.Tests.TestCasesRunner { return attr.AttributeType.Resolve ().DerivesFrom (nameof (BaseInAssemblyAttribute)); } + + bool HasAttribute (ICustomAttributeProvider caProvider, string attributeName) + { + if (caProvider is AssemblyDefinition assembly && assembly.EntryPoint != null) + return assembly.EntryPoint.DeclaringType.CustomAttributes + .Any (attr => attr.AttributeType.Name == attributeName); + + if (caProvider is TypeDefinition type) + return type.CustomAttributes.Any (attr => attr.AttributeType.Name == attributeName); + + return false; + } } } \ No newline at end of file diff --git a/test/Mono.Linker.Tests/Tests/MessageContainerTests.cs b/test/Mono.Linker.Tests/Tests/MessageContainerTests.cs index e9c016dfa..fa69cb62f 100644 --- a/test/Mono.Linker.Tests/Tests/MessageContainerTests.cs +++ b/test/Mono.Linker.Tests/Tests/MessageContainerTests.cs @@ -9,13 +9,13 @@ namespace Mono.Linker.Tests public void MSBuildFormat () { var msg = MessageContainer.CreateErrorMessage ("text", 1000); - Assert.AreEqual ("illinker: error IL1000: text", msg.ToMSBuildString ()); + Assert.AreEqual ("ILlinker: error IL1000: text", msg.ToMSBuildString ()); msg = MessageContainer.CreateWarningMessage ("message", 2001, origin: new MessageOrigin ("logtest", 1, 1)); Assert.AreEqual ("logtest(1,1): warning IL2001: message", msg.ToMSBuildString ()); msg = MessageContainer.CreateInfoMessage ("log test"); - Assert.AreEqual ("illinker: log test", msg.ToMSBuildString ()); + Assert.AreEqual ("ILlinker: log test", msg.ToMSBuildString ()); } } } -- cgit v1.2.3