//
// (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;
+using System.Threading;
+using Microsoft.Win32.SafeHandles;
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 ()
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 ()
}
[Test]
- [ExpectedException (typeof (FileNotFoundException))]
- public void CtorFileNotFoundException1 ()
+ public void CtorFileNotFoundException_Mode_Open ()
{
- string path = TempFolder + DSC + "thisfileshouldnotexists.test";
+ const string file_name = "thisfileshouldnotexist.test";
+ // absolute path
+ 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");
+ Assert.AreEqual (path, ex.FileName, "#A3");
+ Assert.IsNull (ex.InnerException, "#A4");
+ Assert.IsNotNull (ex.Message, "#A5");
+ Assert.IsTrue (ex.Message.IndexOf (path) != -1, "#A6");
+ } finally {
+ if (stream != null) {
+ stream.Close ();
+ stream = null;
+ }
+ DeleteFile (path);
+ }
+
+ // 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 (file_name, FileMode.Open);
+ Assert.Fail ("#B1");
+ } catch (FileNotFoundException ex) {
+ Assert.AreEqual (typeof (FileNotFoundException), ex.GetType (), "#B2");
+ Assert.AreEqual (path, ex.FileName, "#B3");
+ Assert.IsNull (ex.InnerException, "#B4");
+ Assert.IsNotNull (ex.Message, "#B5");
+ Assert.IsTrue (ex.Message.IndexOf (path) != -1, "#B6");
} finally {
+ // restore original current directory
+ Directory.SetCurrentDirectory (orignalCurrentDir);
if (stream != null)
stream.Close ();
DeleteFile (path);
}
[Test]
- [ExpectedException (typeof (FileNotFoundException))]
- public void CtorFileNotFoundException2 ()
+ public void CtorFileNotFoundException_Mode_Truncate ()
{
- string path = TempFolder + DSC + "thisfileshouldNOTexists.test";
+ const string file_name = "thisfileshouldNOTexist.test";
+ // absolute path
+ string path = TempFolder + DSC + file_name;
DeleteFile (path);
FileStream stream = null;
+ try {
+ stream = new FileStream (path, FileMode.Truncate);
+ Assert.Fail ("#A1");
+ } catch (FileNotFoundException ex) {
+ Assert.AreEqual (typeof (FileNotFoundException), ex.GetType (), "#A2");
+ Assert.AreEqual (path, ex.FileName, "#A3");
+ Assert.IsNull (ex.InnerException, "#A4");
+ Assert.IsNotNull (ex.Message, "#A5");
+ Assert.IsTrue (ex.Message.IndexOf (path) != -1, "#A6");
+ } finally {
+ if (stream != null) {
+ stream.Close ();
+ stream = null;
+ }
+ DeleteFile (path);
+ }
+
+ // 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 (TempFolder + DSC + "thisfileshouldNOTexists.test", FileMode.Truncate);
+ stream = new FileStream (file_name, FileMode.Truncate);
+ Assert.Fail ("#B1");
+ } catch (FileNotFoundException ex) {
+ Assert.AreEqual (typeof (FileNotFoundException), ex.GetType (), "#B2");
+ Assert.AreEqual (path, ex.FileName, "#B3");
+ Assert.IsNull (ex.InnerException, "#B4");
+ Assert.IsNotNull (ex.Message, "#B5");
+ Assert.IsTrue (ex.Message.IndexOf (path) != -1, "#B6");
} finally {
+ // restore original current directory
+ Directory.SetCurrentDirectory (orignalCurrentDir);
if (stream != null)
stream.Close ();
-
DeleteFile (path);
}
}
[Test]
- [ExpectedException (typeof (IOException))]
public void CtorIOException1 ()
{
- string path = TempFolder + DSC + "thisfileshouldexists.test";
+ const string file_name = "thisfileshouldexists.test";
+ // absolute path
+ string path = TempFolder + DSC + file_name;
FileStream stream = null;
DeleteFile (path);
try {
stream.Close ();
stream = null;
stream = new FileStream (path, FileMode.CreateNew);
+ Assert.Fail ("#A1");
+ } catch (IOException ex) {
+ Assert.AreEqual (typeof (IOException), ex.GetType (), "#A2");
+ Assert.IsNull (ex.InnerException, "#A3");
+ Assert.IsNotNull (ex.Message, "#A4");
+ Assert.IsTrue (ex.Message.IndexOf (path) != -1, "#A5");
} finally {
+ if (stream != null) {
+ stream.Close ();
+ stream = null;
+ }
+ DeleteFile (path);
+ }
+ // 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 (file_name, FileMode.CreateNew);
+ stream.Close ();
+ stream = null;
+ stream = new FileStream (file_name, FileMode.CreateNew);
+ Assert.Fail ("#B1");
+ } catch (IOException ex) {
+ Assert.AreEqual (typeof (IOException), ex.GetType (), "#B2");
+ Assert.IsNull (ex.InnerException, "#B3");
+ Assert.IsNotNull (ex.Message, "#B4");
+ Assert.IsTrue (ex.Message.IndexOf (path) != -1, "#B5");
+ } finally {
+ // restore original current directory
+ Directory.SetCurrentDirectory (orignalCurrentDir);
if (stream != null)
stream.Close ();
DeleteFile (path);
}
-
}
[Test]
}
[Test]
-#if NET_2_0
+ public void CtorDirectoryNotFound_RelativePath ()
+ {
+ 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 (realTempDir, relativePath);
+ try {
+ new FileStream (relativePath, FileMode.Open);
+ Assert.Fail ("#A1");
+ } catch (DirectoryNotFoundException ex) {
+ Assert.AreEqual (typeof (DirectoryNotFoundException), ex.GetType (), "#A2");
+ Assert.IsNull (ex.InnerException, "#A3");
+ Assert.IsNotNull (ex.Message, "#A4");
+ Assert.IsTrue (ex.Message.IndexOf (fullPath) != -1, "#A5");
+ } finally {
+ // restore original current directory
+ Directory.SetCurrentDirectory (orignalCurrentDir);
+ }
+ }
+
+ [Test]
// 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";
[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";
} catch (FileNotFoundException ex) {
// make sure it is exact this exception, and not a derived type
Assert.AreEqual (typeof (FileNotFoundException), ex.GetType (), "#E2");
+ Assert.AreEqual (path, ex.FileName, "#E3");
+ Assert.IsNull (ex.InnerException, "#E4");
+ Assert.IsNotNull (ex.Message, "#E5");
+ Assert.IsTrue (ex.Message.IndexOf (path) != -1, "#E6");
} finally {
if (stream != null)
stream.Close ();
} catch (FileNotFoundException ex) {
// make sure it is exact this exception, and not a derived type
Assert.AreEqual (typeof (FileNotFoundException), ex.GetType (), "#F2");
+ Assert.AreEqual (path, ex.FileName, "#F3");
+ Assert.IsNull (ex.InnerException, "#F4");
+ Assert.IsNotNull (ex.Message, "#F5");
+ Assert.IsTrue (ex.Message.IndexOf (path) != -1, "#F6");
} finally {
if (stream != null)
stream.Close ();
} catch (FileNotFoundException ex) {
// make sure it is exact this exception, and not a derived type
Assert.AreEqual (typeof (FileNotFoundException), ex.GetType (), "#G2");
+ Assert.AreEqual (path, ex.FileName, "#G3");
+ Assert.IsNull (ex.InnerException, "#G4");
+ Assert.IsNotNull (ex.Message, "#G5");
+ Assert.IsTrue (ex.Message.IndexOf (path) != -1, "#G6");
} finally {
if (stream != null)
stream.Close ();
} catch (FileNotFoundException ex) {
// make sure it is exact this exception, and not a derived type
Assert.AreEqual (typeof (FileNotFoundException), ex.GetType (), "#I2");
+ Assert.AreEqual (path, ex.FileName, "#I3");
+ Assert.IsNull (ex.InnerException, "#I4");
+ Assert.IsNotNull (ex.Message, "#I5");
+ Assert.IsTrue (ex.Message.IndexOf (path) != -1, "#I6");
} finally {
if (stream != null)
stream.Close ();
} catch (FileNotFoundException ex) {
// make sure it is exact this exception, and not a derived type
Assert.AreEqual (typeof (FileNotFoundException), ex.GetType (), "#J2");
+ Assert.AreEqual (path, ex.FileName, "#J3");
+ Assert.IsNull (ex.InnerException, "#J4");
+ Assert.IsNotNull (ex.Message, "#J5");
+ Assert.IsTrue (ex.Message.IndexOf (path) != -1, "#J6");
} finally {
if (stream != null)
stream.Close ();
public void CtorAccess1Read2Write ()
{
string fn = Path.Combine (TempFolder, "temp");
- FileStream fs = null;
+ FileStream fs1 = null;
+ FileStream fs2 = null;
try {
if (!File.Exists (fn)) {
using (TextWriter tw = File.CreateText (fn)) {
tw.Write ("FOO");
}
}
- fs = new FileStream (fn, FileMode.Open, FileAccess.Read);
- fs = new FileStream (fn, FileMode.Create, FileAccess.Write);
+ fs1 = new FileStream (fn, FileMode.Open, FileAccess.Read);
+ fs2 = new FileStream (fn, FileMode.Create, FileAccess.Write);
} finally {
- if (fs != null)
- fs.Close ();
+ if (fs1 != null)
+ fs1.Close ();
+ if (fs2 != null)
+ fs2.Close ();
if (File.Exists (fn))
File.Delete (fn);
}
public void CtorAccess1Write2Write ()
{
string fn = Path.Combine (TempFolder, "temp");
- FileStream fs = null;
+ FileStream fs1 = null;
+ FileStream fs2 = null;
try {
if (File.Exists (fn))
File.Delete (fn);
- fs = new FileStream (fn, FileMode.Create, FileAccess.Write);
- fs = new FileStream (fn, FileMode.Create, FileAccess.Write);
+ fs1 = new FileStream (fn, FileMode.Create, FileAccess.Write);
+ fs2 = new FileStream (fn, FileMode.Create, FileAccess.Write);
} finally {
- if (fs != null)
- fs.Close ();
+ if (fs1 != null)
+ fs1.Close ();
+ if (fs2 != null)
+ fs2.Close ();
if (File.Exists (fn))
File.Delete (fn);
}
}
}
+ [Test] // bug #79250
+ public void FileShare_Delete ()
+ {
+ string fn = Path.Combine (TempFolder, "temp");
+
+ using (Stream s = new FileStream (fn, FileMode.OpenOrCreate, FileAccess.Write, FileShare.Delete)) {
+ s.Write (new byte [1] { 0x5 }, 0, 1);
+ File.Delete (fn);
+ }
+
+ using (Stream s = new FileStream (fn, FileMode.OpenOrCreate, FileAccess.Write, FileShare.ReadWrite | FileShare.Delete)) {
+ s.Write (new byte [1] { 0x5 }, 0, 1);
+ File.Delete (fn);
+ }
+
+ using (Stream s = new FileStream (fn, FileMode.OpenOrCreate, FileAccess.Write, FileShare.Write | FileShare.Delete)) {
+ s.Write (new byte [1] { 0x5 }, 0, 1);
+ File.Delete (fn);
+ }
+
+ using (Stream s = new FileStream (fn, FileMode.OpenOrCreate, FileAccess.Write, FileShare.Read | FileShare.Delete)) {
+ s.Write (new byte [1] { 0x5 }, 0, 1);
+ File.Delete (fn);
+ }
+
+ using (Stream s = new FileStream (fn, FileMode.OpenOrCreate, FileAccess.Write, FileShare.Inheritable | FileShare.Delete)) {
+ s.Write (new byte [1] { 0x5 }, 0, 1);
+ File.Delete (fn);
+ }
+ }
+
[Test]
public void Write ()
{
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]
[ExpectedException (typeof (ObjectDisposedException))]
public void Lock_Disposed ()
}
}
-#if NET_2_0
- [Test] public void DeleteOnClose ()
+ [Test]
+ public void DeleteOnClose ()
{
string path = TempFolder + DSC + "created.txt";
DeleteFile (path);
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
}
}
-