Merge pull request #2102 from AdamBurgess/master
[mono.git] / mcs / class / corlib / Test / System.IO / MemoryStreamTest.cs
1 //
2 // System.IO.MemoryStreamTest
3 //
4 // Authors:
5 //      Marcin Szczepanski (marcins@zipworld.com.au)
6 //      Gonzalo Paniagua Javier (gonzalo@ximian.com)
7 //      Sebastien Pouliot  <sebastien@ximian.com>
8 //  Marek Safar (marek.safar@gmail.com)
9 //
10 // (c) 2003 Ximian, Inc. (http://www.ximian.com)
11 // Copyright (C) 2004 Novell (http://www.novell.com)
12 // Copyright 2011 Xamarin, Inc (http://www.xamarin.com)
13 //
14
15 using System;
16 using System.IO;
17 using System.Runtime.Serialization.Formatters.Binary;
18 using System.Text;
19 using System.Threading;
20 #if NET_4_5
21 using System.Threading.Tasks;
22 #endif
23
24 using NUnit.Framework;
25
26 namespace MonoTests.System.IO
27 {
28         [TestFixture]
29         public class MemoryStreamTest
30         {
31                 class SignaledMemoryStream : MemoryStream
32                 {
33                         WaitHandle w;
34
35                         public SignaledMemoryStream (byte[] buffer, WaitHandle w)
36                                 : base (buffer)
37                         {
38                                 this.w = w;
39                         }
40
41                         public override int Read (byte[] buffer, int offset, int count)
42                         {
43                                 if (!w.WaitOne (2000))
44                                         return -1;
45
46                                 Assert.IsTrue (Thread.CurrentThread.IsThreadPoolThread, "IsThreadPoolThread");
47                                 return base.Read (buffer, offset, count);
48                         }
49                 }
50
51                 class ExceptionalStream : MemoryStream
52                 {
53                         public static string Message = "ExceptionalMessage";
54                         public bool Throw = false;
55
56                         public ExceptionalStream ()
57                         {
58                                 AllowRead = true;
59                                 AllowWrite = true;
60                         }
61
62                         public ExceptionalStream (byte [] buffer, bool writable) : base (buffer, writable)
63                         {
64                                 AllowRead = true;
65                                 AllowWrite = true;  // we are testing the inherited write property
66                         }
67
68
69                         public override int Read(byte[] buffer, int offset, int count)
70                         {
71                                 if (Throw)
72                                         throw new Exception(Message);
73
74                                 return base.Read(buffer, offset, count);
75                         }
76
77                         public override void Write(byte[] buffer, int offset, int count)
78                         {
79                                 if (Throw)
80                                         throw new Exception(Message);
81
82                                 base.Write(buffer, offset, count);
83                         }
84
85                         public bool AllowRead { get; set; }
86                         public override bool CanRead { get { return AllowRead; } }
87
88                         public bool AllowWrite { get; set; }
89                         public override bool CanWrite { get { return AllowWrite; } }
90                         
91                         public override void Flush()
92                         {
93                                 if (Throw)
94                                         throw new Exception(Message);
95
96                                 base.Flush();
97                         }
98                 }
99
100                 MemoryStream testStream;
101                 byte [] testStreamData;
102
103                 [SetUp]
104                 public void SetUp ()
105                 {
106                         testStreamData = new byte [100];
107
108                         for (int i = 0; i < 100; i++)
109                                 testStreamData[i] = (byte) (100 - i);
110
111                         testStream = new MemoryStream (testStreamData);
112                 }
113
114                 // 
115                 // Verify that the first count bytes in testBytes are the same as
116                 // the count bytes from index start in testStreamData
117                 //
118                 void VerifyTestData (string id, byte [] testBytes, int start, int count)
119                 {
120                         if (testBytes == null)
121                                 Assert.Fail (id + "+1 testBytes is null");
122
123                         if (start < 0 ||
124                             count < 0  ||
125                             start + count > testStreamData.Length ||
126                             start > testStreamData.Length)
127                                 throw new ArgumentOutOfRangeException (id + "+2");
128
129                         for (int test = 0; test < count; test++) {
130                                 if (testBytes [test] == testStreamData [start + test])
131                                         continue;
132
133                                 string failStr = "testByte {0} (testStream {1}) was <{2}>, expecting <{3}>";
134                                 failStr = String.Format (failStr,
135                                                         test,
136                                                         start + test,
137                                                         testBytes [test],
138                                                         testStreamData [start + test]);
139                                 Assert.Fail (id + "-3" + failStr);
140                         }
141                 }
142
143                 public void AssertEquals (string message, int expected, int actual)
144                 {
145                         Assert.AreEqual (expected, actual, message);
146                 }
147
148                 public void AssertEquals (string message, long expected, long actual)
149                 {
150                         Assert.AreEqual (expected, actual, message);
151                 }
152
153                 public void AssertEquals (string message, bool expected, bool actual)
154                 {
155                         Assert.AreEqual (expected, actual, message);
156                 }
157
158                 [Test]
159                 public void ConstructorsOne ()
160                 {
161                         MemoryStream ms = new MemoryStream();
162
163                         AssertEquals ("#01", 0L, ms.Length);
164                         AssertEquals ("#02", 0, ms.Capacity);
165                         AssertEquals ("#03", true, ms.CanWrite);
166                 }
167
168                 [Test]
169                 public void ConstructorsTwo ()
170                 {
171                         MemoryStream ms = new MemoryStream (10);
172
173                         AssertEquals ("#01", 0L, ms.Length);
174                         AssertEquals ("#02", 10, ms.Capacity);
175                         ms.Capacity = 0;
176                         byte [] buffer = ms.GetBuffer ();
177                         // Begin: wow!!!
178                         AssertEquals ("#03", -1, ms.ReadByte ());
179                         Assert.IsNull (buffer, "#04"); // <--
180                         ms.Read (new byte [5], 0, 5);
181                         AssertEquals ("#05", 0, ms.Position);
182                         AssertEquals ("#06", 0, ms.Length);
183                         // End
184                 }
185
186                 [Test]
187                 public void ConstructorsThree ()
188                 {
189                         MemoryStream ms = new MemoryStream (testStreamData);
190                         AssertEquals ("#01", 100, ms.Length);
191                         AssertEquals ("#02", 0, ms.Position);
192                 }
193
194                 [Test]
195                 public void ConstructorsFour ()
196                 {
197                         MemoryStream ms = new MemoryStream (testStreamData, true);
198                         AssertEquals ("#01", 100, ms.Length);
199                         AssertEquals ("#02", 0, ms.Position);
200                         ms.Position = 50;
201                         byte saved = testStreamData [50];
202                         try {
203                                 ms.WriteByte (23);
204                                 AssertEquals ("#03", testStreamData [50], 23);
205                         } finally {
206                                 testStreamData [50] = saved;
207                         }
208                         ms.Position = 100;
209                         try {
210                                 ms.WriteByte (23);
211                         } catch (Exception) {
212                                 return;
213                         }
214                         Assert.Fail ("#04");
215                 }
216
217                 [Test]
218                 public void ConstructorsFive ()
219                 {
220                         MemoryStream ms = new MemoryStream (testStreamData, 50, 50);
221                         AssertEquals ("#01", 50, ms.Length);
222                         AssertEquals ("#02", 0, ms.Position);
223                         AssertEquals ("#03", 50, ms.Capacity);
224                         ms.Position = 1;
225                         byte saved = testStreamData [51];
226                         try {
227                                 ms.WriteByte (23);
228                                 AssertEquals ("#04", testStreamData [51], 23);
229                         } finally {
230                                 testStreamData [51] = saved;
231                         }
232                         ms.Position = 100;
233
234                         try {
235                                 ms.WriteByte (23);
236                                 Assert.Fail ("#05");
237                         } catch (NotSupportedException) {
238                         }
239
240                         try {
241                                 ms.Capacity = 100;
242                                 Assert.Fail ("#06");
243                         } catch (NotSupportedException) {
244                         }
245                                            
246                         try {
247                                 ms.Capacity = 51;
248                                 Assert.Fail ("#07");
249                         } catch (NotSupportedException) {
250                         }
251
252                         AssertEquals ("#08", 50, ms.ToArray ().Length);
253                 }
254
255                 [Test]
256                 [ExpectedException (typeof (ArgumentOutOfRangeException))]
257                 public void ConstructorsSix ()
258                 {
259                         MemoryStream ms = new MemoryStream (-2);
260                 }
261
262                 [Test]
263                 public void Read ()
264                 {
265                         byte [] readBytes = new byte [20];
266
267                         /* Test simple read */
268                         testStream.Read (readBytes, 0, 10);
269                         VerifyTestData ("R1", readBytes, 0, 10);
270
271                         /* Seek back to beginning */
272
273                         testStream.Seek (0, SeekOrigin.Begin);
274
275                         /* Read again, bit more this time */
276                         testStream.Read (readBytes, 0, 20);
277                         VerifyTestData ("R2", readBytes, 0, 20);
278
279                         /* Seek to 20 bytes from End */
280                         testStream.Seek (-20, SeekOrigin.End);
281                         testStream.Read (readBytes, 0, 20);
282                         VerifyTestData ("R3", readBytes, 80, 20);
283
284                         int readByte = testStream.ReadByte();
285                         Assert.AreEqual (-1, readByte, "R4");
286                 }
287                 
288                 [Test]
289                 public void BeginRead ()
290                 {
291                         byte [] readBytes = new byte [5];
292
293                         var res = testStream.BeginRead (readBytes, 0, 5, null, null);
294                         Assert.IsTrue (res.AsyncWaitHandle.WaitOne (1000), "#1");
295                         Assert.AreEqual (5, testStream.EndRead (res), "#2");
296                 }
297
298                 [Test]
299                 public void BeginRead_WithState ()
300                 {
301                         byte [] readBytes = new byte [5];
302                         string async_state = null;
303                         var wh = new ManualResetEvent (false);
304
305                         var res = testStream.BeginRead (readBytes, 0, 5, l => {
306                                 async_state = l.AsyncState as string;
307                                 wh.Set ();
308                         }, "state");
309
310                         Assert.IsTrue (res.AsyncWaitHandle.WaitOne (1000), "#1");
311                         Assert.AreEqual ("state", res.AsyncState, "#2");
312                         Assert.IsTrue (res.IsCompleted, "#3");
313                         Assert.AreEqual (5, testStream.EndRead (res), "#4");
314
315                         wh.WaitOne (1000);
316                         Assert.AreEqual ("state", async_state, "#5");
317                         wh.Close ();
318                 }
319                 
320                 [Test]
321                 public void BeginReadAsync ()
322                 {
323                         byte[] readBytes = new byte[5];
324                         var wh = new ManualResetEvent (false);
325                         using (var testStream = new SignaledMemoryStream (testStreamData, wh)) {
326                                 var res = testStream.BeginRead (readBytes, 0, 5, null, null);
327                                 Assert.IsFalse (res.IsCompleted, "#1");
328                                 Assert.IsFalse (res.CompletedSynchronously, "#2");
329                                 wh.Set ();
330                                 Assert.IsTrue (res.AsyncWaitHandle.WaitOne (2000), "#3");
331                                 Assert.IsTrue (res.IsCompleted, "#4");
332                                 Assert.AreEqual (5, testStream.EndRead (res), "#5");
333                         }
334
335                         wh.Close ();
336                 }
337
338                 [Test]
339                 public void BeginReadIsBlockingNextRead ()
340                 {
341                         byte[] readBytes = new byte[5];
342                         byte[] readBytes2 = new byte[3];
343                         ManualResetEvent begin_read_unblock = new ManualResetEvent (false);
344                         ManualResetEvent begin_read_blocking = new ManualResetEvent (false);
345                         Task begin_read_task = null;
346
347                         try {
348                                 using (var testStream = new SignaledMemoryStream (testStreamData, begin_read_unblock)) {
349                                         IAsyncResult begin_read_1_ares = testStream.BeginRead (readBytes, 0, 5, null, null);
350
351                                         begin_read_task = Task.Factory.StartNew (() => {
352                                                 IAsyncResult begin_read_2_ares = testStream.BeginRead (readBytes2, 0, 3, null, null);
353                                                 begin_read_blocking.Set ();
354
355                                                 Assert.IsTrue (begin_read_2_ares.AsyncWaitHandle.WaitOne (2000), "#10");
356                                                 Assert.IsTrue (begin_read_2_ares.IsCompleted, "#11");
357                                                 Assert.AreEqual (3, testStream.EndRead (begin_read_2_ares), "#12");
358                                                 Assert.AreEqual (95, readBytes2[0], "#13");
359                                         });
360
361                                         Assert.IsFalse (begin_read_1_ares.IsCompleted, "#1");
362                                         Assert.IsFalse (begin_read_blocking.WaitOne (500), "#2");
363
364                                         begin_read_unblock.Set ();
365
366                                         Assert.IsTrue (begin_read_1_ares.AsyncWaitHandle.WaitOne (2000), "#3");
367                                         Assert.IsTrue (begin_read_1_ares.IsCompleted, "#4");
368                                         Assert.AreEqual (5, testStream.EndRead (begin_read_1_ares), "#5");
369                                         Assert.IsTrue (begin_read_task.Wait (2000), "#6");
370                                         Assert.AreEqual (100, readBytes[0], "#7");
371                                 }
372                         } finally {
373                                 if (begin_read_task != null)
374                                         begin_read_task.Wait ();
375                         }
376                 }
377
378                 [Test]
379                 public void BeginRead_Read ()
380                 {
381                         byte[] readBytes = new byte[5];
382                         var wh = new ManualResetEvent (false);
383                         using (var testStream = new SignaledMemoryStream (testStreamData, wh)) {
384                                 var res = testStream.BeginRead (readBytes, 0, 5, null, null);
385                                 Assert.AreEqual (100, testStream.ReadByte (), "#0");
386                                 Assert.IsFalse (res.IsCompleted, "#1");
387                                 Assert.IsFalse (res.CompletedSynchronously, "#2");
388                                 wh.Set ();
389                                 Assert.IsTrue (res.AsyncWaitHandle.WaitOne (2000), "#3");
390                                 Assert.IsTrue (res.IsCompleted, "#4");
391                                 Assert.AreEqual (5, testStream.EndRead (res), "#5");
392                                 Assert.AreEqual (99, readBytes [0], "#6");
393                         }
394
395                         wh.Close ();
396                 }
397
398                 [Test]
399                 public void BeginRead_BeginWrite ()
400                 {
401                         byte[] readBytes = new byte[5];
402                         byte[] readBytes2 = new byte[3] { 1, 2, 3 };
403                         ManualResetEvent begin_read_unblock = new ManualResetEvent (false);
404                         ManualResetEvent begin_write_blocking = new ManualResetEvent (false);
405                         Task begin_write_task = null;
406
407                         try {
408                                 using (MemoryStream stream = new SignaledMemoryStream (testStreamData, begin_read_unblock)) {
409                                         IAsyncResult begin_read_ares = stream.BeginRead (readBytes, 0, 5, null, null);
410
411                                         begin_write_task = Task.Factory.StartNew (() => {
412                                                 var begin_write_ares = stream.BeginWrite (readBytes2, 0, 3, null, null);
413                                                 begin_write_blocking.Set ();
414                                                 Assert.IsTrue (begin_write_ares.AsyncWaitHandle.WaitOne (2000), "#10");
415                                                 Assert.IsTrue (begin_write_ares.IsCompleted, "#11");
416                                                 stream.EndWrite (begin_write_ares);
417                                         });
418
419                                         Assert.IsFalse (begin_read_ares.IsCompleted, "#1");
420                                         Assert.IsFalse (begin_write_blocking.WaitOne (500), "#2");
421
422                                         begin_read_unblock.Set ();
423
424                                         Assert.IsTrue (begin_read_ares.AsyncWaitHandle.WaitOne (2000), "#3");
425                                         Assert.IsTrue (begin_read_ares.IsCompleted, "#4");
426                                         Assert.AreEqual (5, stream.EndRead (begin_read_ares), "#5");
427                                         Assert.IsTrue (begin_write_task.Wait (2000), "#6");
428                                 }
429                         } finally {
430                                 if (begin_write_task != null)
431                                         begin_write_task.Wait ();
432                         }
433                 }
434
435                 [Test]
436                 public void BeginWrite ()
437                 {
438                         var writeBytes = new byte [5] { 2, 3, 4, 10, 12 };
439
440                         var res = testStream.BeginWrite (writeBytes, 0, 5, null, null);
441                         Assert.IsTrue (res.AsyncWaitHandle.WaitOne (1000), "#1");
442                         testStream.EndWrite (res);
443                 }
444
445                 [Test]
446                 public void BeginWrite_WithState ()
447                 {
448                         var writeBytes = new byte[5] { 2, 3, 4, 10, 12 };
449                         string async_state = null;
450                         var wh = new ManualResetEvent (false);
451
452                         var res = testStream.BeginWrite (writeBytes, 0, 5, l => {
453                                 async_state = l.AsyncState as string;
454                                 wh.Set ();
455                         }, "state");
456
457                         Assert.IsTrue (res.AsyncWaitHandle.WaitOne (1000), "#1");
458                         Assert.IsTrue (res.IsCompleted, "#2");
459                         Assert.AreEqual ("state", res.AsyncState, "#3");
460                         testStream.EndWrite (res);
461
462                         wh.WaitOne (1000);
463                         Assert.AreEqual ("state", async_state, "#4");
464                         wh.Close ();
465                 }
466                 
467                 [Test]
468                 public void EndRead_Twice ()
469                 {
470                         byte[] readBytes = new byte[5];
471
472                         var res = testStream.BeginRead (readBytes, 0, 5, null, null);
473                         Assert.IsTrue (res.AsyncWaitHandle.WaitOne (1000), "#1");
474                         Assert.AreEqual (5, testStream.EndRead (res), "#2");
475
476                         try {
477                                 testStream.EndRead (res);
478                                 Assert.Fail ("#3");
479                         } catch (ArgumentException) {
480                                 return;
481                         }
482                 }
483
484                 [Test]
485                 public void EndRead_Disposed ()
486                 {
487                         byte[] readBytes = new byte[5];
488
489                         var res = testStream.BeginRead (readBytes, 0, 5, null, null);
490                         Assert.IsTrue (res.AsyncWaitHandle.WaitOne (1000), "#1");
491                         testStream.Dispose ();
492                         Assert.AreEqual (5, testStream.EndRead (res), "#2");
493                 }
494                 
495                 [Test]
496                 public void EndWrite_OnBeginRead ()
497                 {
498                         byte[] readBytes = new byte[5];
499
500                         var res = testStream.BeginRead (readBytes, 0, 5, null, null);
501                         Assert.IsTrue (res.AsyncWaitHandle.WaitOne (1000), "#1");
502
503                         try {
504                                 testStream.EndWrite (res);
505                                 Assert.Fail ("#2");
506                         } catch (ArgumentException) {
507                         }
508
509                         testStream.EndRead (res);
510                 }
511
512                 [Test]
513                 public void EndWrite_Twice ()
514                 {
515                         var wBytes = new byte[5];
516
517                         var res = testStream.BeginWrite (wBytes, 0, 5, null, null);
518                         Assert.IsTrue (res.AsyncWaitHandle.WaitOne (1000), "#1");
519                         testStream.EndWrite (res);
520
521                         try {
522                                 testStream.EndWrite (res);
523                                 Assert.Fail ("#2");
524                         } catch (ArgumentException) {
525                                 return;
526                         }
527                 }
528
529                 
530                 [Test]
531                 public void WriteBytes ()
532                 {
533                         byte[] readBytes = new byte[100];
534
535                         MemoryStream ms = new MemoryStream (100);
536
537                         for (int i = 0; i < 100; i++)
538                                 ms.WriteByte (testStreamData [i]);
539
540                         ms.Seek (0, SeekOrigin.Begin); 
541                         testStream.Read (readBytes, 0, 100);
542                         VerifyTestData ("W1", readBytes, 0, 100);
543                 }
544
545                 [Test]
546                 public void WriteBlock ()
547                 {
548                         byte[] readBytes = new byte[100];
549
550                         MemoryStream ms = new MemoryStream (100);
551
552                         ms.Write (testStreamData, 0, 100);
553                         ms.Seek (0, SeekOrigin.Begin); 
554                         testStream.Read (readBytes, 0, 100);
555                         VerifyTestData ("WB1", readBytes, 0, 100);
556                         byte[] arrayBytes = testStream.ToArray();
557                         AssertEquals ("#01", 100, arrayBytes.Length);
558                         VerifyTestData ("WB2", arrayBytes, 0, 100);
559                 }
560
561                 [Test]
562                 public void PositionLength ()
563                 {
564                         MemoryStream ms = new MemoryStream ();
565                         ms.Position = 4;
566                         ms.WriteByte ((byte) 'M');
567                         ms.WriteByte ((byte) 'O');
568                         AssertEquals ("#01", 6, ms.Length);
569                         AssertEquals ("#02", 6, ms.Position);
570                         ms.Position = 0;
571                         AssertEquals ("#03", 0, ms.Position);
572                 }
573
574                 [Test]
575                 [ExpectedException (typeof (NotSupportedException))]
576                 public void MorePositionLength ()
577                 {
578                         MemoryStream ms = new MemoryStream (testStreamData);
579                         ms.Position = 101;
580                         AssertEquals ("#01", 101, ms.Position);
581                         AssertEquals ("#02", 100, ms.Length);
582                         ms.WriteByte (1); // This should throw the exception
583                 }
584
585                 [Test]
586                 public void GetBufferOne ()
587                 {
588                         MemoryStream ms = new MemoryStream ();
589                         byte [] buffer = ms.GetBuffer ();
590                         AssertEquals ("#01", 0, buffer.Length);
591                 }
592
593                 [Test]
594                 public void GetBufferTwo ()
595                 {
596                         MemoryStream ms = new MemoryStream (100);
597                         byte [] buffer = ms.GetBuffer ();
598                         AssertEquals ("#01", 100, buffer.Length);
599
600                         ms.Write (testStreamData, 0, 100);
601                         ms.Write (testStreamData, 0, 100);
602                         AssertEquals ("#02", 200, ms.Length);
603                         buffer = ms.GetBuffer ();
604                         AssertEquals ("#03", 256, buffer.Length); // Minimun size after writing
605                 }
606
607                 [Test]
608                 public void Closed ()
609                 {
610                         MemoryStream ms = new MemoryStream (100);
611                         ms.Close ();
612                         bool thrown = false;
613                         try {
614                                 int x = ms.Capacity;
615                         } catch (ObjectDisposedException) {
616                                 thrown = true;
617                         }
618
619                         if (!thrown)
620                                 Assert.Fail ("#01");
621
622                         thrown = false;
623                         try {
624                                 ms.Capacity = 1;
625                         } catch (ObjectDisposedException) {
626                                 thrown = true;
627                         }
628
629                         if (!thrown)
630                                 Assert.Fail ("#02");
631
632                         try {
633                                 ms.Read (null, 0, 1);
634                                 Assert.Fail ("#03");
635                         } catch (ArgumentNullException) {
636                         }
637
638                         try {
639                                 ms.Write (null, 0, 1);
640                                 Assert.Fail ("#04");
641                         } catch (ArgumentNullException) {
642                                 thrown = true;
643                         }
644                 }
645
646                 [Test]
647                 [ExpectedException (typeof (ObjectDisposedException))]
648                 public void Close_get_Length () 
649                 {
650                         MemoryStream ms = new MemoryStream (100);
651                         ms.Close ();
652                         long x = ms.Length;
653                 }
654
655                 [Test]
656                 [ExpectedException (typeof (ObjectDisposedException))]
657                 public void Close_get_Position () 
658                 {
659                         MemoryStream ms = new MemoryStream (100);
660                         ms.Close ();
661                         long x = ms.Position;
662                 }
663
664                 [Test]
665                 [ExpectedException (typeof (ObjectDisposedException))]
666                 public void Close_set_Position () 
667                 {
668                         MemoryStream ms = new MemoryStream (100);
669                         ms.Close ();
670                         ms.Position = 0;
671                 }
672
673                 [Test]
674                 public void Seek ()
675                 {
676                         MemoryStream ms = new MemoryStream (100);
677                         ms.Write (testStreamData, 0, 100);
678                         ms.Seek (0, SeekOrigin.Begin);
679                         ms.Position = 50;
680                         ms.Seek (-50, SeekOrigin.Current);
681                         ms.Seek (-50, SeekOrigin.End);
682
683                         bool thrown = false;
684                         ms.Position = 49;
685                         try {
686                                 ms.Seek (-50, SeekOrigin.Current);
687                         } catch (IOException) {
688                                 thrown = true;
689                         }
690                         if (!thrown)
691                                 Assert.Fail ("#01");
692                         
693                         thrown = false;
694                         try {
695                                 ms.Seek (Int64.MaxValue, SeekOrigin.Begin);
696                         } catch (ArgumentOutOfRangeException) {
697                                 thrown = true;
698                         }
699
700                         if (!thrown)
701                                 Assert.Fail ("#02");
702
703                         thrown=false;
704                         try {
705                                 // Oh, yes. They throw IOException for this one, but ArgumentOutOfRange for the previous one
706                                 ms.Seek (Int64.MinValue, SeekOrigin.Begin);
707                         } catch (IOException) {
708                                 thrown = true;
709                         }
710
711                         if (!thrown)
712                                 Assert.Fail ("#03");
713
714                         ms=new MemoryStream (256);
715
716                         ms.Write (testStreamData, 0, 100);
717                         ms.Position=0;
718                         AssertEquals ("#01", 100, ms.Length);
719                         AssertEquals ("#02", 0, ms.Position);
720
721                         ms.Position=128;
722                         AssertEquals ("#03", 100, ms.Length);
723                         AssertEquals ("#04", 128, ms.Position);
724
725                         ms.Position=768;
726                         AssertEquals ("#05", 100, ms.Length);
727                         AssertEquals ("#06", 768, ms.Position);
728
729                         ms.WriteByte (0);
730                         AssertEquals ("#07", 769, ms.Length);
731                         AssertEquals ("#08", 769, ms.Position);
732                 }
733
734                 [Test]
735                 public void Seek_Disposed () 
736                 {
737                         MemoryStream ms = new MemoryStream ();
738                         ms.Close ();
739                         try {
740                                 ms.Seek (0, SeekOrigin.Begin);
741                                 Assert.Fail ();
742                         } catch (ObjectDisposedException) {
743                         }
744                 }
745
746                 [Test]
747                 public void SetLength ()
748                 {
749                         MemoryStream ms = new MemoryStream ();
750                         ms.Write (testStreamData, 0, 100);
751                         ms.Position = 100;
752                         ms.SetLength (150);
753                         AssertEquals ("#01", 150, ms.Length);
754                         AssertEquals ("#02", 100, ms.Position);
755                         ms.SetLength (80);
756                         AssertEquals ("#03", 80, ms.Length);
757                         AssertEquals ("#04", 80, ms.Position);
758                 }
759
760                 [Test]
761                 [ExpectedException (typeof (NotSupportedException))]
762                 public void SetLength_ReadOnly ()
763                 {
764                         MemoryStream ms = new MemoryStream (testStreamData, false);
765                         ms.SetLength (10);
766                 }
767
768                 [Test]
769                 public void Capacity ()
770                 {
771                         MemoryStream ms = new MemoryStream ();
772
773                         Assert.AreEqual (0, ms.Capacity, "#A1");
774                         Assert.AreEqual (0, ms.GetBuffer ().Length, "#A2");
775
776                         ms.WriteByte ((byte)'6');
777                         Assert.AreEqual (256, ms.Capacity, "#B1");
778                         Assert.AreEqual (256, ms.GetBuffer ().Length, "#B2");
779
780                         // Shrink
781                         ms.Capacity = 100;
782                         Assert.AreEqual (100, ms.Capacity, "#C1");
783                         Assert.AreEqual (100, ms.GetBuffer ().Length, "#C2");
784
785                         // Grow
786                         ms.Capacity = 120;
787                         Assert.AreEqual (120, ms.Capacity, "#D1");
788                         Assert.AreEqual (120, ms.GetBuffer ().Length, "#D2");
789
790                         // Grow the buffer, reduce length -so we have a dirty area-
791                         // and then we assign capacity to the same. The idea is that we should
792                         // avoid creating a new internal buffer it's not needed.
793
794                         ms = new MemoryStream ();
795                         ms.Capacity = 8;
796                         byte [] buff = new byte [] { 0x01, 0x02, 0x03, 0x04, 0x05 };
797                         ms.Write (buff, 0, buff.Length);
798                         Assert.AreEqual (8, ms.Capacity, "#E1");
799                         Assert.AreEqual (8, ms.GetBuffer ().Length, "#E2");
800
801                         // Reduce *length*, not capacity
802                         byte [] buff_copy = ms.GetBuffer ();
803                         ms.SetLength (3);
804                         Assert.AreEqual (3, ms.Length, "#F1");
805                         Assert.AreEqual (true, AreBuffersEqual (buff_copy, ms.GetBuffer ()), "#F2");
806
807                         // Set Capacity to the very same value it has now
808                         ms.Capacity = ms.Capacity;
809                         Assert.AreEqual (true, AreBuffersEqual (buff_copy, ms.GetBuffer ()), "#G1"); // keep the same buffer
810
811                         // Finally, growing it discards the prev buff
812                         ms.Capacity = ms.Capacity + 1;
813                         Assert.AreEqual (false, AreBuffersEqual (buff_copy, ms.GetBuffer ()), "#H1");
814                 }
815
816                 bool AreBuffersEqual (byte [] buff1, byte [] buff2)
817                 {
818                         if ((buff1 == null) != (buff2 == null))
819                                 return false;
820
821                         if (buff1.Length != buff2.Length)
822                                 return false;
823
824                         for (int i = 0; i < buff1.Length; i++)
825                                 if (buff1 [i] != buff2 [i])
826                                         return false;
827
828                         return true;
829                 }
830
831                 [Test] // bug #327053
832                 public void ZeroingOnExpand ()
833                 {
834                         byte [] values = { 3, 2, 1 };
835                         byte [] reference = { 3, 2, 1 };
836                         byte [] cropped = { 3, 0, 0 };
837                         MemoryStream ms = new MemoryStream (values);
838                         Assert.AreEqual (values, reference, "#A1");
839                         ms.Seek (3, SeekOrigin.Begin);
840                         Assert.AreEqual (reference, values, "#A2");
841                         ms.SetLength (1);
842                         Assert.AreEqual (reference, values, "#B1");
843                         byte [] read = new byte [5];
844                         ms.Read (read, 0, 5);
845                         Assert.AreEqual (new byte [] { 0, 0, 0, 0, 0 }, read, "#B2");
846                         Assert.AreEqual (reference, values, "#B3");
847                         ms.SetLength (3);
848                         Assert.AreEqual (cropped, values, "#C1");
849                         ms.Seek (0, SeekOrigin.Begin);
850                         read = new byte [3];
851                         ms.Read (read, 0, 3);
852                         Assert.AreEqual (cropped, read, "#C2");
853                         Assert.AreEqual (cropped, values, "#C3");
854                 }
855
856                 [Test]
857                 [ExpectedException (typeof (NotSupportedException))]
858                 public void WriteNonWritable ()
859                 {
860                         MemoryStream ms = new MemoryStream (testStreamData, false);
861                         ms.Write (testStreamData, 0, 100);
862                 }
863
864                 [Test]
865                 [ExpectedException (typeof (NotSupportedException))]
866                 public void WriteExpand ()
867                 {
868                         MemoryStream ms = new MemoryStream (testStreamData);
869                         ms.Write (testStreamData, 0, 100);
870                         ms.Write (testStreamData, 0, 100); // This one throws the exception
871                 }
872
873                 [Test]
874                 public void WriteByte ()
875                 {
876                         MemoryStream ms = new MemoryStream (100);
877                         ms.Write (testStreamData, 0, 100);
878                         ms.Position = 100;
879                         ms.WriteByte (101);
880                         AssertEquals ("#01", 101, ms.Position);
881                         AssertEquals ("#02", 101, ms.Length);
882                         AssertEquals ("#03", 256, ms.Capacity);
883                         ms.Write (testStreamData, 0, 100);
884                         ms.Write (testStreamData, 0, 100);
885                         // 301
886                         AssertEquals ("#04", 301, ms.Position);
887                         AssertEquals ("#05", 301, ms.Length);
888                         AssertEquals ("#06", 512, ms.Capacity);
889                 }
890
891                 [Test]
892                 public void WriteLengths () {
893                         MemoryStream ms=new MemoryStream (256);
894                         BinaryWriter writer=new BinaryWriter (ms);
895
896                         writer.Write ((byte)'1');
897                         AssertEquals ("#01", 1, ms.Length);
898                         AssertEquals ("#02", 256, ms.Capacity);
899                         
900                         writer.Write ((ushort)0);
901                         AssertEquals ("#03", 3, ms.Length);
902                         AssertEquals ("#04", 256, ms.Capacity);
903
904                         writer.Write (testStreamData, 0, 23);
905                         AssertEquals ("#05", 26, ms.Length);
906                         AssertEquals ("#06", 256, ms.Capacity);
907
908                         writer.Write (testStreamData);
909                         writer.Write (testStreamData);
910                         writer.Write (testStreamData);
911                         AssertEquals ("#07", 326, ms.Length);
912                 }
913
914                 [Test]
915                 public void MoreWriteByte ()
916                 {
917                         byte[] buffer = new byte [44];
918                         
919                         MemoryStream ms = new MemoryStream (buffer);
920                         BinaryWriter bw = new BinaryWriter (ms);
921                         for(int i=0; i < 44; i++)
922                                 bw.Write ((byte) 1);
923                 }
924
925                 [Test]
926                 [ExpectedException (typeof (NotSupportedException))]
927                 public void MoreWriteByte2 ()
928                 {
929                         byte[] buffer = new byte [43]; // Note the 43 here
930                         
931                         MemoryStream ms = new MemoryStream (buffer);
932                         BinaryWriter bw = new BinaryWriter (ms);
933                         for(int i=0; i < 44; i++)
934                                 bw.Write ((byte) 1);
935                 }
936
937                 [Test]
938                 public void Expand () 
939                 {
940                         byte[] array = new byte [8] { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 };
941                         MemoryStream ms = new MemoryStream ();
942                         ms.Write (array, 0, array.Length);
943                         ms.SetLength (4);
944                         ms.Seek (4, SeekOrigin.End);
945                         ms.WriteByte (0xFF);
946                         Assert.AreEqual ("01-01-01-01-00-00-00-00-FF", BitConverter.ToString (ms.ToArray ()), "Result");
947                 }
948
949                 [Test]
950                 public void PubliclyVisible ()
951                 {
952                         MemoryStream ms = new MemoryStream ();
953                         Assert.IsNotNull (ms.GetBuffer (), "ctor()");
954
955                         ms = new MemoryStream (1);
956                         Assert.IsNotNull (ms.GetBuffer (), "ctor(1)");
957
958                         ms = new MemoryStream (new byte[1], 0, 1, true, true);
959                         Assert.IsNotNull (ms.GetBuffer (), "ctor(byte[],int,int,bool,bool");
960                 }
961
962                 [Test]
963                 [ExpectedException (typeof (UnauthorizedAccessException))]
964                 public void PubliclyVisible_Ctor_ByteArray ()
965                 {
966                         MemoryStream ms = new MemoryStream (new byte[0]);
967                         Assert.IsNotNull (ms.GetBuffer ());
968                 }
969
970                 [Test]
971                 [ExpectedException (typeof (UnauthorizedAccessException))]
972                 public void PubliclyVisible_Ctor_ByteArray_Boolean ()
973                 {
974                         MemoryStream ms = new MemoryStream (new byte[0], true);
975                         Assert.IsNotNull (ms.GetBuffer ());
976                 }
977
978                 [Test]
979                 [ExpectedException (typeof (UnauthorizedAccessException))]
980                 public void PubliclyVisible_Ctor_ByteArray_Int_Int ()
981                 {
982                         MemoryStream ms = new MemoryStream (new byte[1], 0, 1);
983                         Assert.IsNotNull (ms.GetBuffer ());
984                 }
985
986                 [Test]
987                 [ExpectedException (typeof (UnauthorizedAccessException))]
988                 public void PubliclyVisible_Ctor_ByteArray_Int_Int_Boolean ()
989                 {
990                         MemoryStream ms = new MemoryStream (new byte[1], 0, 1, true);
991                         Assert.IsNotNull (ms.GetBuffer ());
992                 }
993
994                 [Test]
995                 [ExpectedException (typeof (UnauthorizedAccessException))]
996                 public void PubliclyVisible_Ctor_ByteArray_Int_Int_Boolean_Boolean ()
997                 {
998                         MemoryStream ms = new MemoryStream (new byte[1], 0, 1, true, false);
999                         Assert.IsNotNull (ms.GetBuffer ());
1000                 }
1001
1002                 [Test] // bug #350860
1003                 public void ToArray_Empty ()
1004                 {
1005                         MemoryStream ms = new MemoryStream (1);
1006                         ms.Capacity = 0;
1007                         ms.ToArray ();
1008                 }
1009
1010                 [Test] // bug #80205
1011                 [Category ("NotWorking")]
1012                 public void SerializeTest ()
1013                 {
1014                         MemoryStream input = new MemoryStream ();
1015                         byte [] bufferIn = Encoding.UTF8.GetBytes ("some test");
1016                         input.Write (bufferIn, 0, bufferIn.Length);
1017                         input.Position = 0;
1018
1019                         BinaryFormatter bf = new BinaryFormatter ();
1020                         MemoryStream ms = new MemoryStream ();
1021                         bf.Serialize (ms, input);
1022
1023                         byte [] bufferOut = new byte [ms.Length];
1024                         ms.Position = 0;
1025                         ms.Read (bufferOut, 0, bufferOut.Length);
1026
1027                         Assert.AreEqual (_serialized, bufferOut);
1028                 }
1029
1030                 [Test] // bug #676060
1031                 public void ZeroCapacity ()
1032                 {
1033                         MemoryStream ms = new MemoryStream();
1034                         ms.WriteByte(1);
1035                         ms.Position = 0;
1036                         ms.SetLength(0);
1037                         ms.Capacity = 0;
1038                         ms.WriteByte(1);
1039                         byte[] bytes = ms.ToArray();
1040                 }
1041
1042                 [Test] // bug #80205
1043                 [Category ("NotWorking")]
1044                 public void DeserializeTest ()
1045                 {
1046                         MemoryStream ms = new MemoryStream ();
1047                         ms.Write (_serialized, 0, _serialized.Length);
1048                         ms.Position = 0;
1049
1050                         BinaryFormatter bf = new BinaryFormatter ();
1051                         MemoryStream output = (MemoryStream) bf.Deserialize (ms);
1052                         using (StreamReader sr = new StreamReader (output)) {
1053                                 Assert.AreEqual ("some test", sr.ReadToEnd ());
1054                         }
1055                 }
1056
1057                 private static byte [] _serialized = new byte [] {
1058                         0x00, 0x01, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00,
1059                         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x01, 0x00, 0x00, 0x00,
1060                         0x16, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x2e, 0x49, 0x4f, 0x2e,
1061                         0x4d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x53, 0x74, 0x72, 0x65, 0x61,
1062                         0x6d, 0x0a, 0x00, 0x00, 0x00, 0x07, 0x5f, 0x62, 0x75, 0x66, 0x66,
1063                         0x65, 0x72, 0x07, 0x5f, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x09,
1064                         0x5f, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x07, 0x5f,
1065                         0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x09, 0x5f, 0x63, 0x61, 0x70,
1066                         0x61, 0x63, 0x69, 0x74, 0x79, 0x0b, 0x5f, 0x65, 0x78, 0x70, 0x61,
1067                         0x6e, 0x64, 0x61, 0x62, 0x6c, 0x65, 0x09, 0x5f, 0x77, 0x72, 0x69,
1068                         0x74, 0x61, 0x62, 0x6c, 0x65, 0x0a, 0x5f, 0x65, 0x78, 0x70, 0x6f,
1069                         0x73, 0x61, 0x62, 0x6c, 0x65, 0x07, 0x5f, 0x69, 0x73, 0x4f, 0x70,
1070                         0x65, 0x6e, 0x1d, 0x4d, 0x61, 0x72, 0x73, 0x68, 0x61, 0x6c, 0x42,
1071                         0x79, 0x52, 0x65, 0x66, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x2b,
1072                         0x5f, 0x5f, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x07,
1073                         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x08,
1074                         0x08, 0x08, 0x08, 0x01, 0x01, 0x01, 0x01, 0x09, 0x02, 0x00, 0x00,
1075                         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00,
1076                         0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x0a,
1077                         0x0f, 0x02, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x02, 0x73,
1078                         0x6f, 0x6d, 0x65, 0x20, 0x74, 0x65, 0x73, 0x74, 0x00, 0x00, 0x00,
1079                         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1080                         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1081                         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1082                         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1083                         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1084                         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1085                         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1086                         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1087                         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1088                         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1089                         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1090                         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1091                         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1092                         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1093                         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1094                         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1095                         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1096                         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1097                         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1098                         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1099                         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1100                         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1101                         0x00, 0x00, 0x0b };
1102
1103                 class MyMemoryStream : MemoryStream {
1104
1105                         public bool DisposedCalled = false;
1106
1107                         protected override void Dispose(bool disposing)
1108                         {
1109                                 DisposedCalled = true;
1110                         }
1111                 }
1112
1113                 [Test] // https://bugzilla.novell.com/show_bug.cgi?id=322672
1114                 public void BaseDisposeCalled ()
1115                 {
1116                         MyMemoryStream ms = new MyMemoryStream ();
1117                         Assert.IsFalse (ms.DisposedCalled, "Before");
1118                         ms.Close ();
1119                         Assert.IsTrue (ms.DisposedCalled, "After");
1120                 }
1121
1122 #if NET_4_5
1123                 [Test]
1124                 public void ReadAsync ()
1125                 {
1126                         var buffer = new byte[3];
1127                         var t = testStream.ReadAsync (buffer, 0, buffer.Length);
1128                         Assert.AreEqual (t.Result, 3, "#1");
1129                         Assert.AreEqual (99, buffer [1], "#2");
1130
1131                         testStream.Seek (99, SeekOrigin.Begin);
1132                         t = testStream.ReadAsync (buffer, 0, 1);
1133                         Assert.AreEqual (t.Result, 1, "#3");
1134                         Assert.AreEqual (1, buffer[0], "#4");
1135                 }
1136
1137                 [Test]
1138                 public void TestAsyncReadExceptions ()
1139                 {
1140                         var buffer = new byte [3];
1141                         using (var stream = new ExceptionalStream ()) {
1142                                 stream.Write (buffer, 0, buffer.Length);
1143                                 stream.Write (buffer, 0, buffer.Length);
1144                                 stream.Position = 0;
1145                                 var task = stream.ReadAsync (buffer, 0, buffer.Length);
1146                                 Assert.AreEqual (TaskStatus.RanToCompletion, task.Status, "#1");
1147
1148                                 stream.Throw = true;
1149                                 task = stream.ReadAsync (buffer, 0, buffer.Length);
1150                                 Assert.IsTrue (task.IsFaulted, "#2");
1151                                 Assert.AreEqual (ExceptionalStream.Message, task.Exception.InnerException.Message, "#3");
1152                         }
1153                 }
1154
1155                 [Test]
1156                 public void TestAsyncWriteExceptions ()
1157                 {
1158                         var buffer = new byte [3];
1159                         using (var stream = new ExceptionalStream ()) {
1160                                 var task = stream.WriteAsync (buffer, 0, buffer.Length);
1161                                 Assert.AreEqual(TaskStatus.RanToCompletion, task.Status, "#1");
1162
1163                                 stream.Throw = true;
1164                                 task = stream.WriteAsync (buffer, 0, buffer.Length);
1165                                 Assert.IsTrue (task.IsFaulted, "#2");
1166                                 Assert.AreEqual (ExceptionalStream.Message, task.Exception.InnerException.Message, "#3");
1167                         }
1168                 }
1169
1170                 [Test]
1171                 public void TestAsyncArgumentExceptions ()
1172                 {
1173                         var buffer = new byte [3];
1174                         using (var stream = new ExceptionalStream ()) {
1175                                 var task = stream.WriteAsync (buffer, 0, buffer.Length);
1176                                 Assert.IsTrue (task.IsCompleted);
1177
1178                                 Assert.IsTrue (Throws<ArgumentException> (() => { stream.WriteAsync (buffer, 0, 1000); }), "#2");
1179                                 Assert.IsTrue (Throws<ArgumentException> (() => { stream.ReadAsync (buffer, 0, 1000); }), "#3");
1180                                 Assert.IsTrue (Throws<ArgumentException> (() => { stream.WriteAsync (buffer, 0, 1000, new CancellationToken (true)); }), "#4");
1181                                 Assert.IsTrue (Throws<ArgumentException> (() => { stream.ReadAsync (buffer, 0, 1000, new CancellationToken (true)); }), "#5");
1182                                 Assert.IsTrue (Throws<ArgumentException> (() => { stream.WriteAsync (null, 0, buffer.Length, new CancellationToken (true)); }), "#6");
1183                                 Assert.IsTrue (Throws<ArgumentException> (() => { stream.ReadAsync (null, 0, buffer.Length, new CancellationToken (true)); }), "#7");
1184                                 Assert.IsTrue (Throws<ArgumentException> (() => { stream.WriteAsync (buffer, 1000, buffer.Length, new CancellationToken (true)); }), "#8");
1185                                 Assert.IsTrue (Throws<ArgumentException> (() => { stream.ReadAsync (buffer, 1000, buffer.Length, new CancellationToken (true)); }), "#9");
1186
1187                                 stream.AllowRead = false;
1188                                 var read_task = stream.ReadAsync (buffer, 0, buffer.Length);
1189                                 Assert.AreEqual (TaskStatus.RanToCompletion, read_task.Status, "#8");
1190                                 Assert.AreEqual (0, read_task.Result, "#9");
1191
1192                                 stream.Position = 0;
1193                                 read_task = stream.ReadAsync (buffer, 0, buffer.Length);
1194                                 Assert.AreEqual (TaskStatus.RanToCompletion, read_task.Status, "#9");
1195                                 Assert.AreEqual (3, read_task.Result, "#10");
1196
1197                                 var write_task = stream.WriteAsync (buffer, 0, buffer.Length);
1198                                 Assert.AreEqual (TaskStatus.RanToCompletion, write_task.Status, "#10");
1199
1200                                 // test what happens when CanRead is overridden
1201                                 using (var norm = new ExceptionalStream (buffer, false)) {
1202                                         write_task = norm.WriteAsync (buffer, 0, buffer.Length);
1203                                         Assert.AreEqual (TaskStatus.RanToCompletion, write_task.Status, "#11");
1204                                 }
1205
1206                                 stream.AllowWrite = false;
1207                                 Assert.IsTrue (Throws<NotSupportedException> (() => { stream.Write (buffer, 0, buffer.Length); }), "#12");
1208                                 write_task = stream.WriteAsync (buffer, 0, buffer.Length);
1209                                 Assert.AreEqual (TaskStatus.Faulted, write_task.Status, "#13");
1210                         }
1211                 }
1212
1213                 [Test]
1214                 public void TestAsyncFlushExceptions ()
1215                 {
1216                         using (var stream = new ExceptionalStream ()) {
1217                                 var task = stream.FlushAsync ();
1218                                 Assert.IsTrue (task.IsCompleted, "#1");
1219                                 
1220                                 task = stream.FlushAsync (new CancellationToken(true));
1221                                 Assert.IsTrue (task.IsCanceled, "#2");
1222
1223                                 stream.Throw = true;
1224                                 task = stream.FlushAsync ();
1225                                 Assert.IsTrue (task.IsFaulted, "#3");
1226                                 Assert.AreEqual (ExceptionalStream.Message, task.Exception.InnerException.Message, "#4");
1227
1228                                 task = stream.FlushAsync (new CancellationToken (true));
1229                                 Assert.IsTrue (task.IsCanceled, "#5");
1230                         }
1231                 }
1232
1233                 [Test]
1234                 public void TestCopyAsync ()
1235                 {
1236                         using (var stream = new ExceptionalStream ()) {
1237                                 using (var dest = new ExceptionalStream ()) {
1238                                         byte [] buffer = new byte [] { 12, 13, 8 };
1239
1240                                         stream.Write (buffer, 0, buffer.Length);
1241                                         stream.Position = 0;
1242                                         var task = stream.CopyToAsync (dest, 1);
1243                                         Assert.AreEqual (TaskStatus.RanToCompletion, task.Status);
1244                                         Assert.AreEqual (3, stream.Length);
1245                                         Assert.AreEqual (3, dest.Length);
1246
1247                                         stream.Position = 0;
1248                                         dest.Throw = true;
1249                                         task = stream.CopyToAsync (dest, 1);
1250                                         Assert.AreEqual (TaskStatus.Faulted, task.Status);
1251                                         Assert.AreEqual (3, stream.Length);
1252                                         Assert.AreEqual (3, dest.Length);
1253                                 }
1254                         }
1255                 }
1256
1257                 [Test]
1258                 public void WritableOverride ()
1259                 {
1260                         var buffer = new byte [3];
1261                         var stream = new MemoryStream (buffer, false);
1262                         Assert.IsTrue (Throws<NotSupportedException> (() => { stream.Write (buffer, 0, buffer.Length); }), "#1");
1263                         Assert.IsTrue (Throws<ArgumentNullException> (() => { stream.Write (null, 0, buffer.Length); }), "#1.1");
1264                         stream.Close ();
1265                         Assert.IsTrue (Throws<ObjectDisposedException> (() => { stream.Write (buffer, 0, buffer.Length); }), "#2");
1266                         stream = new MemoryStream (buffer, true);
1267                         stream.Close ();
1268                         Assert.IsFalse (stream.CanWrite, "#3");
1269
1270                         var estream = new ExceptionalStream (buffer, false);
1271                         Assert.IsFalse (Throws<Exception> (() => { estream.Write (buffer, 0, buffer.Length); }), "#4");
1272                         estream.AllowWrite = false;
1273                         estream.Position = 0;
1274                         Assert.IsTrue (Throws<NotSupportedException> (() => { estream.Write (buffer, 0, buffer.Length); }), "#5");
1275                         estream.AllowWrite = true;
1276                         estream.Close ();
1277                         Assert.IsTrue (estream.CanWrite, "#6");
1278                         Assert.IsTrue (Throws<ObjectDisposedException> (() => { stream.Write (buffer, 0, buffer.Length); }), "#7");
1279                 }
1280
1281                 [Test]
1282                 public void ReadAsync_Canceled ()
1283                 {
1284                         var buffer = new byte[3];
1285                         var t = testStream.ReadAsync (buffer, 0, buffer.Length, new CancellationToken (true));
1286                         Assert.IsTrue (t.IsCanceled);
1287
1288                         t = testStream.ReadAsync (buffer, 0, buffer.Length);
1289                         Assert.AreEqual (t.Result, 3, "#1");
1290                         Assert.AreEqual (99, buffer[1], "#2");
1291                 }
1292
1293                 [Test]
1294                 public void WriteAsync ()
1295                 {
1296                         var buffer = new byte[3] { 3, 5, 9 };
1297
1298                         var ms = new MemoryStream ();
1299                         var t = ms.WriteAsync (buffer, 0, buffer.Length);
1300                         Assert.IsTrue (t.IsCompleted, "#1");
1301
1302                         ms.Seek (0, SeekOrigin.Begin);
1303                         Assert.AreEqual (3, ms.ReadByte (), "#2");
1304                 }
1305
1306                 [Test]
1307                 public void WriteAsync_Canceled ()
1308                 {
1309                         var buffer = new byte[3] { 1, 2, 3 };
1310                         var t = testStream.WriteAsync (buffer, 0, buffer.Length, new CancellationToken (true));
1311                         Assert.IsTrue (t.IsCanceled);
1312
1313                         t = testStream.WriteAsync (buffer, 0, buffer.Length);
1314                         Assert.IsTrue (t.IsCompleted, "#1");
1315                 }
1316
1317                 bool Throws<T> (Action a) where T : Exception
1318                 {
1319                         try {
1320                                 a ();
1321                                 return false;
1322                         } catch (T) {
1323                                 return true;
1324                         }
1325                 }
1326 #endif
1327         }
1328 }