Merge pull request #823 from DavidKarlas/master
[mono.git] / mcs / class / System.Core / Test / System.Linq / ParallelEnumerableTests.cs
1 // ParallelEnumerableTests.cs
2 //
3 // Copyright (c) 2008 Jérémie "Garuma" Laval
4 //
5 // Based on Enumerable test suite by Jb Evain (jbevain@novell.com)
6 //
7 // Permission is hereby granted, free of charge, to any person obtaining a copy
8 // of this software and associated documentation files (the "Software"), to deal
9 // in the Software without restriction, including without limitation the rights
10 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 // copies of the Software, and to permit persons to whom the Software is
12 // furnished to do so, subject to the following conditions:
13 //
14 // The above copyright notice and this permission notice shall be included in
15 // all copies or substantial portions of the Software.
16 //
17 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23 // THE SOFTWARE.
24 //
25 //
26
27 #if NET_4_0
28
29 using System;
30 using System.Threading;
31 using System.Linq;
32
33 using System.Collections;
34 using System.Collections.Generic;
35
36 using NUnit.Framework;
37
38 namespace MonoTests.System.Linq
39 {
40         internal static class AsParallelHelper
41         {
42                 internal static ParallelQuery<T> AsReallyParallel<T> (this IEnumerable<T> source)
43                 {
44                         return source.AsParallel ().WithExecutionMode (ParallelExecutionMode.ForceParallelism);
45                 }
46         }
47
48         [TestFixtureAttribute]
49         public class ParallelEnumerableTests
50         {
51                 IEnumerable<int> baseEnumerable;
52                 
53                 [SetUpAttribute]
54                 public void Setup ()
55                 {
56                         baseEnumerable = Enumerable.Range(1, 1000);
57                 }
58
59                 static void AreEquivalent (IEnumerable syncEnumerable, IEnumerable async_resEnumerable)
60                 {
61                         Assert.That (async_resEnumerable, new NUnit.Framework.Constraints.CollectionEquivalentConstraint (syncEnumerable));
62                 }
63                 
64                 static void AssertAreSame<T> (IEnumerable<T> expected, IEnumerable<T> actual)
65                 {
66                         if (expected == null) {
67                                 Assert.IsNull (actual);
68                                 return;
69                         }
70
71                         Assert.IsNotNull (actual);
72                         int index = -1;
73
74                         IEnumerator<T> ee = expected.GetEnumerator ();
75                         IEnumerator<T> ea = actual.GetEnumerator ();
76
77                         while (ee.MoveNext ()) {
78                                 Assert.IsTrue (ea.MoveNext (), "'" + ee.Current + "' expected at index '"+ ++index + "'.");
79                                 Assert.AreEqual (ee.Current, ea.Current, "at index '" + index + "'");
80                         }
81
82                         if (ea.MoveNext ())
83                                 Assert.Fail ("Unexpected element: " + ea.Current);
84                 }
85                 
86                 public static void AssertException<T> (Action action) where T : Exception
87                 {
88                         try {
89                                 action ();
90                         }
91                         catch (T) {
92                                 return;
93                         }
94                         Assert.Fail ("Expected: " + typeof (T).Name);
95                 }
96
97                 static void AssertAreSame<K, V> (K expectedKey, IEnumerable<V> expectedValues, IGrouping<K, V> actual)
98                 {
99                         if (expectedValues == null) {
100                                 Assert.IsNull (actual);
101                                 return;
102                         }
103
104                         Assert.IsNotNull (actual);
105
106                         Assert.AreEqual (expectedKey, actual.Key);
107
108                         var ee = expectedValues.GetEnumerator ();
109                         var ea = actual.GetEnumerator ();
110
111                         while (ee.MoveNext ()) {
112                                 Assert.IsTrue (ea.MoveNext (), "'" + ee.Current + "' expected.");
113                                 Assert.AreEqual (ee.Current, ea.Current);
114                         }
115
116                         if (ea.MoveNext ())
117                                 Assert.Fail ("Unexpected element: " + ee.Current);
118                 }
119
120                 static void AssertAreSame<K, V> (IDictionary<K, IEnumerable<V>> expected, IEnumerable<IGrouping<K, V>> actual)
121                 {
122                         if (expected == null) {
123                                 Assert.IsNull (actual);
124                                 return;
125                         }
126
127                         Assert.IsNotNull (actual);
128
129                         var ee = expected.GetEnumerator ();
130                         var ea = actual.GetEnumerator ();
131
132                         while (ee.MoveNext ()) {
133                                 Assert.IsTrue (ea.MoveNext (), "'" + ee.Current.Key + "' expected.");
134                                 AssertAreSame (ee.Current.Key, ee.Current.Value, ea.Current);
135                         }
136
137                         if (ea.MoveNext ())
138                                 Assert.Fail ("Unexpected element: " + ee.Current.Key);
139                 }
140
141                 static void AssertAreSame<K, V> (IDictionary<K, IEnumerable<V>> expected, ILookup<K, V> actual)
142                 {
143                         if (expected == null) {
144                                 Assert.IsNull (actual);
145                                 return;
146                         }
147
148                         Assert.IsNotNull (actual);
149
150                         var ee = expected.GetEnumerator ();
151                         var ea = actual.GetEnumerator ();
152
153                         while (ee.MoveNext ()) {
154                                 Assert.IsTrue (ea.MoveNext (), "'" + ee.Current.Key + "' expected.");
155                                 AssertAreSame (ee.Current.Key, ee.Current.Value, ea.Current);
156                         }
157
158                         if (ea.MoveNext ())
159                                 Assert.Fail ("Unexpected element: " + ee.Current.Key);
160                 }
161
162                 static void AssertAreSame<K, V> (IDictionary<K, V> expected, IDictionary<K, V> actual)
163                 {
164                         if (expected == null) {
165                                 Assert.IsNull (actual);
166                                 return;
167                         }
168
169                         Assert.IsNotNull (actual);
170
171                         var ee = expected.GetEnumerator ();
172                         var ea = actual.GetEnumerator ();
173
174                         while (ee.MoveNext ()) {
175                                 Assert.IsTrue (ea.MoveNext (), "'" + ee.Current.Key + ", " + ee.Current.Value + "' expected.");
176                                 Assert.AreEqual (ee.Current.Key, ea.Current.Key);
177                                 Assert.AreEqual (ee.Current.Value, ea.Current.Value);
178                         }
179
180                         if (ea.MoveNext ())
181                                 Assert.Fail ("Unexpected element: " + ee.Current.Key + ", " + ee.Current.Value);
182                 }
183
184                 [Test]
185                 public void SelectTestCase ()
186                 {
187                         ParallelTestHelper.Repeat (() => {
188                                 IEnumerable<int> sync  = baseEnumerable.Select (i => i * i);
189                                 IEnumerable<int> async_res = baseEnumerable.AsParallel ().Select (i => i * i);
190                                 
191                                 AreEquivalent(sync, async_res);
192                         });
193                 }
194                         
195                 [Test]
196                 public void WhereTestCase ()
197                 {
198                         ParallelTestHelper.Repeat (() => {
199                                 IEnumerable<int> sync  = baseEnumerable.Where(i => i % 2 == 0);
200                                 IEnumerable<int> async_res = baseEnumerable.AsParallel().Where(i => i % 2 == 0);
201                                 
202                                 AreEquivalent(sync, async_res);
203                         });
204                 }
205                 
206                 [Test]
207                 public void CountTestCase ()
208                 {
209                         ParallelTestHelper.Repeat (() => {
210                                 int sync  = baseEnumerable.Count();
211                                 int async_res = baseEnumerable.AsParallel().Count();
212                                 
213                                 Assert.AreEqual(sync, async_res, "#1");
214                         });
215                 }
216                 
217                 [Test]
218                 public void AggregateTestCase ()
219                 {
220                         ParallelTestHelper.Repeat (() => {
221                                 ParallelQuery<int> range = ParallelEnumerable.Repeat (5, 2643);
222                                 double average = range.Aggregate(() => new double[2],
223                                                                  (acc, elem) => { acc[0] += elem; acc[1]++; return acc; },
224                                 (acc1, acc2) => { acc1[0] += acc2[0]; acc1[1] += acc2[1]; return acc1; },
225                                 acc => acc[0] / acc[1]);
226                                 
227                                 Assert.AreEqual(5.0, average, "#1");
228                         });
229                 }
230                 
231                 [Test]
232                 public void TestSimpleExcept ()
233                 {
234                         ParallelTestHelper.Repeat (() => {
235                                 int [] first = {0, 1, 2, 3, 4, 5};
236                                 int [] second = {2, 4, 6};
237                                 int [] result = {0, 1, 3, 5};
238         
239                                 AreEquivalent (result, first.AsReallyParallel ().Except (second.AsParallel ()));
240                         });
241                 }
242
243                 [Test]
244                 public void TestSimpleIntersect ()
245                 {
246                         ParallelTestHelper.Repeat (() => {
247                                 int [] first = {0, 1, 2, 3, 4, 5};
248                                 int [] second = {2, 4, 6};
249                                 int [] result = {2, 4};
250         
251                                 AreEquivalent (result, first.AsReallyParallel ().Intersect (second.AsParallel ()));
252                         });
253                 }
254
255                 [Test]
256                 public void TestSimpleUnion ()
257                 {
258                         ParallelTestHelper.Repeat (() => {
259                                 int [] first = {0, 1, 2, 3, 4, 5};
260                                 int [] second = {2, 4, 6};
261                                 int [] result = {0, 1, 2, 3, 4, 5, 6};
262                                 
263                                 AreEquivalent (result, first.AsReallyParallel ().Union (second.AsParallel ()));
264                         });
265                 }
266
267                 [Test]
268                 public void TestBigUnion ()
269                 {
270                         ParallelTestHelper.Repeat (() => {
271                                 int [] first = Enumerable.Range (1, 10000).ToArray ();
272                                 int [] second = Enumerable.Range (323, 757).ToArray ();
273
274                                 AreEquivalent (first, first.AsReallyParallel ().Union (second.AsParallel ()));
275                         });
276                 }
277
278                 [Test]
279                 public void TestBigIntersect ()
280                 {
281                         ParallelTestHelper.Repeat (() => {
282                                 int [] first = Enumerable.Range (1, 10000).ToArray ();
283                                 int [] second = Enumerable.Range (323, 757).ToArray ();
284
285                                 AreEquivalent (second, first.AsReallyParallel ().Intersect (second.AsParallel ()));
286                         });
287                 }
288                 
289                 class Foo {}
290                 class Bar : Foo {}
291
292                 [Test]
293                 public void TestCast ()
294                 {
295                         Bar a = new Bar ();
296                         Bar b = new Bar ();
297                         Bar c = new Bar ();
298
299                         Foo [] foos = new Foo [] {a, b, c};
300                         Bar [] result = new Bar [] {a, b, c};
301
302                         AreEquivalent (result, foos.AsReallyParallel ().Cast<Bar> ());
303                 }
304                 
305                 [Test]
306                 public void TestSkip ()
307                 {
308                         int [] data = {0, 1, 2, 3, 4, 5};
309                         int [] result = {3, 4, 5};
310
311                         AssertAreSame (result, data.AsReallyParallel ().AsOrdered ().Skip (3).ToArray ());
312                 }
313                 
314                 [Test]
315                 public void TestSkipIterating ()
316                 {
317                         int [] data = {0, 1, 2, 3, 4, 5};
318                         int [] result = {3, 4, 5};
319
320                         AssertAreSame (result, data.AsReallyParallel ().AsOrdered ().Skip (3));
321                 }
322
323                 [Test]
324                 public void TestSkipWhile ()
325                 {
326                         int [] data = {0, 1, 2, 3, 4, 5};
327                         int [] result = {3, 4, 5};
328
329                         AssertAreSame (result, data.AsReallyParallel ().AsOrdered ().SkipWhile (i => i < 3));
330                 }
331
332                 [Test]
333                 public void TestTake ()
334                 {
335                         int [] data = {0, 1, 2, 3, 4, 5};
336                         int [] result = {0, 1, 2};
337
338                         AssertAreSame (result, data.AsReallyParallel ().AsOrdered ().Take (3));
339                 }
340
341                 [Test]
342                 public void TestTakeWhile ()
343                 {
344                         int [] data = {0, 1, 2, 3, 4, 5};
345                         int [] result = {0, 1, 2};
346
347                         AssertAreSame (result, data.AsReallyParallel ().AsOrdered ().TakeWhile (i => i < 3));
348                 }
349
350                 [Test]
351                 public void SelectManyTest ()
352                 {
353                         IEnumerable<int> initial = Enumerable.Range (1, 50);
354                         IEnumerable<int> expected = initial.SelectMany ((i) => Enumerable.Range (1, i));
355
356                         ParallelTestHelper.Repeat (() => {
357                                         var actual = initial.AsReallyParallel ().SelectMany ((i) => Enumerable.Range (1, i));
358                                         AreEquivalent (expected, actual);
359                                 });
360                 }
361
362                 [Test]
363                 public void SelectManyOrderedTest ()
364                 {
365                         IEnumerable<int> initial = Enumerable.Range (1, 50);
366                         IEnumerable<int> expected = initial.SelectMany ((i) => Enumerable.Range (1, i));
367
368                         ParallelTestHelper.Repeat (() => {
369                                         var actual = initial.AsReallyParallel ().AsOrdered ().SelectMany ((i) => Enumerable.Range (1, i));
370                                         AssertAreSame (expected, actual);
371                                 });
372                 }
373                 
374                 [Test]
375                 public void TestLast ()
376                 {
377                         int [] data = {1, 2, 3};
378
379                         Assert.AreEqual (3, data.AsReallyParallel ().AsOrdered ().Last ());
380                 }
381
382                 [Test]
383                 public void TestLastOrDefault ()
384                 {
385                         int [] data = {};
386
387                         Assert.AreEqual (default (int), data.AsReallyParallel ().AsOrdered ().LastOrDefault ());
388                 }
389
390                 [Test]
391                 public void TestFirst ()
392                 {
393                         int [] data = {1, 2, 3};
394
395                         Assert.AreEqual (1, data.AsReallyParallel ().AsOrdered ().First ());
396                 }
397
398                 [Test]
399                 public void TestFirstOrDefault ()
400                 {
401                         int [] data = {};
402
403                         Assert.AreEqual (default (int), data.AsReallyParallel ().AsOrdered ().FirstOrDefault ());
404                 }
405                 
406                 [Test]
407                 public void TestReverse ()
408                 {
409                         int [] data = {0, 1, 2, 3, 4};
410                         int [] result = {4, 3, 2, 1, 0};
411
412                         AssertAreSame (result, ((IEnumerable<int>)data).Select ((i) => i).AsReallyParallel ().AsOrdered ().Reverse ());
413                         AssertAreSame (result, ParallelEnumerable.Range (0, 5).AsReallyParallel ().AsOrdered ().Reverse ());
414                 }
415                 
416                 [Test]
417                 public void TestOrderBy ()
418                 {
419                         ParallelTestHelper.Repeat (() => {
420                                 int [] array = { 14, 53, 3, 9, 11, 14, 5, 32, 2 };
421                                 
422                                 var q = array.AsReallyParallel ().OrderBy ((i) => i);
423                                 AssertIsOrdered (q, array.Length);
424                         });
425                 }
426
427                 class Baz {
428                         string name;
429                         int age;
430
431                         public string Name
432                         {
433                                 get {
434                                         if (string.IsNullOrEmpty (name))
435                                                 return Age.ToString ();
436
437                                         return name + " (" + Age + ")";
438                                 }
439                         }
440
441                         public int Age
442                         {
443                                 get { return age + 1; }
444                         }
445
446                         public Baz (string name, int age)
447                         {
448                                 this.name = name;
449                                 this.age = age;
450                         }
451
452                         public override int GetHashCode ()
453                         {
454                                 return this.Age ^ this.Name.GetHashCode ();
455                         }
456
457                         public override bool Equals (object obj)
458                         {
459                                 Baz b = obj as Baz;
460                                 if (b == null)
461                                         return false;
462
463                                 return b.Age == this.Age && b.Name == this.Name;
464                         }
465
466                         public override string ToString ()
467                         {
468                                 return this.Name;
469                         }
470                 }
471
472                 static IEnumerable<Baz> CreateBazCollection ()
473                 {
474                         return new [] {
475                                 new Baz ("jb", 25),
476                                 new Baz ("ana", 20),
477                                 new Baz ("reg", 28),
478                                 new Baz ("ro", 25),
479                                 new Baz ("jb", 7),
480                         };
481                 }
482
483                 [Test]
484                 public void TestOrderByAgeAscendingTheByNameDescending ()
485                 {
486                         ParallelTestHelper.Repeat (() => {
487                                 var q = from b in CreateBazCollection ().AsReallyParallel ()
488                                                 orderby b.Age ascending, b.Name descending
489                                                 select b;
490         
491                                 var expected = new [] {
492                                         new Baz ("jb", 7),
493                                         new Baz ("ana", 20),
494                                         new Baz ("ro", 25),
495                                         new Baz ("jb", 25),
496                                         new Baz ("reg", 28),
497                                 };
498
499                                 AssertAreSame (expected, q);
500                         });
501                 }
502
503                 class Data {
504                         public int ID { get; set; }
505                         public string Name { get; set; }
506
507                         public override string ToString ()
508                         {
509                                 return ID + " " + Name;
510                         }
511                 }
512
513                 IEnumerable<Data> CreateData ()
514                 {
515                         return new [] {
516                                 new Data { ID = 10, Name = "bcd" },
517                                 new Data { ID = 20, Name = "Abcd" },
518                                 new Data { ID = 20, Name = "Ab" },
519                                 new Data { ID = 10, Name = "Zyx" },
520                         };
521                 }
522
523                 [Test]
524                 public void TestOrderByIdDescendingThenByNameAscending ()
525                 {
526                         ParallelTestHelper.Repeat (() => {
527                                 var q = from d in CreateData ().AsReallyParallel ()
528                                         orderby d.ID descending, d.Name ascending
529                                                 select d;
530                                 
531                                 var list = new List<Data> (q);
532                                 
533                                 Assert.AreEqual ("Ab", list [0].Name);
534                                 Assert.AreEqual ("Abcd", list [1].Name);
535                                 Assert.AreEqual ("bcd", list [2].Name);
536                                 Assert.AreEqual ("Zyx", list [3].Name);
537                         });
538                 }
539
540                 static void AssertIsOrdered (IEnumerable<int> e, int count)
541                 {
542                         int f = int.MinValue;
543                         int c = 0;
544                         
545                         foreach (int i in e) {
546                                 Assert.IsTrue (f <= i, string.Format ("{0} <= {1}", f, i));
547                                 f = i;
548                                 c++;
549                         }
550                         
551                         Assert.AreEqual (count, c);
552                 }
553                 
554                 
555                 [Test]
556                 public void ElementAtTestCase()
557                 {
558                         //ParallelTestHelper.Repeat (() => {
559                                         Assert.AreEqual(1, baseEnumerable.AsReallyParallel ().AsOrdered ().ElementAt(0), "#1");
560                                         Assert.AreEqual(51, baseEnumerable.AsReallyParallel ().AsOrdered ().ElementAt(50), "#2");
561                                         Assert.AreEqual(489, baseEnumerable.AsReallyParallel ().AsOrdered ().ElementAt(488), "#3");
562                         //});
563                 }
564
565                 [Test]
566                 public void TestJoin ()
567                 {
568                         int num = 100;
569                         Tuple<int, int>[] outer = Enumerable.Range (1, 50).Select ((i) => Tuple.Create (i, num - 2 * i)).ToArray ();
570                         Tuple<int, int>[] inner = Enumerable.Range (1, 50).Reverse ().Select ((i) => Tuple.Create (i, 2 * i)).ToArray ();
571
572                         IEnumerable<int> expected = outer.Join (inner, (e) => e.Item1, (e) => e.Item1, (e1, e2) => e1.Item2 + e2.Item2, EqualityComparer<int>.Default);
573
574                         ParallelTestHelper.Repeat (() => {
575                                 ParallelQuery<int> actual = outer.AsReallyParallel ().Join (inner.AsParallel (),
576                                                                                             (e) => e.Item1,
577                                                                                             (e) => e.Item1,
578                                                                                             (e1, e2) => e1.Item2 + e2.Item2,
579                                                                                             EqualityComparer<int>.Default);
580                                 AreEquivalent (expected, actual);
581                         });
582                 }
583
584                 [Test]
585                 public void SmallJoinTest ()
586                 {
587                         var items = new [] { 1, 2, 3 };
588                         var items2 = new [] { 1, 2, 3, 4 };
589                         var actual = items.AsReallyParallel ().Join (items2.AsReallyParallel (), i => i, i => i, (e1, e2) => e1 + e2);
590                         AreEquivalent (new[] { 2, 4, 6 }, actual);
591                 }
592
593                 [Test]
594                 [Category ("NotWorking")] // Deadlocks randomly
595                 public void TestGroupBy ()
596                 {
597                         int num = 100;
598                         Tuple<int, int>[] source = Enumerable.Range (0, num).Select ((i) => Tuple.Create (i / 10, i)).ToArray ();
599
600                         ParallelTestHelper.Repeat (() => {
601                                 ParallelQuery<IGrouping<int, int>> actual = source.AsReallyParallel ().GroupBy ((e) => e.Item1, (e) => e.Item2, EqualityComparer<int>.Default);
602                                 foreach (var group in actual) {
603                                         Assert.IsTrue (group.Key >= 0);
604                                         Assert.IsTrue (group.Key < num / 10);
605
606                                         int count = 0;
607                                         foreach (var e in group) {
608                                                 count++;
609                                                 Assert.IsTrue (e >= group.Key * 10);
610                                                 Assert.IsTrue (e <  (group.Key + 1) * 10);
611                                         }
612
613                                         Assert.AreEqual (10, count, "count");
614                                 }
615                         });
616                 }
617                 
618                 [Test]
619                 public void TakeTestCase()
620                 {
621                         ParallelTestHelper.Repeat (() => {
622                                 ParallelQuery<int> async_res = baseEnumerable.AsReallyParallel ().AsOrdered ().Take(800);
623                                 IEnumerable<int> sync = baseEnumerable.Take(800);
624
625                                 AreEquivalent(sync, async_res);
626
627                                 async_res = baseEnumerable.AsReallyParallel ().AsOrdered ().Take(100);
628                                 sync = baseEnumerable.Take(100);
629
630                                 AreEquivalent(sync, async_res);
631                         });
632                 }
633
634                 [TestAttribute]
635                 public void UnorderedTakeTestCase()
636                 {
637                         ParallelTestHelper.Repeat (() => {
638                                 ParallelQuery<int> async_res = baseEnumerable.AsReallyParallel ().Take(800);
639                                 IEnumerable<int> sync = baseEnumerable.Take (800);
640
641                                 Assert.AreEqual (sync.Count (), async_res.Count (), "#1");
642
643                                 async_res = baseEnumerable.AsReallyParallel ().Take(100);
644                                 sync = baseEnumerable.Take(100);
645
646                                 Assert.AreEqual (sync.Count (), async_res.Count (), "#2");
647                         });
648                 }
649                 
650                 [Test]
651                 public void SkipTestCase()
652                 {
653                         ParallelTestHelper.Repeat (() => {
654                                 ParallelQuery<int> async_res = baseEnumerable.AsReallyParallel ().AsOrdered().Skip (800);
655                                 IEnumerable<int> sync = baseEnumerable.Skip (800);
656                                 
657                                 AreEquivalent (sync, async_res);
658                         });
659                 }
660
661                 [Test]
662                 public void SkipTestCaseSmall ()
663                 {
664                         ParallelTestHelper.Repeat (() => {
665                                 var async_res = baseEnumerable.AsReallyParallel ().Skip(100);
666                                 var sync = baseEnumerable.Skip(100);
667                                 
668                                 Assert.AreEqual (sync.Count (), async_res.Count ());
669                         });
670                 }
671
672                 [Test]
673                 public void ZipTestCase()
674                 {
675                         ParallelTestHelper.Repeat (() => {
676                                 ParallelQuery<int> async_res1 = ParallelEnumerable.Range(0, 10000);
677                                 ParallelQuery<int> async_res2 = ParallelEnumerable.Repeat(1, 10000).Zip(async_res1, (e1, e2) => e1 + e2);
678                                 
679                                 int[] expected = Enumerable.Range (1, 10000).ToArray ();
680                                 AreEquivalent(expected, Enumerable.ToArray (async_res2));
681                         });
682                 }
683                 
684                 [Test]
685                 public void Range ()
686                 {
687                         ParallelTestHelper.Repeat (() => {
688                                 IEnumerable<int> sync  = Enumerable.Range(1, 1000);
689                                 IEnumerable<int> async_res = ParallelEnumerable.Range(1, 1000);
690                                 
691                                 AreEquivalent (sync, async_res);
692                         });
693                 }
694         
695                 [Test]
696                 public void Range_StartOffset ()
697                 {
698                         ParallelTestHelper.Repeat (() => {
699                                 IEnumerable<int> sync  = Enumerable.Range (30, 10);
700                                 IEnumerable<int> async_res = ParallelEnumerable.Range (30, 10);
701                                 
702                                 AreEquivalent (sync, async_res);
703                         });
704                 }
705
706                 [Test]
707                 public void RepeatTestCase ()
708                 {
709                         ParallelTestHelper.Repeat (() => {
710                                 IEnumerable<int> sync  = Enumerable.Repeat(1, 1000);
711                                 IEnumerable<int> async_res = ParallelEnumerable.Repeat(1, 1000);
712                                 
713                                 AreEquivalent (sync, async_res);
714                         });
715                 }
716                 
717                 [Test]
718                 public void TestSum ()
719                 {
720                         int [] data = {1, 2, 3, 4};
721
722                         Assert.AreEqual (10, data.AsReallyParallel ().Sum ());
723                 }
724
725                 [Test]
726                 public void SumOnEmpty ()
727                 {
728                         int [] data = {};
729
730                         Assert.AreEqual (0, data.AsReallyParallel ().Sum ());
731                 }
732
733                 [Test]
734                 public void TestMax ()
735                 {
736                         int [] data = {1, 3, 5, 2};
737
738                         Assert.AreEqual (5, data.AsReallyParallel ().Max ());
739                 }
740
741                 [Test]
742                 public void TestMin ()
743                 {
744                         int [] data = {3, 5, 2, 6, 1, 7};
745
746                         Assert.AreEqual (1, data.AsReallyParallel ().Min ());
747                 }
748                 
749                 [Test]
750                 public void TestToListOrdered ()
751                 {
752                         int [] data = { 2, 3, 5 };
753
754                         var list = data.AsParallel().AsOrdered().WithExecutionMode (ParallelExecutionMode.ForceParallelism).ToList ();
755
756                         AssertAreSame (data, list);
757                         AssertIsOrdered (list, data.Length);
758
759                         Assert.AreEqual (typeof (List<int>), list.GetType ());
760                 }
761
762                 [Test]
763                 public void TestToArrayOrdered ()
764                 {
765                         ICollection<int> coll = new List<int> ();
766                         coll.Add (0);
767                         coll.Add (1);
768                         coll.Add (2);
769
770                         int [] result = {0, 1, 2};
771
772                         var array = coll.AsReallyParallel ().AsOrdered().ToArray ();
773
774                         AssertAreSame (result, array);
775                         AssertIsOrdered (array, result.Length);
776
777                         Assert.AreEqual (typeof (int []), array.GetType ());
778
779                         array = Enumerable.Range (1, 100).Select ((i) => i).AsReallyParallel ().AsOrdered().ToArray ();
780                         result = Enumerable.Range (1, 100).ToArray ();
781
782                         AssertAreSame (result, array);
783                         AssertIsOrdered (array, result.Length);
784
785                         Assert.AreEqual (typeof (int []), array.GetType ());
786
787                 }
788
789                 [Test]
790                 public void TestToList ()
791                 {
792                         int [] data = {3, 5, 2};
793
794                         var list = data.AsReallyParallel ().ToList ();
795
796                         AreEquivalent (data, list);
797
798                         Assert.AreEqual (typeof (List<int>), list.GetType ());
799                 }
800
801                 [Test]
802                 public void TestToArray ()
803                 {
804                         ICollection<int> coll = new List<int> ();
805                         coll.Add (0);
806                         coll.Add (1);
807                         coll.Add (2);
808
809                         int [] result = {0, 1, 2};
810
811                         var array = coll.AsReallyParallel ().ToArray ();
812
813                         AreEquivalent (result, array);
814
815                         Assert.AreEqual (typeof (int []), array.GetType ());
816                 }
817                 
818                 
819                 [Test]
820                 public void TestAverageOnInt32 ()
821                 {
822                         Assert.AreEqual (23.25, (new int [] { 24, 7, 28, 34 }).Average ());
823                 }
824
825                 [Test]
826                 public void TestAverageOnInt64 ()
827                 {
828                         Assert.AreEqual (23.25, (new long [] { 24, 7, 28, 34 }).Average ());
829                 }
830                 
831                 
832                 [Test]
833                 public void AnyArgumentNullTest ()
834                 {
835                         string [] data = { "2", "1", "5", "3", "4" };
836
837
838                         // Any<TSource> ()
839                         AssertException<ArgumentNullException> (delegate () { ((IEnumerable<string>) null).AsReallyParallel ().Any (); });
840
841                         // Any<TSource> (Func<TSource, bool>)
842                         AssertException<ArgumentNullException> (delegate () { ((IEnumerable<string>) null).AsReallyParallel ().Any (x => true); });
843                         AssertException<ArgumentNullException> (delegate () { data.AsReallyParallel ().Any ((Func<string, bool>) null); });
844                 }
845
846                 [Test]
847                 public void AnyTest ()
848                 {
849                         int [] data = { 5, 2, 3, 1, 6 };
850                         int [] empty = { };
851
852
853                         // Any<TSource> ()
854                         Assert.IsTrue (data.AsReallyParallel ().Any ());
855                         Assert.IsFalse (empty.AsReallyParallel ().Any ());
856
857                         // Any<TSource> (Func<TSource, bool>)
858                         Assert.IsTrue (data.AsReallyParallel ().Any (x => x == 5));
859                         Assert.IsFalse (data.AsReallyParallel ().Any (x => x == 9));
860                         Assert.IsFalse (empty.AsReallyParallel ().Any (x => true));
861                 }
862
863                 
864                 [Test]
865                 public void AllArgumentNullTest ()
866                 {
867                         string [] data = { "2", "1", "5", "3", "4" };
868
869                         AssertException<ArgumentNullException> (delegate () { ((IEnumerable<string>) null).AsReallyParallel ().All (x => true); });
870                         AssertException<ArgumentNullException> (delegate () { data.AsReallyParallel ().All ((Func<string, bool>) null); });
871                 }
872
873                 [Test]
874                 public void AllTest ()
875                 {
876                         int [] data = { 5, 2, 3, 1, 6 };
877                         int [] empty = { };
878
879                         Assert.IsTrue (data.AsReallyParallel ().All (x => true));
880                         Assert.IsFalse (data.AsReallyParallel ().All (x => x != 1));
881                         Assert.IsTrue (empty.AsReallyParallel ().All (x => false));
882                 }
883
884                 [Test]
885                 public void SequenceEqualsTest ()
886                 {
887                         var data1 = new int[] { 1, 2, 3 };
888                         var data2 = new int[] { 1, 2, 4 };
889                         var data3 = new int[] { 1, 2, 3, 4 };
890
891                         Assert.IsTrue (data1.AsReallyParallel ().SequenceEqual (data1.AsReallyParallel ()));
892                         Assert.IsTrue (data2.AsReallyParallel ().SequenceEqual (data2.AsReallyParallel ()));
893                         Assert.IsTrue (data3.AsReallyParallel ().SequenceEqual (data3.AsReallyParallel ()));
894                         Assert.IsFalse (data1.AsReallyParallel ().SequenceEqual (data2.AsReallyParallel ()));
895                         Assert.IsFalse (data1.AsReallyParallel ().SequenceEqual (data3.AsReallyParallel ()));
896                         Assert.IsFalse (data2.AsReallyParallel ().SequenceEqual (data3.AsReallyParallel ()));
897                 }
898
899                 [Test]
900                 public void ContainsTest ()
901                 {
902                         var data1 = new int[] { 1, 2, 3 };
903                         var data2 = new int[] { 1, 2, 4 };
904                         var data3 = new int[] { 1, 2, 3, 4 };
905
906                         Assert.IsTrue (data1.AsReallyParallel ().Contains (3));
907                         Assert.IsFalse (data2.AsReallyParallel ().Contains (3));
908                         Assert.IsTrue (data3.AsReallyParallel ().Contains (3));
909                         Assert.IsFalse (data3.AsReallyParallel ().Contains (5));
910                         Assert.IsTrue (data2.AsReallyParallel ().Contains (2));
911                 }
912         }
913 }
914
915 #endif