From 88f6462d5c0b9db2a548bfebc9849a973506f7f2 Mon Sep 17 00:00:00 2001 From: Jonathan Peppers Date: Tue, 8 Sep 2026 17:19:00 -0500 Subject: [PATCH] [tests] Move type map rewrite tests to net11 Run the JNI rewriter cases that directly consume the trimmable type map generator in the existing net11 integration test assembly. This removes the accidental transitive reference from the net10 Xamarin.Android.Build.Tests project. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --- .../JniRemapping/JniAssemblyRewriterTests.cs | 80 -------------- .../JniAssemblyRewriterTests.cs | 103 ++++++++++++++++++ .../MockBuildEngine.cs | 10 +- 3 files changed, 112 insertions(+), 81 deletions(-) create mode 100644 tests/Microsoft.Android.Sdk.TrimmableTypeMap.IntegrationTests/JniAssemblyRewriterTests.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/JniAssemblyRewriterTests.cs b/tests/Microsoft.Android.Sdk.TrimmableTypeMap.IntegrationTests/JniAssemblyRewriterTests.cs new file mode 100644 index 00000000000..a2673ac1535 --- /dev/null +++ b/tests/Microsoft.Android.Sdk.TrimmableTypeMap.IntegrationTests/JniAssemblyRewriterTests.cs @@ -0,0 +1,103 @@ +using System; +using System.Collections.Generic; +using System.Collections.Immutable; +using System.IO; +using System.Linq; +using System.Reflection.Metadata; +using System.Reflection.PortableExecutable; +using Microsoft.Build.Framework; +using Microsoft.Build.Utilities; +using Xamarin.Android.Tasks.JniRemapping; +using Xunit; + +namespace Microsoft.Android.Sdk.TrimmableTypeMap.IntegrationTests; + +public class JniAssemblyRewriterTests +{ + [Fact] + 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); + + Assert.Equal (new [] { "()V", "a", "b" }, ReadUtf8Values (result.Image).OrderBy (value => value, StringComparer.Ordinal)); + Assert.DoesNotContain (warnings, warning => warning.Code == "XA4326"); + } + + [Fact] + 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); + + Assert.Equal (new [] { "()V", "a", "n_Run" }, ReadUtf8Values (result.Image).OrderBy (value => value, StringComparer.Ordinal)); + Assert.DoesNotContain (warnings, warning => warning.Code == "XA4326"); + } + + static JniRewriteResult Rewrite (byte [] sourceImage, R8Mapping mapping, IList warnings) + { + var log = new TaskLoggingHelper (new MockBuildEngine (warnings), nameof (JniAssemblyRewriterTests)); + return JniAssemblyRewriter.Rewrite (sourceImage, mapping, log); + } + + static R8Mapping Mapping (string text) => R8Mapping.Parse (new StringReader (text)); + + 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..1d53a4603ac 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,13 @@ namespace Microsoft.Android.Sdk.TrimmableTypeMap.IntegrationTests; /// sealed class MockBuildEngine : IBuildEngine { + readonly IList? warnings; + + public MockBuildEngine (IList? warnings = null) + { + this.warnings = warnings; + } + public bool ContinueOnError => false; public int LineNumberOfTaskNode => 0; public int ColumnNumberOfTaskNode => 0; @@ -18,5 +26,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); }