Merge pull request #3451 from BrzVlad/fix-armel-emulation
[mono.git] / mcs / class / corlib / Test / System.IO / FileStreamTest.cs
1 // FileStreamTests.cs - NUnit2 Test Cases for System.IO.FileStream class
2 //
3 // Authors:
4 //      Ville Palo (vi64pa@koti.soon.fi)
5 //      Gert Driesen (gert.driesen@ardatis.com)
6 //      Gonzalo Paniagua Javier (gonzalo@ximian.com)
7 // 
8 // (C) Ville Palo
9 // (c) 2003 Ximian, Inc. (http://www.ximian.com)
10 // Copyright 2011 Xamarin Inc (http://www.xamarin.com).
11 // 
12
13 using NUnit.Framework;
14 using System;
15 using System.IO;
16 using System.Runtime.InteropServices;
17 using System.Text;
18 using System.Threading;
19 using Microsoft.Win32.SafeHandles;
20
21 namespace MonoTests.System.IO
22 {
23         [TestFixture]
24         public class FileStreamTest
25         {
26                 string TempFolder = Path.Combine (Path.GetTempPath (), "MonoTests.System.IO.Tests");
27                 static readonly char DSC = Path.DirectorySeparatorChar;
28
29                 [TearDown]
30                 public void TearDown ()
31                 {
32                         if (Directory.Exists (TempFolder))
33                                 Directory.Delete (TempFolder, true);
34                 }
35
36                 [SetUp]
37                 public void SetUp ()
38                 {
39                         if (Directory.Exists (TempFolder))
40                                 Directory.Delete (TempFolder, true);
41
42                         Directory.CreateDirectory (TempFolder);
43                 }
44
45                 public void TestCtr ()
46                 {
47                         string path = TempFolder + DSC + "testfilestream.tmp.1";
48                         DeleteFile (path);
49                         FileStream stream = null;
50                         try {
51                                 stream = new FileStream (path, FileMode.Create);
52                         } finally {
53
54                                 if (stream != null)
55                                         stream.Close ();
56                                 DeleteFile (path);
57                         }
58                 }
59
60                 [Test]
61                 [ExpectedException (typeof (ArgumentException))]
62                 public void CtorArgumentException1 ()
63                 {
64                         FileStream stream;
65                         stream = new FileStream ("", FileMode.Create);
66                         stream.Close ();
67                 }
68
69                 [Test]
70                 [ExpectedException (typeof (ArgumentNullException))]
71                 public void CtorArgumentNullException ()
72                 {
73                         FileStream stream = new FileStream (null, FileMode.Create);
74                         stream.Close ();
75                 }
76
77                 [Test]
78                 public void CtorFileNotFoundException_Mode_Open ()
79                 {
80                         const string file_name = "thisfileshouldnotexist.test";
81                         // absolute path
82                         string path = TempFolder + DSC + file_name;
83                         DeleteFile (path);
84                         FileStream stream = null;
85                         try {
86                                 stream = new FileStream (TempFolder + DSC + file_name, FileMode.Open);
87                                 Assert.Fail ("#A1");
88                         } catch (FileNotFoundException ex) {
89                                 Assert.AreEqual (typeof (FileNotFoundException), ex.GetType (), "#A2");
90                                 Assert.AreEqual (path, ex.FileName, "#A3");
91                                 Assert.IsNull (ex.InnerException, "#A4");
92                                 Assert.IsNotNull (ex.Message, "#A5");
93                                 Assert.IsTrue (ex.Message.IndexOf (path) != -1, "#A6");
94                         } finally {
95                                 if (stream != null) {
96                                         stream.Close ();
97                                         stream = null;
98                                 }
99                                 DeleteFile (path);
100                         }
101
102                         // relative path
103                         string orignalCurrentDir = Directory.GetCurrentDirectory ();
104                         Directory.SetCurrentDirectory (TempFolder);
105
106                         // If TempFolder is a symlink, Mono will follow it and ex.FileName below will contain
107                         // the real directory name, not that of the TempFolder symlink and the test will fail
108                         // (happens e.g. on Android M)
109                         string realTempDir = Directory.GetCurrentDirectory ();
110                         path = realTempDir + DSC + file_name;
111
112                         try {
113                                 stream = new FileStream (file_name, FileMode.Open);
114                                 Assert.Fail ("#B1");
115                         } catch (FileNotFoundException ex) {
116                                 Assert.AreEqual (typeof (FileNotFoundException), ex.GetType (), "#B2");
117                                 Assert.AreEqual (path, ex.FileName, "#B3");
118                                 Assert.IsNull (ex.InnerException, "#B4");
119                                 Assert.IsNotNull (ex.Message, "#B5");
120                                 Assert.IsTrue (ex.Message.IndexOf (path) != -1, "#B6");
121                         } finally {
122                                 // restore original current directory
123                                 Directory.SetCurrentDirectory (orignalCurrentDir);
124                                 if (stream != null)
125                                         stream.Close ();
126                                 DeleteFile (path);
127                         }
128                 }
129
130                 [Test]
131                 public void CtorFileNotFoundException_Mode_Truncate ()
132                 {
133                         const string file_name = "thisfileshouldNOTexist.test";
134                         // absolute path
135                         string path = TempFolder + DSC + file_name;
136                         DeleteFile (path);
137                         FileStream stream = null;
138                         try {
139                                 stream = new FileStream (path, FileMode.Truncate);
140                                 Assert.Fail ("#A1");
141                         } catch (FileNotFoundException ex) {
142                                 Assert.AreEqual (typeof (FileNotFoundException), ex.GetType (), "#A2");
143                                 Assert.AreEqual (path, ex.FileName, "#A3");
144                                 Assert.IsNull (ex.InnerException, "#A4");
145                                 Assert.IsNotNull (ex.Message, "#A5");
146                                 Assert.IsTrue (ex.Message.IndexOf (path) != -1, "#A6");
147                         } finally {
148                                 if (stream != null) {
149                                         stream.Close ();
150                                         stream = null;
151                                 }
152                                 DeleteFile (path);
153                         }
154
155                         // relative path
156                         string orignalCurrentDir = Directory.GetCurrentDirectory ();
157                         Directory.SetCurrentDirectory (TempFolder);
158
159                         // If TempFolder is a symlink, Mono will follow it and ex.FileName below will contain
160                         // the real directory name, not that of the TempFolder symlink and the test will fail
161                         // (happens e.g. on Android M)
162                         string realTempDir = Directory.GetCurrentDirectory ();
163                         path = realTempDir + DSC + file_name;
164
165                         try {
166                                 stream = new FileStream (file_name, FileMode.Truncate);
167                                 Assert.Fail ("#B1");
168                         } catch (FileNotFoundException ex) {
169                                 Assert.AreEqual (typeof (FileNotFoundException), ex.GetType (), "#B2");
170                                 Assert.AreEqual (path, ex.FileName, "#B3");
171                                 Assert.IsNull (ex.InnerException, "#B4");
172                                 Assert.IsNotNull (ex.Message, "#B5");
173                                 Assert.IsTrue (ex.Message.IndexOf (path) != -1, "#B6");
174                         } finally {
175                                 // restore original current directory
176                                 Directory.SetCurrentDirectory (orignalCurrentDir);
177                                 if (stream != null)
178                                         stream.Close ();
179                                 DeleteFile (path);
180                         }
181                 }
182
183                 [Test]
184                 public void CtorIOException1 ()
185                 {
186                         const string file_name = "thisfileshouldexists.test";
187                         // absolute path
188                         string path = TempFolder + DSC + file_name;
189                         FileStream stream = null;
190                         DeleteFile (path);
191                         try {
192                                 stream = new FileStream (path, FileMode.CreateNew);
193                                 stream.Close ();
194                                 stream = null;
195                                 stream = new FileStream (path, FileMode.CreateNew);
196                                 Assert.Fail ("#A1");
197                         } catch (IOException ex) {
198                                 Assert.AreEqual (typeof (IOException), ex.GetType (), "#A2");
199                                 Assert.IsNull (ex.InnerException, "#A3");
200                                 Assert.IsNotNull (ex.Message, "#A4");
201                                 Assert.IsTrue (ex.Message.IndexOf (path) != -1, "#A5");
202                         } finally {
203                                 if (stream != null) {
204                                         stream.Close ();
205                                         stream = null;
206                                 }
207                                 DeleteFile (path);
208                         }
209
210                         // relative path
211                         string orignalCurrentDir = Directory.GetCurrentDirectory ();
212                         Directory.SetCurrentDirectory (TempFolder);
213
214                         // If TempFolder is a symlink, Mono will follow it and ex.FileName below will contain
215                         // the real directory name, not that of the TempFolder symlink and the test will fail
216                         // (happens e.g. on Android M)
217                         string realTempDir = Directory.GetCurrentDirectory ();
218                         path = realTempDir + DSC + file_name;
219
220                         try {
221                                 stream = new FileStream (file_name, FileMode.CreateNew);
222                                 stream.Close ();
223                                 stream = null;
224                                 stream = new FileStream (file_name, FileMode.CreateNew);
225                                 Assert.Fail ("#B1");
226                         } catch (IOException ex) {
227                                 Assert.AreEqual (typeof (IOException), ex.GetType (), "#B2");
228                                 Assert.IsNull (ex.InnerException, "#B3");
229                                 Assert.IsNotNull (ex.Message, "#B4");
230                                 Assert.IsTrue (ex.Message.IndexOf (path) != -1, "#B5");
231                         } finally {
232                                 // restore original current directory
233                                 Directory.SetCurrentDirectory (orignalCurrentDir);
234                                 if (stream != null)
235                                         stream.Close ();
236                                 DeleteFile (path);
237                         }
238                 }
239
240                 [Test]
241                 [ExpectedException (typeof (ArgumentOutOfRangeException))]
242                 public void CtorArgumentOutOfRangeException1 ()
243                 {
244                         FileStream stream = null;
245                         string path = TempFolder + Path.DirectorySeparatorChar + "temp";
246                         DeleteFile (path);
247                         try {
248                                 stream = new FileStream (path, FileMode.Append | FileMode.CreateNew);
249                         } finally {
250                                 if (stream != null)
251                                         stream.Close ();
252                                 DeleteFile (path);
253                         }
254                 }
255
256                 [Test]
257                 [ExpectedException (typeof (ArgumentOutOfRangeException))]
258                 public void CtorArgumentOutOfRangeException2 ()
259                 {
260                         FileStream stream = null;
261                         string path = TempFolder + Path.DirectorySeparatorChar + "temp";
262                         DeleteFile (path);
263                         try {
264                                 stream = new FileStream ("test.test.test", FileMode.Append | FileMode.Open);
265                         } finally {
266                                 if (stream != null)
267                                         stream.Close ();
268                                 DeleteFile (path);
269                         }
270                 }
271
272                 private void CtorDirectoryNotFoundException (FileMode mode)
273                 {
274                         string path = TempFolder + DSC + "thisDirectoryShouldNotExists";
275                         if (Directory.Exists (path))
276                                 Directory.Delete (path, true);
277
278                         FileStream stream = null;
279                         try {
280                                 stream = new FileStream (path + DSC + "eitherthisfile.test", mode);
281                         } finally {
282
283                                 if (stream != null)
284                                         stream.Close ();
285
286                                 if (Directory.Exists (path))
287                                         Directory.Delete (path, true);
288                         }
289                 }
290
291                 [Test]
292                 [ExpectedException (typeof (DirectoryNotFoundException))]
293                 public void CtorDirectoryNotFoundException_CreateNew ()
294                 {
295                         CtorDirectoryNotFoundException (FileMode.CreateNew);
296                 }
297
298                 [Test]
299                 [ExpectedException (typeof (DirectoryNotFoundException))]
300                 public void CtorDirectoryNotFoundException_Create ()
301                 {
302                         CtorDirectoryNotFoundException (FileMode.Create);
303                 }
304
305                 [Test]
306                 [ExpectedException (typeof (DirectoryNotFoundException))]
307                 public void CtorDirectoryNotFoundException_Open ()
308                 {
309                         CtorDirectoryNotFoundException (FileMode.Open);
310                 }
311
312                 [Test]
313                 [ExpectedException (typeof (DirectoryNotFoundException))]
314                 public void CtorDirectoryNotFoundException_OpenOrCreate ()
315                 {
316                         CtorDirectoryNotFoundException (FileMode.OpenOrCreate);
317                 }
318
319                 [Test]
320                 [ExpectedException (typeof (DirectoryNotFoundException))]
321                 public void CtorDirectoryNotFoundException_Truncate ()
322                 {
323                         CtorDirectoryNotFoundException (FileMode.Truncate);
324                 }
325
326                 [Test]
327                 [ExpectedException (typeof (DirectoryNotFoundException))]
328                 public void CtorDirectoryNotFoundException_Append ()
329                 {
330                         CtorDirectoryNotFoundException (FileMode.Append);
331                 }
332
333                 [Test]
334                 public void CtorDirectoryNotFound_RelativePath ()
335                 {
336                         string orignalCurrentDir = Directory.GetCurrentDirectory ();
337                         Directory.SetCurrentDirectory (TempFolder);
338
339                         // If TempFolder is a symlink, Mono will follow it and ex.FileName below will contain
340                         // the real directory name, not that of the TempFolder symlink and the test will fail
341                         // (happens e.g. on Android M)
342                         string realTempDir = Directory.GetCurrentDirectory ();
343                         
344                         string relativePath = "DirectoryDoesNotExist" + Path.DirectorySeparatorChar + "file.txt";
345                         string fullPath = Path.Combine (realTempDir, relativePath);
346                         try {
347                                 new FileStream (relativePath, FileMode.Open);
348                                 Assert.Fail ("#A1");
349                         } catch (DirectoryNotFoundException ex) {
350                                 Assert.AreEqual (typeof (DirectoryNotFoundException), ex.GetType (), "#A2");
351                                 Assert.IsNull (ex.InnerException, "#A3");
352                                 Assert.IsNotNull (ex.Message, "#A4");
353                                 Assert.IsTrue (ex.Message.IndexOf (fullPath) != -1, "#A5");
354                         } finally {
355                                 // restore original current directory
356                                 Directory.SetCurrentDirectory (orignalCurrentDir);
357                         }
358                 }
359
360                 [Test]
361                 // FileShare.Inheritable is ignored, but file does not exist
362                 [ExpectedException (typeof (FileNotFoundException))]
363                 public void CtorArgumentOutOfRangeException3 ()
364                 {
365                         string path = TempFolder + DSC + "CtorArgumentOutOfRangeException1";
366                         DeleteFile (path);
367
368                         FileStream stream = null;
369                         try {
370                                 stream = new FileStream (path, FileMode.Open, FileAccess.Read, FileShare.Inheritable);
371                         } finally {
372                                 if (stream != null)
373                                         stream.Close ();
374                                 DeleteFile (path);
375                         }
376                 }
377
378                 [Test]
379                 [ExpectedException (typeof (ArgumentOutOfRangeException))]
380                 public void CtorArgumentOutOfRangeException4 ()
381                 {
382                         string path = TempFolder + DSC + "CtorArgumentOutOfRangeException4";
383                         DeleteFile (path);
384
385                         FileStream stream = null;
386                         try {
387                                 stream = new FileStream (path, FileMode.OpenOrCreate, FileAccess.Read, FileShare.ReadWrite, -1);
388                         } finally {
389                                 if (stream != null)
390                                         stream.Close ();
391                                 DeleteFile (path);
392                         }
393                 }
394
395                 [Test]
396                 [ExpectedException (typeof (ArgumentOutOfRangeException))]
397                 public void CtorBufferSizeZero ()
398                 {
399                         // Buffer size can't be zero
400
401                         string path = Path.Combine (TempFolder, "CtorBufferSizeZero");
402                         DeleteFile (path);
403
404                         FileStream stream = null;
405                         try {
406                                 stream = new FileStream (path, FileMode.CreateNew, FileAccess.Write, FileShare.ReadWrite, 0);
407                         } finally {
408                                 if (stream != null)
409                                         stream.Close ();
410                                 DeleteFile (path);
411                         }
412                 }
413
414                 [Test]
415                 [ExpectedException (typeof (ArgumentException))]
416                 public void CtorArgumentException2 ()
417                 {
418                         // FileMode.CreateNew && FileAccess.Read
419
420                         string path = TempFolder + Path.DirectorySeparatorChar + "temp";
421                         FileStream stream = null;
422
423                         DeleteFile (path);
424
425                         try {
426                                 stream = new FileStream (".test.test.test.2", FileMode.CreateNew, FileAccess.Read, FileShare.None | FileShare.Write);
427                         } finally {
428
429                                 if (stream != null)
430                                         stream.Close ();
431                                 DeleteFile (path);
432                         }
433                 }
434
435
436                 [Test]
437                 // FileShare.Inheritable is ignored, but file does not exist
438                 [ExpectedException (typeof (FileNotFoundException))]
439                 public void CtorArgumentOutOfRangeException5 ()
440                 {
441                         string path = TempFolder + Path.DirectorySeparatorChar + "temp";
442                         DeleteFile (path);
443
444                         FileStream stream = null;
445                         try {
446                                 stream = new FileStream (path, FileMode.Open, FileAccess.Read, FileShare.Inheritable | FileShare.ReadWrite);
447                         } finally {
448                                 if (stream != null)
449                                         stream.Close ();
450                                 DeleteFile (path);
451                         }
452                 }
453
454
455                 [Test]
456                 [ExpectedException (typeof (ArgumentException))]
457                 public void CtorArgumentException3 ()
458                 {
459                         string path = TempFolder + Path.DirectorySeparatorChar + "temp";
460                         FileStream stream = null;
461
462                         DeleteFile (path);
463
464                         try {
465                                 stream = new FileStream (".test.test.test.2", FileMode.Truncate, FileAccess.Read);
466                         } finally {
467                                 if (stream != null)
468                                         stream.Close ();
469
470                                 DeleteFile (path);
471                         }
472                 }
473
474                 [Test]
475                 public void ModeAndAccessCombinations ()
476                 {
477                         string path = TempFolder + Path.DirectorySeparatorChar + "temp";
478                         DeleteFile (path);
479                         FileStream stream = null;
480
481                         // Append / Read
482                         try {
483                                 // Append access can be requested only in write-only mode
484                                 stream = new FileStream (path, FileMode.Append, FileAccess.Read);
485                                 Assert.Fail ("#A1");
486                         } catch (ArgumentException ex) {
487                                 Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#A2");
488                         } finally {
489                                 if (stream != null)
490                                         stream.Close ();
491
492                                 DeleteFile (path);
493                         }
494
495                         // Append / ReadWrite
496                         try {
497                                 // Append access can be requested only in write-only mode
498                                 stream = new FileStream (path, FileMode.Append, FileAccess.ReadWrite);
499                                 Assert.Fail ("#B1");
500                         } catch (ArgumentException ex) {
501                                 // make sure it is exact this exception, and not a derived type
502                                 Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#B2");
503                         } finally {
504                                 if (stream != null)
505                                         stream.Close ();
506
507                                 DeleteFile (path);
508                         }
509
510                         // Append / Write
511                         try {
512                                 stream = new FileStream (path, FileMode.Append, FileAccess.Write);
513                         } finally {
514                                 if (stream != null)
515                                         stream.Close ();
516
517                                 DeleteFile (path);
518                         }
519
520                         // Create / Read
521                         try {
522                                 stream = new FileStream (path, FileMode.Create, FileAccess.Read);
523                                 Assert.Fail ("#C1");
524                         } catch (ArgumentException ex) {
525                                 // make sure it is exact this exception, and not a derived type
526                                 Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#C2");
527                         } finally {
528                                 if (stream != null)
529                                         stream.Close ();
530
531                                 DeleteFile (path);
532                         }
533
534                         // Create / ReadWrite
535                         try {
536                                 stream = new FileStream (path, FileMode.Create, FileAccess.ReadWrite);
537                         } finally {
538                                 if (stream != null)
539                                         stream.Close ();
540
541                                 DeleteFile (path);
542                         }
543
544                         // Create / Write
545                         try {
546                                 stream = new FileStream (path, FileMode.Create, FileAccess.Write);
547                         } finally {
548                                 if (stream != null)
549                                         stream.Close ();
550
551                                 DeleteFile (path);
552                         }
553
554                         // CreateNew / Read
555                         try {
556                                 stream = new FileStream (path, FileMode.CreateNew, FileAccess.Read);
557                                 Assert.Fail ("#D1");
558                         } catch (ArgumentException ex) {
559                                 // make sure it is exact this exception, and not a derived type
560                                 Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#D2");
561                         } finally {
562                                 if (stream != null)
563                                         stream.Close ();
564
565                                 DeleteFile (path);
566                         }
567
568                         // CreateNew / ReadWrite
569                         try {
570                                 stream = new FileStream (path, FileMode.CreateNew, FileAccess.ReadWrite);
571                         } finally {
572                                 if (stream != null)
573                                         stream.Close ();
574
575                                 DeleteFile (path);
576                         }
577
578                         // CreateNew / Write
579                         try {
580                                 stream = new FileStream (path, FileMode.CreateNew, FileAccess.Write);
581                         } finally {
582                                 if (stream != null)
583                                         stream.Close ();
584
585                                 DeleteFile (path);
586                         }
587
588                         // Open / Read
589                         try {
590                                 stream = new FileStream (path, FileMode.Open, FileAccess.Read);
591                                 Assert.Fail ("#E1");
592                         } catch (FileNotFoundException ex) {
593                                 // make sure it is exact this exception, and not a derived type
594                                 Assert.AreEqual (typeof (FileNotFoundException), ex.GetType (), "#E2");
595                                 Assert.AreEqual (path, ex.FileName, "#E3");
596                                 Assert.IsNull (ex.InnerException, "#E4");
597                                 Assert.IsNotNull (ex.Message, "#E5");
598                                 Assert.IsTrue (ex.Message.IndexOf (path) != -1, "#E6");
599                         } finally {
600                                 if (stream != null)
601                                         stream.Close ();
602
603                                 DeleteFile (path);
604                         }
605
606                         // Open / ReadWrite
607                         try {
608                                 stream = new FileStream (path, FileMode.Open, FileAccess.ReadWrite);
609                                 Assert.Fail ("#F1");
610                         } catch (FileNotFoundException ex) {
611                                 // make sure it is exact this exception, and not a derived type
612                                 Assert.AreEqual (typeof (FileNotFoundException), ex.GetType (), "#F2");
613                                 Assert.AreEqual (path, ex.FileName, "#F3");
614                                 Assert.IsNull (ex.InnerException, "#F4");
615                                 Assert.IsNotNull (ex.Message, "#F5");
616                                 Assert.IsTrue (ex.Message.IndexOf (path) != -1, "#F6");
617                         } finally {
618                                 if (stream != null)
619                                         stream.Close ();
620
621                                 DeleteFile (path);
622                         }
623
624                         // Open / Write
625                         try {
626                                 stream = new FileStream (path, FileMode.Open, FileAccess.Write);
627                                 Assert.Fail ("#G1");
628                         } catch (FileNotFoundException ex) {
629                                 // make sure it is exact this exception, and not a derived type
630                                 Assert.AreEqual (typeof (FileNotFoundException), ex.GetType (), "#G2");
631                                 Assert.AreEqual (path, ex.FileName, "#G3");
632                                 Assert.IsNull (ex.InnerException, "#G4");
633                                 Assert.IsNotNull (ex.Message, "#G5");
634                                 Assert.IsTrue (ex.Message.IndexOf (path) != -1, "#G6");
635                         } finally {
636                                 if (stream != null)
637                                         stream.Close ();
638
639                                 DeleteFile (path);
640                         }
641
642                         // OpenOrCreate / Read
643                         try {
644                                 stream = new FileStream (path, FileMode.OpenOrCreate, FileAccess.Read);
645                         } finally {
646                                 if (stream != null)
647                                         stream.Close ();
648
649                                 DeleteFile (path);
650                         }
651
652                         // OpenOrCreate / ReadWrite
653                         try {
654                                 stream = new FileStream (path, FileMode.OpenOrCreate, FileAccess.ReadWrite);
655                         } finally {
656                                 if (stream != null)
657                                         stream.Close ();
658
659                                 DeleteFile (path);
660                         }
661
662                         // OpenOrCreate / Write
663                         try {
664                                 stream = new FileStream (path, FileMode.OpenOrCreate, FileAccess.Write);
665                         } finally {
666                                 if (stream != null)
667                                         stream.Close ();
668
669                                 DeleteFile (path);
670                         }
671
672                         // Truncate / Read
673                         try {
674                                 stream = new FileStream (path, FileMode.Truncate, FileAccess.Read);
675                                 Assert.Fail ("#H1");
676                         } catch (ArgumentException ex) {
677                                 // make sure it is exact this exception, and not a derived type
678                                 Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#H2");
679                         } finally {
680                                 if (stream != null)
681                                         stream.Close ();
682
683                                 DeleteFile (path);
684                         }
685
686                         // Truncate / ReadWrite
687                         try {
688                                 stream = new FileStream (path, FileMode.Truncate, FileAccess.ReadWrite);
689                                 Assert.Fail ("#I1");
690                         } catch (FileNotFoundException ex) {
691                                 // make sure it is exact this exception, and not a derived type
692                                 Assert.AreEqual (typeof (FileNotFoundException), ex.GetType (), "#I2");
693                                 Assert.AreEqual (path, ex.FileName, "#I3");
694                                 Assert.IsNull (ex.InnerException, "#I4");
695                                 Assert.IsNotNull (ex.Message, "#I5");
696                                 Assert.IsTrue (ex.Message.IndexOf (path) != -1, "#I6");
697                         } finally {
698                                 if (stream != null)
699                                         stream.Close ();
700
701                                 DeleteFile (path);
702                         }
703
704                         // Truncate / Write
705                         try {
706                                 stream = new FileStream (path, FileMode.Truncate, FileAccess.Write);
707                                 Assert.Fail ("#J1");
708                         } catch (FileNotFoundException ex) {
709                                 // make sure it is exact this exception, and not a derived type
710                                 Assert.AreEqual (typeof (FileNotFoundException), ex.GetType (), "#J2");
711                                 Assert.AreEqual (path, ex.FileName, "#J3");
712                                 Assert.IsNull (ex.InnerException, "#J4");
713                                 Assert.IsNotNull (ex.Message, "#J5");
714                                 Assert.IsTrue (ex.Message.IndexOf (path) != -1, "#J6");
715                         } finally {
716                                 if (stream != null)
717                                         stream.Close ();
718
719                                 DeleteFile (path);
720                         }
721                 }
722
723                 [Test, ExpectedException (typeof (IOException))]
724                 public void CtorIOException2 ()
725                 {
726                         FileStream stream = null;
727                         try {
728                                 stream = new FileStream (new IntPtr (Int32.MaxValue), FileAccess.Read);
729                         } finally {
730                                 if (stream != null)
731                                         stream.Close ();
732                         }
733                 }
734
735                 [Test, ExpectedException (typeof (IOException))]
736                 public void CtorIOException ()
737                 {
738                         string path = TempFolder + DSC + "CTorIOException.Test";
739                         FileStream stream = null;
740                         FileStream stream2 = null;
741                         DeleteFile (path);
742
743                         try {
744                                 stream = new FileStream (path, FileMode.CreateNew);
745
746                                 // used by an another process
747                                 stream2 = new FileStream (path, FileMode.OpenOrCreate);
748                         } finally {
749                                 if (stream != null)
750                                         stream.Close ();
751                                 if (stream2 != null)
752                                         stream2.Close ();
753                                 DeleteFile (path);
754                         }
755                 }
756
757                 [Test]
758                 public void CtorAccess1Read2Read ()
759                 {
760                         FileStream fs = null;
761                         FileStream fs2 = null;
762                         string fn = Path.Combine (TempFolder, "temp");
763                         try {
764                                 if (!File.Exists (fn)) {
765                                         TextWriter tw = File.CreateText (fn);
766                                         tw.Write ("FOO");
767                                         tw.Close ();
768                                 }
769                                 fs = new FileStream (fn, FileMode.Open, FileAccess.Read);
770                                 fs2 = new FileStream (fn, FileMode.Open, FileAccess.Read);
771                         } finally {
772                                 if (fs != null)
773                                         fs.Close ();
774                                 if (fs2 != null)
775                                         fs2.Close ();
776                                 if (File.Exists (fn))
777                                         File.Delete (fn);
778                         }
779                 }
780
781                 [Test]
782                 [ExpectedException (typeof (IOException))]
783                 public void CtorAccess1Read2Write ()
784                 {
785                         string fn = Path.Combine (TempFolder, "temp");
786                         FileStream fs1 = null;
787                         FileStream fs2 = null;
788                         try {
789                                 if (!File.Exists (fn)) {
790                                         using (TextWriter tw = File.CreateText (fn)) {
791                                                 tw.Write ("FOO");
792                                         }
793                                 }
794                                 fs1 = new FileStream (fn, FileMode.Open, FileAccess.Read);
795                                 fs2 = new FileStream (fn, FileMode.Create, FileAccess.Write);
796                         } finally {
797                                 if (fs1 != null)
798                                         fs1.Close ();
799                                 if (fs2 != null)
800                                         fs2.Close ();
801                                 if (File.Exists (fn))
802                                         File.Delete (fn);
803                         }
804                 }
805
806                 [Test]
807                 [ExpectedException (typeof (IOException))]
808                 public void CtorAccess1Write2Write ()
809                 {
810                         string fn = Path.Combine (TempFolder, "temp");
811                         FileStream fs1 = null;
812                         FileStream fs2 = null;
813                         try {
814                                 if (File.Exists (fn))
815                                         File.Delete (fn);
816                                 fs1 = new FileStream (fn, FileMode.Create, FileAccess.Write);
817                                 fs2 = new FileStream (fn, FileMode.Create, FileAccess.Write);
818                         } finally {
819                                 if (fs1 != null)
820                                         fs1.Close ();
821                                 if (fs2 != null)
822                                         fs2.Close ();
823                                 if (File.Exists (fn))
824                                         File.Delete (fn);
825                         }
826                 }
827
828                 [Test]
829                 [ExpectedException (typeof (UnauthorizedAccessException))]
830                 public void CtorReadDirectoryAsFile ()
831                 {
832                         FileStream stream = null;
833                         try {
834                                 stream = new FileStream (TempFolder, FileMode.Open, FileAccess.Read);
835                         } finally {
836                                 if (stream != null)
837                                         stream.Close ();
838                         }
839                 }
840
841                 [Test] // bug #79250
842                 public void FileShare_Delete ()
843                 {
844                         string fn = Path.Combine (TempFolder, "temp");
845                         
846                         using (Stream s = new FileStream (fn, FileMode.OpenOrCreate, FileAccess.Write, FileShare.Delete)) {
847                                 s.Write (new byte [1] { 0x5 }, 0, 1);
848                                 File.Delete (fn);
849                         }
850
851                         using (Stream s = new FileStream (fn, FileMode.OpenOrCreate, FileAccess.Write, FileShare.ReadWrite | FileShare.Delete)) {
852                                 s.Write (new byte [1] { 0x5 }, 0, 1);
853                                 File.Delete (fn);
854                         }
855
856                         using (Stream s = new FileStream (fn, FileMode.OpenOrCreate, FileAccess.Write, FileShare.Write | FileShare.Delete)) {
857                                 s.Write (new byte [1] { 0x5 }, 0, 1);
858                                 File.Delete (fn);
859                         }
860
861                         using (Stream s = new FileStream (fn, FileMode.OpenOrCreate, FileAccess.Write, FileShare.Read | FileShare.Delete)) {
862                                 s.Write (new byte [1] { 0x5 }, 0, 1);
863                                 File.Delete (fn);
864                         }
865
866                         using (Stream s = new FileStream (fn, FileMode.OpenOrCreate, FileAccess.Write, FileShare.Inheritable | FileShare.Delete)) {
867                                 s.Write (new byte [1] { 0x5 }, 0, 1);
868                                 File.Delete (fn);
869                         }
870                 }
871
872                 [Test]
873                 public void Write ()
874                 {
875                         string path = TempFolder + DSC + "FileStreamTest.Write";
876
877                         DeleteFile (path);
878
879                         FileStream stream = new FileStream (path, FileMode.CreateNew, FileAccess.ReadWrite, FileShare.ReadWrite, 8);
880
881                         byte[] outbytes = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 };
882                         byte[] bytes = new byte[15];
883
884                         // Check that the data is flushed when we overflow the buffer
885                         // with a large amount of data
886                         stream.Write (outbytes, 0, 5);
887                         stream.Write (outbytes, 5, 10);
888                         stream.Seek (0, SeekOrigin.Begin);
889
890                         stream.Read (bytes, 0, 15);
891                         for (int i = 0; i < 15; ++i)
892                                 Assert.AreEqual (i + 1, bytes[i], "#1");
893
894                         // Check that the data is flushed when we overflow the buffer
895                         // with a small amount of data
896                         stream.Write (outbytes, 0, 7);
897                         stream.Write (outbytes, 7, 7);
898                         stream.Write (outbytes, 14, 1);
899
900                         stream.Read (bytes, 0, 15);
901                         stream.Seek (15, SeekOrigin.Begin);
902                         for (int i = 0; i < 15; ++i)
903                                 Assert.AreEqual (i + 1, bytes[i], "#2");
904                         stream.Close ();
905                 }
906
907                 [Test]
908                 public void Length ()
909                 {
910                         // Test that the Length property takes into account the data
911                         // in the buffer
912                         string path = TempFolder + DSC + "FileStreamTest.Length";
913
914                         DeleteFile (path);
915
916                         FileStream stream = new FileStream (path, FileMode.CreateNew);
917
918                         byte[] outbytes = new byte[] { 1, 2, 3, 4 };
919
920                         stream.Write (outbytes, 0, 4);
921                         Assert.AreEqual (4, stream.Length);
922                         stream.Close ();
923                 }
924
925                 [Test]
926                 public void Flush ()
927                 {
928                         string path = TempFolder + DSC + "FileStreamTest.Flush";
929                         FileStream stream = null;
930                         FileStream stream2 = null;
931
932                         DeleteFile (path);
933
934                         try {
935                                 stream = new FileStream (path, FileMode.CreateNew, FileAccess.ReadWrite, FileShare.ReadWrite);
936                                 stream2 = new FileStream (path, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite);
937
938                                 stream.Write (new byte[] { 1, 2, 3, 4, 5 }, 0, 5);
939
940                                 byte[] bytes = new byte[5];
941                                 stream2.Read (bytes, 0, 5);
942                                 Assert.AreEqual (0, bytes[0], "#A1");
943                                 Assert.AreEqual (0, bytes[1], "#A2");
944                                 Assert.AreEqual (0, bytes[2], "#A3");
945                                 Assert.AreEqual (0, bytes[3], "#A4");
946
947                                 stream.Flush ();
948                                 stream2.Read (bytes, 0, 5);
949                                 Assert.AreEqual (1, bytes[0], "#B1");
950                                 Assert.AreEqual (2, bytes[1], "#B2");
951                                 Assert.AreEqual (3, bytes[2], "#B3");
952                                 Assert.AreEqual (4, bytes[3], "#B4");
953                         } finally {
954                                 if (stream != null)
955                                         stream.Close ();
956                                 if (stream2 != null)
957                                         stream2.Close ();
958
959                                 DeleteFile (path);
960                         }
961                 }
962
963                 public void TestDefaultProperties ()
964                 {
965                         string path = TempFolder + Path.DirectorySeparatorChar + "testfilestream.tmp.2";
966                         DeleteFile (path);
967
968                         FileStream stream = new FileStream (path, FileMode.Create);
969
970                         Assert.IsTrue (stream.CanRead, "#A1");
971                         Assert.IsTrue (stream.CanSeek, "#A2");
972                         Assert.IsTrue (stream.CanWrite, "#A3");
973                         Assert.IsFalse (stream.IsAsync, "#A4");
974                         Assert.IsTrue (stream.Name.EndsWith (path), "#A5");
975                         Assert.AreEqual (0, stream.Position, "#A6");
976                         Assert.AreEqual ("System.IO.FileStream", stream.ToString (), "#A7");
977                         stream.Close ();
978                         DeleteFile (path);
979
980                         stream = new FileStream (path, FileMode.OpenOrCreate, FileAccess.Read);
981                         Assert.IsTrue (stream.CanRead, "#B1");
982                         Assert.IsTrue (stream.CanSeek, "#B2");
983                         Assert.IsFalse (stream.CanWrite, "#B3");
984                         Assert.IsFalse (stream.IsAsync, "#B4");
985                         Assert.IsTrue (stream.Name.EndsWith (path), "#B5");
986                         Assert.AreEqual (0, stream.Position, "#B6");
987                         Assert.AreEqual ("System.IO.FileStream", stream.ToString (), "#B7");
988                         stream.Close ();
989
990                         stream = new FileStream (path, FileMode.Truncate, FileAccess.Write, FileShare.ReadWrite);
991                         Assert.IsFalse (stream.CanRead, "#C1");
992                         Assert.IsTrue (stream.CanSeek, "#C2");
993                         Assert.IsTrue (stream.CanWrite, "#C3");
994                         Assert.IsFalse (stream.IsAsync, "#C4");
995                         Assert.IsTrue (stream.Name.EndsWith ("testfilestream.tmp.2"), "#C5");
996                         Assert.AreEqual (0, stream.Position, "#C6");
997                         Assert.AreEqual ("System.IO.FileStream", stream.ToString (), "#C7");
998                         stream.Close ();
999                         DeleteFile (path);
1000                 }
1001
1002                 [Category ("NotWorking")]
1003                 // Bug: 71371 -> duplicate and WONTFIX.
1004                 public void TestLock_FailsOnMono ()
1005                 {
1006                         string path = TempFolder + Path.DirectorySeparatorChar + "TestLock";
1007                         DeleteFile (path);
1008
1009                         FileStream stream = new FileStream (path, FileMode.CreateNew, FileAccess.ReadWrite);
1010
1011                         stream.Write (new Byte[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }, 0, 10);
1012                         stream.Close ();
1013
1014                         stream = new FileStream (path, FileMode.Open, FileAccess.ReadWrite);
1015
1016                         stream.Lock (0, 5);
1017
1018                         FileStream stream2 = new FileStream (path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
1019
1020                         byte[] bytes = new byte[5];
1021                         try {
1022                                 stream2.Read (bytes, 0, 5);
1023                                 Assert.Fail ("#1");
1024                         } catch (Exception e) {
1025                                 Assert.AreEqual (typeof (IOException), e.GetType (), "#2");
1026                         }
1027
1028                         stream.Close ();
1029                         stream2.Close ();
1030
1031                         DeleteFile (path);
1032                 }
1033
1034                 public void TestLock ()
1035                 {
1036                         string path = TempFolder + Path.DirectorySeparatorChar + "TestLock";
1037                         DeleteFile (path);
1038
1039                         FileStream stream = new FileStream (path, FileMode.CreateNew, FileAccess.ReadWrite);
1040
1041                         stream.Write (new Byte[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }, 0, 10);
1042                         stream.Close ();
1043
1044                         stream = new FileStream (path, FileMode.Open, FileAccess.ReadWrite);
1045
1046                         stream.Lock (0, 5);
1047
1048                         FileStream stream2 = new FileStream (path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
1049
1050                         byte[] bytes = new byte[5];
1051                         try {
1052                                 stream2.Read (bytes, 0, 5);
1053                                 Assert.Fail ("#A1");
1054                         } catch (Exception) {
1055                                 // Bug #71371: on MS.NET you get an IOException detailing a lock
1056                                 // Assert.AreEqual (typeof (IOException), e.GetType (), "#A2");
1057                         }
1058
1059                         stream2.Seek (5, SeekOrigin.Begin);
1060                         stream2.Read (bytes, 0, 5);
1061
1062                         Assert.AreEqual (5, bytes[0], "#B1");
1063                         Assert.AreEqual (6, bytes[1], "#B2");
1064                         Assert.AreEqual (7, bytes[2], "#B3");
1065                         Assert.AreEqual (8, bytes[3], "#B4");
1066                         Assert.AreEqual (9, bytes[4], "#B5");
1067
1068                         stream.Unlock (0, 5);
1069                         stream2.Seek (0, SeekOrigin.Begin);
1070                         stream2.Read (bytes, 0, 5);
1071
1072                         Assert.AreEqual (0, bytes[0], "#C1");
1073                         Assert.AreEqual (1, bytes[1], "#C2");
1074                         Assert.AreEqual (2, bytes[2], "#C3");
1075                         Assert.AreEqual (3, bytes[3], "#C4");
1076                         Assert.AreEqual (4, bytes[4], "#C5");
1077
1078                         stream.Close ();
1079                         stream2.Close ();
1080
1081                         DeleteFile (path);
1082                 }
1083
1084                 [Test]
1085                 public void Seek ()
1086                 {
1087                         string path = TempFolder + DSC + "FST.Seek.Test";
1088                         DeleteFile (path);
1089
1090                         FileStream stream = new FileStream (path, FileMode.CreateNew, FileAccess.ReadWrite, FileShare.ReadWrite);
1091                         FileStream stream2 = new FileStream (path, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite);
1092
1093                         stream.Write (new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 10 }, 0, 9);
1094                         Assert.AreEqual (5, stream2.Seek (5, SeekOrigin.Begin), "#1");
1095                         Assert.AreEqual (-1, stream2.ReadByte (), "#2");
1096
1097                         Assert.AreEqual (2, stream2.Seek (-3, SeekOrigin.Current), "#3");
1098                         Assert.AreEqual (-1, stream2.ReadByte (), "#4");
1099
1100                         Assert.AreEqual (12, stream.Seek (3, SeekOrigin.Current), "#5");
1101                         Assert.AreEqual (-1, stream.ReadByte (), "#6");
1102
1103                         Assert.AreEqual (5, stream.Seek (-7, SeekOrigin.Current), "#7");
1104                         Assert.AreEqual (6, stream.ReadByte (), "#8");
1105
1106                         Assert.AreEqual (5, stream2.Seek (5, SeekOrigin.Begin), "#9");
1107                         Assert.AreEqual (6, stream2.ReadByte (), "#10");
1108
1109                         stream.Close ();
1110                         stream2.Close ();
1111
1112                         DeleteFile (path);
1113                 }
1114
1115                 public void TestSeek ()
1116                 {
1117                         string path = TempFolder + Path.DirectorySeparatorChar + "TestSeek";
1118                         DeleteFile (path);
1119
1120                         FileStream stream = new FileStream (path, FileMode.CreateNew, FileAccess.ReadWrite, FileShare.ReadWrite);
1121                         stream.Write (new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }, 0, 10);
1122
1123                         stream.Seek (5, SeekOrigin.End);
1124                         Assert.AreEqual (-1, stream.ReadByte (), "#1");
1125
1126                         stream.Seek (-5, SeekOrigin.End);
1127                         Assert.AreEqual (6, stream.ReadByte (), "#2");
1128
1129                         try {
1130                                 stream.Seek (-11, SeekOrigin.End);
1131                                 Assert.Fail ("#3");
1132                         } catch (Exception e) {
1133                                 Assert.AreEqual (typeof (IOException), e.GetType (), "#4");
1134                         }
1135
1136                         stream.Seek (19, SeekOrigin.Begin);
1137                         Assert.AreEqual (-1, stream.ReadByte (), "#5");
1138
1139                         stream.Seek (1, SeekOrigin.Begin);
1140                         Assert.AreEqual (2, stream.ReadByte (), "#6");
1141
1142                         stream.Seek (3, SeekOrigin.Current);
1143                         Assert.AreEqual (6, stream.ReadByte (), "#7");
1144
1145                         stream.Seek (-2, SeekOrigin.Current);
1146                         Assert.AreEqual (5, stream.ReadByte (), "#8");
1147
1148                         stream.Flush ();
1149
1150                         // Test that seeks work correctly when seeking inside the buffer
1151                         stream.Seek (0, SeekOrigin.Begin);
1152                         stream.WriteByte (0);
1153                         stream.WriteByte (1);
1154                         stream.Seek (0, SeekOrigin.Begin);
1155                         byte[] buf = new byte[1];
1156                         buf[0] = 2;
1157                         stream.Write (buf, 0, 1);
1158                         stream.Write (buf, 0, 1);
1159                         stream.Flush ();
1160                         stream.Seek (0, SeekOrigin.Begin);
1161                         Assert.AreEqual (2, stream.ReadByte (), "#9");
1162                         Assert.AreEqual (2, stream.ReadByte (), "#10");
1163
1164                         stream.Close ();
1165
1166                         DeleteFile (path);
1167                 }
1168
1169                 public void TestClose ()
1170                 {
1171                         string path = TempFolder + Path.DirectorySeparatorChar + "TestClose";
1172                         DeleteFile (path);
1173
1174                         FileStream stream = new FileStream (path, FileMode.CreateNew, FileAccess.ReadWrite);
1175
1176                         stream.Write (new byte[] { 1, 2, 3, 4 }, 0, 4);
1177                         stream.ReadByte ();
1178                         stream.Close ();
1179
1180                         try {
1181                                 stream.ReadByte ();
1182                                 Assert.Fail ("#A1");
1183                         } catch (Exception e) {
1184                                 Assert.AreEqual (typeof (ObjectDisposedException), e.GetType (), "#A2");
1185                         }
1186
1187                         try {
1188                                 stream.WriteByte (64);
1189                                 Assert.Fail ("#B1");
1190                         } catch (Exception e) {
1191                                 Assert.AreEqual (typeof (ObjectDisposedException), e.GetType (), "#B2");
1192                         }
1193
1194                         try {
1195                                 stream.Flush ();
1196                                 Assert.Fail ("#C1");
1197                         } catch (Exception e) {
1198                                 Assert.AreEqual (typeof (ObjectDisposedException), e.GetType (), "#C2");
1199                         }
1200
1201                         try {
1202                                 long l = stream.Length;
1203                                 Assert.Fail ("#D1");
1204                         } catch (Exception e) {
1205                                 Assert.AreEqual (typeof (ObjectDisposedException), e.GetType (), "#D2");
1206                         }
1207
1208                         try {
1209                                 long l = stream.Position;
1210                                 Assert.Fail ("#E1");
1211                         } catch (Exception e) {
1212                                 Assert.AreEqual (typeof (ObjectDisposedException), e.GetType (), "#E2");
1213                         }
1214
1215                         Assert.IsFalse (stream.CanRead, "#F1");
1216                         Assert.IsFalse (stream.CanSeek, "#F2");
1217                         Assert.IsFalse (stream.CanWrite, "#F3");
1218                         Assert.IsTrue (stream.Name.EndsWith (path), "#F4");
1219
1220                         DeleteFile (path);
1221                 }
1222
1223
1224                 /// <summary>
1225                 /// Checks whether the <see cref="FileStream" /> throws a <see cref="NotSupportedException" />
1226                 /// when the stream is opened with access mode <see cref="FileAccess.Read" /> and the
1227                 /// <see cref="FileStream.Write(byte[], int, int)" /> method is called.
1228                 /// </summary>
1229                 [Test]
1230                 [ExpectedException (typeof (NotSupportedException))]
1231                 public void TestWriteVerifyAccessMode ()
1232                 {
1233                         string path = TempFolder + Path.DirectorySeparatorChar + "temp";
1234                         DeleteFile (path);
1235
1236                         FileStream stream = null;
1237                         byte[] buffer;
1238
1239                         try {
1240                                 buffer = Encoding.ASCII.GetBytes ("test");
1241                                 stream = new FileStream (path, FileMode.OpenOrCreate, FileAccess.Read);
1242                                 stream.Write (buffer, 0, buffer.Length);
1243                         } finally {
1244                                 if (stream != null)
1245                                         stream.Close ();
1246                                 DeleteFile (path);
1247                         }
1248                 }
1249
1250                 /// <summary>
1251                 /// Checks whether the <see cref="FileStream" /> throws a <see cref="NotSupportedException" />
1252                 /// when the stream is opened with access mode <see cref="FileAccess.Read" /> and the
1253                 /// <see cref="FileStream.WriteByte(byte)" /> method is called.
1254                 /// </summary>
1255                 [Test]
1256                 [ExpectedException (typeof (NotSupportedException))]
1257                 public void TestWriteByteVerifyAccessMode ()
1258                 {
1259                         string path = TempFolder + Path.DirectorySeparatorChar + "temp";
1260                         DeleteFile (path);
1261
1262                         FileStream stream = null;
1263
1264                         try {
1265                                 stream = new FileStream (path, FileMode.OpenOrCreate, FileAccess.Read);
1266                                 stream.WriteByte (Byte.MinValue);
1267                         } finally {
1268                                 if (stream != null)
1269                                         stream.Close ();
1270                                 DeleteFile (path);
1271                         }
1272                 }
1273
1274                 /// <summary>
1275                 /// Checks whether the <see cref="FileStream" /> throws a <see cref="NotSupportedException" />
1276                 /// when the stream is opened with access mode <see cref="FileAccess.Write" /> and the
1277                 /// <see cref="FileStream.Read(byte[], int, int)" /> method is called.
1278                 /// </summary>
1279                 [Test]
1280                 [ExpectedException (typeof (NotSupportedException))]
1281                 public void TestReadVerifyAccessMode ()
1282                 {
1283                         string path = TempFolder + Path.DirectorySeparatorChar + "temp";
1284                         DeleteFile (path);
1285
1286                         FileStream stream = null;
1287                         byte[] buffer = new byte[100];
1288
1289                         try {
1290                                 stream = new FileStream (path, FileMode.OpenOrCreate, FileAccess.Write);
1291                                 stream.Read (buffer, 0, buffer.Length);
1292                         } finally {
1293                                 if (stream != null)
1294                                         stream.Close ();
1295                         }
1296                 }
1297
1298                 /// <summary>
1299                 /// Checks whether the <see cref="FileStream" /> throws a <see cref="NotSupportedException" />
1300                 /// when the stream is opened with access mode <see cref="FileAccess.Write" /> and the
1301                 /// <see cref="FileStream.ReadByte()" /> method is called.
1302                 /// </summary>
1303                 [Test]
1304                 [ExpectedException (typeof (NotSupportedException))]
1305                 public void TestReadByteVerifyAccessMode ()
1306                 {
1307                         string path = TempFolder + Path.DirectorySeparatorChar + "temp";
1308                         DeleteFile (path);
1309
1310                         FileStream stream = null;
1311
1312                         try {
1313                                 stream = new FileStream (path, FileMode.OpenOrCreate, FileAccess.Write);
1314                                 int readByte = stream.ReadByte ();
1315                         } finally {
1316                                 if (stream != null)
1317                                         stream.Close ();
1318                                 DeleteFile (path);
1319                         }
1320                 }
1321
1322                 // Check that the stream is flushed even when it doesn't own the
1323                 // handle
1324                 [Test]
1325                 public void TestFlushNotOwningHandle ()
1326                 {
1327                         string path = Path.Combine (TempFolder, "TestFlushNotOwningHandle");
1328                         DeleteFile (path);
1329
1330                         FileStream s = new FileStream (path, FileMode.Create);
1331                         using (FileStream s2 = new FileStream (s.Handle, FileAccess.Write, false)) {
1332                                 byte[] buf = new byte[2];
1333                                 buf[0] = (int) '1';
1334                                 s2.Write (buf, 0, 1);
1335                         }
1336
1337                         s.Position = 0;
1338                         Assert.AreEqual ((int) '1', s.ReadByte ());
1339                         s.Close ();
1340                 }
1341
1342                 private void DeleteFile (string path)
1343                 {
1344                         if (File.Exists (path))
1345                                 File.Delete (path);
1346                 }
1347
1348                 [Test]
1349                 [ExpectedException (typeof (ArgumentOutOfRangeException))]
1350                 public void Read_OffsetNegative ()
1351                 {
1352                         string path = TempFolder + Path.DirectorySeparatorChar + "temp";
1353                         DeleteFile (path);
1354
1355                         using (FileStream stream = new FileStream (path, FileMode.OpenOrCreate, FileAccess.Read)) {
1356                                 stream.Read (new byte[0], -1, 1);
1357                         }
1358                 }
1359
1360                 [Test]
1361                 [ExpectedException (typeof (ArgumentException))]
1362                 public void Read_OffsetOverflow ()
1363                 {
1364                         string path = TempFolder + Path.DirectorySeparatorChar + "temp";
1365                         DeleteFile (path);
1366
1367                         using (FileStream stream = new FileStream (path, FileMode.OpenOrCreate, FileAccess.Read)) {
1368                                 stream.Read (new byte[0], Int32.MaxValue, 1);
1369                         }
1370                 }
1371
1372                 [Test]
1373                 [ExpectedException (typeof (ArgumentOutOfRangeException))]
1374                 public void Read_CountNegative ()
1375                 {
1376                         string path = TempFolder + Path.DirectorySeparatorChar + "temp";
1377                         DeleteFile (path);
1378
1379                         using (FileStream stream = new FileStream (path, FileMode.OpenOrCreate, FileAccess.Read)) {
1380                                 stream.Read (new byte[0], 1, -1);
1381                         }
1382                 }
1383
1384                 [Test]
1385                 [ExpectedException (typeof (ArgumentException))]
1386                 public void Read_CountOverflow ()
1387                 {
1388                         string path = TempFolder + Path.DirectorySeparatorChar + "temp";
1389                         DeleteFile (path);
1390
1391                         using (FileStream stream = new FileStream (path, FileMode.OpenOrCreate, FileAccess.Read)) {
1392                                 stream.Read (new byte[0], 1, Int32.MaxValue);
1393                         }
1394                 }
1395
1396                 [Test]
1397                 [ExpectedException (typeof (ArgumentOutOfRangeException))]
1398                 public void Write_OffsetNegative ()
1399                 {
1400                         string path = TempFolder + Path.DirectorySeparatorChar + "temp";
1401                         DeleteFile (path);
1402
1403                         using (FileStream stream = new FileStream (path, FileMode.OpenOrCreate, FileAccess.Write)) {
1404                                 stream.Write (new byte[0], -1, 1);
1405                         }
1406                 }
1407
1408                 [Test]
1409                 [ExpectedException (typeof (ArgumentException))]
1410                 public void Write_OffsetOverflow ()
1411                 {
1412                         string path = TempFolder + Path.DirectorySeparatorChar + "temp";
1413                         DeleteFile (path);
1414
1415                         using (FileStream stream = new FileStream (path, FileMode.OpenOrCreate, FileAccess.Write)) {
1416                                 stream.Write (new byte[0], Int32.MaxValue, 1);
1417                         }
1418                 }
1419
1420                 [Test]
1421                 [ExpectedException (typeof (ArgumentOutOfRangeException))]
1422                 public void Write_CountNegative ()
1423                 {
1424                         string path = TempFolder + Path.DirectorySeparatorChar + "temp";
1425                         DeleteFile (path);
1426
1427                         using (FileStream stream = new FileStream (path, FileMode.OpenOrCreate, FileAccess.Write)) {
1428                                 stream.Write (new byte[0], 1, -1);
1429                         }
1430                 }
1431
1432                 [Test]
1433                 [ExpectedException (typeof (ArgumentException))]
1434                 public void Write_CountOverflow ()
1435                 {
1436                         string path = TempFolder + Path.DirectorySeparatorChar + "temp";
1437                         DeleteFile (path);
1438
1439                         using (FileStream stream = new FileStream (path, FileMode.OpenOrCreate, FileAccess.Write)) {
1440                                 stream.Write (new byte[0], 1, Int32.MaxValue);
1441                         }
1442                 }
1443
1444                 [Test]
1445                 [ExpectedException (typeof (ArgumentException))]
1446                 public void Seek_InvalidSeekOrigin ()
1447                 {
1448                         string path = TempFolder + Path.DirectorySeparatorChar + "temp";
1449                         DeleteFile (path);
1450
1451                         using (FileStream stream = new FileStream (path, FileMode.OpenOrCreate, FileAccess.Read)) {
1452                                 stream.Seek (0, (SeekOrigin) (-1));
1453                         }
1454                 }
1455
1456                 [Test]
1457                 [ExpectedException (typeof (ArgumentException))]
1458                 public void Constructor_InvalidFileHandle ()
1459                 {
1460                         new FileStream ((IntPtr) (-1L), FileAccess.Read);
1461                 }
1462
1463                 [Test]
1464                 public void PositionAfterSetLength ()
1465                 {
1466                         string path = TempFolder + Path.DirectorySeparatorChar + "temp";
1467                         DeleteFile (path);
1468
1469                         using (FileStream stream = new FileStream (path, FileMode.OpenOrCreate, FileAccess.Write)) {
1470                                 stream.SetLength (32);
1471                                 stream.Position = 32;
1472                                 stream.SetLength (16);
1473                                 Assert.AreEqual (16, stream.Position);
1474                         }
1475                 }
1476
1477                 [Test]
1478                 [ExpectedException (typeof (ObjectDisposedException))]
1479                 public void SetLength_Disposed ()
1480                 {
1481                         string path = TempFolder + Path.DirectorySeparatorChar + "temp";
1482                         DeleteFile (path);
1483                         FileStream stream = new FileStream (path, FileMode.OpenOrCreate, FileAccess.Write);
1484                         stream.Close ();
1485                         stream.SetLength (16);
1486                 }
1487
1488                 [Test]
1489                 [ExpectedException (typeof (ObjectDisposedException))]
1490                 public void Position_Disposed ()
1491                 {
1492                         string path = TempFolder + Path.DirectorySeparatorChar + "temp";
1493                         DeleteFile (path);
1494                         FileStream stream = new FileStream (path, FileMode.OpenOrCreate, FileAccess.Read);
1495                         stream.Close ();
1496                         stream.Position = 0;
1497                 }
1498
1499                 [Test]
1500                 [ExpectedException (typeof (ObjectDisposedException))]
1501                 public void BeginRead_Disposed ()
1502                 {
1503                         string path = TempFolder + Path.DirectorySeparatorChar + "temp";
1504                         DeleteFile (path);
1505                         FileStream stream = new FileStream (path, FileMode.OpenOrCreate, FileAccess.Read);
1506                         stream.Close ();
1507                         stream.EndRead (stream.BeginRead (new byte[8], 0, 8, null, null));
1508                 }
1509
1510                 [Test]
1511                 [ExpectedException (typeof (ObjectDisposedException))]
1512                 public void BeginWrite_Disposed ()
1513                 {
1514                         string path = TempFolder + Path.DirectorySeparatorChar + "temp";
1515                         DeleteFile (path);
1516                         FileStream stream = new FileStream (path, FileMode.OpenOrCreate, FileAccess.Write);
1517                         stream.Close ();
1518                         stream.EndWrite (stream.BeginWrite (new byte[8], 0, 8, null, null));
1519                 }
1520
1521                 static IAsyncResult DoBeginWrite(Stream stream, ManualResetEvent mre, byte[] RandomBuffer)
1522                 {
1523                         return stream.BeginWrite (RandomBuffer, 0, RandomBuffer.Length, ar => {
1524                                 IAsyncResult begin_write_recursive_ares;
1525
1526                                 try {
1527                                         stream.EndWrite (ar);
1528
1529                                         // we don't supply an ManualResetEvent so this will throw an NRE on the second run
1530                                         // which nunit-console will ignore (but other test runners don't like that)
1531                                         if (mre == null)
1532                                                 return;
1533
1534                                         begin_write_recursive_ares = DoBeginWrite (stream, null, RandomBuffer);
1535                                         begin_write_recursive_ares.AsyncWaitHandle.WaitOne ();
1536
1537                                         mre.Set ();
1538                                 } catch (ObjectDisposedException e) {
1539                                         Console.WriteLine ("stream was disposed: {0}", e);
1540                                 }
1541                         }, null);
1542                 }
1543
1544                 [Test]
1545                 public void BeginWrite_Recursive ()
1546                 {
1547                         string path = TempFolder + Path.DirectorySeparatorChar + "temp";
1548                         DeleteFile (path);
1549
1550                         IAsyncResult begin_write_ares = null;
1551
1552                         try {
1553                                 using (FileStream stream = new FileStream (path, FileMode.OpenOrCreate, FileAccess.Write)) {
1554                                         var mre = new ManualResetEvent (false);
1555                                         var RandomBuffer = new byte[1024];
1556                                         begin_write_ares = DoBeginWrite (stream, mre, RandomBuffer);
1557                                         Assert.IsTrue (mre.WaitOne (5000), "#1");
1558                                 }
1559                         } finally {
1560                                 if (begin_write_ares != null)
1561                                         begin_write_ares.AsyncWaitHandle.WaitOne ();
1562                         }
1563                 }
1564
1565                 [Test]
1566                 [ExpectedException (typeof (ObjectDisposedException))]
1567                 public void Lock_Disposed ()
1568                 {
1569                         string path = TempFolder + Path.DirectorySeparatorChar + "temp";
1570                         DeleteFile (path);
1571                         FileStream stream = new FileStream (path, FileMode.OpenOrCreate, FileAccess.Write);
1572                         stream.Close ();
1573                         stream.Lock (0, 1);
1574                 }
1575
1576                 [Test]
1577                 [ExpectedException (typeof (ObjectDisposedException))]
1578                 public void Unlock_Disposed ()
1579                 {
1580                         string path = TempFolder + Path.DirectorySeparatorChar + "temp";
1581                         DeleteFile (path);
1582                         FileStream stream = new FileStream (path, FileMode.OpenOrCreate, FileAccess.Write);
1583                         stream.Close ();
1584                         stream.Unlock (0, 1);
1585                 }
1586
1587                 [Test]
1588                 public void ReadBytePastEndOfStream ()
1589                 {
1590                         string path = TempFolder + Path.DirectorySeparatorChar + "temp";
1591                         DeleteFile (path);
1592                         using (FileStream stream = new FileStream (path, FileMode.OpenOrCreate, FileAccess.Read)) {
1593                                 stream.Seek (0, SeekOrigin.End);
1594                                 Assert.AreEqual (-1, stream.ReadByte ());
1595                                 stream.Close ();
1596                         }
1597                 }
1598
1599                 [Test]
1600                 [ExpectedException (typeof (NotSupportedException))]
1601                 public void SetLengthWithClosedBaseStream ()
1602                 {
1603                         string fn = Path.Combine (TempFolder, "temp");
1604                         try {
1605                                 FileStream fs = new FileStream (fn, FileMode.Create);
1606                                 BufferedStream bs = new BufferedStream (fs);
1607                                 fs.Close ();
1608
1609                                 bs.SetLength (1000);
1610                         } finally {
1611                                 File.Delete (fn);
1612                         }
1613                 }
1614
1615                 [Test]
1616                 public void LengthAfterWrite ()
1617                 {
1618                         string path = TempFolder + DSC + "oneofthefilescreated.txt";
1619                         FileStream fs = null;
1620                         DeleteFile (path);
1621                         try {
1622                                 fs = new FileStream (path, FileMode.CreateNew);
1623                                 fs.WriteByte (Convert.ToByte ('A'));
1624                                 byte [] buffer = Encoding.ASCII.GetBytes (" is a first character.");
1625                                 fs.Write (buffer, 0, buffer.Length);
1626                                 fs.Seek (0, SeekOrigin.Begin);
1627                                 char a = Convert.ToChar (fs.ReadByte ());
1628                                 Assert.AreEqual ('A', a, "#A1");
1629                                 Assert.AreEqual (23, fs.Length, "#A2");
1630                                 int nread = fs.Read (buffer, 0, 5);
1631                                 Assert.AreEqual (5, nread, "#A3");
1632                         } finally {
1633                                 if (fs != null)
1634                                         fs.Close ();
1635                                 DeleteFile (path);
1636                         }
1637                 }
1638
1639                 [Test]
1640                 public void DeleteOnClose ()
1641                 {
1642                         string path = TempFolder + DSC + "created.txt";
1643                         DeleteFile (path);
1644                         FileStream fs = new FileStream (path, FileMode.CreateNew, FileAccess.Write, FileShare.None, 1024,
1645                                                         FileOptions.DeleteOnClose);
1646                         Assert.AreEqual (true, File.Exists (path), "DOC#1");
1647                         fs.Close ();
1648                         Assert.AreEqual (false, File.Exists (path), "DOC#2");
1649                         
1650                 }
1651
1652                 [Test]
1653                 public void OpenCharDeviceRepeatedly ()
1654                 {
1655                         // https://bugzilla.xamarin.com/show_bug.cgi?id=38408
1656                         try {
1657                                 using (var f = new FileStream ("/dev/zero", FileMode.Open))
1658                                 {
1659                                 }
1660                         } catch (FileNotFoundException) {
1661                                 // Only run this test on platforms where /dev/zero exists
1662                                 Assert.Ignore();
1663                         } catch (DirectoryNotFoundException) {
1664                                 // Only run this test on platforms where /dev exists
1665                                 Assert.Ignore();
1666                         }
1667
1668                         // this shouldn't throw
1669                         using (var g = new FileStream ("/dev/zero", FileMode.Open))
1670                         {
1671                         }
1672                 }
1673
1674 #if !MOBILE
1675                 [Test]
1676                 public void WriteWithExposedHandle ()
1677                 {
1678                         string path = TempFolder + DSC + "exposed-handle.txt";
1679                         FileStream fs1 = null;
1680                         FileStream fs2 = null;
1681                         DeleteFile (path);
1682                         
1683                         try {
1684                                 fs1 = new FileStream (path, FileMode.Create);
1685                                 fs2 = new FileStream (fs1.SafeFileHandle, FileAccess.ReadWrite);
1686                                 fs1.WriteByte (Convert.ToByte ('H'));
1687                                 fs1.WriteByte (Convert.ToByte ('E'));
1688                                 fs1.WriteByte (Convert.ToByte ('L'));
1689                                 fs2.WriteByte (Convert.ToByte ('L'));
1690                                 fs2.WriteByte (Convert.ToByte ('O'));
1691                                 long fs1Pos = fs1.Position;
1692                                 fs1.Flush ();
1693                                 fs2.Flush (); 
1694                                 fs1.Close ();
1695                                 fs2.Close ();
1696
1697                                 var check = Encoding.ASCII.GetString (File.ReadAllBytes (path));
1698                                 Assert.AreEqual ("HELLO", check, "EXPOSED#1");
1699                                 Assert.AreEqual (5, fs1Pos, "EXPOSED#2");
1700                         } finally {
1701                                 if (fs1 != null)
1702                                         fs1.Close ();
1703                                 if (fs2 != null)
1704                                         fs2.Close ();
1705                                 DeleteFile (path);
1706                         }
1707                 }
1708
1709                 [Test]
1710                 public void Ctor_InvalidSafeHandle ()
1711                 {
1712                         var sf = new SafeFileHandle (IntPtr.Zero, true);
1713                         try {
1714                                 new FileStream (sf, FileAccess.ReadWrite);
1715                                 Assert.Fail ("#1");
1716                         } catch (ArgumentException) {
1717                         }
1718                 }
1719 #endif
1720
1721                 [Test] // Covers #11699
1722                 public void ReadWriteFileLength ()
1723                 {
1724                         int bufferSize = 128;
1725                         int readLength = 1;
1726                         int writeLength = bufferSize + 1;
1727
1728                         string path = TempFolder + DSC + "readwritefilelength.tmp";
1729
1730                         try {
1731                                 File.WriteAllBytes (path, new byte [readLength + 1]);
1732
1733                                 using (var file = new FileStream (path, FileMode.Open, FileAccess.ReadWrite, FileShare.Read,
1734                                                                                                  bufferSize, FileOptions.SequentialScan))
1735                                 {
1736                                         file.Read (new byte [readLength], 0, readLength);
1737                                         file.Write (new byte [writeLength], 0, writeLength);
1738
1739                                         Assert.AreEqual (readLength + writeLength, file.Length);
1740                                 }
1741                         } finally {
1742                                 DeleteFile (path);
1743                         }
1744                 }
1745         }
1746 }