Rework exception handling in MemoryStream async methods
[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                         var wh = new ManualResetEvent (false);
344                         var end = new ManualResetEvent (false);
345
346                         using (var testStream = new SignaledMemoryStream (testStreamData, wh)) {
347                                 var res = testStream.BeginRead (readBytes, 0, 5, null, null);
348
349                                 bool blocking = true;
350                                 ThreadPool.QueueUserWorkItem (l => {
351                                         var res2 = testStream.BeginRead (readBytes2, 0, 3, null, null);
352                                         blocking = false;
353                                         Assert.IsTrue (res2.AsyncWaitHandle.WaitOne (2000), "#10");
354                                         Assert.IsTrue (res2.IsCompleted, "#11");
355                                         Assert.AreEqual (3, testStream.EndRead (res2), "#12");
356                                         Assert.AreEqual (95, readBytes2[0], "#13");
357                                         end.Set ();
358                                 });
359
360                                 Assert.IsFalse (res.IsCompleted, "#1");
361                                 Thread.Sleep (500);     // Lame but don't know how to wait for another BeginRead which does not return
362                                 Assert.IsTrue (blocking, "#2");
363
364                                 wh.Set ();
365                                 Assert.IsTrue (res.AsyncWaitHandle.WaitOne (2000), "#3");
366                                 Assert.IsTrue (res.IsCompleted, "#4");
367                                 Assert.AreEqual (5, testStream.EndRead (res), "#5");
368                                 Assert.IsTrue (end.WaitOne (2000), "#6");
369                                 Assert.AreEqual (100, readBytes[0], "#7");
370                         }
371                 }
372
373                 [Test]
374                 public void BeginRead_Read ()
375                 {
376                         byte[] readBytes = new byte[5];
377                         var wh = new ManualResetEvent (false);
378                         using (var testStream = new SignaledMemoryStream (testStreamData, wh)) {
379                                 var res = testStream.BeginRead (readBytes, 0, 5, null, null);
380                                 Assert.AreEqual (100, testStream.ReadByte (), "#0");
381                                 Assert.IsFalse (res.IsCompleted, "#1");
382                                 Assert.IsFalse (res.CompletedSynchronously, "#2");
383                                 wh.Set ();
384                                 Assert.IsTrue (res.AsyncWaitHandle.WaitOne (2000), "#3");
385                                 Assert.IsTrue (res.IsCompleted, "#4");
386                                 Assert.AreEqual (5, testStream.EndRead (res), "#5");
387                                 Assert.AreEqual (99, readBytes [0], "#6");
388                         }
389
390                         wh.Close ();
391                 }
392
393                 [Test]
394                 public void BeginRead_BeginWrite ()
395                 {
396                         byte[] readBytes = new byte[5];
397                         byte[] readBytes2 = new byte[3] { 1, 2, 3 };
398                         var wh = new ManualResetEvent (false);
399                         var end = new ManualResetEvent (false);
400
401                         using (var testStream = new SignaledMemoryStream (testStreamData, wh)) {
402                                 var res = testStream.BeginRead (readBytes, 0, 5, null, null);
403
404                                 bool blocking = true;
405                                 ThreadPool.QueueUserWorkItem (l => {
406                                         var res2 = testStream.BeginWrite (readBytes2, 0, 3, null, null);
407                                         blocking = false;
408                                         Assert.IsTrue (res2.AsyncWaitHandle.WaitOne (2000), "#10");
409                                         Assert.IsTrue (res2.IsCompleted, "#11");
410                                         testStream.EndWrite (res2);
411                                         end.Set ();
412                                 });
413
414                                 Assert.IsFalse (res.IsCompleted, "#1");
415                                 Thread.Sleep (500);     // Lame but don't know how to wait for another BeginWrite which does not return
416                                 Assert.IsTrue (blocking, "#2");
417
418                                 wh.Set ();
419                                 Assert.IsTrue (res.AsyncWaitHandle.WaitOne (2000), "#3");
420                                 Assert.IsTrue (res.IsCompleted, "#4");
421                                 Assert.AreEqual (5, testStream.EndRead (res), "#5");
422                                 Assert.IsTrue (end.WaitOne (2000), "#6");
423                         }
424                 }
425                 
426                 [Test]
427                 public void BeginWrite ()
428                 {
429                         var writeBytes = new byte [5] { 2, 3, 4, 10, 12 };
430
431                         var res = testStream.BeginWrite (writeBytes, 0, 5, null, null);
432                         Assert.IsTrue (res.AsyncWaitHandle.WaitOne (1000), "#1");
433                         testStream.EndWrite (res);
434                 }
435
436                 [Test]
437                 public void BeginWrite_WithState ()
438                 {
439                         var writeBytes = new byte[5] { 2, 3, 4, 10, 12 };
440                         string async_state = null;
441                         var wh = new ManualResetEvent (false);
442
443                         var res = testStream.BeginWrite (writeBytes, 0, 5, l => {
444                                 async_state = l.AsyncState as string;
445                                 wh.Set ();
446                         }, "state");
447
448                         Assert.IsTrue (res.AsyncWaitHandle.WaitOne (1000), "#1");
449                         Assert.IsTrue (res.IsCompleted, "#2");
450                         Assert.AreEqual ("state", res.AsyncState, "#3");
451                         testStream.EndWrite (res);
452
453                         wh.WaitOne (1000);
454                         Assert.AreEqual ("state", async_state, "#4");
455                         wh.Close ();
456                 }
457                 
458                 [Test]
459                 public void EndRead_Twice ()
460                 {
461                         byte[] readBytes = new byte[5];
462
463                         var res = testStream.BeginRead (readBytes, 0, 5, null, null);
464                         Assert.IsTrue (res.AsyncWaitHandle.WaitOne (1000), "#1");
465                         Assert.AreEqual (5, testStream.EndRead (res), "#2");
466
467                         try {
468                                 testStream.EndRead (res);
469                                 Assert.Fail ("#3");
470                         } catch (ArgumentException) {
471                                 return;
472                         }
473                 }
474
475                 [Test]
476                 public void EndRead_Disposed ()
477                 {
478                         byte[] readBytes = new byte[5];
479
480                         var res = testStream.BeginRead (readBytes, 0, 5, null, null);
481                         Assert.IsTrue (res.AsyncWaitHandle.WaitOne (1000), "#1");
482                         testStream.Dispose ();
483                         Assert.AreEqual (5, testStream.EndRead (res), "#2");
484                 }
485                 
486                 [Test]
487                 public void EndWrite_OnBeginRead ()
488                 {
489                         byte[] readBytes = new byte[5];
490
491                         var res = testStream.BeginRead (readBytes, 0, 5, null, null);
492                         Assert.IsTrue (res.AsyncWaitHandle.WaitOne (1000), "#1");
493
494                         try {
495                                 testStream.EndWrite (res);
496                                 Assert.Fail ("#2");
497                         } catch (ArgumentException) {
498                         }
499
500                         testStream.EndRead (res);
501                 }
502
503                 [Test]
504                 public void EndWrite_Twice ()
505                 {
506                         var wBytes = new byte[5];
507
508                         var res = testStream.BeginWrite (wBytes, 0, 5, null, null);
509                         Assert.IsTrue (res.AsyncWaitHandle.WaitOne (1000), "#1");
510                         testStream.EndWrite (res);
511
512                         try {
513                                 testStream.EndWrite (res);
514                                 Assert.Fail ("#2");
515                         } catch (ArgumentException) {
516                                 return;
517                         }
518                 }
519
520                 
521                 [Test]
522                 public void WriteBytes ()
523                 {
524                         byte[] readBytes = new byte[100];
525
526                         MemoryStream ms = new MemoryStream (100);
527
528                         for (int i = 0; i < 100; i++)
529                                 ms.WriteByte (testStreamData [i]);
530
531                         ms.Seek (0, SeekOrigin.Begin); 
532                         testStream.Read (readBytes, 0, 100);
533                         VerifyTestData ("W1", readBytes, 0, 100);
534                 }
535
536                 [Test]
537                 public void WriteBlock ()
538                 {
539                         byte[] readBytes = new byte[100];
540
541                         MemoryStream ms = new MemoryStream (100);
542
543                         ms.Write (testStreamData, 0, 100);
544                         ms.Seek (0, SeekOrigin.Begin); 
545                         testStream.Read (readBytes, 0, 100);
546                         VerifyTestData ("WB1", readBytes, 0, 100);
547                         byte[] arrayBytes = testStream.ToArray();
548                         AssertEquals ("#01", 100, arrayBytes.Length);
549                         VerifyTestData ("WB2", arrayBytes, 0, 100);
550                 }
551
552                 [Test]
553                 public void PositionLength ()
554                 {
555                         MemoryStream ms = new MemoryStream ();
556                         ms.Position = 4;
557                         ms.WriteByte ((byte) 'M');
558                         ms.WriteByte ((byte) 'O');
559                         AssertEquals ("#01", 6, ms.Length);
560                         AssertEquals ("#02", 6, ms.Position);
561                         ms.Position = 0;
562                         AssertEquals ("#03", 0, ms.Position);
563                 }
564
565                 [Test]
566                 [ExpectedException (typeof (NotSupportedException))]
567                 public void MorePositionLength ()
568                 {
569                         MemoryStream ms = new MemoryStream (testStreamData);
570                         ms.Position = 101;
571                         AssertEquals ("#01", 101, ms.Position);
572                         AssertEquals ("#02", 100, ms.Length);
573                         ms.WriteByte (1); // This should throw the exception
574                 }
575
576                 [Test]
577                 public void GetBufferOne ()
578                 {
579                         MemoryStream ms = new MemoryStream ();
580                         byte [] buffer = ms.GetBuffer ();
581                         AssertEquals ("#01", 0, buffer.Length);
582                 }
583
584                 [Test]
585                 public void GetBufferTwo ()
586                 {
587                         MemoryStream ms = new MemoryStream (100);
588                         byte [] buffer = ms.GetBuffer ();
589                         AssertEquals ("#01", 100, buffer.Length);
590
591                         ms.Write (testStreamData, 0, 100);
592                         ms.Write (testStreamData, 0, 100);
593                         AssertEquals ("#02", 200, ms.Length);
594                         buffer = ms.GetBuffer ();
595                         AssertEquals ("#03", 256, buffer.Length); // Minimun size after writing
596                 }
597
598                 [Test]
599                 public void Closed ()
600                 {
601                         MemoryStream ms = new MemoryStream (100);
602                         ms.Close ();
603                         bool thrown = false;
604                         try {
605                                 int x = ms.Capacity;
606                         } catch (ObjectDisposedException) {
607                                 thrown = true;
608                         }
609
610                         if (!thrown)
611                                 Assert.Fail ("#01");
612
613                         thrown = false;
614                         try {
615                                 ms.Capacity = 1;
616                         } catch (ObjectDisposedException) {
617                                 thrown = true;
618                         }
619
620                         if (!thrown)
621                                 Assert.Fail ("#02");
622
623                         try {
624                                 ms.Read (null, 0, 1);
625                                 Assert.Fail ("#03");
626                         } catch (ArgumentNullException) {
627                         }
628
629                         try {
630                                 ms.Write (null, 0, 1);
631                                 Assert.Fail ("#04");
632                         } catch (ArgumentNullException) {
633                                 thrown = true;
634                         }
635                 }
636
637                 [Test]
638                 [ExpectedException (typeof (ObjectDisposedException))]
639                 public void Close_get_Length () 
640                 {
641                         MemoryStream ms = new MemoryStream (100);
642                         ms.Close ();
643                         long x = ms.Length;
644                 }
645
646                 [Test]
647                 [ExpectedException (typeof (ObjectDisposedException))]
648                 public void Close_get_Position () 
649                 {
650                         MemoryStream ms = new MemoryStream (100);
651                         ms.Close ();
652                         long x = ms.Position;
653                 }
654
655                 [Test]
656                 [ExpectedException (typeof (ObjectDisposedException))]
657                 public void Close_set_Position () 
658                 {
659                         MemoryStream ms = new MemoryStream (100);
660                         ms.Close ();
661                         ms.Position = 0;
662                 }
663
664                 [Test]
665                 public void Seek ()
666                 {
667                         MemoryStream ms = new MemoryStream (100);
668                         ms.Write (testStreamData, 0, 100);
669                         ms.Seek (0, SeekOrigin.Begin);
670                         ms.Position = 50;
671                         ms.Seek (-50, SeekOrigin.Current);
672                         ms.Seek (-50, SeekOrigin.End);
673
674                         bool thrown = false;
675                         ms.Position = 49;
676                         try {
677                                 ms.Seek (-50, SeekOrigin.Current);
678                         } catch (IOException) {
679                                 thrown = true;
680                         }
681                         if (!thrown)
682                                 Assert.Fail ("#01");
683                         
684                         thrown = false;
685                         try {
686                                 ms.Seek (Int64.MaxValue, SeekOrigin.Begin);
687                         } catch (ArgumentOutOfRangeException) {
688                                 thrown = true;
689                         }
690
691                         if (!thrown)
692                                 Assert.Fail ("#02");
693
694                         thrown=false;
695                         try {
696                                 // Oh, yes. They throw IOException for this one, but ArgumentOutOfRange for the previous one
697                                 ms.Seek (Int64.MinValue, SeekOrigin.Begin);
698                         } catch (IOException) {
699                                 thrown = true;
700                         }
701
702                         if (!thrown)
703                                 Assert.Fail ("#03");
704
705                         ms=new MemoryStream (256);
706
707                         ms.Write (testStreamData, 0, 100);
708                         ms.Position=0;
709                         AssertEquals ("#01", 100, ms.Length);
710                         AssertEquals ("#02", 0, ms.Position);
711
712                         ms.Position=128;
713                         AssertEquals ("#03", 100, ms.Length);
714                         AssertEquals ("#04", 128, ms.Position);
715
716                         ms.Position=768;
717                         AssertEquals ("#05", 100, ms.Length);
718                         AssertEquals ("#06", 768, ms.Position);
719
720                         ms.WriteByte (0);
721                         AssertEquals ("#07", 769, ms.Length);
722                         AssertEquals ("#08", 769, ms.Position);
723                 }
724
725                 [Test]
726                 public void Seek_Disposed () 
727                 {
728                         MemoryStream ms = new MemoryStream ();
729                         ms.Close ();
730                         try {
731                                 ms.Seek (0, SeekOrigin.Begin);
732                                 Assert.Fail ();
733                         } catch (ObjectDisposedException) {
734                         }
735                 }
736
737                 [Test]
738                 public void SetLength ()
739                 {
740                         MemoryStream ms = new MemoryStream ();
741                         ms.Write (testStreamData, 0, 100);
742                         ms.Position = 100;
743                         ms.SetLength (150);
744                         AssertEquals ("#01", 150, ms.Length);
745                         AssertEquals ("#02", 100, ms.Position);
746                         ms.SetLength (80);
747                         AssertEquals ("#03", 80, ms.Length);
748                         AssertEquals ("#04", 80, ms.Position);
749                 }
750
751                 [Test]
752                 [ExpectedException (typeof (NotSupportedException))]
753                 public void SetLength_ReadOnly ()
754                 {
755                         MemoryStream ms = new MemoryStream (testStreamData, false);
756                         ms.SetLength (10);
757                 }
758
759                 [Test]
760                 public void Capacity ()
761                 {
762                         MemoryStream ms = new MemoryStream ();
763
764                         Assert.AreEqual (0, ms.Capacity, "#A1");
765                         Assert.AreEqual (0, ms.GetBuffer ().Length, "#A2");
766
767                         ms.WriteByte ((byte)'6');
768                         Assert.AreEqual (256, ms.Capacity, "#B1");
769                         Assert.AreEqual (256, ms.GetBuffer ().Length, "#B2");
770
771                         // Shrink
772                         ms.Capacity = 100;
773                         Assert.AreEqual (100, ms.Capacity, "#C1");
774                         Assert.AreEqual (100, ms.GetBuffer ().Length, "#C2");
775
776                         // Grow
777                         ms.Capacity = 120;
778                         Assert.AreEqual (120, ms.Capacity, "#D1");
779                         Assert.AreEqual (120, ms.GetBuffer ().Length, "#D2");
780
781                         // Grow the buffer, reduce length -so we have a dirty area-
782                         // and then we assign capacity to the same. The idea is that we should
783                         // avoid creating a new internal buffer it's not needed.
784
785                         ms = new MemoryStream ();
786                         ms.Capacity = 8;
787                         byte [] buff = new byte [] { 0x01, 0x02, 0x03, 0x04, 0x05 };
788                         ms.Write (buff, 0, buff.Length);
789                         Assert.AreEqual (8, ms.Capacity, "#E1");
790                         Assert.AreEqual (8, ms.GetBuffer ().Length, "#E2");
791
792                         // Reduce *length*, not capacity
793                         byte [] buff_copy = ms.GetBuffer ();
794                         ms.SetLength (3);
795                         Assert.AreEqual (3, ms.Length, "#F1");
796                         Assert.AreEqual (true, AreBuffersEqual (buff_copy, ms.GetBuffer ()), "#F2");
797
798                         // Set Capacity to the very same value it has now
799                         ms.Capacity = ms.Capacity;
800                         Assert.AreEqual (true, AreBuffersEqual (buff_copy, ms.GetBuffer ()), "#G1"); // keep the same buffer
801
802                         // Finally, growing it discards the prev buff
803                         ms.Capacity = ms.Capacity + 1;
804                         Assert.AreEqual (false, AreBuffersEqual (buff_copy, ms.GetBuffer ()), "#H1");
805                 }
806
807                 bool AreBuffersEqual (byte [] buff1, byte [] buff2)
808                 {
809                         if ((buff1 == null) != (buff2 == null))
810                                 return false;
811
812                         if (buff1.Length != buff2.Length)
813                                 return false;
814
815                         for (int i = 0; i < buff1.Length; i++)
816                                 if (buff1 [i] != buff2 [i])
817                                         return false;
818
819                         return true;
820                 }
821
822                 [Test] // bug #327053
823                 public void ZeroingOnExpand ()
824                 {
825                         byte [] values = { 3, 2, 1 };
826                         byte [] reference = { 3, 2, 1 };
827                         byte [] cropped = { 3, 0, 0 };
828                         MemoryStream ms = new MemoryStream (values);
829                         Assert.AreEqual (values, reference, "#A1");
830                         ms.Seek (3, SeekOrigin.Begin);
831                         Assert.AreEqual (reference, values, "#A2");
832                         ms.SetLength (1);
833                         Assert.AreEqual (reference, values, "#B1");
834                         byte [] read = new byte [5];
835                         ms.Read (read, 0, 5);
836                         Assert.AreEqual (new byte [] { 0, 0, 0, 0, 0 }, read, "#B2");
837                         Assert.AreEqual (reference, values, "#B3");
838                         ms.SetLength (3);
839                         Assert.AreEqual (cropped, values, "#C1");
840                         ms.Seek (0, SeekOrigin.Begin);
841                         read = new byte [3];
842                         ms.Read (read, 0, 3);
843                         Assert.AreEqual (cropped, read, "#C2");
844                         Assert.AreEqual (cropped, values, "#C3");
845                 }
846
847                 [Test]
848                 [ExpectedException (typeof (NotSupportedException))]
849                 public void WriteNonWritable ()
850                 {
851                         MemoryStream ms = new MemoryStream (testStreamData, false);
852                         ms.Write (testStreamData, 0, 100);
853                 }
854
855                 [Test]
856                 [ExpectedException (typeof (NotSupportedException))]
857                 public void WriteExpand ()
858                 {
859                         MemoryStream ms = new MemoryStream (testStreamData);
860                         ms.Write (testStreamData, 0, 100);
861                         ms.Write (testStreamData, 0, 100); // This one throws the exception
862                 }
863
864                 [Test]
865                 public void WriteByte ()
866                 {
867                         MemoryStream ms = new MemoryStream (100);
868                         ms.Write (testStreamData, 0, 100);
869                         ms.Position = 100;
870                         ms.WriteByte (101);
871                         AssertEquals ("#01", 101, ms.Position);
872                         AssertEquals ("#02", 101, ms.Length);
873                         AssertEquals ("#03", 256, ms.Capacity);
874                         ms.Write (testStreamData, 0, 100);
875                         ms.Write (testStreamData, 0, 100);
876                         // 301
877                         AssertEquals ("#04", 301, ms.Position);
878                         AssertEquals ("#05", 301, ms.Length);
879                         AssertEquals ("#06", 512, ms.Capacity);
880                 }
881
882                 [Test]
883                 public void WriteLengths () {
884                         MemoryStream ms=new MemoryStream (256);
885                         BinaryWriter writer=new BinaryWriter (ms);
886
887                         writer.Write ((byte)'1');
888                         AssertEquals ("#01", 1, ms.Length);
889                         AssertEquals ("#02", 256, ms.Capacity);
890                         
891                         writer.Write ((ushort)0);
892                         AssertEquals ("#03", 3, ms.Length);
893                         AssertEquals ("#04", 256, ms.Capacity);
894
895                         writer.Write (testStreamData, 0, 23);
896                         AssertEquals ("#05", 26, ms.Length);
897                         AssertEquals ("#06", 256, ms.Capacity);
898
899                         writer.Write (testStreamData);
900                         writer.Write (testStreamData);
901                         writer.Write (testStreamData);
902                         AssertEquals ("#07", 326, ms.Length);
903                 }
904
905                 [Test]
906                 public void MoreWriteByte ()
907                 {
908                         byte[] buffer = new byte [44];
909                         
910                         MemoryStream ms = new MemoryStream (buffer);
911                         BinaryWriter bw = new BinaryWriter (ms);
912                         for(int i=0; i < 44; i++)
913                                 bw.Write ((byte) 1);
914                 }
915
916                 [Test]
917                 [ExpectedException (typeof (NotSupportedException))]
918                 public void MoreWriteByte2 ()
919                 {
920                         byte[] buffer = new byte [43]; // Note the 43 here
921                         
922                         MemoryStream ms = new MemoryStream (buffer);
923                         BinaryWriter bw = new BinaryWriter (ms);
924                         for(int i=0; i < 44; i++)
925                                 bw.Write ((byte) 1);
926                 }
927
928                 [Test]
929                 public void Expand () 
930                 {
931                         byte[] array = new byte [8] { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 };
932                         MemoryStream ms = new MemoryStream ();
933                         ms.Write (array, 0, array.Length);
934                         ms.SetLength (4);
935                         ms.Seek (4, SeekOrigin.End);
936                         ms.WriteByte (0xFF);
937                         Assert.AreEqual ("01-01-01-01-00-00-00-00-FF", BitConverter.ToString (ms.ToArray ()), "Result");
938                 }
939
940                 [Test]
941                 public void PubliclyVisible ()
942                 {
943                         MemoryStream ms = new MemoryStream ();
944                         Assert.IsNotNull (ms.GetBuffer (), "ctor()");
945
946                         ms = new MemoryStream (1);
947                         Assert.IsNotNull (ms.GetBuffer (), "ctor(1)");
948
949                         ms = new MemoryStream (new byte[1], 0, 1, true, true);
950                         Assert.IsNotNull (ms.GetBuffer (), "ctor(byte[],int,int,bool,bool");
951                 }
952
953                 [Test]
954                 [ExpectedException (typeof (UnauthorizedAccessException))]
955                 public void PubliclyVisible_Ctor_ByteArray ()
956                 {
957                         MemoryStream ms = new MemoryStream (new byte[0]);
958                         Assert.IsNotNull (ms.GetBuffer ());
959                 }
960
961                 [Test]
962                 [ExpectedException (typeof (UnauthorizedAccessException))]
963                 public void PubliclyVisible_Ctor_ByteArray_Boolean ()
964                 {
965                         MemoryStream ms = new MemoryStream (new byte[0], true);
966                         Assert.IsNotNull (ms.GetBuffer ());
967                 }
968
969                 [Test]
970                 [ExpectedException (typeof (UnauthorizedAccessException))]
971                 public void PubliclyVisible_Ctor_ByteArray_Int_Int ()
972                 {
973                         MemoryStream ms = new MemoryStream (new byte[1], 0, 1);
974                         Assert.IsNotNull (ms.GetBuffer ());
975                 }
976
977                 [Test]
978                 [ExpectedException (typeof (UnauthorizedAccessException))]
979                 public void PubliclyVisible_Ctor_ByteArray_Int_Int_Boolean ()
980                 {
981                         MemoryStream ms = new MemoryStream (new byte[1], 0, 1, true);
982                         Assert.IsNotNull (ms.GetBuffer ());
983                 }
984
985                 [Test]
986                 [ExpectedException (typeof (UnauthorizedAccessException))]
987                 public void PubliclyVisible_Ctor_ByteArray_Int_Int_Boolean_Boolean ()
988                 {
989                         MemoryStream ms = new MemoryStream (new byte[1], 0, 1, true, false);
990                         Assert.IsNotNull (ms.GetBuffer ());
991                 }
992
993                 [Test] // bug #350860
994                 public void ToArray_Empty ()
995                 {
996                         MemoryStream ms = new MemoryStream (1);
997                         ms.Capacity = 0;
998                         ms.ToArray ();
999                 }
1000
1001                 [Test] // bug #80205
1002                 [Category ("NotWorking")]
1003                 public void SerializeTest ()
1004                 {
1005                         MemoryStream input = new MemoryStream ();
1006                         byte [] bufferIn = Encoding.UTF8.GetBytes ("some test");
1007                         input.Write (bufferIn, 0, bufferIn.Length);
1008                         input.Position = 0;
1009
1010                         BinaryFormatter bf = new BinaryFormatter ();
1011                         MemoryStream ms = new MemoryStream ();
1012                         bf.Serialize (ms, input);
1013
1014                         byte [] bufferOut = new byte [ms.Length];
1015                         ms.Position = 0;
1016                         ms.Read (bufferOut, 0, bufferOut.Length);
1017
1018                         Assert.AreEqual (_serialized, bufferOut);
1019                 }
1020
1021                 [Test] // bug #676060
1022                 public void ZeroCapacity ()
1023                 {
1024                         MemoryStream ms = new MemoryStream();
1025                         ms.WriteByte(1);
1026                         ms.Position = 0;
1027                         ms.SetLength(0);
1028                         ms.Capacity = 0;
1029                         ms.WriteByte(1);
1030                         byte[] bytes = ms.ToArray();
1031                 }
1032
1033                 [Test] // bug #80205
1034                 [Category ("NotWorking")]
1035                 public void DeserializeTest ()
1036                 {
1037                         MemoryStream ms = new MemoryStream ();
1038                         ms.Write (_serialized, 0, _serialized.Length);
1039                         ms.Position = 0;
1040
1041                         BinaryFormatter bf = new BinaryFormatter ();
1042                         MemoryStream output = (MemoryStream) bf.Deserialize (ms);
1043                         using (StreamReader sr = new StreamReader (output)) {
1044                                 Assert.AreEqual ("some test", sr.ReadToEnd ());
1045                         }
1046                 }
1047
1048                 private static byte [] _serialized = new byte [] {
1049                         0x00, 0x01, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00,
1050                         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x01, 0x00, 0x00, 0x00,
1051                         0x16, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x2e, 0x49, 0x4f, 0x2e,
1052                         0x4d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x53, 0x74, 0x72, 0x65, 0x61,
1053                         0x6d, 0x0a, 0x00, 0x00, 0x00, 0x07, 0x5f, 0x62, 0x75, 0x66, 0x66,
1054                         0x65, 0x72, 0x07, 0x5f, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x09,
1055                         0x5f, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x07, 0x5f,
1056                         0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x09, 0x5f, 0x63, 0x61, 0x70,
1057                         0x61, 0x63, 0x69, 0x74, 0x79, 0x0b, 0x5f, 0x65, 0x78, 0x70, 0x61,
1058                         0x6e, 0x64, 0x61, 0x62, 0x6c, 0x65, 0x09, 0x5f, 0x77, 0x72, 0x69,
1059                         0x74, 0x61, 0x62, 0x6c, 0x65, 0x0a, 0x5f, 0x65, 0x78, 0x70, 0x6f,
1060                         0x73, 0x61, 0x62, 0x6c, 0x65, 0x07, 0x5f, 0x69, 0x73, 0x4f, 0x70,
1061                         0x65, 0x6e, 0x1d, 0x4d, 0x61, 0x72, 0x73, 0x68, 0x61, 0x6c, 0x42,
1062                         0x79, 0x52, 0x65, 0x66, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x2b,
1063                         0x5f, 0x5f, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x07,
1064                         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x08,
1065                         0x08, 0x08, 0x08, 0x01, 0x01, 0x01, 0x01, 0x09, 0x02, 0x00, 0x00,
1066                         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00,
1067                         0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x0a,
1068                         0x0f, 0x02, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x02, 0x73,
1069                         0x6f, 0x6d, 0x65, 0x20, 0x74, 0x65, 0x73, 0x74, 0x00, 0x00, 0x00,
1070                         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1071                         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1072                         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1073                         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1074                         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1075                         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1076                         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1077                         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1078                         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 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, 0x0b };
1093
1094                 class MyMemoryStream : MemoryStream {
1095
1096                         public bool DisposedCalled = false;
1097
1098                         protected override void Dispose(bool disposing)
1099                         {
1100                                 DisposedCalled = true;
1101                         }
1102                 }
1103
1104                 [Test] // https://bugzilla.novell.com/show_bug.cgi?id=322672
1105                 public void BaseDisposeCalled ()
1106                 {
1107                         MyMemoryStream ms = new MyMemoryStream ();
1108                         Assert.IsFalse (ms.DisposedCalled, "Before");
1109                         ms.Close ();
1110                         Assert.IsTrue (ms.DisposedCalled, "After");
1111                 }
1112
1113 #if NET_4_5
1114                 [Test]
1115                 public void ReadAsync ()
1116                 {
1117                         var buffer = new byte[3];
1118                         var t = testStream.ReadAsync (buffer, 0, buffer.Length);
1119                         Assert.AreEqual (t.Result, 3, "#1");
1120                         Assert.AreEqual (99, buffer [1], "#2");
1121
1122                         testStream.Seek (99, SeekOrigin.Begin);
1123                         t = testStream.ReadAsync (buffer, 0, 1);
1124                         Assert.AreEqual (t.Result, 1, "#3");
1125                         Assert.AreEqual (1, buffer[0], "#4");
1126                 }
1127
1128                 [Test]
1129                 public void TestAsyncReadExceptions ()
1130                 {
1131                         var buffer = new byte [3];
1132                         using (var stream = new ExceptionalStream ()) {
1133                                 stream.Write (buffer, 0, buffer.Length);
1134                                 stream.Write (buffer, 0, buffer.Length);
1135                                 stream.Position = 0;
1136                                 var task = stream.ReadAsync (buffer, 0, buffer.Length);
1137                                 Assert.AreEqual (TaskStatus.RanToCompletion, task.Status, "#1");
1138
1139                                 stream.Throw = true;
1140                                 task = stream.ReadAsync (buffer, 0, buffer.Length);
1141                                 Assert.IsTrue (task.IsFaulted, "#2");
1142                                 Assert.AreEqual (ExceptionalStream.Message, task.Exception.InnerException.Message, "#3");
1143                         }
1144                 }
1145
1146                 [Test]
1147                 public void TestAsyncWriteExceptions ()
1148                 {
1149                         var buffer = new byte [3];
1150                         using (var stream = new ExceptionalStream ()) {
1151                                 var task = stream.WriteAsync (buffer, 0, buffer.Length);
1152                                 Assert.AreEqual(TaskStatus.RanToCompletion, task.Status, "#1");
1153
1154                                 stream.Throw = true;
1155                                 task = stream.WriteAsync (buffer, 0, buffer.Length);
1156                                 Assert.IsTrue (task.IsFaulted, "#2");
1157                                 Assert.AreEqual (ExceptionalStream.Message, task.Exception.InnerException.Message, "#3");
1158                         }
1159                 }
1160
1161                 [Test]
1162                 public void TestAsyncArgumentExceptions ()
1163                 {
1164                         var buffer = new byte [3];
1165                         using (var stream = new ExceptionalStream ()) {
1166                                 var task = stream.WriteAsync (buffer, 0, buffer.Length);
1167                                 Assert.IsTrue (task.IsCompleted);
1168
1169                                 Assert.IsTrue (Throws<ArgumentException> (() => { stream.WriteAsync (buffer, 0, 1000); }), "#2");
1170                                 Assert.IsTrue (Throws<ArgumentException> (() => { stream.ReadAsync (buffer, 0, 1000); }), "#3");
1171                                 Assert.IsTrue (Throws<ArgumentException> (() => { stream.WriteAsync (buffer, 0, 1000, new CancellationToken (true)); }), "#4");
1172                                 Assert.IsTrue (Throws<ArgumentException> (() => { stream.ReadAsync (buffer, 0, 1000, new CancellationToken (true)); }), "#5");
1173                                 Assert.IsTrue (Throws<ArgumentException> (() => { stream.WriteAsync (null, 0, buffer.Length, new CancellationToken (true)); }), "#6");
1174                                 Assert.IsTrue (Throws<ArgumentException> (() => { stream.ReadAsync (null, 0, buffer.Length, new CancellationToken (true)); }), "#7");
1175                                 Assert.IsTrue (Throws<ArgumentException> (() => { stream.WriteAsync (buffer, 1000, buffer.Length, new CancellationToken (true)); }), "#8");
1176                                 Assert.IsTrue (Throws<ArgumentException> (() => { stream.ReadAsync (buffer, 1000, buffer.Length, new CancellationToken (true)); }), "#9");
1177
1178                                 stream.AllowRead = false;
1179                                 var read_task = stream.ReadAsync (buffer, 0, buffer.Length);
1180                                 Assert.AreEqual (TaskStatus.RanToCompletion, read_task.Status, "#8");
1181                                 Assert.AreEqual (0, read_task.Result, "#9");
1182
1183                                 stream.Position = 0;
1184                                 read_task = stream.ReadAsync (buffer, 0, buffer.Length);
1185                                 Assert.AreEqual (TaskStatus.RanToCompletion, read_task.Status, "#9");
1186                                 Assert.AreEqual (3, read_task.Result, "#10");
1187
1188                                 var write_task = stream.WriteAsync (buffer, 0, buffer.Length);
1189                                 Assert.AreEqual (TaskStatus.RanToCompletion, write_task.Status, "#10");
1190
1191                                 // test what happens when CanRead is overridden
1192                                 using (var norm = new ExceptionalStream (buffer, false)) {
1193                                         write_task = norm.WriteAsync (buffer, 0, buffer.Length);
1194                                         Assert.AreEqual (TaskStatus.RanToCompletion, write_task.Status, "#11");
1195                                 }
1196
1197                                 stream.AllowWrite = false;
1198                                 Assert.IsTrue (Throws<NotSupportedException> (() => { stream.Write (buffer, 0, buffer.Length); }), "#12");
1199                                 write_task = stream.WriteAsync (buffer, 0, buffer.Length);
1200                                 Assert.AreEqual (TaskStatus.Faulted, write_task.Status, "#13");
1201                         }
1202                 }
1203
1204                 [Test]
1205                 public void TestAsyncFlushExceptions ()
1206                 {
1207                         using (var stream = new ExceptionalStream ()) {
1208                                 var task = stream.FlushAsync ();
1209                                 Assert.IsTrue (task.IsCompleted, "#1");
1210                                 
1211                                 task = stream.FlushAsync (new CancellationToken(true));
1212                                 Assert.IsTrue (task.IsCanceled, "#2");
1213
1214                                 stream.Throw = true;
1215                                 task = stream.FlushAsync ();
1216                                 Assert.IsTrue (task.IsFaulted, "#3");
1217                                 Assert.AreEqual (ExceptionalStream.Message, task.Exception.InnerException.Message, "#4");
1218
1219                                 task = stream.FlushAsync (new CancellationToken (true));
1220                                 Assert.IsTrue (task.IsCanceled, "#5");
1221                         }
1222                 }
1223
1224                 [Test]
1225                 public void TestCopyAsync ()
1226                 {
1227                         using (var stream = new ExceptionalStream ()) {
1228                                 using (var dest = new ExceptionalStream ()) {
1229                                         byte [] buffer = new byte [] { 12, 13, 8 };
1230
1231                                         stream.Write (buffer, 0, buffer.Length);
1232                                         stream.Position = 0;
1233                                         var task = stream.CopyToAsync (dest, 1);
1234                                         Assert.AreEqual (TaskStatus.RanToCompletion, task.Status);
1235                                         Assert.AreEqual (3, stream.Length);
1236                                         Assert.AreEqual (3, dest.Length);
1237
1238                                         stream.Position = 0;
1239                                         dest.Throw = true;
1240                                         task = stream.CopyToAsync (dest, 1);
1241                                         Assert.AreEqual (TaskStatus.Faulted, task.Status);
1242                                         Assert.AreEqual (3, stream.Length);
1243                                         Assert.AreEqual (3, dest.Length);
1244                                 }
1245                         }
1246                 }
1247
1248                 [Test]
1249                 public void WritableOverride ()
1250                 {
1251                         var buffer = new byte [3];
1252                         var stream = new MemoryStream (buffer, false);
1253                         Assert.IsTrue (Throws<NotSupportedException> (() => { stream.Write (buffer, 0, buffer.Length); }), "#1");
1254                         Assert.IsTrue (Throws<ArgumentNullException> (() => { stream.Write (null, 0, buffer.Length); }), "#1.1");
1255                         stream.Close ();
1256                         Assert.IsTrue (Throws<ObjectDisposedException> (() => { stream.Write (buffer, 0, buffer.Length); }), "#2");
1257                         stream = new MemoryStream (buffer, true);
1258                         stream.Close ();
1259                         Assert.IsFalse (stream.CanWrite, "#3");
1260
1261                         var estream = new ExceptionalStream (buffer, false);
1262                         Assert.IsFalse (Throws<Exception> (() => { estream.Write (buffer, 0, buffer.Length); }), "#4");
1263                         estream.AllowWrite = false;
1264                         estream.Position = 0;
1265                         Assert.IsTrue (Throws<NotSupportedException> (() => { estream.Write (buffer, 0, buffer.Length); }), "#5");
1266                         estream.AllowWrite = true;
1267                         estream.Close ();
1268                         Assert.IsTrue (estream.CanWrite, "#6");
1269                         Assert.IsTrue (Throws<ObjectDisposedException> (() => { stream.Write (buffer, 0, buffer.Length); }), "#7");
1270                 }
1271
1272                 [Test]
1273                 public void ReadAsync_Canceled ()
1274                 {
1275                         var buffer = new byte[3];
1276                         var t = testStream.ReadAsync (buffer, 0, buffer.Length, new CancellationToken (true));
1277                         Assert.IsTrue (t.IsCanceled);
1278
1279                         t = testStream.ReadAsync (buffer, 0, buffer.Length);
1280                         Assert.AreEqual (t.Result, 3, "#1");
1281                         Assert.AreEqual (99, buffer[1], "#2");
1282                 }
1283
1284                 [Test]
1285                 public void WriteAsync ()
1286                 {
1287                         var buffer = new byte[3] { 3, 5, 9 };
1288
1289                         var ms = new MemoryStream ();
1290                         var t = ms.WriteAsync (buffer, 0, buffer.Length);
1291                         Assert.IsTrue (t.IsCompleted, "#1");
1292
1293                         ms.Seek (0, SeekOrigin.Begin);
1294                         Assert.AreEqual (3, ms.ReadByte (), "#2");
1295                 }
1296
1297                 [Test]
1298                 public void WriteAsync_Canceled ()
1299                 {
1300                         var buffer = new byte[3] { 1, 2, 3 };
1301                         var t = testStream.WriteAsync (buffer, 0, buffer.Length, new CancellationToken (true));
1302                         Assert.IsTrue (t.IsCanceled);
1303
1304                         t = testStream.WriteAsync (buffer, 0, buffer.Length);
1305                         Assert.IsTrue (t.IsCompleted, "#1");
1306                 }
1307
1308                 bool Throws<T> (Action a) where T : Exception
1309                 {
1310                         try {
1311                                 a ();
1312                                 return false;
1313                         } catch (T) {
1314                                 return true;
1315                         }
1316                 }
1317 #endif
1318         }
1319 }