[resgen] Implement conditional resources (#if/#ifdef)
[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                 class CannotSeekStream : MemoryStream
94                 {
95                         public CannotSeekStream ()
96                                 : base (new byte [11])
97                         {
98                         }
99
100                         public override bool CanSeek {
101                                 get {
102                                         return false;
103                                 }
104                         }
105                 }
106
107                 [Test]
108                 public void Ctor_Invalid ()
109                 {
110                         try {
111                                 new StreamContent (null);
112                                 Assert.Fail ("#1");
113                         } catch (ArgumentNullException) {
114                         }
115
116                         try {
117                                 new StreamContent (new MemoryStream (), 0);
118                                 Assert.Fail ("#2");
119                         } catch (ArgumentOutOfRangeException) {
120                         }
121                 }
122
123                 [Test]
124                 public void Ctor ()
125                 {
126                         var ms = new MemoryStream ();
127                         ms.WriteByte (44);
128
129                         using (var m = new StreamContent (ms)) {
130                         }
131                 }
132
133                 [Test]
134                 public void CopyToAsync_Invalid ()
135                 {
136                         var m = new MemoryStream ();
137
138                         var sc = new StreamContent (new MemoryStream ());
139                         try {
140                                 sc.CopyToAsync (null);
141                                 Assert.Fail ("#1");
142                         } catch (ArgumentNullException) {
143                         }
144
145                         //
146                         // For some reason does not work on .net
147                         //
148                         /*
149                         sc = new StreamContent (new ExceptionStream ());
150                         try {
151                             sc.CopyToAsync (m).Wait ();
152                             Assert.Fail ("#2");
153                         } catch (AggregateException) {
154                         }
155                         */ 
156                 }
157
158                 [Test]
159                 /*
160                  * The .NET runtime hits the "#9" assertion.
161                  * The test succeeds with Mono.
162                  */
163                 [Category ("NotDotNet")]
164                 public void CopyToAsync ()
165                 {
166                         var ms = new MemoryStream ();
167                         ms.WriteByte (4);
168                         ms.WriteByte (2);
169                         ms.Seek (0, SeekOrigin.Begin);
170
171                         var sc = new StreamContent (ms);
172
173                         var dest = new MemoryStream ();
174                         var task = sc.CopyToAsync (dest);
175                         task.Wait ();
176                         Assert.AreEqual (2, dest.Length, "#1");
177
178                         bool hit = false;
179                         dest = new MemoryStream ();
180                         var scm = new StreamContentMock (new ExceptionStream ());
181                         scm.OnSerializeToStreamAsync = () => { hit = true; };
182                         task = scm.CopyToAsync (dest);
183                         try {
184                                 task.Wait ();
185                                 Assert.Fail ("#9");
186                         } catch (AggregateException) {
187                         }
188
189                         Assert.IsTrue (hit, "#10");
190                 }
191
192                 [Test]
193                 public void CopyToAsync_ClosedInput ()
194                 {
195                         var stream = new MemoryStream (new byte[] { 1 });
196                         var content = new StreamContent (stream);
197                         Assert.IsTrue (content.LoadIntoBufferAsync ().Wait (3000), "#1");
198                         stream.Close ();
199
200                         var stream_out = new MemoryStream (10);
201                         Assert.IsTrue (content.CopyToAsync (stream_out).Wait (3000), "#2");
202                 }
203
204                 [Test]
205                 public void Headers ()
206                 {
207                         var ms = new MemoryStream ();
208                         ms.WriteByte (4);
209                         ms.WriteByte (2);
210                         ms.Seek (0, SeekOrigin.Begin);
211
212                         var sc = new StreamContent (ms);
213                         var headers = sc.Headers;
214                         Assert.AreEqual (2, headers.ContentLength, "#1");
215
216                         headers.ContentLength = 400;
217                         Assert.AreEqual (400, headers.ContentLength, "#1a");
218                         headers.ContentLength = null;
219
220                         var scm = new StreamContentMock (MemoryStream.Null);
221                         scm.OnTryComputeLength = () => 330;
222                         Assert.AreEqual (330, scm.Headers.ContentLength, "#2");
223
224                         headers.Allow.Add ("a1");
225                         headers.ContentDisposition = new ContentDispositionHeaderValue ("cd1");
226                         headers.ContentEncoding.Add ("ce1");
227                         headers.ContentLanguage.Add ("cl1");
228                         headers.ContentLength = 23;
229                         headers.ContentLocation = new Uri ("http://xamarin.com");
230                         headers.ContentMD5 = new byte[] { 3, 5 };
231                         headers.ContentRange = new ContentRangeHeaderValue (88, 444);
232                         headers.ContentType = new MediaTypeHeaderValue ("multipart/*");
233                         headers.Expires = new DateTimeOffset (DateTime.Today);
234                         headers.LastModified = new DateTimeOffset (DateTime.Today);
235
236
237                         headers.Add ("allow", "a2");
238                         try {
239                                 headers.Add ("content-disposition", "cd2");
240                                 Assert.Fail ("content-disposition");
241                         } catch (FormatException) {
242                         }
243
244                         headers.Add ("content-encoding", "ce3");
245                         headers.Add ("content-language", "cl2");
246
247                         try {
248                                 headers.Add ("content-length", "444");
249                                 Assert.Fail ("content-length");
250                         } catch (FormatException) {
251                         }
252
253                         try {
254                                 headers.Add ("content-location", "cl2");
255                                 Assert.Fail ("content-location");
256                         } catch (FormatException) {
257                         }
258
259                         try {
260                                 headers.Add ("content-MD5", "cmd5");
261                                 Assert.Fail ("content-MD5");
262                         } catch (FormatException) {
263                         }
264
265                         try {
266                                 headers.Add ("content-range", "133");
267                                 Assert.Fail ("content-range");
268                         } catch (FormatException) {
269                         }
270
271                         try {
272                                 headers.Add ("content-type", "ctype");
273                                 Assert.Fail ("content-type");
274                         } catch (FormatException) {
275                         }
276
277                         try {
278                                 headers.Add ("expires", "ctype");
279                                 Assert.Fail ("expires");
280                         } catch (FormatException) {
281                         }
282
283                         try {
284                                 headers.Add ("last-modified", "lmo");
285                                 Assert.Fail ("last-modified");
286                         } catch (FormatException) {
287                         }
288
289                         Assert.IsTrue (headers.Allow.SequenceEqual (
290                                 new[] {
291                                         "a1",
292                                         "a2"
293                                 }
294                         ));
295
296                         Assert.IsTrue (headers.ContentEncoding.SequenceEqual (
297                                 new[] {
298                                         "ce1",
299                                         "ce3"
300                                 }
301                         ));
302
303                         Assert.IsTrue (headers.ContentLanguage.SequenceEqual (
304                                 new[] {
305                                         "cl1",
306                                         "cl2"
307                                 }
308                         ));
309
310                         Assert.AreEqual (23, headers.ContentLength);
311                         Assert.AreEqual (new Uri ("http://xamarin.com"), headers.ContentLocation);
312                         Assert.AreEqual (new byte[] { 3, 5 }, headers.ContentMD5);
313                         Assert.AreEqual (new ContentRangeHeaderValue (88, 444), headers.ContentRange);
314                         Assert.AreEqual (new MediaTypeHeaderValue ("multipart/*"), headers.ContentType);
315                         Assert.AreEqual (new DateTimeOffset (DateTime.Today), headers.Expires);
316                         Assert.AreEqual (new DateTimeOffset (DateTime.Today), headers.LastModified);
317                         Assert.AreEqual (new ContentDispositionHeaderValue ("cd1"), headers.ContentDisposition);
318                 }
319
320                 [Test]
321                 public void Headers_ToString ()
322                 {
323                         var sc = new StreamContent (new MemoryStream ());
324                         var headers = sc.Headers;
325                         headers.ContentMD5 = new byte[] { 3, 5 };
326
327                         Assert.AreEqual ("Content-MD5: AwU=\r\n", headers.ToString (), "#1");
328                 }
329
330                 [Test]
331                 public void Headers_Invalid ()
332                 {
333                         var sc = new StreamContent (MemoryStream.Null);
334                         var h = sc.Headers;
335
336                         try {
337                                 h.Add ("Age", "");
338                                 Assert.Fail ("#1");
339                         } catch (InvalidOperationException) {
340                         }
341                 }
342
343                 [Test]
344                 public void Headers_Multi ()
345                 {
346                         var sc = new StreamContent (MemoryStream.Null);
347                         var headers = sc.Headers;
348
349                         headers.Add ("Allow", "");
350                         headers.Add ("Allow", "a , b, c");
351
352                         Assert.AreEqual (3, headers.Allow.Count, "#1a");
353                         Assert.IsTrue (headers.Allow.SequenceEqual (
354                                 new[] { "a", "b", "c" }
355                         ), "#1b");
356                 }
357
358                 [Test]
359                 public void LoadIntoBuffer ()
360                 {
361                         var ms = new MemoryStream ();
362                         ms.WriteByte (4);
363                         ms.Seek (0, SeekOrigin.Begin);
364
365                         var sc = new StreamContent (ms);
366                         Assert.IsTrue (sc.LoadIntoBufferAsync (400).Wait (200));
367                 }
368
369                 [Test]
370                 public void LoadIntoBuffer_BufferOverflow ()
371                 {
372                         var ms = new MemoryStream ();
373                         ms.Write (new byte[10000], 0, 10000);
374                         ms.Seek (0, SeekOrigin.Begin);
375
376                         var sc = new StreamContent (ms);
377                         try {
378                                 Assert.IsTrue (sc.LoadIntoBufferAsync (50).Wait (200));
379                                 Assert.Fail ("#1");
380                         } catch (AggregateException e) {
381                                 Assert.IsTrue (e.InnerException is HttpRequestException, "#2");
382                         }
383                 }
384
385                 [Test]
386                 public void ReadAsByteArrayAsync ()
387                 {
388                         var ms = new MemoryStream ();
389                         ms.WriteByte (4);
390                         ms.WriteByte (55);
391
392                         var sc = new StreamContent (ms);
393                         var res = sc.ReadAsByteArrayAsync ().Result;
394                         Assert.AreEqual (0, res.Length, "#1");
395
396                         ms.Seek (0, SeekOrigin.Begin);
397                         sc = new StreamContent (ms);
398                         res = sc.ReadAsByteArrayAsync ().Result;
399                         Assert.AreEqual (2, res.Length, "#10");
400                         Assert.AreEqual (55, res[1], "#11");
401                 }
402
403                 [Test]
404                 public void ReadAsString ()
405                 {
406                         var ms = new MemoryStream ();
407                         ms.WriteByte (77);
408                         ms.WriteByte (55);
409                         ms.Seek (0, SeekOrigin.Begin);
410
411                         var sc = new StreamContent (ms);
412                         var res = sc.ReadAsStringAsync ().Result;
413                         Assert.AreEqual ("M7", res, "#1");
414                 }
415
416                 [Test]
417                 public void ReadAsStream ()
418                 {
419                         var ms = new MemoryStream ();
420                         ms.WriteByte (77);
421                         ms.WriteByte (55);
422                         ms.Seek (0, SeekOrigin.Begin);
423
424                         var sc = new StreamContent (ms);
425                         var res = sc.ReadAsStreamAsync ().Result;
426                         Assert.AreEqual (77, res.ReadByte (), "#1");
427                 }
428
429                 [Test]
430                 public void ReadAsStreamAsync_ClosedInput ()
431                 {
432                         var stream = new MemoryStream (new byte[] { 1 });
433                         var content = new StreamContent (stream);
434                         Assert.IsTrue (content.LoadIntoBufferAsync ().Wait (3000), "#1");
435                         stream.Close ();
436
437                         var stream_read = content.ReadAsStreamAsync ().Result;
438                         Assert.IsTrue (stream_read.CanSeek, "#2");
439                         Assert.AreEqual (0, stream_read.Position, "#3");        
440                         Assert.AreEqual (1, stream_read.Length, "#4");
441                 }
442
443                 [Test]
444                 public void ContentLengthAfterLoad ()
445                 {
446                         var sc = new StreamContent (new CannotSeekStream ());
447                         Assert.IsTrue (sc.LoadIntoBufferAsync ().Wait (3000), "#1");
448                         Assert.AreEqual (11, sc.Headers.ContentLength, "#2");
449                 }
450         }
451 }