From 140cae6ee2c171ae3bce8446ca8060bb39d8ac9c Mon Sep 17 00:00:00 2001 From: Simon Rozsival Date: Tue, 8 Sep 2026 23:33:11 +0200 Subject: [PATCH] [tests] Move typemap rewrite coverage to net11 Move the cross-component generated typemap rewrite tests out of the net10 Build.Tests project now that the typemap generator targets net11. Keep the same assertions in the existing net11 integration test project, which references both components directly. Fixes the solution compilation regression introduced by #12631. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --- .../JniRemapping/JniAssemblyRewriterTests.cs | 80 --------------- .../JniAssemblyRewriterIntegrationTests.cs | 98 +++++++++++++++++++ .../MockBuildEngine.cs | 5 +- 3 files changed, 102 insertions(+), 81 deletions(-) create mode 100644 tests/Microsoft.Android.Sdk.TrimmableTypeMap.IntegrationTests/JniAssemblyRewriterIntegrationTests.cs diff --git a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Utilities/JniRemapping/JniAssemblyRewriterTests.cs b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Utilities/JniRemapping/JniAssemblyRewriterTests.cs index 21c93763bdc..f05d4f16851 100644 --- a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Utilities/JniRemapping/JniAssemblyRewriterTests.cs +++ b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Utilities/JniRemapping/JniAssemblyRewriterTests.cs @@ -7,7 +7,6 @@ using System.Reflection.Metadata; using System.Reflection.Metadata.Ecma335; using System.Reflection.PortableExecutable; -using Microsoft.Android.Sdk.TrimmableTypeMap; using Microsoft.Build.Framework; using Microsoft.Build.Utilities; using NUnit.Framework; @@ -891,85 +890,6 @@ public void FailsWhenASharedUtf8DatumNeedsTwoDifferentNames () StringAssert.Contains ("shared", exception.Message.ToLowerInvariant ()); } - [Test] - public void RewritesGeneratedTypeMapWithOwnerSpecificMethodNames () - { - byte [] source = GenerateTypeMapWithSharedMethodName (); - var warnings = new List (); - - JniRewriteResult result = Rewrite (source, Mapping ( - "test.First -> a.b.First:\n" + - " void n_Run() -> a\n" + - "test.Second -> a.b.Second:\n" + - " void n_Run() -> b\n"), warnings); - - CollectionAssert.AreEquivalent (new [] { "a", "b", "()V" }, ReadUtf8Values (result.Image)); - CollectionAssert.DoesNotContain (warnings.Select (warning => warning.Code).ToArray (), "XA4326"); - } - - [Test] - public void RewritesGeneratedTypeMapWithMappedAndUnmappedMethodNames () - { - byte [] source = GenerateTypeMapWithSharedMethodName (); - var warnings = new List (); - - JniRewriteResult result = Rewrite (source, Mapping ( - "test.First -> a.b.First:\n" + - " void n_Run() -> a\n" + - "test.Second -> test.Second:\n"), warnings); - - CollectionAssert.AreEquivalent (new [] { "a", "n_Run", "()V" }, ReadUtf8Values (result.Image)); - CollectionAssert.DoesNotContain (warnings.Select (warning => warning.Code).ToArray (), "XA4326"); - } - - static byte [] GenerateTypeMapWithSharedMethodName () - { - var peers = new [] { - CreatePeer ("test/First", "Test.First"), - CreatePeer ("test/Second", "Test.Second"), - }; - using var stream = new MemoryStream (); - new TypeMapAssemblyGenerator (new Version (11, 0, 0, 0)).Generate (peers, stream, "OwnerSpecificNames"); - return stream.ToArray (); - - static JavaPeerInfo CreatePeer (string javaName, string managedName) - { - int separator = managedName.LastIndexOf ('.'); - return new JavaPeerInfo { - JavaName = javaName, - CompatJniName = javaName, - ManagedTypeName = managedName, - ManagedTypeNamespace = managedName.Substring (0, separator), - ManagedTypeShortName = managedName.Substring (separator + 1), - AssemblyName = "TestAsm", - DoNotGenerateAcw = false, - ActivationCtor = new ActivationCtorInfo { - DeclaringTypeName = managedName, - DeclaringAssemblyName = "TestAsm", - Style = ActivationCtorStyle.XamarinAndroid, - }, - MarshalMethods = [ - new MarshalMethodInfo { - JniName = "run", - NativeCallbackName = "n_Run", - JniSignature = "()V", - ManagedMethodName = "Run", - }, - ], - }; - } - } - - static string [] ReadUtf8Values (byte [] image) - { - using var peReader = new PEReader (ImmutableArray.Create (image)); - MetadataReader reader = peReader.GetMetadataReader (); - return FieldRvaTable.Read (peReader, reader).Entries - .Select (entry => entry.Utf8Value) - .OfType () - .ToArray (); - } - [Test] public void FailsWhenASharedUtf8DatumMustRemainUnmappedForOneProxy () { diff --git a/tests/Microsoft.Android.Sdk.TrimmableTypeMap.IntegrationTests/JniAssemblyRewriterIntegrationTests.cs b/tests/Microsoft.Android.Sdk.TrimmableTypeMap.IntegrationTests/JniAssemblyRewriterIntegrationTests.cs new file mode 100644 index 00000000000..4923e0f55c1 --- /dev/null +++ b/tests/Microsoft.Android.Sdk.TrimmableTypeMap.IntegrationTests/JniAssemblyRewriterIntegrationTests.cs @@ -0,0 +1,98 @@ +using System; +using System.Collections.Immutable; +using System.IO; +using System.Linq; +using System.Reflection.Metadata; +using System.Reflection.PortableExecutable; +using Microsoft.Build.Utilities; +using Xunit; +using Xamarin.Android.Tasks.JniRemapping; + +namespace Microsoft.Android.Sdk.TrimmableTypeMap.IntegrationTests; + +public class JniAssemblyRewriterIntegrationTests +{ + [Fact] + public void RewritesGeneratedTypeMapWithOwnerSpecificMethodNames () + { + var engine = new MockBuildEngine (); + JniRewriteResult result = Rewrite (GenerateTypeMapWithSharedMethodName (), """ + test.First -> a.b.First: + void n_Run() -> a + test.Second -> a.b.Second: + void n_Run() -> b + """, engine); + + Assert.Equal (new [] { "()V", "a", "b" }, ReadUtf8Values (result.Image).OrderBy (value => value)); + Assert.DoesNotContain (engine.Warnings, warning => warning.Code == "XA4326"); + } + + [Fact] + public void RewritesGeneratedTypeMapWithMappedAndUnmappedMethodNames () + { + var engine = new MockBuildEngine (); + JniRewriteResult result = Rewrite (GenerateTypeMapWithSharedMethodName (), """ + test.First -> a.b.First: + void n_Run() -> a + test.Second -> test.Second: + """, engine); + + Assert.Equal (new [] { "()V", "a", "n_Run" }, ReadUtf8Values (result.Image).OrderBy (value => value)); + Assert.DoesNotContain (engine.Warnings, warning => warning.Code == "XA4326"); + } + + static JniRewriteResult Rewrite (byte [] sourceImage, string mappingText, MockBuildEngine engine) + { + R8Mapping mapping = R8Mapping.Parse (new StringReader (mappingText)); + var log = new TaskLoggingHelper (engine, nameof (JniAssemblyRewriterIntegrationTests)); + return JniAssemblyRewriter.Rewrite (sourceImage, mapping, log); + } + + static byte [] GenerateTypeMapWithSharedMethodName () + { + var peers = new [] { + CreatePeer ("test/First", "Test.First"), + CreatePeer ("test/Second", "Test.Second"), + }; + using var stream = new MemoryStream (); + new TypeMapAssemblyGenerator (new Version (11, 0, 0, 0)).Generate (peers, stream, "OwnerSpecificNames"); + return stream.ToArray (); + } + + static JavaPeerInfo CreatePeer (string javaName, string managedName) + { + int separator = managedName.LastIndexOf ('.'); + return new JavaPeerInfo { + JavaName = javaName, + CompatJniName = javaName, + ManagedTypeName = managedName, + ManagedTypeNamespace = managedName.Substring (0, separator), + ManagedTypeShortName = managedName.Substring (separator + 1), + AssemblyName = "TestAsm", + DoNotGenerateAcw = false, + ActivationCtor = new ActivationCtorInfo { + DeclaringTypeName = managedName, + DeclaringAssemblyName = "TestAsm", + Style = ActivationCtorStyle.XamarinAndroid, + }, + MarshalMethods = [ + new MarshalMethodInfo { + JniName = "run", + NativeCallbackName = "n_Run", + JniSignature = "()V", + ManagedMethodName = "Run", + }, + ], + }; + } + + static string [] ReadUtf8Values (byte [] image) + { + using var peReader = new PEReader (ImmutableArray.Create (image)); + MetadataReader reader = peReader.GetMetadataReader (); + return FieldRvaTable.Read (peReader, reader).Entries + .Select (entry => entry.Utf8Value) + .OfType () + .ToArray (); + } +} diff --git a/tests/Microsoft.Android.Sdk.TrimmableTypeMap.IntegrationTests/MockBuildEngine.cs b/tests/Microsoft.Android.Sdk.TrimmableTypeMap.IntegrationTests/MockBuildEngine.cs index d6c8c19d1eb..fd8bded3a40 100644 --- a/tests/Microsoft.Android.Sdk.TrimmableTypeMap.IntegrationTests/MockBuildEngine.cs +++ b/tests/Microsoft.Android.Sdk.TrimmableTypeMap.IntegrationTests/MockBuildEngine.cs @@ -1,5 +1,6 @@ using System; using System.Collections; +using System.Collections.Generic; using Microsoft.Build.Framework; namespace Microsoft.Android.Sdk.TrimmableTypeMap.IntegrationTests; @@ -9,6 +10,8 @@ namespace Microsoft.Android.Sdk.TrimmableTypeMap.IntegrationTests; /// sealed class MockBuildEngine : IBuildEngine { + public List Warnings { get; } = []; + public bool ContinueOnError => false; public int LineNumberOfTaskNode => 0; public int ColumnNumberOfTaskNode => 0; @@ -18,5 +21,5 @@ sealed class MockBuildEngine : IBuildEngine public void LogCustomEvent (CustomBuildEventArgs e) { } public void LogErrorEvent (BuildErrorEventArgs e) { } public void LogMessageEvent (BuildMessageEventArgs e) { } - public void LogWarningEvent (BuildWarningEventArgs e) { } + public void LogWarningEvent (BuildWarningEventArgs e) => Warnings.Add (e); }