540 строки
17 KiB
C#
540 строки
17 KiB
C#
//
|
|
// Link All [Regression] Tests
|
|
//
|
|
// Authors:
|
|
// Sebastien Pouliot <sebastien@xamarin.com>
|
|
//
|
|
// Copyright 2012-2016 Xamarin Inc. All rights reserved.
|
|
//
|
|
|
|
using System;
|
|
using System.ComponentModel;
|
|
using System.Globalization;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using System.Net;
|
|
using System.Net.Security;
|
|
using System.Reflection;
|
|
using System.Security.Cryptography.X509Certificates;
|
|
|
|
using MonoTouch;
|
|
#if XAMCORE_2_0
|
|
using CoreGraphics;
|
|
using Foundation;
|
|
using ObjCRuntime;
|
|
#if !__WATCHOS__
|
|
using StoreKit;
|
|
#endif
|
|
using UIKit;
|
|
#else
|
|
using MonoTouch.CoreGraphics;
|
|
using MonoTouch.Foundation;
|
|
using MonoTouch.ObjCRuntime;
|
|
using MonoTouch.StoreKit;
|
|
using MonoTouch.UIKit;
|
|
#endif
|
|
using NUnit.Framework;
|
|
|
|
namespace LinkAll {
|
|
|
|
// we DO NOT want the code to be "fully" available
|
|
public partial class NotPreserved {
|
|
|
|
public byte One {
|
|
get; set;
|
|
}
|
|
|
|
[DefaultValue (2)]
|
|
public int Two {
|
|
get; set;
|
|
}
|
|
}
|
|
|
|
// nothing directly uses Parent
|
|
public class Parent {
|
|
// but the nested type is a subclass of NSObject and gets preserved (as it's not part of monotouch.dll)
|
|
public class Derived : NSObject {
|
|
[Export ("foo")]
|
|
public void Foo () {}
|
|
}
|
|
|
|
public void UnusedMethod () {}
|
|
}
|
|
|
|
[TestFixture]
|
|
// we want the tests to be available because we use the linker
|
|
[Preserve (AllMembers = true)]
|
|
public class LinkAllRegressionTest {
|
|
#if __IOS__
|
|
#if XAMCORE_2_0
|
|
public const string NamespacePrefix = "";
|
|
public const string AssemblyName = "Xamarin.iOS";
|
|
#else
|
|
public const string NamespacePrefix = "MonoTouch.";
|
|
public const string AssemblyName = "monotouch";
|
|
#endif
|
|
#elif __TVOS__
|
|
public const string NamespacePrefix = "";
|
|
public const string AssemblyName = "Xamarin.TVOS";
|
|
#elif __WATCHOS__
|
|
public const string NamespacePrefix = "";
|
|
public const string AssemblyName = "Xamarin.WatchOS";
|
|
#else
|
|
#error Unknown platform
|
|
#endif
|
|
|
|
class TypeAttribute : Attribute {
|
|
public TypeAttribute (Type type) {}
|
|
}
|
|
|
|
[Type (null)]
|
|
public void NullTypeInAttribute ()
|
|
{
|
|
// there's no need to execute this test.
|
|
// desk #68380.
|
|
}
|
|
|
|
[Test]
|
|
public void GetterOnly ()
|
|
{
|
|
// that ensure the getter is not linked away,
|
|
// which means the property will be available for MEF_3862
|
|
NotPreserved np = new NotPreserved ();
|
|
Assert.That (np.Two, Is.EqualTo (0), "Two==0");
|
|
PropertyInfo pi = typeof (NotPreserved).GetProperty ("Two");
|
|
// check the *unused* setter absence from the application
|
|
Assert.NotNull (pi.GetGetMethod (), "getter");
|
|
Assert.Null (pi.GetSetMethod (), "setter");
|
|
}
|
|
|
|
[Test]
|
|
public void SetterOnly ()
|
|
{
|
|
// that ensure the setter is not linked away,
|
|
NotPreserved np = new NotPreserved ();
|
|
np.One = 1;
|
|
PropertyInfo pi = typeof (NotPreserved).GetProperty ("One");
|
|
// check the *unused* setter absence from the application
|
|
Assert.Null (pi.GetGetMethod (), "getter");
|
|
Assert.NotNull (pi.GetSetMethod (), "setter");
|
|
}
|
|
|
|
[Test]
|
|
public void MEF_3862 ()
|
|
{
|
|
// note: avoiding using "typeof(DefaultValueAttribute)" in the code
|
|
// so the linker does not keep it just because of it
|
|
PropertyInfo pi = typeof (NotPreserved).GetProperty ("Two");
|
|
object [] attrs = pi.GetCustomAttributes (false);
|
|
bool default_value = false;
|
|
foreach (var ca in attrs) {
|
|
if (ca.GetType ().Name == "DefaultValueAttribute") {
|
|
default_value = true;
|
|
break;
|
|
}
|
|
}
|
|
Assert.True (default_value, "DefaultValue");
|
|
}
|
|
|
|
class TestPolicy : ICertificatePolicy {
|
|
|
|
const int RecoverableTrustFailure = 5; // SecTrustResult
|
|
|
|
public TestPolicy ()
|
|
{
|
|
CheckCount = 0;
|
|
}
|
|
|
|
public int CheckCount { get; private set; }
|
|
|
|
public bool CheckValidationResult (ServicePoint srvPoint, X509Certificate certificate, WebRequest request, int certificateProblem)
|
|
{
|
|
Assert.That (certificateProblem, Is.EqualTo (0), "certificateProblem");
|
|
CheckCount++;
|
|
return true;
|
|
}
|
|
}
|
|
|
|
static TestPolicy test_policy = new TestPolicy ();
|
|
|
|
[Test]
|
|
public void TrustUsingOldPolicy ()
|
|
{
|
|
// Three similar tests exists in dontlink, linkall and linksdk to test 3 different cases
|
|
// untrusted, custom ICertificatePolicy and ServerCertificateValidationCallback without
|
|
// having caching issues (in S.Net or the SSL handshake cache)
|
|
ICertificatePolicy old = ServicePointManager.CertificatePolicy;
|
|
try {
|
|
ServicePointManager.CertificatePolicy = test_policy;
|
|
WebClient wc = new WebClient ();
|
|
Assert.IsNotNull (wc.DownloadString ("https://wrench.internalx.com/Wrench/Login.aspx"));
|
|
// caching means it will be called at least for the first run, but it might not
|
|
// be called again in subsequent requests (unless it expires)
|
|
Assert.That (test_policy.CheckCount, Is.GreaterThan (0), "policy checked");
|
|
}
|
|
finally {
|
|
ServicePointManager.CertificatePolicy = old;
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
public void DetectPlatform ()
|
|
{
|
|
#if !__WATCHOS__
|
|
// for (future) nunit[lite] platform detection - if this test fails then platform detection won't work
|
|
Assert.NotNull (Type.GetType (NamespacePrefix + "UIKit.UIApplicationDelegate, " + AssemblyName), "UIApplicationDelegate");
|
|
#endif
|
|
// and you can trust the old trick with the linker
|
|
Assert.NotNull (Type.GetType ("Mono.Runtime"), "Mono.Runtime");
|
|
}
|
|
|
|
[Test]
|
|
#if !XAMCORE_2_0
|
|
// internal (to be removed) in unified
|
|
[Since (9,9)]
|
|
#endif
|
|
#if !XAMCORE_3_0
|
|
[Availability ()]
|
|
[iOS (9,9)]
|
|
[Mac (10, 99)]
|
|
#endif
|
|
[Introduced (PlatformName.None)]
|
|
[Deprecated (PlatformName.None)]
|
|
[Obsoleted (PlatformName.None)]
|
|
[Unavailable (PlatformName.None)]
|
|
[ThreadSafe]
|
|
public void RemovedAttributes ()
|
|
{
|
|
const string prefix = NamespacePrefix;
|
|
const string suffix = ", " + AssemblyName;
|
|
|
|
// since we're linking the attributes will NOT be available - even if they are used
|
|
#if !XAMCORE_3_0
|
|
Assert.Null (Type.GetType (prefix + "ObjCRuntime.AvailabilityAttribute, " + suffix), "AvailabilityAttribute");
|
|
Assert.Null (Type.GetType (prefix + "ObjCRuntime.iOSAttribute, " + suffix), "AvailabilityAttribute");
|
|
Assert.Null (Type.GetType (prefix + "ObjCRuntime.AvailabilityAttribute, " + suffix), "AvailabilityAttribute");
|
|
Assert.Null (Type.GetType (prefix + "ObjCRuntime.SinceAttribute, " + suffix), "SinceAttribute");
|
|
#endif
|
|
Assert.Null (Type.GetType (prefix + "ObjCRuntime.IntroducedAttribute, " + suffix), "IntroducedAttribute");
|
|
Assert.Null (Type.GetType (prefix + "ObjCRuntime.DeprecatedAttribute, " + suffix), "DeprecatedAttribute");
|
|
Assert.Null (Type.GetType (prefix + "ObjCRuntime.ObsoletedAttribute, " + suffix), "ObsoletedAttribute");
|
|
Assert.Null (Type.GetType (prefix + "ObjCRuntime.UnavailableAttribute, " + suffix), "UnavailableAttribute");
|
|
Assert.Null (Type.GetType (prefix + "ObjCRuntime.ThreadSafeAttribute, " + suffix), "ThreadSafeAttribute");
|
|
}
|
|
|
|
[Test]
|
|
public void Assembly_Load ()
|
|
{
|
|
Assembly mscorlib = Assembly.Load ("mscorlib.dll");
|
|
Assert.NotNull (mscorlib, "mscorlib");
|
|
|
|
Assembly system = Assembly.Load ("System.dll");
|
|
Assert.NotNull (system, "System");
|
|
}
|
|
|
|
[Test]
|
|
public void Assembly_LoadFile ()
|
|
{
|
|
string filename = Path.GetFileName (GetType ().Assembly.Location);
|
|
try {
|
|
Assert.NotNull (Assembly.LoadFile (filename), "1");
|
|
}
|
|
catch (FileNotFoundException) {
|
|
// 2nd chance since FAT 32/64 applications moved the assemblies (but that could prove an issue too)
|
|
filename = Path.Combine (IntPtr.Size == 4 ? ".monotouch-32" : ".monotouch-64", filename);
|
|
Assert.NotNull (Assembly.LoadFile (filename), "2");
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
public void Assembly_LoadFrom ()
|
|
{
|
|
string filename = Path.GetFileName (GetType ().Assembly.Location);
|
|
try {
|
|
Assert.NotNull (Assembly.LoadFrom (filename), "1");
|
|
}
|
|
catch (FileNotFoundException) {
|
|
// 2nd chance since FAT 32/64 applications moved the assemblies (but that could prove an issue too)
|
|
filename = Path.Combine (IntPtr.Size == 4 ? ".monotouch-32" : ".monotouch-64", filename);
|
|
Assert.NotNull (Assembly.LoadFrom (filename), "2");
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
public void Assembly_ReflectionOnlyLoadFrom ()
|
|
{
|
|
string filename = Path.GetFileName (GetType ().Assembly.Location);
|
|
try {
|
|
Assert.NotNull (Assembly.ReflectionOnlyLoadFrom (filename), "1");
|
|
}
|
|
catch (FileNotFoundException) {
|
|
// 2nd chance since FAT 32/64 applications moved the assemblies (but that could prove an issue too)
|
|
filename = Path.Combine (IntPtr.Size == 4 ? ".monotouch-32" : ".monotouch-64", filename);
|
|
Assert.NotNull (Assembly.ReflectionOnlyLoadFrom (filename), "2");
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
public void SystemDataSqlClient ()
|
|
{
|
|
// notes:
|
|
// * this test is mean to fail when building the application using a Community or Indie licenses
|
|
// * linksdk.app references System.Data (assembly) but not types in SqlClient namespace
|
|
using (var sc = new System.Data.SqlClient.SqlConnection ()) {
|
|
Assert.NotNull (sc);
|
|
}
|
|
}
|
|
|
|
#if !__TVOS__ && !__WATCHOS__
|
|
[Test]
|
|
public void Pasteboard_ImagesTest ()
|
|
{
|
|
string file = Path.Combine (NSBundle.MainBundle.ResourcePath, "basn3p08.png");
|
|
using (var dp = new CGDataProvider (file)) {
|
|
using (var cgimg = CGImage.FromPNG (dp, null, false, CGColorRenderingIntent.Default)) {
|
|
using (var img = new UIImage (cgimg)) {
|
|
UIPasteboard.General.Images = new UIImage[] { img };
|
|
Assert.AreEqual (1, UIPasteboard.General.Images.Length, "a - length");
|
|
|
|
UIPasteboard.General.Images = new UIImage[] { img, img };
|
|
Assert.AreEqual (2, UIPasteboard.General.Images.Length, "b - length");
|
|
Assert.IsNotNull (UIPasteboard.General.Images [0], "b - nonnull[0]");
|
|
Assert.IsNotNull (UIPasteboard.General.Images [1], "b - nonnull[0]");
|
|
}
|
|
}
|
|
}
|
|
}
|
|
#endif // !__TVOS__
|
|
|
|
[Test]
|
|
public void UltimateBindings ()
|
|
{
|
|
Assert.IsNotNull (Bindings.Test.UltimateMachine.SharedInstance, "SharedInstance");
|
|
}
|
|
|
|
#region bug 14456
|
|
|
|
[TypeConverter (typeof (TestEnumTypeConverter))]
|
|
public enum TestEnum {
|
|
One,Two
|
|
}
|
|
|
|
[Preserve (AllMembers = true)]
|
|
public class TestEnumTypeConverter : System.ComponentModel.TypeConverter {
|
|
|
|
public override object ConvertTo (ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
|
|
{
|
|
return "hello";
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
public void Bug14456 ()
|
|
{
|
|
var tc = TypeDescriptor.GetConverter (typeof (TestEnum));
|
|
// not using Is.TypeOf since it would give additional clue to the linker
|
|
Assert.That (tc.GetType ().Name, Is.EqualTo ("TestEnumTypeConverter"), "TestEnumTypeConverter");
|
|
// notes:
|
|
// * without [Preserve (AllMembers = true)] -> MissingMethodException : Default constructor
|
|
// * without [TypeConverter (typeof (TestEnumTypeConverter))] -> EnumConverter
|
|
}
|
|
|
|
#endregion
|
|
|
|
[Test]
|
|
public void SingleEpsilon_Compare ()
|
|
{
|
|
if (Runtime.Arch == Arch.DEVICE)
|
|
Assert.Ignore ("Known to fail on devices, see bug #15802");
|
|
// works on some ARM CPU (e.g. iPhone5S) but not others (iPad4 or iPodTouch5)
|
|
Assert.That (Single.Epsilon, Is.Not.EqualTo (0f), "Epsilon");
|
|
Assert.That (-Single.Epsilon, Is.Not.EqualTo (0f), "-Epsilon");
|
|
}
|
|
|
|
[Test]
|
|
public void SingleEpsilon_ToString ()
|
|
{
|
|
if (Runtime.Arch == Arch.DEVICE)
|
|
Assert.Ignore ("Known to fail on devices, see bug #15802");
|
|
var ci = CultureInfo.InvariantCulture;
|
|
Assert.That (Single.Epsilon.ToString (ci), Is.EqualTo ("1.401298E-45"), "Epsilon.ToString()");
|
|
Assert.That ((-Single.Epsilon).ToString (ci), Is.EqualTo ("-1.401298E-45"), "-Epsilon.ToString()");
|
|
}
|
|
|
|
[Test]
|
|
public void DoubleEpsilon_Compare ()
|
|
{
|
|
if (Runtime.Arch == Arch.DEVICE)
|
|
Assert.Ignore ("Known to fail on devices, see bug #15802");
|
|
// works on some ARM CPU (e.g. iPhone5S) but not others (iPad4 or iPodTouch5)
|
|
Assert.That (Double.Epsilon, Is.Not.EqualTo (0f), "Epsilon");
|
|
Assert.That (-Double.Epsilon, Is.Not.EqualTo (0f), "-Epsilon");
|
|
}
|
|
|
|
[Test]
|
|
public void DoubleEpsilon_ToString ()
|
|
{
|
|
if (Runtime.Arch == Arch.DEVICE)
|
|
Assert.Ignore ("Known to fail on devices, see bug #15802");
|
|
var ci = CultureInfo.InvariantCulture;
|
|
// note: unlike Single this works on both my iPhone5S and iPodTouch5
|
|
Assert.That (Double.Epsilon.ToString (ci), Is.EqualTo ("4.94065645841247E-324"), "Epsilon.ToString()");
|
|
Assert.That ((-Double.Epsilon).ToString (ci), Is.EqualTo ("-4.94065645841247E-324"), "-Epsilon.ToString()");
|
|
}
|
|
|
|
[Test]
|
|
public void AssemblyReferences_16213 ()
|
|
{
|
|
foreach (var assembly in typeof (System.Data.AcceptRejectRule).Assembly.GetReferencedAssemblies ()) {
|
|
// Unlike the original bug report the unit tests uses Mono.Data.Tds so it will be part of the .app
|
|
// so we check for System.Transactions which is not used (but referenced by the original System.Data)
|
|
if (assembly.Name == "System.Transactions")
|
|
Assert.Fail ("System.Transactions reference should have removed by the linker");
|
|
}
|
|
}
|
|
|
|
#if !__WATCHOS__
|
|
[Test]
|
|
public void OpenTk10_Preserved ()
|
|
{
|
|
// that will bring OpenTK-1.0 into the .app
|
|
OpenTK.WindowState state = OpenTK.WindowState.Normal;
|
|
|
|
var gl = Type.GetType ("OpenTK.Graphics.ES11.GL, OpenTK-1.0", false);
|
|
Assert.NotNull (gl, "ES11/GL");
|
|
var core = Type.GetType ("OpenTK.Graphics.ES11.GL/Core, OpenTK-1.0", false);
|
|
Assert.NotNull (core, "ES11/Core");
|
|
|
|
gl = Type.GetType ("OpenTK.Graphics.ES20.GL, OpenTK-1.0", false);
|
|
Assert.NotNull (gl, "ES20/GL");
|
|
core = Type.GetType ("OpenTK.Graphics.ES20.GL/Core, OpenTK-1.0", false);
|
|
Assert.NotNull (core, "ES20/Core");
|
|
}
|
|
#endif // !__WATCHOS__
|
|
|
|
[Test]
|
|
public void NestedNSObject ()
|
|
{
|
|
// Parent type is not used - but it's not linked out
|
|
var p = Type.GetType ("LinkAll.Parent");
|
|
Assert.NotNull (p, "Parent");
|
|
// because a nested type is a subclass of NSObject (and not part of monotouch.dll)
|
|
var n = p.GetNestedType ("Derived");
|
|
Assert.NotNull (n, "Derived");
|
|
// however other stuff in Parent, like unused methods, will be removed
|
|
Assert.Null (p.GetMethod ("UnusedMethod"), "unused method");
|
|
// while exported stuff will be present
|
|
Assert.NotNull (n.GetMethod ("Foo"), "unused Export method");
|
|
}
|
|
|
|
[Test]
|
|
public void Bug20363 ()
|
|
{
|
|
// testing compile time error
|
|
CancelEventArgs cea = new CancelEventArgs ();
|
|
Assert.NotNull (cea, "CancelEventArgs");
|
|
}
|
|
|
|
string GetField (object o, string s)
|
|
{
|
|
var f = o.GetType ().GetField (s, BindingFlags.Instance | BindingFlags.NonPublic);
|
|
if (f == null)
|
|
return s;
|
|
//Console.WriteLine (f.GetValue (o));
|
|
return null;
|
|
}
|
|
|
|
string FromPattern (string pattern, object o)
|
|
{
|
|
var s = GetField (o, "<action>");
|
|
if (s != null)
|
|
return s;
|
|
s = GetField (o, "<id>");
|
|
if (s != null)
|
|
return s;
|
|
return GetField (o, "<contentType>");
|
|
}
|
|
|
|
[Test]
|
|
public void AnonymousType ()
|
|
{
|
|
var result = FromPattern ("/{action}/{id}.{contentType}", new {
|
|
action = "foo",
|
|
id = 1234,
|
|
contentType = "xml"
|
|
});
|
|
Assert.Null (result, result);
|
|
}
|
|
|
|
#if !__WATCHOS__
|
|
[Test]
|
|
public void Events ()
|
|
{
|
|
using (var pr = new SKProductsRequest ()) {
|
|
Assert.Null (pr.WeakDelegate, "none");
|
|
// event on SKProductsRequest itself
|
|
pr.ReceivedResponse += (object sender, SKProductsRequestResponseEventArgs e) => {};
|
|
|
|
var t = pr.WeakDelegate.GetType ();
|
|
Assert.That (t.Name, Is.EqualTo ("_SKProductsRequestDelegate"), "delegate");
|
|
|
|
var fi = t.GetField ("receivedResponse", BindingFlags.NonPublic | BindingFlags.Instance);
|
|
Assert.NotNull (fi, "receivedResponse");
|
|
var value = fi.GetValue (pr.WeakDelegate);
|
|
Assert.NotNull (value, "value");
|
|
|
|
#if XAMCORE_2_0
|
|
// and on the SKRequest defined one
|
|
pr.RequestFailed += (object sender, SKRequestErrorEventArgs e) => {};
|
|
// and the existing (initial field) is still set
|
|
fi = t.GetField ("receivedResponse", BindingFlags.NonPublic | BindingFlags.Instance);
|
|
Assert.NotNull (fi, "receivedResponse/SKRequest");
|
|
#else
|
|
// In Classic SKRequest also defines a RequestFailed event, so make sure we get the SKRequest one
|
|
// that's because event are re-defined (new) in classic
|
|
((SKRequest) pr).RequestFailed += (object sender, SKRequestErrorEventArgs e) => {};
|
|
|
|
t = pr.WeakDelegate.GetType ();
|
|
Assert.That (t.Name, Is.EqualTo ("_SKRequestDelegate"), "delegate-2");
|
|
|
|
fi = t.GetField ("receivedResponse", BindingFlags.NonPublic | BindingFlags.Instance);
|
|
Assert.Null (fi, "receivedResponse/SKRequest");
|
|
#endif
|
|
}
|
|
}
|
|
#endif // !__WATCHOS__
|
|
|
|
[Test]
|
|
public void Aot_27116 ()
|
|
{
|
|
var nix = (from nic in System.Net.NetworkInformation.NetworkInterface.GetAllNetworkInterfaces ()
|
|
where nic.Id.StartsWith ("en") || nic.Id.StartsWith ("pdp_ip") select nic);
|
|
Assert.NotNull (nix);
|
|
}
|
|
|
|
[Test]
|
|
public void TlsProvider_Legacy ()
|
|
{
|
|
var provider = Mono.Security.Interface.MonoTlsProviderFactory.GetProvider ();
|
|
Assert.NotNull (provider, "provider");
|
|
Assert.That (provider.ID, Is.EqualTo (new Guid ("97d31751-d0b3-4707-99f7-a6456b972a19")), "correct provider");
|
|
}
|
|
|
|
[Test]
|
|
public void OldTlsProvider_Selected ()
|
|
{
|
|
// make test work for classic (monotouch) and unified (iOS, tvOS and watchOS)
|
|
var fqn = typeof (NSObject).AssemblyQualifiedName.Replace ("Foundation.NSObject", "Security.Tls.OldTlsProvider");
|
|
Assert.NotNull (Type.GetType (fqn), "Should be included");
|
|
}
|
|
|
|
[Test]
|
|
public void AppleTls_OptOut ()
|
|
{
|
|
// make test work for classic (monotouch) and unified (iOS, tvOS and watchOS)
|
|
var fqn = typeof (NSObject).AssemblyQualifiedName.Replace ("Foundation.NSObject", "Security.Tls.AppleTlsProvider");
|
|
Assert.Null (Type.GetType (fqn), "Should not be included");
|
|
}
|
|
}
|
|
}
|