Merge pull request #2024 from BogdanovKirill/webrequesttest
[mono.git] / mcs / class / corlib / Test / System.IO / FileStreamTest.cs
index efefdf3c0b3c756239c1f2a1d84f7e2b84d2981f..dca54d652affc4eb71ca1c2c335bc4b7ffdfe327 100644 (file)
@@ -15,6 +15,8 @@ using System;
 using System.IO;
 using System.Runtime.InteropServices;
 using System.Text;
+using System.Threading;
+using Microsoft.Win32.SafeHandles;
 
 namespace MonoTests.System.IO
 {
@@ -42,12 +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 ()
@@ -85,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");
@@ -109,14 +113,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 ("thisfileshouldnotexists.test", FileMode.Open);
+                               stream = new FileStream (file_name, FileMode.Open);
                                Assert.Fail ("#B1");
                        } catch (FileNotFoundException ex) {
                                Assert.AreEqual (typeof (FileNotFoundException), ex.GetType (), "#B2");
-                               // under OSX 'var' is a symlink to 'private/var'
-                               if (MacOSX)
-                                       path = "/private" + path;
                                Assert.AreEqual (path, ex.FileName, "#B3");
                                Assert.IsNull (ex.InnerException, "#B4");
                                Assert.IsNotNull (ex.Message, "#B5");
@@ -133,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 {
@@ -157,14 +166,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 ("thisfileshouldNOTexists.test", FileMode.Truncate);
+                               stream = new FileStream (file_name, FileMode.Truncate);
                                Assert.Fail ("#B1");
                        } catch (FileNotFoundException ex) {
                                Assert.AreEqual (typeof (FileNotFoundException), ex.GetType (), "#B2");
-                               // under OSX 'var' is a symlink to 'private/var'
-                               if (MacOSX)
-                                       path = "/private" + path;
                                Assert.AreEqual (path, ex.FileName, "#B3");
                                Assert.IsNull (ex.InnerException, "#B4");
                                Assert.IsNotNull (ex.Message, "#B5");
@@ -181,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 {
@@ -207,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");
@@ -325,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");
@@ -704,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 ()
                {
@@ -716,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 ()
                {
@@ -766,7 +790,6 @@ namespace MonoTests.System.IO
                }
 
                [Test]
-               [Category("TargetJvmNotSupported")] // File sharing not supported for TARGET_JVM
                [ExpectedException (typeof (IOException))]
                public void CtorAccess1Read2Write ()
                {
@@ -792,7 +815,6 @@ namespace MonoTests.System.IO
                }
 
                [Test]
-               [Category("TargetJvmNotSupported")] // File sharing not supported for TARGET_JVM
                [ExpectedException (typeof (IOException))]
                public void CtorAccess1Write2Write ()
                {
@@ -1020,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";
@@ -1309,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]
@@ -1329,7 +1349,6 @@ namespace MonoTests.System.IO
                        Assert.AreEqual ((int) '1', s.ReadByte ());
                        s.Close ();
                }
-#endif // TARGET_JVM
 
                private void DeleteFile (string path)
                {
@@ -1445,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 ()
@@ -1491,7 +1508,6 @@ namespace MonoTests.System.IO
                }
 
                [Test]
-               [Category("TargetJvmNotSupported")] // Async IO not supported for TARGET_JVM
                [ExpectedException (typeof (ObjectDisposedException))]
                public void BeginRead_Disposed ()
                {
@@ -1503,7 +1519,6 @@ namespace MonoTests.System.IO
                }
 
                [Test]
-               [Category("TargetJvmNotSupported")] // Async IO not supported for TARGET_JVM
                [ExpectedException (typeof (ObjectDisposedException))]
                public void BeginWrite_Disposed ()
                {
@@ -1514,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 ()
                {
@@ -1527,7 +1570,6 @@ namespace MonoTests.System.IO
                }
 
                [Test]
-               [Category("TargetJvmNotSupported")] // File locking not supported for TARGET_JVM
                [ExpectedException (typeof (ObjectDisposedException))]
                public void Unlock_Disposed ()
                {
@@ -1590,7 +1632,6 @@ namespace MonoTests.System.IO
                        }
                }
 
-               [Category("TargetJvmNotSupported")] // FileOptions.DeleteOnClose not supported for TARGET_JVM
                [Test]
                public void DeleteOnClose ()
                {
@@ -1603,5 +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
        }
 }