Merge pull request #435 from mono-soc-2012/svick/dataflow
[mono.git] / mcs / class / System.Threading.Tasks.Dataflow / Test / System.Threading.Tasks.Dataflow / BatchedJoinBlockTest.cs
1 // BatchedJoinBlockTest.cs
2 //  
3 // Copyright (c) 2012 Petr Onderka
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 using System;
24 using System.Collections.Generic;
25 using System.Threading;
26 using System.Threading.Tasks.Dataflow;
27 using NUnit.Framework;
28
29 namespace MonoTests.System.Threading.Tasks.Dataflow {
30         [TestFixture]
31         public class BatchedJoinBlockTest {
32                 [Test]
33                 public void BasicUsageTest()
34                 {
35                         Tuple<IList<int>, IList<int>> result = null;
36                         var evt = new ManualResetEventSlim (false);
37
38                         var actionBlock = new ActionBlock<Tuple<IList<int>, IList<int>>> (r =>
39                         {
40                                 result = r;
41                                 evt.Set ();
42                         });
43                         var block = new BatchedJoinBlock<int, int> (2);
44
45                         block.LinkTo (actionBlock);
46
47                         // both targets once
48                         Assert.IsTrue (block.Target1.Post (1));
49
50                         Assert.IsFalse(evt.Wait(100));
51                         Assert.IsNull (result);
52
53                         Assert.IsTrue (block.Target2.Post (2));
54
55                         Assert.IsTrue (evt.Wait (100));
56
57                         Assert.IsNotNull (result);
58                         CollectionAssert.AreEqual (new[] { 1 }, result.Item1);
59                         CollectionAssert.AreEqual (new[] { 2 }, result.Item2);
60
61                         result = null;
62                         evt.Reset ();
63
64                         // target 1 twice
65                         Assert.IsTrue (block.Target1.Post (3));
66
67                         Assert.IsFalse(evt.Wait(100));
68                         Assert.IsNull (result);
69
70                         Assert.IsTrue (block.Target1.Post (4));
71                         Assert.IsTrue (evt.Wait (100));
72
73                         Assert.IsNotNull (result);
74                         CollectionAssert.AreEqual (new[] { 3, 4 }, result.Item1);
75                         CollectionAssert.IsEmpty (result.Item2);
76
77                         result = null;
78                         evt.Reset ();
79
80                         // target 2 twice
81                         Assert.IsTrue (block.Target2.Post (5));
82
83                         Assert.IsFalse(evt.Wait(100));
84                         Assert.IsNull (result);
85
86                         Assert.IsTrue (block.Target2.Post (6));
87                         Assert.IsTrue (evt.Wait (100));
88
89                         Assert.IsNotNull (result);
90                         CollectionAssert.IsEmpty (result.Item1);
91                         CollectionAssert.AreEqual (new[] { 5, 6 }, result.Item2);
92                 }
93
94                 [Test]
95                 public void BoundedCapacityTest ()
96                 {
97                         AssertEx.Throws<ArgumentException> (
98                                 () =>
99                                 new BatchedJoinBlock<int, int> (2,
100                                         new GroupingDataflowBlockOptions { BoundedCapacity = 3 }));
101                 }
102
103                 [Test]
104                 public void CompletionTest ()
105                 {
106                         var block = new BatchedJoinBlock<int, int> (2);
107
108                         Assert.IsTrue (block.Target1.Post (1));
109
110                         block.Complete ();
111
112                         Tuple<IList<int>, IList<int>> batch;
113                         Assert.IsTrue (block.TryReceive (out batch));
114                         CollectionAssert.AreEqual (new[] { 1 }, batch.Item1);
115                         CollectionAssert.IsEmpty (batch.Item2);
116
117                         Assert.IsTrue (block.Completion.Wait (100));
118                 }
119
120                 [Test]
121                 public void MaxNumberOfGroupsTest ()
122                 {
123                         var scheduler = new TestScheduler ();
124                         var block = new BatchedJoinBlock<int, int> (1,
125                                 new GroupingDataflowBlockOptions
126                                 { MaxNumberOfGroups = 2, TaskScheduler = scheduler });
127
128                         Assert.IsTrue (block.Target1.Post (1));
129
130                         Assert.IsTrue (block.Target2.Post (2));
131
132                         Assert.IsFalse (block.Target2.Post (3));
133                         Assert.IsFalse (block.Target1.Post (4));
134
135                         Tuple<IList<int>, IList<int>> batch;
136                         Assert.IsTrue (block.TryReceive (out batch));
137                         CollectionAssert.AreEqual (new[] { 1 }, batch.Item1);
138                         CollectionAssert.IsEmpty (batch.Item2);
139
140                         Assert.IsTrue (block.TryReceive (out batch));
141                         CollectionAssert.IsEmpty (batch.Item1);
142                         CollectionAssert.AreEqual (new[] { 2 }, batch.Item2);
143
144                         scheduler.ExecuteAll ();
145
146                         Assert.IsTrue (block.Completion.Wait (100));
147                 }
148         }
149 }