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