Merge pull request #819 from brendanzagaeski/patch-1
[mono.git] / mcs / class / System.Net.Http / Test / System.Net.Http / StreamContentTest.cs
1 //
2 // StreamContentTest.cs
3 //
4 // Authors:
5 //      Marek Safar  <marek.safar@gmail.com>
6 //
7 // Copyright (C) 2012 Xamarin Inc (http://www.xamarin.com)
8 //
9 // Permission is hereby granted, free of charge, to any person obtaining
10 // a copy of this software and associated documentation files (the
11 // "Software"), to deal in the Software without restriction, including
12 // without limitation the rights to use, copy, modify, merge, publish,
13 // distribute, sublicense, and/or sell copies of the Software, and to
14 // permit persons to whom the Software is furnished to do so, subject to
15 // the following conditions:
16 //
17 // The above copyright notice and this permission notice shall be
18 // included in all copies or substantial portions of the Software.
19 //
20 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
24 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
25 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27 //
28
29 using System;
30 using System.Collections;
31 using System.Collections.Generic;
32 using NUnit.Framework;
33 using System.Net.Http;
34 using System.Net.Http.Headers;
35 using System.IO;
36 using System.Threading.Tasks;
37 using System.Net;
38 using System.Linq;
39
40 namespace MonoTests.System.Net.Http
41 {
42         [TestFixture]
43         public class StreamContentTest
44         {
45                 class StreamContentMock : StreamContent
46                 {
47                         public Func<long> OnTryComputeLength;
48                         public Action OnSerializeToStreamAsync;
49
50                         public StreamContentMock (Stream stream)
51                                 : base (stream)
52                         {
53                         }
54
55                         protected override bool TryComputeLength (out long length)
56                         {
57                                 if (OnTryComputeLength != null) {
58                                         length = OnTryComputeLength ();
59                                         return true;
60                                 }
61
62                                 return base.TryComputeLength (out length);
63                         }
64
65                         protected override Task SerializeToStreamAsync (Stream stream, TransportContext context)
66                         {
67                                 if (OnSerializeToStreamAsync != null)
68                                         OnSerializeToStreamAsync ();
69
70                                 return base.SerializeToStreamAsync (stream, context);
71                         }
72                 }
73
74                 class ExceptionStream : MemoryStream
75                 {
76                         public ExceptionStream ()
77                         {
78                                 base.WriteByte (10);
79                                 base.Seek (0, SeekOrigin.Begin);
80                         }
81
82                         public override int Read (byte[] buffer, int offset, int count)
83                         {
84                                 throw new ApplicationException ("Read");
85                         }
86
87                         public override byte[] GetBuffer ()
88                         {
89                                 throw new ApplicationException ("GetBuffer");
90                         }
91                 }
92
93                 [Test]
94                 public void Ctor_Invalid ()
95                 {
96                         try {
97                                 new StreamContent (null);
98                                 Assert.Fail ("#1");
99                         } catch (ArgumentNullException) {
100                         }
101
102                         try {
103                                 new StreamContent (new MemoryStream (), 0);
104                                 Assert.Fail ("#2");
105                         } catch (ArgumentOutOfRangeException) {
106                         }
107                 }
108
109                 [Test]
110                 public void Ctor ()
111                 {
112                         var ms = new MemoryStream ();
113                         ms.WriteByte (44);
114
115                         using (var m = new StreamContent (ms)) {
116                         }
117                 }
118
119                 [Test]
120                 public void CopyToAsync_Invalid ()
121                 {
122                         var m = new MemoryStream ();
123
124                         var sc = new StreamContent (new MemoryStream ());
125                         try {
126                                 sc.CopyToAsync (null);
127                                 Assert.Fail ("#1");
128                         } catch (ArgumentNullException) {
129                         }
130
131                         //
132                         // For some reason does not work on .net
133                         //
134                         /*
135                         sc = new StreamContent (new ExceptionStream ());
136                         try {
137                             sc.CopyToAsync (m).Wait ();
138                             Assert.Fail ("#2");
139                         } catch (AggregateException) {
140                         }
141                         */ 
142                 }
143
144                 [Test]
145                 /*
146                  * The .NET runtime hits the "#9" assertion.
147                  * The test succeeds with Mono.
148                  */
149                 [Category ("NotWorking")]
150                 public void CopyToAsync ()
151                 {
152                         var ms = new MemoryStream ();
153                         ms.WriteByte (4);
154                         ms.WriteByte (2);
155                         ms.Seek (0, SeekOrigin.Begin);
156
157                         var sc = new StreamContent (ms);
158
159                         var dest = new MemoryStream ();
160                         var task = sc.CopyToAsync (dest);
161                         task.Wait ();
162                         Assert.AreEqual (2, dest.Length, "#1");
163
164                         bool hit = false;
165                         dest = new MemoryStream ();
166                         var scm = new StreamContentMock (new ExceptionStream ());
167                         scm.OnSerializeToStreamAsync = () => { hit = true; };
168                         task = scm.CopyToAsync (dest);
169                         try {
170                                 task.Wait ();
171                                 Assert.Fail ("#9");
172                         } catch (AggregateException) {
173                         }
174
175                         Assert.IsTrue (hit, "#10");
176                 }
177
178                 [Test]
179                 public void CopyToAsync_ClosedInput ()
180                 {
181                         var stream = new MemoryStream (new byte[] { 1 });
182                         var content = new StreamContent (stream);
183                         Assert.IsTrue (content.LoadIntoBufferAsync ().Wait (3000), "#1");
184                         stream.Close ();
185
186                         var stream_out = new MemoryStream (10);
187                         Assert.IsTrue (content.CopyToAsync (stream_out).Wait (3000), "#2");
188                 }
189
190                 [Test]
191                 public void Headers ()
192                 {
193                         var ms = new MemoryStream ();
194                         ms.WriteByte (4);
195                         ms.WriteByte (2);
196                         ms.Seek (0, SeekOrigin.Begin);
197
198                         var sc = new StreamContent (ms);
199                         var headers = sc.Headers;
200                         Assert.AreEqual (2, headers.ContentLength, "#1");
201
202                         headers.ContentLength = 400;
203                         Assert.AreEqual (400, headers.ContentLength, "#1a");
204                         headers.ContentLength = null;
205
206                         var scm = new StreamContentMock (MemoryStream.Null);
207                         scm.OnTryComputeLength = () => 330;
208                         Assert.AreEqual (330, scm.Headers.ContentLength, "#2");
209
210                         headers.Allow.Add ("a1");
211                         headers.ContentEncoding.Add ("ce1");
212                         headers.ContentLanguage.Add ("cl1");
213                         headers.ContentLength = 23;
214                         headers.ContentLocation = new Uri ("http://xamarin.com");
215                         headers.ContentMD5 = new byte[] { 3, 5 };
216                         headers.ContentRange = new ContentRangeHeaderValue (88, 444);
217                         headers.ContentType = new MediaTypeHeaderValue ("multipart/*");
218                         headers.Expires = new DateTimeOffset (DateTime.Today);
219                         headers.LastModified = new DateTimeOffset (DateTime.Today);
220
221
222                         headers.Add ("allow", "a2");
223                         headers.Add ("content-encoding", "ce3");
224                         headers.Add ("content-language", "cl2");
225
226                         try {
227                                 headers.Add ("content-length", "444");
228                                 Assert.Fail ("content-length");
229                         } catch (FormatException) {
230                         }
231
232                         try {
233                                 headers.Add ("content-location", "cl2");
234                                 Assert.Fail ("content-location");
235                         } catch (FormatException) {
236                         }
237
238                         try {
239                                 headers.Add ("content-MD5", "cmd5");
240                                 Assert.Fail ("content-MD5");
241                         } catch (FormatException) {
242                         }
243
244                         try {
245                                 headers.Add ("content-range", "133");
246                                 Assert.Fail ("content-range");
247                         } catch (FormatException) {
248                         }
249
250                         try {
251                                 headers.Add ("content-type", "ctype");
252                                 Assert.Fail ("content-type");
253                         } catch (FormatException) {
254                         }
255
256                         try {
257                                 headers.Add ("expires", "ctype");
258                                 Assert.Fail ("expires");
259                         } catch (FormatException) {
260                         }
261
262                         try {
263                                 headers.Add ("last-modified", "lmo");
264                                 Assert.Fail ("last-modified");
265                         } catch (FormatException) {
266                         }
267
268                         Assert.IsTrue (headers.Allow.SequenceEqual (
269                                 new[] {
270                                         "a1",
271                                         "a2"
272                                 }
273                         ));
274
275                         Assert.IsTrue (headers.ContentEncoding.SequenceEqual (
276                                 new[] {
277                                         "ce1",
278                                         "ce3"
279                                 }
280                         ));
281
282                         Assert.IsTrue (headers.ContentLanguage.SequenceEqual (
283                                 new[] {
284                                         "cl1",
285                                         "cl2"
286                                 }
287                         ));
288
289                         Assert.AreEqual (23, headers.ContentLength);
290                         Assert.AreEqual (new Uri ("http://xamarin.com"), headers.ContentLocation);
291                         Assert.AreEqual (new byte[] { 3, 5 }, headers.ContentMD5);
292                         Assert.AreEqual (new ContentRangeHeaderValue (88, 444), headers.ContentRange);
293                         Assert.AreEqual (new MediaTypeHeaderValue ("multipart/*"), headers.ContentType);
294                         Assert.AreEqual (new DateTimeOffset (DateTime.Today), headers.Expires);
295                         Assert.AreEqual (new DateTimeOffset (DateTime.Today), headers.LastModified);
296                 }
297
298                 [Test]
299                 public void Headers_Invalid ()
300                 {
301                         var sc = new StreamContent (MemoryStream.Null);
302                         var h = sc.Headers;
303
304                         try {
305                                 h.Add ("Age", "");
306                                 Assert.Fail ("#1");
307                         } catch (InvalidOperationException) {
308                         }
309                 }
310
311                 [Test]
312                 public void Headers_Multi ()
313                 {
314                         var sc = new StreamContent (MemoryStream.Null);
315                         var headers = sc.Headers;
316
317                         headers.Add ("Allow", "");
318                         headers.Add ("Allow", "a , b, c");
319
320                         Assert.AreEqual (3, headers.Allow.Count, "#1a");
321                         Assert.IsTrue (headers.Allow.SequenceEqual (
322                                 new[] { "a", "b", "c" }
323                         ), "#1b");
324                 }
325
326                 [Test]
327                 public void LoadIntoBuffer ()
328                 {
329                         var ms = new MemoryStream ();
330                         ms.WriteByte (4);
331                         ms.Seek (0, SeekOrigin.Begin);
332
333                         var sc = new StreamContent (ms);
334                         Assert.IsTrue (sc.LoadIntoBufferAsync (400).Wait (200));
335                 }
336
337                 [Test]
338                 public void LoadIntoBuffer_BufferOverflow ()
339                 {
340                         var ms = new MemoryStream ();
341                         ms.Write (new byte[10000], 0, 10000);
342                         ms.Seek (0, SeekOrigin.Begin);
343
344                         var sc = new StreamContent (ms);
345                         try {
346                                 Assert.IsTrue (sc.LoadIntoBufferAsync (50).Wait (200));
347                                 Assert.Fail ("#1");
348                         } catch (AggregateException e) {
349                                 Assert.IsTrue (e.InnerException is HttpRequestException, "#2");
350                         }
351                 }
352
353                 [Test]
354                 public void ReadAsByteArrayAsync ()
355                 {
356                         var ms = new MemoryStream ();
357                         ms.WriteByte (4);
358                         ms.WriteByte (55);
359
360                         var sc = new StreamContent (ms);
361                         var res = sc.ReadAsByteArrayAsync ().Result;
362                         Assert.AreEqual (0, res.Length, "#1");
363
364                         ms.Seek (0, SeekOrigin.Begin);
365                         sc = new StreamContent (ms);
366                         res = sc.ReadAsByteArrayAsync ().Result;
367                         Assert.AreEqual (2, res.Length, "#10");
368                         Assert.AreEqual (55, res[1], "#11");
369                 }
370
371                 [Test]
372                 public void ReadAsString ()
373                 {
374                         var ms = new MemoryStream ();
375                         ms.WriteByte (77);
376                         ms.WriteByte (55);
377                         ms.Seek (0, SeekOrigin.Begin);
378
379                         var sc = new StreamContent (ms);
380                         var res = sc.ReadAsStringAsync ().Result;
381                         Assert.AreEqual ("M7", res, "#1");
382                 }
383
384                 [Test]
385                 public void ReadAsStream ()
386                 {
387                         var ms = new MemoryStream ();
388                         ms.WriteByte (77);
389                         ms.WriteByte (55);
390                         ms.Seek (0, SeekOrigin.Begin);
391
392                         var sc = new StreamContent (ms);
393                         var res = sc.ReadAsStreamAsync ().Result;
394                         Assert.AreEqual (77, res.ReadByte (), "#1");
395                 }
396
397                 [Test]
398                 public void ReadAsStreamAsync_ClosedInput ()
399                 {
400                         var stream = new MemoryStream (new byte[] { 1 });
401                         var content = new StreamContent (stream);
402                         Assert.IsTrue (content.LoadIntoBufferAsync ().Wait (3000), "#1");
403                         stream.Close ();
404
405                         var stream_read = content.ReadAsStreamAsync ().Result;
406                         Assert.IsTrue (stream_read.CanSeek, "#2");
407                         Assert.AreEqual (0, stream_read.Position, "#3");        
408                         Assert.AreEqual (1, stream_read.Length, "#4");
409                 }
410         }
411 }