[MSBuild] Fix minor assembly resolution issue
[mono.git] / mcs / class / corlib / Test / System.Runtime.InteropServices / SafeHandleTest.cs
index cc2488a647cd9a3f127a5a9491549966298c46ba..da5c093e24b778a265325f16b15b4878dd39ff54 100644 (file)
@@ -6,7 +6,6 @@
 //
 // Copyright (C) 2004-2006 Novell, Inc (http://www.novell.com)
 //
-#if NET_2_0
 using NUnit.Framework;
 using System;
 using System.Runtime.InteropServices;
@@ -25,6 +24,7 @@ namespace MonoTests.System.Runtime.InteropServices
                public class FakeSafeHandle : SafeHandleZeroOrMinusOneIsInvalid
                {
                        public bool released = false;
+                       public bool disposed = false;
                        
                        public FakeSafeHandle (): base (true)
                        {
@@ -34,16 +34,27 @@ namespace MonoTests.System.Runtime.InteropServices
                        {
                        }
 
+                       public void ChangeHandle (IntPtr hnd)
+                       {
+                               this.handle = hnd;
+                       }
+
                        protected override bool ReleaseHandle ()
                        {
                                released = true;
                                return true;
                        }
+
+                       protected override void Dispose (bool manual)
+                       {
+                               disposed = true;
+                               base.Dispose (manual);
+                       }
                }
                
                [Test]
                [ExpectedException (typeof (ObjectDisposedException))]
-               public void Dispose1 ()
+               public void BadDispose1 ()
                {
                        FakeSafeHandle sf = new FakeSafeHandle ();
 
@@ -53,21 +64,201 @@ namespace MonoTests.System.Runtime.InteropServices
 
                [Test]
                [ExpectedException (typeof (ObjectDisposedException))]
-               public void Dispose2 ()
+               public void BadDispose2 ()
                {
                        FakeSafeHandle sf = new FakeSafeHandle ();
 
-                       sf.DangerousRelease ();
                        sf.Close ();
+                       sf.DangerousRelease ();
                }
 
                [Test]
                [ExpectedException (typeof (ObjectDisposedException))]
-               public void Dispose3 ()
+               public void BadDispose3 ()
+               {
+                       FakeSafeHandle sf = new FakeSafeHandle ();
+
+                       sf.Dispose ();
+                       sf.DangerousRelease ();
+               }
+
+               [Test]
+               public void MultipleDisposes ()
+               {
+                       FakeSafeHandle sf = new FakeSafeHandle ();
+
+                       sf.Dispose ();
+                       sf.Dispose ();
+                       sf.Dispose ();
+               }
+
+               [Test]
+               public void CloseWillDispose ()
                {
                        FakeSafeHandle sf = new FakeSafeHandle ();
 
                        sf.Close ();
+                       Assert.IsTrue (sf.disposed, "disposed");
+               }
+
+               [Test]
+               public void GoodDispose ()
+               {
+                       int dummyHandle = 0xDEAD;
+                       FakeSafeHandle sf = new FakeSafeHandle ();
+                       sf.ChangeHandle (new IntPtr (dummyHandle));
+                       Assert.AreEqual ((int)sf.DangerousGetHandle(), dummyHandle, "handle");
+
+                       sf.DangerousRelease ();
+
+                       try {
+                               sf.Close ();
+                               Assert.Fail ("#1");
+                       } catch (ObjectDisposedException) {
+                       }
+
+                       try {
+                               sf.Dispose ();
+                               Assert.Fail ("#2");
+                       } catch (ObjectDisposedException) {
+                       }
+
+                       //In Ms.Net SafeHandle does not change the value of the handle after being SetInvalid or Disposed.
+                       Assert.AreEqual ((int)sf.DangerousGetHandle(), dummyHandle, "handle");
+                       //Handle was closed properly.
+                       Assert.IsTrue (sf.released, "released");
+                       Assert.IsTrue (sf.IsClosed, "closed");
+                       //Handle value is not changed, so the value itself is still valid (not 0 or -1)
+                       Assert.IsFalse (sf.IsInvalid, "invalid");
+               }
+
+               [Test]
+               public void SetHandleAsInvalid ()
+               {
+                       int dummyHandle = 0xDEAD;
+                       FakeSafeHandle sf = new FakeSafeHandle ();
+
+                       sf.ChangeHandle (new IntPtr (dummyHandle));
+                       Assert.AreEqual ((int)sf.DangerousGetHandle(), dummyHandle, "handle");
+
+                       sf.SetHandleAsInvalid();
+
+                       //In Ms.Net SafeHandle does not change the value of the handle after being SetInvalid or Disposed.
+                       Assert.AreEqual ((int)sf.DangerousGetHandle(), dummyHandle, "handle");
+                       //Released == false since handle was not released, Set Invalid was called before it could be released.
+                       Assert.IsFalse (sf.released, "released");
+                       //IsClosed == true since handle is pointing to a disposed or invalid object.
+                       Assert.IsTrue (sf.IsClosed, "closed");
+                       //Handle value is not changed, so the value itself is still valid (not 0 or -1)
+                       Assert.IsFalse (sf.IsInvalid, "invalid");
+               }
+
+               [Test]
+               public void SetInvalidDispose ()
+               {
+                       int dummyHandle = 0xDEAD;
+                       FakeSafeHandle sf = new FakeSafeHandle (true);
+
+                       sf.ChangeHandle (new IntPtr (dummyHandle));
+                       Assert.AreEqual ((int)sf.DangerousGetHandle(), dummyHandle, "handle");
+
+                       sf.SetHandleAsInvalid();
+                       sf.Dispose ();
+
+                       //In Ms.Net SafeHandle does not change the value of the handle after being SetInvalid or Disposed.
+                       Assert.AreEqual ((int)sf.DangerousGetHandle(), dummyHandle, "handle");
+                       //Released == false since handle was not released, Set Invalid was called before it could be released.
+                       Assert.IsFalse (sf.released, "released");
+                       //IsClosed == true since handle is pointing to a disposed or invalid object.
+                       Assert.IsTrue (sf.IsClosed, "closed");
+                       //Handle value is not changed, so the value itself is still valid (not 0 or -1)
+                       Assert.IsFalse (sf.IsInvalid, "invalid");
+               }
+
+               [Test]
+               public void SetInvalidRelease1 ()
+               {
+                       FakeSafeHandle sf = new FakeSafeHandle (true);
+
+                       bool success = false;
+                       sf.DangerousAddRef(ref success);
+                       Assert.IsTrue (success, "dar");
+
+                       sf.SetHandleAsInvalid();
+
+                       Assert.IsFalse (sf.released, "released");
+                       Assert.IsTrue (sf.IsClosed, "closed");
+
+                       //Allow remaining refs to be released after SetHandleAsInvalid
+                       sf.DangerousRelease ();
+                       sf.DangerousRelease ();
+
+                       Assert.IsFalse (sf.released, "released");
+                       Assert.IsTrue (sf.IsClosed, "closed");
+               }
+
+               [Test]
+               [ExpectedException (typeof (ObjectDisposedException))]
+               public void SetInvalidRelease2 ()
+               {
+                       FakeSafeHandle sf = new FakeSafeHandle (true);
+
+                       bool success = false;
+                       sf.DangerousAddRef(ref success);
+                       Assert.IsTrue (success, "dar");
+
+                       sf.SetHandleAsInvalid();
+                       sf.DangerousRelease ();
+                       sf.DangerousRelease ();
+
+                       //This release need to throw ObjectDisposedException.
+                       //No more ref to release.
+                       sf.DangerousRelease ();
+               }
+
+               [Test]
+               public void ReleaseAfterDispose1 ()
+               {
+                       int dummyHandle = 0xDEAD;
+                       FakeSafeHandle sf = new FakeSafeHandle (true);
+                       sf.ChangeHandle (new IntPtr (dummyHandle));
+                       Assert.AreEqual ((int)sf.DangerousGetHandle(), dummyHandle, "handle");
+
+                       bool success = false;
+                       sf.DangerousAddRef(ref success);
+                       Assert.IsTrue (success, "dar");
+
+                       sf.Dispose ();
+                       //Still one ref left.
+                       Assert.IsFalse (sf.released, "released");
+                       Assert.IsFalse (sf.IsClosed, "closed");
+
+                       sf.DangerousRelease ();
+                       //In Ms.Net SafeHandle does not change the value of the handle after being SetInvalid or Disposed.
+                       Assert.AreEqual ((int)sf.DangerousGetHandle(), dummyHandle, "handle");
+                       //Handle was closed properly.
+                       Assert.IsTrue (sf.released, "released");
+                       Assert.IsTrue (sf.IsClosed, "closed");
+                       //Handle value is not changed, so the value itself is still valid (not 0 or -1)
+                       Assert.IsFalse (sf.IsInvalid, "invalid");
+               }
+
+               [Test]
+               [ExpectedException (typeof (ObjectDisposedException))]
+               public void ReleaseAfterDispose2 ()
+               {
+                       FakeSafeHandle sf = new FakeSafeHandle (true);
+
+                       bool success = false;
+                       sf.DangerousAddRef(ref success);
+                       Assert.IsTrue (success, "dar");
+
+                       sf.Dispose ();
+
+                       sf.DangerousRelease ();
+
+                       //Second release need to throw ObjectDisposedException.
+                       //No more ref to release.
                        sf.DangerousRelease ();
                }
 
@@ -77,15 +268,18 @@ namespace MonoTests.System.Runtime.InteropServices
                        FakeSafeHandle sf = new FakeSafeHandle (false);
 
                        sf.Close ();
-                       Assert.AreEqual (sf.released, false, "r1");
+                       Assert.IsFalse (sf.released, "r1");
+                       Assert.IsTrue (sf.IsClosed, "c1");
 
                        sf = new FakeSafeHandle (false);
                        sf.DangerousRelease ();
-                       Assert.AreEqual (sf.released, false, "r2");
+                       Assert.IsFalse (sf.released, "r2");
+                       Assert.IsTrue (sf.IsClosed, "c2");
 
                        sf = new FakeSafeHandle (false);
                        ((IDisposable) sf).Dispose ();
-                       Assert.AreEqual (sf.released, false, "r3");
+                       Assert.IsFalse (sf.released, "r3");
+                       Assert.IsTrue (sf.IsClosed, "c3");
                }
 
                //
@@ -100,30 +294,14 @@ namespace MonoTests.System.Runtime.InteropServices
                [Test]
                public void DangerousAddRefOnNewInstance ()
                {
-                       var h = new IntPtrSafe ();
-                       var success = false;
-                       h.DangerousAddRef (ref success);
-                       Assert.AreEqual (success, true, "daroni");
-               }
-               
-               public class IntPtrSafe : SafeHandle {
-                       public IntPtrSafe() : base(IntPtr.Zero, true)
-                       {
-                       }
-
-                       protected override bool ReleaseHandle()
-                       {
-                               return true;
-                       }
-
-                       public IntPtr Handle { get; set; }
+                       FakeSafeHandle sf = new FakeSafeHandle ();
+                       sf.ChangeHandle (IntPtr.Zero);
+                       Assert.IsTrue (sf.IsInvalid, "invalid");
 
-                       public override bool IsInvalid
-                       {
-                               get { return Handle == IntPtr.Zero; }
-                       }
+                       bool success = false;
+                       sf.DangerousAddRef (ref success);
+                       Assert.IsTrue (success, "daroni");
                }
        }
 }
 
-#endif