From fe451491f6d6d17561df642a6c23de2fcfc90790 Mon Sep 17 00:00:00 2001 From: monojenkins Date: Wed, 26 Feb 2020 16:16:04 -0500 Subject: [PATCH] [xcode11.4] [tests] Add `.cctor` execution to introspection (#7987) This will spot cases like https://github.com/xamarin/xamarin-macios/issues/7959 where a type (static) constructor can fail at runtime, leading to `TypeLoadException` Ideally it's covered by it's own tests but it's better covered twice than never :) On iOS 64bits [1] simulator we hit some failures [2], later, if the `.cctor` is executed. It's not a big deal to avoid those types since we it will be executed on devices later. [1] API not present on 32bits [2] Fixing the following triggers similar failures for `DCDevice` ``` ApiClassPtrTest.VerifyClassPtr: class_ptr and RegisterAttribute are different: NFCIso15693CustomCommandConfiguration Expected: 0 But was: 140735471513712 ApiSelectorTest.StaticMethods: 7 errors found in 2788 static selector validated: CoreNFC.NFCIso15693ReaderSession : readingAvailable CoreNFC.NFCNdefMessage : ndefMessageWithData: CoreNFC.NFCNdefPayload : wellKnownTypeURIPayloadWithString: CoreNFC.NFCNdefPayload : wellKnownTypeURIPayloadWithURL: CoreNFC.NFCNdefPayload : wellKnownTypeTextPayloadWithString:locale: CoreNFC.NFCNdefReaderSession : readingAvailable CoreNFC.NFCReaderSession : readingAvailable Expected: 0 But was: 7 ``` Co-authored-by: Sebastien Pouliot --- tests/introspection/ApiTypeTest.cs | 58 +++++++++++++++++++ .../Mac/introspection-mac.csproj | 3 + .../iOS/introspection-ios.csproj | 3 + 3 files changed, 64 insertions(+) create mode 100644 tests/introspection/ApiTypeTest.cs diff --git a/tests/introspection/ApiTypeTest.cs b/tests/introspection/ApiTypeTest.cs new file mode 100644 index 0000000000..6366aef4f1 --- /dev/null +++ b/tests/introspection/ApiTypeTest.cs @@ -0,0 +1,58 @@ +using System; +using System.Reflection; +using System.Runtime.CompilerServices; + +using NUnit.Framework; +using Xamarin.Utils; + +using Foundation; +using ObjCRuntime; + +namespace Introspection { + + [TestFixture] + // we want the tests to be available because we use the linker + [Preserve (AllMembers = true)] + public class ApiTypeTest : ApiBaseTest { + + bool Skip (Type type) + { + switch (type.Namespace) { +#if __IOS__ + // running the .cctor on the simulator works... but makes some other CoreNFC intro tests fail later + // we'll still get the results from device tests + case "CoreNFC": + case "DeviceCheck": + // we can't call the `NFCNdefReaderSession.ReadingAvailable` API on 32bits (PlatformNotSupportedException) + // and if we call it then the .cctor is executed and we get the same failures :() + return ((IntPtr.Size == 4) || (Runtime.Arch == Arch.SIMULATOR)); +#endif + default: + return false; + } + } + + [Test] + public void StaticCtor () + { + ContinueOnFailure = true; + foreach (Type t in Assembly.GetTypes ()) { + if (Skip (t)) + continue; + + var cctor = t.GetConstructor (BindingFlags.Static | BindingFlags.NonPublic, null, Type.EmptyTypes, null); + if (cctor == null) + continue; + // we don't skip based on availability attributes since the execution of .cctor can easily happen indirectly and + // we rather catch them all here *now* than trying to figure out how to replicate the specific conditions *later* + try { + RuntimeHelpers.RunClassConstructor (t.TypeHandle); + } + catch (TypeInitializationException e) { + ReportError ($"{t.FullName} .cctor could not execute properly: {e}"); + } + } + AssertIfErrors ($"{Errors} execution failure(s)"); + } + } +} \ No newline at end of file diff --git a/tests/introspection/Mac/introspection-mac.csproj b/tests/introspection/Mac/introspection-mac.csproj index 8e5c94e1ec..78a1165f24 100644 --- a/tests/introspection/Mac/introspection-mac.csproj +++ b/tests/introspection/Mac/introspection-mac.csproj @@ -132,6 +132,9 @@ ApiFrameworkTest.cs + + ApiTypeTest.cs + diff --git a/tests/introspection/iOS/introspection-ios.csproj b/tests/introspection/iOS/introspection-ios.csproj index e7c7baa662..8ec909d01c 100644 --- a/tests/introspection/iOS/introspection-ios.csproj +++ b/tests/introspection/iOS/introspection-ios.csproj @@ -223,6 +223,9 @@ ApiFrameworkTest.cs + + ApiTypeTest.cs +