1 // WriteOnceBlockTest.cs
4 // Jérémie "garuma" Laval <jeremie.laval@gmail.com>
5 // Petr Onderka <gsvick@gmail.com>
7 // Copyright (c) 2011 Jérémie "garuma" Laval
8 // Copyright (c) 2012 Petr Onderka
10 // Permission is hereby granted, free of charge, to any person obtaining a copy
11 // of this software and associated documentation files (the "Software"), to deal
12 // in the Software without restriction, including without limitation the rights
13 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14 // copies of the Software, and to permit persons to whom the Software is
15 // furnished to do so, subject to the following conditions:
17 // The above copyright notice and this permission notice shall be included in
18 // all copies or substantial portions of the Software.
20 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
29 using System.Threading;
30 using System.Collections.Generic;
31 using System.Threading.Tasks.Dataflow;
32 using NUnit.Framework;
34 namespace MonoTests.System.Threading.Tasks.Dataflow {
36 public class WriteOnceBlockTest {
38 public void BasicUsageTest ()
40 bool act1 = false, act2 = false;
41 var evt = new CountdownEvent (2);
43 var block = new WriteOnceBlock<int> (null);
44 var action1 = new ActionBlock<int> (i =>
49 var action2 = new ActionBlock<int> (i =>
55 block.LinkTo (action1);
56 block.LinkTo (action2);
58 Assert.IsTrue (block.Post (42));
59 Assert.IsFalse (block.Post (43));
61 Assert.IsTrue (evt.Wait (100));
68 public void LinkAfterPostTest ()
71 var evt = new ManualResetEventSlim ();
73 var block = new WriteOnceBlock<int> (null);
74 var action = new ActionBlock<int> (i =>
80 Assert.IsTrue (block.Post (42));
82 block.LinkTo (action);
84 Assert.IsTrue (evt.Wait (100));
90 public void PostponedTest ()
92 var block = new WriteOnceBlock<int> (null);
93 var target = new BufferBlock<int> (
94 new DataflowBlockOptions { BoundedCapacity = 1 });
95 block.LinkTo (target);
97 Assert.IsTrue (target.Post (1));
99 Assert.IsTrue (block.Post (2));
101 Assert.AreEqual (1, target.Receive (TimeSpan.FromMilliseconds (100)));
102 Assert.AreEqual (2, target.Receive (TimeSpan.FromMilliseconds (100)));
106 public void QueuedMessageTest ()
108 var scheduler = new TestScheduler ();
109 var block = new WriteOnceBlock<int> (null,
110 new DataflowBlockOptions { TaskScheduler = scheduler });
111 var target = new BufferBlock<int> ();
112 block.LinkTo (target);
114 Assert.IsTrue (block.Post (1));
116 AssertEx.Throws<TimeoutException> (
117 () => target.Receive (TimeSpan.FromMilliseconds (100)));
119 scheduler.ExecuteAll ();
122 Assert.IsTrue (target.TryReceive (out item));
123 Assert.AreEqual (1, item);
127 public void CloningTest ()
129 object act1 = null, act2 = null;
130 var evt = new CountdownEvent (2);
132 object source = new object ();
133 var block = new WriteOnceBlock<object> (o => new object ());
134 var action1 = new ActionBlock<object> (i =>
139 var action2 = new ActionBlock<object> (i =>
145 block.LinkTo (action1);
146 block.LinkTo (action2);
148 Assert.IsTrue (block.Post (source));
150 Assert.IsTrue (evt.Wait (100));
152 Assert.IsNotNull (act1);
153 Assert.IsNotNull (act2);
155 Assert.IsFalse (source.Equals (act1));
156 Assert.IsFalse (source.Equals (act2));
157 Assert.IsFalse (act2.Equals (act1));
161 public void WriteOnceBehaviorTest ()
163 bool act1 = false, act2 = false;
164 var evt = new CountdownEvent (2);
166 var broadcast = new WriteOnceBlock<int> (null);
167 var action1 = new ActionBlock<int> (i =>
172 var action2 = new ActionBlock<int> (i =>
178 broadcast.LinkTo (action1);
179 broadcast.LinkTo (action2);
181 Assert.IsTrue (broadcast.Post (42));
183 Assert.IsTrue (evt.Wait (100));
185 Assert.IsTrue (act1);
186 Assert.IsTrue (act2);
188 Assert.IsFalse (broadcast.Post (24));
191 Assert.IsTrue (act1);
192 Assert.IsTrue (act2);
196 public void TryReceiveBehaviorTest ()
198 var block = new WriteOnceBlock<int> (null);
200 Assert.IsFalse (block.TryReceive (null, out foo));
202 Assert.IsTrue (block.TryReceive (null, out foo));
203 Assert.AreEqual (42, foo);
204 Assert.IsTrue (block.TryReceive (null, out foo));
205 Assert.IsFalse (block.TryReceive (i => i == 0, out foo));
207 Assert.IsTrue (((IReceivableSourceBlock<int>)block).TryReceiveAll (out bar));
208 CollectionAssert.AreEqual (new[] { 42 }, bar);
212 public void DontOfferTwiceTest ()
214 var scheduler = new TestScheduler ();
215 var block = new WriteOnceBlock<int> (null,
216 new DataflowBlockOptions { TaskScheduler = scheduler });
218 new TestTargetBlock<int> { Postpone = true };
219 block.LinkTo (target);
221 Assert.IsFalse (target.HasPostponed);
223 Assert.IsTrue (block.Post (1));
225 scheduler.ExecuteAll ();
227 Assert.IsTrue (target.HasPostponed);
229 target.Postpone = false;
232 Assert.IsTrue (target.RetryPostponed (out value));
233 Assert.AreEqual (1, value);
235 block.LinkTo (new BufferBlock<int> ());
237 scheduler.ExecuteAll ();
239 Assert.AreEqual (default(int), target.DirectlyAccepted);