column name and ordinal fix...tested on 10.1
[mono.git] / mcs / class / corlib / Test / System.Collections.Concurrent / ConcurrentDictionaryTests.cs
1 // ConcurrentDictionaryTests.cs
2 //
3 // Copyright (c) 2008 Jérémie "Garuma" Laval
4 //
5 // Permission is hereby granted, free of charge, to any person obtaining a copy
6 // of this software and associated documentation files (the "Software"), to deal
7 // in the Software without restriction, including without limitation the rights
8 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 // copies of the Software, and to permit persons to whom the Software is
10 // furnished to do so, subject to the following conditions:
11 //
12 // The above copyright notice and this permission notice shall be included in
13 // all copies or substantial portions of the Software.
14 //
15 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 // THE SOFTWARE.
22 //
23 //
24
25 using System;
26 using System.Linq;
27 using System.Threading;
28 using MonoTests.System.Threading.Tasks;
29 using System.Collections;
30 using System.Collections.Generic;
31 using System.Collections.Concurrent;
32
33 using NUnit;
34 using NUnit.Framework;
35 #if !MOBILE
36 using NUnit.Framework.SyntaxHelpers;
37 #endif
38
39 namespace MonoTests.System.Collections.Concurrent
40 {
41         [TestFixture]
42         public class ConcurrentDictionaryTests
43         {
44                 ConcurrentDictionary<string, int> map;
45                 
46                 [SetUp]
47                 public void Setup ()
48                 {
49                         map = new ConcurrentDictionary<string, int> ();
50                         AddStuff();
51                 }
52                 
53                 void AddStuff ()
54                 {
55                         map.TryAdd ("foo", 1);
56                         map.TryAdd ("bar", 2);
57                         map["foobar"] = 3;
58                 }
59                 
60                 [Test]
61                 public void AddWithoutDuplicateTest ()
62                 {
63                         map.TryAdd("baz", 2);
64                         int val;
65                         
66                         Assert.IsTrue (map.TryGetValue("baz", out val));
67                         Assert.AreEqual(2, val);
68                         Assert.AreEqual(2, map["baz"]);
69                         Assert.AreEqual(4, map.Count);
70                 }
71                 
72                 [Test]
73                 public void AddParallelWithoutDuplicateTest ()
74                 {
75                         ParallelTestHelper.Repeat (delegate {
76                                 Setup ();
77                                 int index = 0;
78                                 
79                                 ParallelTestHelper.ParallelStressTest (map, delegate {
80                                         int own = Interlocked.Increment (ref index);
81                                         
82                                         while (!map.TryAdd ("monkey" + own.ToString (), own));
83                                         
84                                 }, 4);
85                                 
86                                 Assert.AreEqual (7, map.Count);
87                                 int value;
88                                 
89                                 Assert.IsTrue (map.TryGetValue ("monkey1", out value), "#1");
90                                 Assert.AreEqual (1, value, "#1b");
91                                 
92                                 Assert.IsTrue (map.TryGetValue ("monkey2", out value), "#2");
93                                 Assert.AreEqual (2, value, "#2b");
94                                 
95                                 Assert.IsTrue (map.TryGetValue ("monkey3", out value), "#3");
96                                 Assert.AreEqual (3, value, "#3b");
97                                 
98                                 Assert.IsTrue (map.TryGetValue ("monkey4", out value), "#4");
99                                 Assert.AreEqual (4, value, "#4b");
100                         });
101                 }
102                 
103                 [Test]
104                 public void RemoveParallelTest ()
105                 {
106                         ParallelTestHelper.Repeat (delegate {
107                                 Setup ();
108                                 int index = 0;
109                                 bool r1 = false, r2 = false, r3 = false;
110                                 int val;
111                                 
112                                 ParallelTestHelper.ParallelStressTest (map, delegate {
113                                         int own = Interlocked.Increment (ref index);
114                                         switch (own) {
115                                         case 1:
116                                                 r1 = map.TryRemove ("foo", out val);
117                                                 break;
118                                         case 2:
119                                                 r2 =map.TryRemove ("bar", out val);
120                                                 break;
121                                         case 3:
122                                                 r3 = map.TryRemove ("foobar", out val);
123                                                 break;
124                                         }
125                                 }, 3);
126                                 
127                                 Assert.AreEqual (0, map.Count);
128                                 int value;
129         
130                                 Assert.IsTrue (r1, "1");
131                                 Assert.IsTrue (r2, "2");
132                                 Assert.IsTrue (r3, "3");
133                                 
134                                 Assert.IsFalse (map.TryGetValue ("foo", out value), "#1b " + value.ToString ());
135                                 Assert.IsFalse (map.TryGetValue ("bar", out value), "#2b");
136                                 Assert.IsFalse (map.TryGetValue ("foobar", out value), "#3b");
137                         });
138                 }
139                 
140                 [Test]
141                 public void AddWithDuplicate()
142                 {
143                         Assert.IsFalse (map.TryAdd("foo", 6));
144                 }
145                 
146                 [Test]
147                 public void GetValueTest()
148                 {
149                         Assert.AreEqual(1, map["foo"], "#1");
150                         Assert.AreEqual(2, map["bar"], "#2");
151                         Assert.AreEqual(3, map.Count, "#3");
152                 }
153                 
154                 [Test, ExpectedException(typeof(KeyNotFoundException))]
155                 public void GetValueUnknownTest()
156                 {
157                         int val;
158                         Assert.IsFalse(map.TryGetValue("barfoo", out val));
159                         val = map["barfoo"];
160                 }
161                 
162                 [Test]
163                 public void ModificationTest()
164                 {
165                         map["foo"] = 9;
166                         int val;
167                         
168                         Assert.AreEqual(9, map["foo"], "#1");
169                         Assert.IsTrue(map.TryGetValue("foo", out val), "#3");
170                         Assert.AreEqual(9, val, "#4");
171                 }
172
173                 [Test]
174                 public void IterateTest ()
175                 {
176                         string[] keys = { "foo", "bar", "foobar" };
177                         int[] occurence = new int[3];
178
179                         foreach (var kvp in map) {
180                                 int index = Array.IndexOf (keys, kvp.Key);
181                                 Assert.AreNotEqual (-1, index, "#a");
182                                 Assert.AreEqual (index + 1, kvp.Value, "#b");
183                                 Assert.That (++occurence[index], Is.LessThan (2), "#c");
184                         }
185                 }
186
187                 [Test]
188                 public void GetOrAddTest ()
189                 {
190                         Assert.AreEqual (1, map.GetOrAdd ("foo", (_) => 12));
191                         Assert.AreEqual (13, map.GetOrAdd ("baz", (_) => 13));
192                 }
193
194                 [Test]
195                 public void TryUpdateTest ()
196                 {
197                         Assert.IsFalse (map.TryUpdate ("foo", 12, 11));
198                         Assert.AreEqual (1, map["foo"]);
199                         Assert.IsTrue (map.TryUpdate ("foo", 11, 1));
200                         Assert.AreEqual (11, map["foo"]);
201                 }
202
203                 [Test]
204                 public void AddOrUpdateTest ()
205                 {
206                         Assert.AreEqual (11, map.AddOrUpdate ("bar", (_) => 12, (_, __) => 11));
207                         Assert.AreEqual (12, map.AddOrUpdate ("baz", (_) => 12, (_, __) => 11));
208                 }
209
210                 [Test]
211                 public void ContainsTest ()
212                 {
213                         Assert.IsTrue (map.ContainsKey ("foo"));
214                         Assert.IsTrue (map.ContainsKey ("bar"));
215                         Assert.IsTrue (map.ContainsKey ("foobar"));
216                         Assert.IsFalse (map.ContainsKey ("baz"));
217                         Assert.IsFalse (map.ContainsKey ("oof"));
218                 }
219
220                 class DumbClass : IEquatable<DumbClass>
221                 {
222                         int foo;
223
224                         public DumbClass (int foo)
225                         {
226                                 this.foo = foo;
227                         }
228
229                         public int Foo {
230                                 get {
231                                         return foo;
232                                 }
233                         }
234
235                         public override bool Equals (object rhs)
236                         {
237                                 DumbClass temp = rhs as DumbClass;
238                                 return temp == null ? false : Equals (temp);
239                         }
240
241                         public bool Equals (DumbClass rhs)
242                         {
243                                 return this.foo == rhs.foo;
244                         }
245
246                         public override int GetHashCode ()
247                         {
248                                 return 5;
249                         }
250                 }
251
252                 [Test]
253                 public void SameHashCodeInsertTest ()
254                 {
255                         var classMap = new ConcurrentDictionary<DumbClass, string> ();
256
257                         var class1 = new DumbClass (1);
258                         var class2 = new DumbClass (2);
259
260                         Assert.IsTrue (classMap.TryAdd (class1, "class1"), "class 1");
261                         Console.WriteLine ();
262                         Assert.IsTrue (classMap.TryAdd (class2, "class2"), "class 2");
263
264                         Assert.AreEqual ("class1", classMap[class1], "class 1 check");
265                         Assert.AreEqual ("class2", classMap[class2], "class 2 check");
266                 }
267
268                 [Test]
269                 public void InitWithEnumerableTest ()
270                 {
271                         int[] data = {1,2,3,4,5,6,7,8,9,10};
272                         var ndic = data.ToDictionary (x => x);
273                         var cdic = new ConcurrentDictionary<int, int> (ndic);
274
275                         foreach (var index in data) {
276                                 Assert.IsTrue (cdic.ContainsKey (index));
277                                 int val;
278                                 Assert.IsTrue (cdic.TryGetValue (index, out val));
279                                 Assert.AreEqual (index, val);
280                         }
281                 }
282
283                 [Test]
284                 public void QueryWithSameHashCodeTest ()
285                 {
286                         var ids = new long[] {
287                                 34359738370, 
288                                 34359738371, 
289                                 34359738372, 
290                                 34359738373, 
291                                 34359738374, 
292                                 34359738375, 
293                                 34359738376, 
294                                 34359738377, 
295                                 34359738420
296                         };
297
298                         var dict = new ConcurrentDictionary<long, long>();
299                         long result;
300
301                         for (var i = 0; i < 20; i++)
302                                 dict[-i] = -i * 1000;
303
304                         foreach (var id in ids)
305                                 Assert.IsFalse (dict.TryGetValue (id, out result), id.ToString ());
306
307                         foreach (var id in ids) {
308                                 Assert.IsTrue (dict.TryAdd (id, id));
309                                 Assert.AreEqual (id, dict[id]);
310                         }
311
312                         foreach (var id in ids) {
313                                 Assert.IsTrue (dict.TryRemove (id, out result));
314                                 Assert.AreEqual (id, result);
315                         }
316
317                         foreach (var id in ids)
318                                 Assert.IsFalse (dict.TryGetValue (id, out result), id.ToString () + " (second)");
319                 }
320
321                 [Test]
322                 public void NullArgumentsTest ()
323                 {
324                         AssertThrowsArgumentNullException (() => { var x = map[null]; });
325                         AssertThrowsArgumentNullException (() => map[null] = 0);
326                         AssertThrowsArgumentNullException (() => map.AddOrUpdate (null, k => 0, (k, v) => v));
327                         AssertThrowsArgumentNullException (() => map.AddOrUpdate ("", null, (k, v) => v));
328                         AssertThrowsArgumentNullException (() => map.AddOrUpdate ("", k => 0, null));
329                         AssertThrowsArgumentNullException (() => map.AddOrUpdate (null, 0, (k, v) => v));
330                         AssertThrowsArgumentNullException (() => map.AddOrUpdate ("", 0, null));
331                         AssertThrowsArgumentNullException (() => map.ContainsKey (null));
332                         AssertThrowsArgumentNullException (() => map.GetOrAdd (null, 0));
333                         int value;
334                         AssertThrowsArgumentNullException (() => map.TryGetValue (null, out value));
335                         AssertThrowsArgumentNullException (() => map.TryRemove (null, out value));
336                         AssertThrowsArgumentNullException (() => map.TryUpdate (null, 0, 0));
337                 }
338
339                 [Test]
340                 public void IDictionaryNullOnNonExistingKey ()
341                 {
342                         IDictionary dict = new ConcurrentDictionary<long, string> ();
343                         object val = dict [1234L];
344                         Assert.IsNull (val);
345                 }
346
347                 void AssertThrowsArgumentNullException (Action action)
348                 {
349                         try {
350                                 action ();
351                                 Assert.Fail ("Expected ArgumentNullException.");
352                         } catch (ArgumentNullException ex) {
353                         }
354                 }
355                 
356                 [Test]
357                 public void ContainsKeyPairTest ()
358                 {
359                         var validKeyPair = new KeyValuePair<string, string> ("key", "validValue");
360                         var wrongKeyPair = new KeyValuePair<string, string> ("key", "wrongValue");
361
362                         IDictionary<string, string> dict = new ConcurrentDictionary<string, string> ();
363                         dict.Add (validKeyPair);
364
365                         Assert.IsTrue (dict.Contains (validKeyPair));
366                         Assert.IsFalse (dict.Contains (wrongKeyPair));
367                 }
368         }
369 }