1 // DataflowBlockTest.cs 2 // 3 // Author: 4 // Petr Onderka <gsvick@gmail.com> 5 // 6 // Copyright (c) 2012 Petr Onderka 7 // 8 // Permission is hereby granted, free of charge, to any person obtaining a copy 9 // of this software and associated documentation files (the "Software"), to deal 10 // in the Software without restriction, including without limitation the rights 11 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 // copies of the Software, and to permit persons to whom the Software is 13 // furnished to do so, subject to the following conditions: 14 // 15 // The above copyright notice and this permission notice shall be included in 16 // all copies or substantial portions of the Software. 17 // 18 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 24 // THE SOFTWARE. 25 26 using System; 27 using System.Threading; 28 using System.Threading.Tasks; 29 using System.Threading.Tasks.Dataflow; 30 using NUnit.Framework; 31 32 namespace MonoTests.System.Threading.Tasks.Dataflow { 33 [TestFixture] 34 public class ChooseTest { 35 [Test] BasicTest()36 public void BasicTest () 37 { 38 var source1 = new BufferBlock<int> (); 39 var source2 = new BufferBlock<long> (); 40 41 bool action1 = false; 42 bool action2 = false; 43 var completion = DataflowBlock.Choose ( 44 source1, _ => action1 = true, 45 source2, _ => action2 = true); 46 47 source1.Post (42); 48 49 Assert.IsTrue (completion.Wait (1000)); 50 Assert.AreEqual (0, completion.Result); 51 Assert.IsTrue (action1); 52 Assert.IsFalse (action2); 53 } 54 55 [Test] OnlyOneConsumedTest()56 public void OnlyOneConsumedTest () 57 { 58 var source1 = new BufferBlock<int> (); 59 var source2 = new BufferBlock<long> (); 60 61 int action1 = 0; 62 int action2 = 0; 63 var completion = DataflowBlock.Choose ( 64 source1, _ => action1++, 65 source2, _ => action2++); 66 67 source1.Post (42); 68 source1.Post (43); 69 70 Assert.IsTrue (completion.Wait (1000)); 71 Assert.AreEqual (0, completion.Result); 72 Assert.AreEqual (1, action1); 73 Assert.AreEqual (0, action2); 74 75 int item; 76 Assert.IsTrue (source1.TryReceive (out item)); 77 Assert.AreEqual (43, item); 78 } 79 80 [Test] RaceTest()81 public void RaceTest () 82 { 83 var source1 = new BufferBlock<int> (); 84 var source2 = new BufferBlock<int> (); 85 86 int action1 = 0; 87 int action2 = 0; 88 var completion = DataflowBlock.Choose ( 89 source1, _ => action1++, 90 source2, _ => action2++); 91 92 var barrier = new Barrier (2); 93 94 var t1 = Task.Run (() => 95 { 96 barrier.SignalAndWait (); 97 source1.Post (10); 98 }); 99 var t2 = Task.Run (() => 100 { 101 barrier.SignalAndWait (); 102 source2.Post (20); 103 }); 104 105 Task.WaitAll (t1, t2); 106 107 Assert.IsTrue (completion.Wait (1000)); 108 Assert.AreEqual (1, action1 + action2); 109 110 int item; 111 Assert.IsTrue (source1.TryReceive (out item) || source2.TryReceive (out item)); 112 } 113 114 [Test] BlockCompletionTest()115 public void BlockCompletionTest () 116 { 117 var source1 = new BufferBlock<int> (); 118 var source2 = new BufferBlock<long> (); 119 120 var completion = DataflowBlock.Choose ( 121 source1, _ => { }, source2, _ => { }); 122 123 Assert.IsFalse (completion.IsCanceled); 124 125 ((IDataflowBlock)source1).Fault (new Exception ()); 126 source2.Complete (); 127 128 Thread.Sleep (100); 129 130 Assert.IsTrue (completion.IsCanceled); 131 } 132 133 [Test] CancellationTest()134 public void CancellationTest () 135 { 136 var source1 = new BufferBlock<int> (); 137 var source2 = new BufferBlock<long> (); 138 139 var tokenSource = new CancellationTokenSource (); 140 var options = new DataflowBlockOptions 141 { CancellationToken = tokenSource.Token }; 142 143 var completion = DataflowBlock.Choose ( 144 source1, _ => { }, source2, _ => { }, options); 145 146 Assert.IsFalse (completion.IsCanceled); 147 148 tokenSource.Cancel (); 149 150 Thread.Sleep (100); 151 152 Assert.IsTrue (completion.IsCanceled); 153 } 154 155 [Test] ConsumeToAcceptTest()156 public void ConsumeToAcceptTest () 157 { 158 var source1 = new BroadcastBlock<int> (_ => 42); 159 var source2 = new BufferBlock<int> (); 160 161 int action1 = 0; 162 int action2 = 0; 163 var completion = DataflowBlock.Choose ( 164 source1, i => action1 = i, 165 source2, i => action2 = i); 166 167 source1.Post (10); 168 169 Assert.IsTrue (completion.Wait (1000)); 170 Assert.AreEqual (0, completion.Result); 171 Assert.AreEqual (42, action1); 172 Assert.AreEqual (0, action2); 173 } 174 175 [Test] ExceptionTest()176 public void ExceptionTest () 177 { 178 var source1 = new BufferBlock<int> (); 179 var source2 = new BufferBlock<long> (); 180 181 var exception = new Exception (); 182 var completion = DataflowBlock.Choose ( 183 source1, _ => { throw exception; }, 184 source2, _ => { }); 185 186 source1.Post (42); 187 188 var ae = AssertEx.Throws<AggregateException> (() => completion.Wait (1000)); 189 Assert.AreEqual (1, ae.InnerExceptions.Count); 190 Assert.AreSame (exception, ae.InnerException); 191 } 192 193 [Test] BasicTest_3()194 public void BasicTest_3 () 195 { 196 var source1 = new BufferBlock<int> (); 197 var source2 = new BufferBlock<long> (); 198 var source3 = new BufferBlock<object> (); 199 200 bool action1 = false; 201 bool action2 = false; 202 bool action3 = false; 203 var completion = DataflowBlock.Choose ( 204 source1, _ => action1 = true, 205 source2, _ => action2 = true, 206 source3, _ => action3 = true); 207 208 source3.Post (new object ()); 209 210 Assert.IsTrue (completion.Wait (1000)); 211 Assert.AreEqual (2, completion.Result); 212 Assert.IsFalse (action1); 213 Assert.IsFalse (action2); 214 Assert.IsTrue (action3); 215 } 216 } 217 }