2 // ConcurrentQueueTest.cs
4 // Copyright (c) 2008 Jérémie "Garuma" Laval
6 // Permission is hereby granted, free of charge, to any person obtaining a copy
7 // of this software and associated documentation files (the "Software"), to deal
8 // in the Software without restriction, including without limitation the rights
9 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 // copies of the Software, and to permit persons to whom the Software is
11 // furnished to do so, subject to the following conditions:
13 // The above copyright notice and this permission notice shall be included in
14 // all copies or substantial portions of the Software.
16 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
28 using System.Threading;
29 using System.Collections.Generic;
30 using System.Collections.Concurrent;
32 using NUnit.Framework;
33 using MonoTests.System.Threading.Tasks;
35 namespace MonoTests.System.Collections.Concurrent
40 public class ConcurrentQueueTests
42 ConcurrentQueue<int> queue;
47 queue = new ConcurrentQueue<int>();
48 for (int i = 0; i < 10; i++) {
54 public void StressEnqueueTestCase ()
56 /*ParallelTestHelper.Repeat (delegate {
57 queue = new ConcurrentQueue<int> ();
60 const int threads = 5;
62 ParallelTestHelper.ParallelStressTest (queue, (q) => {
63 int t = Interlocked.Increment (ref amount);
64 for (int i = 0; i < count; i++)
68 Assert.AreEqual (threads * count, queue.Count, "#-1");
69 int[] values = new int[threads];
71 while (queue.TryDequeue (out temp)) {
75 for (int i = 0; i < threads; i++)
76 Assert.AreEqual (count, values[i], "#" + i);
79 CollectionStressTestHelper.AddStressTest (new ConcurrentQueue<int> ());
83 public void StressDequeueTestCase ()
85 /*ParallelTestHelper.Repeat (delegate {
86 queue = new ConcurrentQueue<int> ();
88 const int threads = 5;
91 for (int i = 0; i < (count + delta) * threads; i++)
96 ParallelTestHelper.ParallelStressTest (queue, (q) => {
98 for (int i = 0; i < count; i++)
99 state &= queue.TryDequeue (out t);
102 Assert.IsTrue (state, "#1");
103 Assert.AreEqual (delta * threads, queue.Count, "#2");
105 string actual = string.Empty;
107 while (queue.TryDequeue (out temp)) {
110 string expected = Enumerable.Range (count * threads, delta * threads)
111 .Aggregate (string.Empty, (acc, v) => acc + v);
113 Assert.AreEqual (expected, actual, "#3");
116 CollectionStressTestHelper.RemoveStressTest (new ConcurrentQueue<int> (), CheckOrderingType.InOrder);
120 public void StressTryPeekTestCase ()
122 ParallelTestHelper.Repeat (delegate {
123 var queue = new ConcurrentQueue<object> ();
124 queue.Enqueue (new object());
126 const int threads = 10;
127 int threadCounter = 0;
130 ParallelTestHelper.ParallelStressTest (queue, (q) => {
131 int threadId = Interlocked.Increment (ref threadCounter);
133 if (threadId < threads)
135 while (queue.TryPeek (out temp))
139 queue.TryDequeue (out temp);
143 Assert.IsTrue (success, "TryPeek returned unexpected null value.");
148 public void CountTestCase()
150 Assert.AreEqual(10, queue.Count, "#1");
152 queue.TryPeek(out value);
153 queue.TryDequeue(out value);
154 queue.TryDequeue(out value);
155 Assert.AreEqual(8, queue.Count, "#2");
160 public void EnumerateTestCase()
162 string s = string.Empty;
163 foreach (int i in queue) {
166 Assert.AreEqual("0123456789", s, "#1 : " + s);
170 public void TryPeekTestCase()
173 queue.TryPeek(out value);
174 Assert.AreEqual(0, value, "#1 : " + value);
175 queue.TryDequeue(out value);
176 Assert.AreEqual(0, value, "#2 : " + value);
177 queue.TryDequeue(out value);
178 Assert.AreEqual(1, value, "#3 : " + value);
179 queue.TryPeek(out value);
180 Assert.AreEqual(2, value, "#4 : " + value);
181 queue.TryPeek(out value);
182 Assert.AreEqual(2, value, "#5 : " + value);
186 public void TryDequeueTestCase()
189 queue.TryPeek(out value);
190 Assert.AreEqual(0, value, "#1");
191 Assert.IsTrue(queue.TryDequeue(out value), "#2");
192 Assert.IsTrue(queue.TryDequeue(out value), "#3");
193 Assert.AreEqual(1, value, "#4");
197 public void TryDequeueEmptyTestCase()
200 queue = new ConcurrentQueue<int> ();
202 Assert.IsTrue(queue.TryDequeue(out value), "#1");
203 Assert.IsFalse(queue.TryDequeue(out value), "#2");
204 Assert.IsTrue(queue.IsEmpty, "#3");
208 public void ToArrayTest()
210 int[] array = queue.ToArray();
211 string s = string.Empty;
212 foreach (int i in array) {
215 Assert.AreEqual("0123456789", s, "#1 : " + s);
216 queue.CopyTo(array, 0);
218 foreach (int i in array) {
221 Assert.AreEqual("0123456789", s, "#2 : " + s);
224 [Test, ExpectedException (typeof (ArgumentNullException))]
225 public void ToExistingArray_Null ()
227 queue.CopyTo (null, 0);
230 [Test, ExpectedException (typeof (ArgumentOutOfRangeException))]
231 public void ToExistingArray_OutOfRange ()
233 queue.CopyTo (new int[3], -1);
236 [Test, ExpectedException (typeof (ArgumentException))]
237 public void ToExistingArray_IndexOverflow ()
239 queue.CopyTo (new int[3], 4);
242 [Test, ExpectedException (typeof (ArgumentException))]
243 public void ToExistingArray_Overflow ()
245 queue.CopyTo (new int[3], 0);
248 static WeakReference CreateWeakReference (object obj)
250 return new WeakReference (obj);
254 // This depends on precise stack scanning
255 [Category ("NotWorking")]
256 public void TryDequeueReferenceTest ()
258 var obj = new Object ();
259 var weakReference = CreateWeakReference(obj);
260 var queue = new ConcurrentQueue<object> ();
263 queue.TryDequeue (out obj);
267 GC.WaitForPendingFinalizers ();
269 Assert.IsFalse (weakReference.IsAlive);