Merge pull request #2024 from BogdanovKirill/webrequesttest
[mono.git] / mcs / class / corlib / Test / System.IO / FileStreamTest.cs
index 3a7ec1c8d7b433f1fecf47fa19ade9888b72804b..dca54d652affc4eb71ca1c2c335bc4b7ffdfe327 100644 (file)
@@ -7,15 +7,16 @@
 // 
 // (C) Ville Palo
 // (c) 2003 Ximian, Inc. (http://www.ximian.com)
+// Copyright 2011 Xamarin Inc (http://www.xamarin.com).
 // 
 
 using NUnit.Framework;
 using System;
 using System.IO;
+using System.Runtime.InteropServices;
 using System.Text;
-#if NET_2_0
+using System.Threading;
 using Microsoft.Win32.SafeHandles;
-#endif
 
 namespace MonoTests.System.IO
 {
@@ -24,6 +25,10 @@ namespace MonoTests.System.IO
        {
                string TempFolder = Path.Combine (Path.GetTempPath (), "MonoTests.System.IO.Tests");
                static readonly char DSC = Path.DirectorySeparatorChar;
+               static bool MacOSX = false;
+
+               [DllImport ("libc")]
+               static extern int uname (IntPtr buf);
 
                [TearDown]
                public void TearDown ()
@@ -39,6 +44,13 @@ namespace MonoTests.System.IO
                                Directory.Delete (TempFolder, true);
 
                        Directory.CreateDirectory (TempFolder);
+#if !MOBILE                    
+                       // from XplatUI.cs
+                       IntPtr buf = Marshal.AllocHGlobal (8192);
+                       if (uname (buf) == 0)
+                               MacOSX = Marshal.PtrToStringAnsi (buf) == "Darwin";
+                       Marshal.FreeHGlobal (buf);
+#endif
                }
 
                public void TestCtr ()
@@ -76,12 +88,13 @@ namespace MonoTests.System.IO
                [Test]
                public void CtorFileNotFoundException_Mode_Open ()
                {
+                       const string file_name = "thisfileshouldnotexist.test";
                        // absolute path
-                       string path = TempFolder + DSC + "thisfileshouldnotexists.test";
+                       string path = TempFolder + DSC + file_name;
                        DeleteFile (path);
                        FileStream stream = null;
                        try {
-                               stream = new FileStream (TempFolder + DSC + "thisfileshouldnotexists.test", FileMode.Open);
+                               stream = new FileStream (TempFolder + DSC + file_name, FileMode.Open);
                                Assert.Fail ("#A1");
                        } catch (FileNotFoundException ex) {
                                Assert.AreEqual (typeof (FileNotFoundException), ex.GetType (), "#A2");
@@ -100,8 +113,15 @@ namespace MonoTests.System.IO
                        // relative path
                        string orignalCurrentDir = Directory.GetCurrentDirectory ();
                        Directory.SetCurrentDirectory (TempFolder);
+
+                       // If TempFolder is a symlink, Mono will follow it and ex.FileName below will contain
+                       // the real directory name, not that of the TempFolder symlink and the test will fail
+                       // (happens e.g. on Android M)
+                       string realTempDir = Directory.GetCurrentDirectory ();
+                       path = realTempDir + DSC + file_name;
+
                        try {
-                               stream = new FileStream ("thisfileshouldnotexists.test", FileMode.Open);
+                               stream = new FileStream (file_name, FileMode.Open);
                                Assert.Fail ("#B1");
                        } catch (FileNotFoundException ex) {
                                Assert.AreEqual (typeof (FileNotFoundException), ex.GetType (), "#B2");
@@ -121,8 +141,9 @@ namespace MonoTests.System.IO
                [Test]
                public void CtorFileNotFoundException_Mode_Truncate ()
                {
+                       const string file_name = "thisfileshouldNOTexist.test";
                        // absolute path
-                       string path = TempFolder + DSC + "thisfileshouldNOTexists.test";
+                       string path = TempFolder + DSC + file_name;
                        DeleteFile (path);
                        FileStream stream = null;
                        try {
@@ -145,8 +166,15 @@ namespace MonoTests.System.IO
                        // relative path
                        string orignalCurrentDir = Directory.GetCurrentDirectory ();
                        Directory.SetCurrentDirectory (TempFolder);
+
+                       // If TempFolder is a symlink, Mono will follow it and ex.FileName below will contain
+                       // the real directory name, not that of the TempFolder symlink and the test will fail
+                       // (happens e.g. on Android M)
+                       string realTempDir = Directory.GetCurrentDirectory ();
+                       path = realTempDir + DSC + file_name;
+
                        try {
-                               stream = new FileStream ("thisfileshouldNOTexists.test", FileMode.Truncate);
+                               stream = new FileStream (file_name, FileMode.Truncate);
                                Assert.Fail ("#B1");
                        } catch (FileNotFoundException ex) {
                                Assert.AreEqual (typeof (FileNotFoundException), ex.GetType (), "#B2");
@@ -166,8 +194,9 @@ namespace MonoTests.System.IO
                [Test]
                public void CtorIOException1 ()
                {
+                       const string file_name = "thisfileshouldexists.test";
                        // absolute path
-                       string path = TempFolder + DSC + "thisfileshouldexists.test";
+                       string path = TempFolder + DSC + file_name;
                        FileStream stream = null;
                        DeleteFile (path);
                        try {
@@ -192,11 +221,18 @@ namespace MonoTests.System.IO
                        // relative path
                        string orignalCurrentDir = Directory.GetCurrentDirectory ();
                        Directory.SetCurrentDirectory (TempFolder);
+
+                       // If TempFolder is a symlink, Mono will follow it and ex.FileName below will contain
+                       // the real directory name, not that of the TempFolder symlink and the test will fail
+                       // (happens e.g. on Android M)
+                       string realTempDir = Directory.GetCurrentDirectory ();
+                       path = realTempDir + DSC + file_name;
+
                        try {
-                               stream = new FileStream ("thisfileshouldexists.test", FileMode.CreateNew);
+                               stream = new FileStream (file_name, FileMode.CreateNew);
                                stream.Close ();
                                stream = null;
-                               stream = new FileStream ("thisfileshouldexists.test", FileMode.CreateNew);
+                               stream = new FileStream (file_name, FileMode.CreateNew);
                                Assert.Fail ("#B1");
                        } catch (IOException ex) {
                                Assert.AreEqual (typeof (IOException), ex.GetType (), "#B2");
@@ -310,8 +346,14 @@ namespace MonoTests.System.IO
                {
                        string orignalCurrentDir = Directory.GetCurrentDirectory ();
                        Directory.SetCurrentDirectory (TempFolder);
+
+                       // If TempFolder is a symlink, Mono will follow it and ex.FileName below will contain
+                       // the real directory name, not that of the TempFolder symlink and the test will fail
+                       // (happens e.g. on Android M)
+                       string realTempDir = Directory.GetCurrentDirectory ();
+                       
                        string relativePath = "DirectoryDoesNotExist" + Path.DirectorySeparatorChar + "file.txt";
-                       string fullPath = Path.Combine (TempFolder, relativePath);
+                       string fullPath = Path.Combine (realTempDir, relativePath);
                        try {
                                new FileStream (relativePath, FileMode.Open);
                                Assert.Fail ("#A1");
@@ -327,14 +369,8 @@ namespace MonoTests.System.IO
                }
 
                [Test]
-#if NET_2_0
                // FileShare.Inheritable is ignored, but file does not exist
                [ExpectedException (typeof (FileNotFoundException))]
-#else
-               // share: Enum value was out of legal range.
-               // (FileShare.Inheritable is not valid)
-               [ExpectedException (typeof (ArgumentOutOfRangeException))]
-#endif
                public void CtorArgumentOutOfRangeException3 ()
                {
                        string path = TempFolder + DSC + "CtorArgumentOutOfRangeException1";
@@ -409,14 +445,8 @@ namespace MonoTests.System.IO
 
 
                [Test]
-#if NET_2_0
                // FileShare.Inheritable is ignored, but file does not exist
                [ExpectedException (typeof (FileNotFoundException))]
-#else
-               // share: Enum value was out of legal range.
-               // (FileShare.Inheritable is not valid)
-               [ExpectedException (typeof (ArgumentOutOfRangeException))]
-#endif
                public void CtorArgumentOutOfRangeException5 ()
                {
                        string path = TempFolder + Path.DirectorySeparatorChar + "temp";
@@ -452,32 +482,6 @@ namespace MonoTests.System.IO
                        }
                }
 
-#if NET_2_0
-               [Test]
-               [ExpectedException (typeof (NullReferenceException))]
-               public void CtorSafeHandleException1 ()
-               {
-                       // .NET doesn't check for null here, so won't we
-                       SafeFileHandle sfh = null;
-                       FileStream fs = new FileStream (sfh, FileAccess.Read, 1, false);
-               }
-
-               [Test]
-               [ExpectedException (typeof (ArgumentException))]
-               public void CtorSafeHandleException2 ()
-               {
-                       SafeFileHandle sfh = new SafeFileHandle ((IntPtr)0, true);
-                       FileStream fs = new FileStream (sfh, FileAccess.Read, 1, false);
-               }
-
-               [Test]
-               [ExpectedException (typeof (ArgumentException))]
-               public void CtorSafeHandleException3 ()
-               {
-                       SafeFileHandle sfh = new SafeFileHandle ((IntPtr)(-1), true);
-                       FileStream fs = new FileStream (sfh, FileAccess.Read, 1, false);
-               }
-#endif
                [Test]
                public void ModeAndAccessCombinations ()
                {
@@ -727,7 +731,6 @@ namespace MonoTests.System.IO
                        }
                }
 
-#if !TARGET_JVM // No support IntPtr file handles under TARGET_JVM
                [Test, ExpectedException (typeof (IOException))]
                public void CtorIOException2 ()
                {
@@ -739,9 +742,7 @@ namespace MonoTests.System.IO
                                        stream.Close ();
                        }
                }
-#endif // TARGET_JVM
 
-               [Category("TargetJvmNotSupported")] // File sharing not supported for TARGET_JVM
                [Test, ExpectedException (typeof (IOException))]
                public void CtorIOException ()
                {
@@ -789,7 +790,6 @@ namespace MonoTests.System.IO
                }
 
                [Test]
-               [Category("TargetJvmNotSupported")] // File sharing not supported for TARGET_JVM
                [ExpectedException (typeof (IOException))]
                public void CtorAccess1Read2Write ()
                {
@@ -815,7 +815,6 @@ namespace MonoTests.System.IO
                }
 
                [Test]
-               [Category("TargetJvmNotSupported")] // File sharing not supported for TARGET_JVM
                [ExpectedException (typeof (IOException))]
                public void CtorAccess1Write2Write ()
                {
@@ -850,7 +849,6 @@ namespace MonoTests.System.IO
                        }
                }
 
-#if NET_2_0
                [Test] // bug #79250
                public void FileShare_Delete ()
                {
@@ -881,7 +879,6 @@ namespace MonoTests.System.IO
                                File.Delete (fn);
                        }
                }
-#endif
 
                [Test]
                public void Write ()
@@ -1045,7 +1042,6 @@ namespace MonoTests.System.IO
                        DeleteFile (path);
                }
 
-               [Category("TargetJvmNotSupported")] // File locking not supported for TARGET_JVM
                public void TestLock ()
                {
                        string path = TempFolder + Path.DirectorySeparatorChar + "TestLock";
@@ -1334,7 +1330,6 @@ namespace MonoTests.System.IO
                        }
                }
 
-#if !TARGET_JVM // No support IntPtr file handles under TARGET_JVM
                // Check that the stream is flushed even when it doesn't own the
                // handle
                [Test]
@@ -1354,7 +1349,6 @@ namespace MonoTests.System.IO
                        Assert.AreEqual ((int) '1', s.ReadByte ());
                        s.Close ();
                }
-#endif // TARGET_JVM
 
                private void DeleteFile (string path)
                {
@@ -1470,14 +1464,12 @@ namespace MonoTests.System.IO
                        }
                }
 
-#if !TARGET_JVM // No support IntPtr file handles under TARGET_JVM
                [Test]
                [ExpectedException (typeof (ArgumentException))]
                public void Constructor_InvalidFileHandle ()
                {
                        new FileStream ((IntPtr) (-1L), FileAccess.Read);
                }
-#endif // TARGET_JVM
 
                [Test]
                public void PositionAfterSetLength ()
@@ -1516,7 +1508,6 @@ namespace MonoTests.System.IO
                }
 
                [Test]
-               [Category("TargetJvmNotSupported")] // Async IO not supported for TARGET_JVM
                [ExpectedException (typeof (ObjectDisposedException))]
                public void BeginRead_Disposed ()
                {
@@ -1528,7 +1519,6 @@ namespace MonoTests.System.IO
                }
 
                [Test]
-               [Category("TargetJvmNotSupported")] // Async IO not supported for TARGET_JVM
                [ExpectedException (typeof (ObjectDisposedException))]
                public void BeginWrite_Disposed ()
                {
@@ -1539,8 +1529,36 @@ namespace MonoTests.System.IO
                        stream.EndWrite (stream.BeginWrite (new byte[8], 0, 8, null, null));
                }
 
+               static IAsyncResult DoBeginWrite(Stream stream, ManualResetEvent mre, byte[] RandomBuffer)
+               {
+                       return stream.BeginWrite (RandomBuffer, 0, RandomBuffer.Length, ar => {
+                               stream.EndWrite (ar);
+
+                               // we don't supply an ManualResetEvent so this will throw an NRE on the second run
+                               // which nunit-console will ignore (but other test runners don't like that)
+                               if (mre == null)
+                                       return;
+
+                               DoBeginWrite (stream, null, RandomBuffer).AsyncWaitHandle.WaitOne ();
+                               mre.Set ();
+                       }, null);
+               }
+
+               [Test]
+               public void BeginWrite_Recursive ()
+               {
+                       string path = TempFolder + Path.DirectorySeparatorChar + "temp";
+                       DeleteFile (path);
+       
+                       using (FileStream stream = new FileStream (path, FileMode.OpenOrCreate, FileAccess.Write)) {
+                               var mre = new ManualResetEvent (false); 
+                               var RandomBuffer = new byte[1024];                      
+                               DoBeginWrite (stream, mre, RandomBuffer);
+                               Assert.IsTrue (mre.WaitOne (5000), "#1");
+                       }
+               }
+
                [Test]
-               [Category("TargetJvmNotSupported")] // File locking not supported for TARGET_JVM
                [ExpectedException (typeof (ObjectDisposedException))]
                public void Lock_Disposed ()
                {
@@ -1552,7 +1570,6 @@ namespace MonoTests.System.IO
                }
 
                [Test]
-               [Category("TargetJvmNotSupported")] // File locking not supported for TARGET_JVM
                [ExpectedException (typeof (ObjectDisposedException))]
                public void Unlock_Disposed ()
                {
@@ -1615,8 +1632,6 @@ namespace MonoTests.System.IO
                        }
                }
 
-#if NET_2_0
-               [Category("TargetJvmNotSupported")] // FileOptions.DeleteOnClose not supported for TARGET_JVM
                [Test]
                public void DeleteOnClose ()
                {
@@ -1629,6 +1644,52 @@ namespace MonoTests.System.IO
                        Assert.AreEqual (false, File.Exists (path), "DOC#2");
                        
                }
+
+#if !MOBILE
+               [Test]
+               public void WriteWithExposedHandle ()
+               {
+                       string path = TempFolder + DSC + "exposed-handle.txt";
+                       FileStream fs1 = null;
+                       FileStream fs2 = null;
+                       DeleteFile (path);
+                       
+                       try {
+                               fs1 = new FileStream (path, FileMode.Create);
+                               fs2 = new FileStream (fs1.SafeFileHandle, FileAccess.ReadWrite);
+                               fs1.WriteByte (Convert.ToByte ('H'));
+                               fs1.WriteByte (Convert.ToByte ('E'));
+                               fs1.WriteByte (Convert.ToByte ('L'));
+                               fs2.WriteByte (Convert.ToByte ('L'));
+                               fs2.WriteByte (Convert.ToByte ('O'));
+                               long fs1Pos = fs1.Position;
+                               fs1.Flush ();
+                               fs2.Flush (); 
+                               fs1.Close ();
+                               fs2.Close ();
+
+                               var check = Encoding.ASCII.GetString (File.ReadAllBytes (path));
+                               Assert.AreEqual ("HELLO", check, "EXPOSED#1");
+                               Assert.AreEqual (5, fs1Pos, "EXPOSED#2");
+                       } finally {
+                               if (fs1 != null)
+                                       fs1.Close ();
+                               if (fs2 != null)
+                                       fs2.Close ();
+                               DeleteFile (path);
+                       }
+               }
+
+               [Test]
+               public void Ctor_InvalidSafeHandle ()
+               {
+                       var sf = new SafeFileHandle (IntPtr.Zero, true);
+                       try {
+                               new FileStream (sf, FileAccess.ReadWrite);
+                               Assert.Fail ("#1");
+                       } catch (ArgumentException) {
+                       }
+               }
 #endif
        }
 }