Merge pull request #1936 from esdrubal/DotNetRelativeOrAbsolute
[mono.git] / mcs / class / Mono.Parallel / Test / Mono.Collections.Concurrent / CollectionStressTestHelper.cs
1 // 
2 // CollectionStressTestHelper.cs
3 //  
4 // Author:
5 //       Jérémie "Garuma" Laval <jeremie.laval@gmail.com>
6 // 
7 // Copyright (c) 2009 Jérémie "Garuma" Laval
8 // 
9 // Permission is hereby granted, free of charge, to any person obtaining a copy
10 // of this software and associated documentation files (the "Software"), to deal
11 // in the Software without restriction, including without limitation the rights
12 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13 // copies of the Software, and to permit persons to whom the Software is
14 // furnished to do so, subject to the following conditions:
15 // 
16 // The above copyright notice and this permission notice shall be included in
17 // all copies or substantial portions of the Software.
18 // 
19 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25 // THE SOFTWARE.
26
27 using System;
28 using System.Collections;
29 using System.Collections.Generic;
30 using System.Collections.Concurrent;
31
32 using System.Threading;
33 using System.Linq;
34 using System.Threading.Tasks;
35
36 using NUnit;
37 using NUnit.Framework;
38 using MonoTests.Mono.Threading.Tasks;
39
40 namespace MonoTests.Mono.Collections.Concurrent
41 {
42         public enum CheckOrderingType {
43                 InOrder,
44                 Reversed,
45                 DontCare
46         }
47         
48         public static class CollectionStressTestHelper
49         {
50                 public static void AddStressTest (IProducerConsumerCollection<int> coll)
51                 {
52                         ParallelTestHelper.Repeat (delegate {
53                                 int amount = -1;
54                                 const int count = 10;
55                                 const int threads = 5;
56                                 
57                                 ParallelTestHelper.ParallelStressTest (coll, (q) => {
58                                         int t = Interlocked.Increment (ref amount);
59                                         for (int i = 0; i < count; i++)
60                                                 coll.TryAdd (t);
61                                 }, threads);
62                                 
63                                 Assert.AreEqual (threads * count, coll.Count, "#-1");
64                                 int[] values = new int[threads];
65                                 int temp;
66                                 while (coll.TryTake (out temp)) {
67                                         values[temp]++;
68                                 }
69                                 
70                                 for (int i = 0; i < threads; i++)
71                                         Assert.AreEqual (count, values[i], "#" + i);
72                         });
73                 }
74                 
75                 public static void RemoveStressTest (IProducerConsumerCollection<int> coll, CheckOrderingType order)
76                 {
77                         ParallelTestHelper.Repeat (delegate {
78                                 
79                                 const int count = 10;
80                                 const int threads = 5;
81                                 const int delta = 5;
82                                 
83                                 for (int i = 0; i < (count + delta) * threads; i++)
84                                         while (!coll.TryAdd (i));
85                                 
86                                 bool state = true;
87                                 
88                                 Assert.AreEqual ((count + delta) * threads, coll.Count, "#0");
89                                 
90                                 ParallelTestHelper.ParallelStressTest (coll, (q) => {
91                                         bool s = true;
92                                         int t;
93                                         
94                                         for (int i = 0; i < count; i++) {
95                                                 s &= coll.TryTake (out t);
96                                                 // try again in case it was a transient failure
97                                                 if (!s && coll.TryTake (out t))
98                                                         s = true;
99                                         }
100                                         
101                                         if (!s)
102                                                 state = false;
103                                 }, threads);
104                                 
105                                 Assert.IsTrue (state, "#1");
106                                 Assert.AreEqual (delta * threads, coll.Count, "#2");
107                                 
108                                 string actual = string.Empty;
109                                 int temp;
110                                 while (coll.TryTake (out temp)) {
111                                         actual += temp.ToString ();;
112                                 }
113                                 
114                                 IEnumerable<int> range = Enumerable.Range (order == CheckOrderingType.Reversed ? 0 : count * threads, delta * threads);
115                                 if (order == CheckOrderingType.Reversed)
116                                         range = range.Reverse ();
117                                 
118                                 string expected = range.Aggregate (string.Empty, (acc, v) => acc + v);
119                                 
120                                 if (order == CheckOrderingType.DontCare)
121                                         CollectionAssert.AreEquivalent (expected, actual, "#3");
122                                 else 
123                                         Assert.AreEqual (expected, actual, "#3");
124                         }, 1000);
125                 }
126         }
127 }