[Tests] Fail with message in case symlink fails
[mono.git] / mcs / class / corlib / Test / System.IO / FileTest.cs
index b926c3c71e0ccb246fdf121dc15e24076e8f68e0..7e01ce544d7240a073f1ca6fbc32d2cf3cb54c71 100644 (file)
@@ -14,6 +14,8 @@ using System;
 using System.IO;
 using System.Globalization;
 using System.Threading;
+using System.Runtime.InteropServices;
+
 
 using NUnit.Framework;
 
@@ -530,6 +532,12 @@ namespace MonoTests.System.IO
                        }
                }
 
+               [Test]
+               public void Delete_NonExisting_NoException ()
+               {
+                       File.Delete (Path.Combine (Directory.GetDirectoryRoot (Directory.GetCurrentDirectory ()), "monononexistingfile.dat"));
+               }
+
                [Test]
                public void GetAttributes_Archive ()
                {
@@ -2491,6 +2499,7 @@ namespace MonoTests.System.IO
                }
 
                [Test]
+               [Category ("LargeFileSupport")]
                public void Position_Large ()
                {
                        // fails if HAVE_LARGE_FILE_SUPPORT is not enabled in device builds
@@ -2513,6 +2522,7 @@ namespace MonoTests.System.IO
                }
 
                [Test]
+               [Category ("LargeFileSupport")]
                public void Seek_Large ()
                {
                        // fails if HAVE_LARGE_FILE_SUPPORT is not enabled in device builds
@@ -2537,6 +2547,7 @@ namespace MonoTests.System.IO
                }
 
                [Test]
+               [Category ("LargeFileSupport")]
                public void Lock_Large ()
                {
                        // note: already worked without HAVE_LARGE_FILE_SUPPORT
@@ -2677,5 +2688,55 @@ namespace MonoTests.System.IO
                        MoveTest (FileAccess.ReadWrite, FileShare.Write | FileShare.Delete, true);
                        MoveTest (FileAccess.ReadWrite, FileShare.ReadWrite | FileShare.Delete, true);
                }
+
+
+               [DllImport ("libc", SetLastError=true)]
+               public static extern int symlink (string oldpath, string newpath);
+
+               [Test]
+               public void SymLinkLoop ()
+               {
+                       if (!RunningOnUnix)
+                               Assert.Ignore ("Symlink are hard on windows");
+
+                       var name1 = Path.GetRandomFileName ();
+                       var name2 = Path.GetRandomFileName ();
+
+                       var path1 = Path.Combine (Path.GetTempPath (), name1);
+                       var path2 = Path.Combine (Path.GetTempPath (), name2);
+
+                       File.Delete (path1);
+                       File.Delete (path2);
+
+                       try {
+                               if (symlink (path1, path2) != 0)
+                                       Assert.Fail ("symlink #1 failed with errno={0}", Marshal.GetLastWin32Error ());
+                               if (symlink (path2, path1) != 0)
+                                       Assert.Fail ("symlink #2 failed with errno={0}", Marshal.GetLastWin32Error ());
+
+                               Assert.IsTrue (File.Exists (path1), "File.Exists must return true for path1 symlink loop");
+                               Assert.IsTrue (File.Exists (path2), "File.Exists must return true for path2 symlink loop");
+
+                               try {
+                                       using (var f = File.Open (path1, FileMode.Open, FileAccess.Read)) {
+                                               Assert.Fail ("File.Open must throw for symlink loops");
+                                       }
+                               } catch (IOException ex) {
+                                       Assert.AreEqual (0x80070781u, (uint)ex.HResult, "Ensure HRESULT is correct");
+                               }
+
+                               File.Delete (path1); //Delete must not throw and must work
+                               Assert.IsFalse (File.Exists (path1), "File.Delete must delete symlink loops");
+
+                       } finally {
+                               try {
+                                       File.Delete (path1);
+                                       File.Delete (path2);
+                               } catch (IOException) {
+                                       //Don't double fault any exception from the tests.
+                               }
+
+                       }
+               }
        }
 }