2 // System.Runtime.InteropServices.GCHandle Test Cases
5 // Paolo Molaro (lupus@ximian.com)
7 // Copyright (C) 2005, 2009 Novell, Inc (http://www.novell.com)
10 using NUnit.Framework;
12 using System.Reflection;
13 using System.Runtime.InteropServices;
14 using System.Globalization;
16 namespace MonoTests.System.Runtime.InteropServices
19 public class GCHandleTest
21 // Expected warning, the tests that reference this handle are testing for the default values of the object
22 #pragma warning disable 649
23 static GCHandle handle;
24 #pragma warning restore 649
27 public void DefaultZeroValue_Allocated ()
29 Assert.IsFalse (handle.IsAllocated, "IsAllocated");
33 [ExpectedException (typeof (InvalidOperationException))]
34 public void DefaultZeroValue_Target ()
36 Assert.IsNull (handle.Target, "Target");
40 public void AllocNull ()
42 IntPtr ptr = (IntPtr) GCHandle.Alloc (null);
43 Assert.IsFalse (ptr == IntPtr.Zero, "ptr");
44 GCHandle gch = (GCHandle) ptr;
45 Assert.IsTrue (gch.IsAllocated, "IsAllocated");
46 Assert.IsNull (gch.Target, "Target");
50 public void AllocNullWeakTrack ()
52 GCHandle gch = GCHandle.Alloc (null, GCHandleType.WeakTrackResurrection);
53 Assert.IsTrue (gch.IsAllocated, "IsAllocated");
54 Assert.IsNull (gch.Target, "Target");
58 [ExpectedException (typeof (InvalidOperationException))]
59 public void AddrOfPinnedObjectNormal ()
61 GCHandle handle = GCHandle.Alloc (new Object (), GCHandleType.Normal);
63 IntPtr ptr = handle.AddrOfPinnedObject();
71 [ExpectedException (typeof (InvalidOperationException))]
72 public void AddrOfPinnedObjectWeak ()
74 GCHandle handle = GCHandle.Alloc (new Object (), GCHandleType.Weak);
76 IntPtr ptr = handle.AddrOfPinnedObject();
84 [ExpectedException (typeof (InvalidOperationException))]
85 public void AddrOfPinnedObjectWeakTrackResurrection ()
87 GCHandle handle = GCHandle.Alloc (new Object (), GCHandleType.WeakTrackResurrection);
89 IntPtr ptr = handle.AddrOfPinnedObject();
97 public void AddrOfPinnedObjectNull ()
99 GCHandle handle = GCHandle.Alloc (null, GCHandleType.Pinned);
101 IntPtr ptr = handle.AddrOfPinnedObject();
102 Assert.AreEqual (new IntPtr (0), ptr);
110 [Ignore ("throw non-catchable ExecutionEngineException")]
111 [ExpectedException (typeof (ExecutionEngineException))]
112 public void AllocMinusOne ()
114 // -1 is a special value used by the mono runtime
115 // looks like it's special too in MS CLR (since it will crash)
116 GCHandle.Alloc (null, (GCHandleType) (-1));
120 public void AllocInvalidType ()
122 GCHandle gch = GCHandle.Alloc (null, (GCHandleType) Int32.MinValue);
124 Assert.IsTrue (gch.IsAllocated, "IsAllocated");
125 Assert.IsNull (gch.Target, "Target");
131 #if !MONOTOUCH && !MOBILE_STATIC
133 [Category("MobileNotWorking")] // SIGSEGV, probably on AppDomain.Unload
134 public void WeakHandleWorksOnNonRootDomain ()
136 //Console.WriteLine("current app domain: " + AppDomain.CurrentDomain.Id);
137 AppDomain domain = AppDomain.CreateDomain("testdomain");
139 Assembly ea = Assembly.GetExecutingAssembly ();
140 domain.CreateInstanceFrom (ea.CodeBase,
141 typeof (AssemblyResolveHandler).FullName,
143 BindingFlags.Public | BindingFlags.Instance,
145 new object [] { ea.Location, ea.FullName },
146 CultureInfo.InvariantCulture,
151 var testerType = typeof (CrossDomainGCHandleRunner);
152 var r = (CrossDomainGCHandleRunner)domain.CreateInstanceAndUnwrap (
153 testerType.Assembly.FullName, testerType.FullName, false,
154 BindingFlags.Public | BindingFlags.Instance, null, new object [0],
155 CultureInfo.InvariantCulture, new object [0], null);
158 Assert.IsTrue (r.RunTest (), "#1");
159 AppDomain.Unload (domain);
162 public class CrossDomainGCHandleRunner : MarshalByRefObject {
163 public bool RunTest () {
164 object o = new object();
165 GCHandle gcHandle = GCHandle.Alloc (o, GCHandleType.Weak);
166 IntPtr intPtr = (IntPtr)gcHandle;
169 object target = GCHandle.FromIntPtr(intPtr).Target;
171 } catch (Exception) {}
177 class AssemblyResolveHandler
179 public AssemblyResolveHandler (string assemblyFile, string assemblyName)
181 _assemblyFile = assemblyFile;
182 _assemblyName = assemblyName;
184 AppDomain.CurrentDomain.AssemblyResolve +=
185 new ResolveEventHandler (ResolveAssembly);
188 private Assembly ResolveAssembly (object sender, ResolveEventArgs args)
190 if (args.Name == _assemblyName)
191 return Assembly.LoadFrom (_assemblyFile);
196 private readonly string _assemblyFile;
197 private readonly string _assemblyName;