1 // InvalidArgumentsTest.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 InvalidArgumentsTest {
32 		[Test]
FaultNullTest()33 		public void FaultNullTest()
34 		{
35 			foreach (var block in Blocks.CreateBlocks ()) {
36 				AssertEx.Throws<ArgumentNullException> (() => block.Fault (null));
37 			}
38 		}
39 
40 		[Test]
ActionBlockTest()41 		public void  ActionBlockTest ()
42 		{
43 			AssertEx.Throws<ArgumentNullException> (
44 				() => new ActionBlock<int> ((Action<int>)null));
45 			AssertEx.Throws<ArgumentNullException> (
46 				() => new ActionBlock<int> (i => { }, null));
47 		}
48 
49 		[Test]
BatchBlockTest()50 		public void BatchBlockTest()
51 		{
52 			AssertEx.Throws<ArgumentOutOfRangeException> (() => new BatchBlock<int> (0));
53 			AssertEx.Throws<ArgumentOutOfRangeException> (() => new BatchBlock<int> (-1));
54 
55 			AssertEx.Throws<ArgumentOutOfRangeException> (
56 				() => new BatchBlock<int> (2,
57 					      new GroupingDataflowBlockOptions { BoundedCapacity = 1 }));
58 
59 			AssertEx.Throws<ArgumentNullException> (() => new BatchBlock<int> (2, null));
60 		}
61 
62 		[Test]
BatchedJoinBlockTest()63 		public void BatchedJoinBlockTest()
64 		{
65 			AssertEx.Throws<ArgumentOutOfRangeException> (() => new BatchedJoinBlock<int, int> (0));
66 			AssertEx.Throws<ArgumentOutOfRangeException> (() => new BatchedJoinBlock<int, int> (-1));
67 
68 			AssertEx.Throws<ArgumentException> (
69 				() => new BatchedJoinBlock<int, int> (1,
70 					      new GroupingDataflowBlockOptions { BoundedCapacity = 1 }));
71 			AssertEx.Throws<ArgumentException> (
72 				() => new BatchedJoinBlock<int, int> (1,
73 					      new GroupingDataflowBlockOptions { Greedy = false }));
74 
75 			AssertEx.Throws<ArgumentNullException> (() => new BatchedJoinBlock<int, int> (2, null));
76 		}
77 
78 		[Test]
BatchedJoinBlock3Test()79 		public void BatchedJoinBlock3Test()
80 		{
81 			AssertEx.Throws<ArgumentOutOfRangeException> (() => new BatchedJoinBlock<int, int, int> (0));
82 			AssertEx.Throws<ArgumentOutOfRangeException> (() => new BatchedJoinBlock<int, int, int> (-1));
83 
84 			AssertEx.Throws<ArgumentException> (
85 				() => new BatchedJoinBlock<int, int, int> (1,
86 					      new GroupingDataflowBlockOptions { BoundedCapacity = 1 }));
87 			AssertEx.Throws<ArgumentException> (
88 				() => new BatchedJoinBlock<int, int, int> (1,
89 					      new GroupingDataflowBlockOptions { Greedy = false }));
90 
91 			AssertEx.Throws<ArgumentNullException> (() => new BatchedJoinBlock<int, int, int> (2, null));
92 		}
93 
94 		[Test]
BroadcastBlock()95 		public void BroadcastBlock()
96 		{
97 			// null is valid argument for BroadcastBlock, so this shouldn't throw
98 			new BroadcastBlock<int> (null);
99 			AssertEx.Throws<ArgumentNullException> (() => new BroadcastBlock<int> (i => i, null));
100 		}
101 
102 		[Test]
BufferBlockTest()103 		public void BufferBlockTest()
104 		{
105 			AssertEx.Throws<ArgumentNullException> (() => new BufferBlock<int> (null));
106 		}
107 
108 		[Test]
JoinBlockTest()109 		public void JoinBlockTest()
110 		{
111 			AssertEx.Throws<ArgumentNullException> (() => new JoinBlock<int, int> (null));
112 		}
113 
114 		[Test]
JoinBlock3Test()115 		public void JoinBlock3Test()
116 		{
117 			AssertEx.Throws<ArgumentNullException> (() => new JoinBlock<int, int, int> (null));
118 		}
119 
120 		[Test]
TransformBlockTest()121 		public void TransformBlockTest()
122 		{
123 			AssertEx.Throws<ArgumentNullException> (
124 				() => new TransformBlock<int, int> ((Func<int, int>)null));
125 			AssertEx.Throws<ArgumentNullException> (
126 				() => new TransformBlock<int, int> ((Func<int, int>)null,
127 					      new ExecutionDataflowBlockOptions ()));
128 			AssertEx.Throws<ArgumentNullException> (
129 				() => new TransformBlock<int, int> (i => i, null));
130 		}
131 
132 		[Test]
TransformManyBlockTest()133 		public void TransformManyBlockTest()
134 		{
135 			AssertEx.Throws<ArgumentNullException> (
136 				() => new TransformManyBlock<int, int> ((Func<int, IEnumerable<int>>)null));
137 			AssertEx.Throws<ArgumentNullException> (
138 				() => new TransformManyBlock<int, int> ((Func<int, IEnumerable<int>>)null,
139 					      new ExecutionDataflowBlockOptions ()));
140 			AssertEx.Throws<ArgumentNullException> (
141 				() => new TransformManyBlock<int, int> (i => new int[0], null));
142 		}
143 
144 		[Test]
WriteOnceBlock()145 		public void WriteOnceBlock()
146 		{
147 			// null is valid argument for WriteOnceBlock, so this shouldn't throw
148 			new WriteOnceBlock<int> (null);
149 			AssertEx.Throws<ArgumentNullException> (() => new WriteOnceBlock<int> (i => i, null));
150 		}
151 
152 		[Test]
SourceBlockTest()153 		public void SourceBlockTest()
154 		{
155 			foreach (var block in Blocks.CreateSimpleSourceBlocks<int> ())
156 				SourceBlockTestInternal (block);
157 			SourceBlockTestInternal (new BatchBlock<int>(5));
158 			SourceBlockTestInternal (new BatchedJoinBlock<int, int>(5));
159 			SourceBlockTestInternal (new BatchedJoinBlock<int, int, int>(5));
160 			SourceBlockTestInternal (new JoinBlock<int, int> ());
161 			SourceBlockTestInternal (new JoinBlock<int, int, int> ());
162 		}
163 
SourceBlockTestInternal(ISourceBlock<T> block)164 		static void SourceBlockTestInternal<T>(ISourceBlock<T> block)
165 		{
166 			var target = new BufferBlock<T> ();
167 
168 			bool consumed;
169 			// invalid header
170 			AssertEx.Throws<ArgumentException> (
171 				() =>
172 				block.ConsumeMessage (new DataflowMessageHeader (), target, out consumed));
173 
174 			// header that wasn't sent by the block doesn't throw
175 			block.ConsumeMessage (new DataflowMessageHeader (1), target, out consumed);
176 
177 			AssertEx.Throws<ArgumentNullException> (
178 				() =>
179 				block.ConsumeMessage (new DataflowMessageHeader (1), null, out consumed));
180 
181 
182 			AssertEx.Throws<ArgumentException> (
183 				() =>
184 				block.ReserveMessage (new DataflowMessageHeader (), target));
185 
186 			// header that wasn't sent by the block doesn't throw
187 			block.ReserveMessage (new DataflowMessageHeader (1), target);
188 
189 			AssertEx.Throws<ArgumentNullException> (
190 				() =>
191 				block.ReserveMessage (new DataflowMessageHeader (1), null));
192 
193 			AssertEx.Throws<ArgumentException> (
194 				() =>
195 				block.ReleaseReservation (new DataflowMessageHeader (), target));
196 
197 			AssertEx.Throws<ArgumentNullException>(() => block.LinkTo(null, new DataflowLinkOptions()));
198 
199 			AssertEx.Throws<ArgumentNullException>(() => block.LinkTo(target, null));
200 		}
201 
202 		[Test]
TargetBlockTest()203 		public void TargetBlockTest()
204 		{
205 			foreach (var block in Blocks.CreateTargetBlocks<int> ()) {
206 				// invalid header
207 				AssertEx.Throws<ArgumentException> (
208 					() => block.OfferMessage (new DataflowMessageHeader (), 42, null, false));
209 
210 				// consumeToAccept with null source
211 				AssertEx.Throws<ArgumentException> (
212 					() => block.OfferMessage (new DataflowMessageHeader (1), 42, null, true));
213 			}
214 		}
215 
216 		[Test]
ReactiveTest()217 		public void ReactiveTest()
218 		{
219 			IPropagatorBlock<int, int> block = null;
220 
221 			AssertEx.Throws<ArgumentNullException> (() => block.AsObservable ());
222 			AssertEx.Throws<ArgumentNullException> (() => block.AsObserver ());
223 		}
224 
225 		[Test]
ChooseTest()226 		public void ChooseTest()
227 		{
228 			ISourceBlock<int> nullSource = null;
229 			var realSource = new BufferBlock<int> ();
230 			var options = new DataflowBlockOptions ();
231 
232 			AssertEx.Throws<ArgumentNullException> (
233 				() => DataflowBlock.Choose (nullSource, i => { }, realSource, i => { }));
234 			AssertEx.Throws<ArgumentNullException> (
235 				() => DataflowBlock.Choose (realSource, null, realSource, i => { }));
236 			AssertEx.Throws<ArgumentNullException> (
237 				() => DataflowBlock.Choose (realSource, i => { }, nullSource, i => { }));
238 			AssertEx.Throws<ArgumentNullException> (
239 				() => DataflowBlock.Choose (realSource, i => { }, realSource, null));
240 
241 			AssertEx.Throws<ArgumentNullException> (
242 				() => DataflowBlock.Choose (nullSource, i => { }, realSource, i => { }, options));
243 			AssertEx.Throws<ArgumentNullException> (
244 				() => DataflowBlock.Choose (realSource, null, realSource, i => { }, options));
245 			AssertEx.Throws<ArgumentNullException> (
246 				() => DataflowBlock.Choose (realSource, i => { }, nullSource, i => { }, options));
247 			AssertEx.Throws<ArgumentNullException> (
248 				() => DataflowBlock.Choose (realSource, i => { }, realSource, null, options));
249 			AssertEx.Throws<ArgumentNullException> (
250 				() => DataflowBlock.Choose (realSource, i => { }, realSource, i => { }, null));
251 
252 			AssertEx.Throws<ArgumentNullException> (
253 				() => DataflowBlock.Choose (nullSource, i => { }, realSource, i => { }, realSource, i => { }));
254 			AssertEx.Throws<ArgumentNullException> (
255 				() => DataflowBlock.Choose (realSource, null, realSource, i => { }, realSource, i => { }));
256 			AssertEx.Throws<ArgumentNullException> (
257 				() => DataflowBlock.Choose (realSource, i => { }, nullSource, i => { }, realSource, i => { }));
258 			AssertEx.Throws<ArgumentNullException> (
259 				() => DataflowBlock.Choose (realSource, i => { }, realSource, null, realSource, i => { }));
260 			AssertEx.Throws<ArgumentNullException> (
261 				() => DataflowBlock.Choose (nullSource, i => { }, realSource, i => { }, nullSource, i => { }));
262 			AssertEx.Throws<ArgumentNullException> (
263 				() => DataflowBlock.Choose (nullSource, i => { }, realSource, i => { }, realSource, null));
264 
265 			AssertEx.Throws<ArgumentNullException> (
266 				() => DataflowBlock.Choose (nullSource, i => { }, realSource, i => { }, realSource, i => { }, options));
267 			AssertEx.Throws<ArgumentNullException> (
268 				() => DataflowBlock.Choose (realSource, null, realSource, i => { }, realSource, i => { }, options));
269 			AssertEx.Throws<ArgumentNullException> (
270 				() => DataflowBlock.Choose (realSource, i => { }, nullSource, i => { }, realSource, i => { }, options));
271 			AssertEx.Throws<ArgumentNullException> (
272 				() => DataflowBlock.Choose (realSource, i => { }, realSource, null, realSource, i => { }, options));
273 			AssertEx.Throws<ArgumentNullException> (
274 				() => DataflowBlock.Choose (realSource, i => { }, realSource, i => { }, nullSource, i => { }, options));
275 			AssertEx.Throws<ArgumentNullException> (
276 				() => DataflowBlock.Choose (realSource, i => { }, realSource, i => { }, realSource, null, options));
277 			AssertEx.Throws<ArgumentNullException> (
278 				() => DataflowBlock.Choose (realSource, i => { }, realSource, i => { }, realSource, i => { }, null));
279 		}
280 
281 		[Test]
EncapsulateTest()282 		public void EncapsulateTest()
283 		{
284 			AssertEx.Throws<ArgumentNullException> (
285 				() =>
286 				DataflowBlock.Encapsulate ((ITargetBlock<int>)null, new BufferBlock<int> ()));
287 			AssertEx.Throws<ArgumentNullException> (
288 				() =>
289 				DataflowBlock.Encapsulate (new BufferBlock<int> (), (ISourceBlock<int>)null));
290 		}
291 
292 		[Test]
LinkToTest()293 		public void LinkToTest()
294 		{
295 			IPropagatorBlock<int, int> nullBlock = null;
296 			var realBlock = new BufferBlock<int> ();
297 
298 			AssertEx.Throws<ArgumentNullException> (
299 				() => DataflowBlock.LinkTo (nullBlock, realBlock));
300 			AssertEx.Throws<ArgumentNullException> (
301 				() => DataflowBlock.LinkTo (realBlock, nullBlock));
302 
303 			AssertEx.Throws<ArgumentNullException> (
304 				() => DataflowBlock.LinkTo (nullBlock, realBlock, i => true));
305 			AssertEx.Throws<ArgumentNullException> (
306 				() => DataflowBlock.LinkTo (realBlock, nullBlock, i => true));
307 			AssertEx.Throws<ArgumentNullException> (
308 				() => DataflowBlock.LinkTo (realBlock, realBlock, null));
309 
310 			AssertEx.Throws<ArgumentNullException> (
311 				() => DataflowBlock.LinkTo (nullBlock, realBlock, new DataflowLinkOptions (), i => true));
312 			AssertEx.Throws<ArgumentNullException> (
313 				() => DataflowBlock.LinkTo (realBlock, nullBlock, new DataflowLinkOptions (), i => true));
314 			AssertEx.Throws<ArgumentNullException> (
315 				() => DataflowBlock.LinkTo (realBlock, realBlock, null, i => true));
316 			AssertEx.Throws<ArgumentNullException> (
317 				() => DataflowBlock.LinkTo (realBlock, realBlock, new DataflowLinkOptions (), null));
318 		}
319 
320 		[Test]
PostTest()321 		public void PostTest()
322 		{
323 			AssertEx.Throws<ArgumentNullException> (() => DataflowBlock.Post (null, 42));
324 		}
325 
326 		[Test]
ReceiveTest()327 		public void ReceiveTest()
328 		{
329 			var source = new BufferBlock<int> ();
330 			source.Post(1);
331 			source.Post(2);
332 			source.Post(3);
333 			source.Post(4);
334 
335 			AssertEx.Throws<ArgumentNullException> (
336 				() => DataflowBlock.Receive ((ISourceBlock<int>)null));
337 
338 			AssertEx.Throws<ArgumentNullException> (
339 				() => DataflowBlock.Receive ((ISourceBlock<int>)null,
340 					new CancellationToken (false)));
341 			AssertEx.Throws<OperationCanceledException> (
342 				() => DataflowBlock.Receive (source, new CancellationToken (true)));
343 
344 			AssertEx.Throws<ArgumentNullException> (
345 				() => DataflowBlock.Receive ((ISourceBlock<int>)null,
346 					TimeSpan.FromMinutes (1)));
347 			// shouldn't throw
348 			DataflowBlock.Receive (source, TimeSpan.FromMilliseconds (-1));
349 			AssertEx.Throws<ArgumentOutOfRangeException> (
350 				() => DataflowBlock.Receive (source, TimeSpan.FromMilliseconds (-2)));
351 			// shouldn't throw
352 			DataflowBlock.Receive (source, TimeSpan.FromMilliseconds (int.MaxValue));
353 			AssertEx.Throws<ArgumentOutOfRangeException> (
354 				() => DataflowBlock.Receive (source,
355 					TimeSpan.FromMilliseconds (int.MaxValue + 1L)));
356 
357 			AssertEx.Throws<ArgumentNullException> (
358 				() => DataflowBlock.Receive ((ISourceBlock<int>)null,
359 					TimeSpan.FromMinutes (1), new CancellationToken(false)));
360 			AssertEx.Throws<OperationCanceledException> (
361 				() => DataflowBlock.Receive (source, TimeSpan.FromMinutes (1),
362 					new CancellationToken (true)));
363 			// shouldn't throw
364 			DataflowBlock.Receive (source, TimeSpan.FromMilliseconds (-1),
365 				new CancellationToken (false));
366 			AssertEx.Throws<ArgumentOutOfRangeException> (
367 				() => DataflowBlock.Receive (source, TimeSpan.FromMilliseconds (-2),
368 					new CancellationToken (false)));
369 			// shouldn't throw
370 			DataflowBlock.Receive (source, TimeSpan.FromMilliseconds (int.MaxValue),
371 				new CancellationToken (false));
372 			AssertEx.Throws<ArgumentOutOfRangeException> (
373 				() => DataflowBlock.Receive (source,
374 					TimeSpan.FromMilliseconds (int.MaxValue + 1L),
375 					new CancellationToken (false)));
376 		}
377 
378 		[Test]
ReceiveAsyncTest()379 		public void ReceiveAsyncTest()
380 		{
381 			var source = new BufferBlock<int> ();
382 
383 			AssertEx.Throws<ArgumentNullException> (
384 				() => DataflowBlock.ReceiveAsync ((ISourceBlock<int>)null));
385 
386 			AssertEx.Throws<ArgumentNullException> (
387 				() => DataflowBlock.ReceiveAsync ((ISourceBlock<int>)null,
388 					new CancellationToken (false)));
389 
390 			AssertEx.Throws<ArgumentNullException> (
391 				() => DataflowBlock.ReceiveAsync ((ISourceBlock<int>)null,
392 					TimeSpan.FromMinutes (1)));
393 			// shouldn't throw
394 			DataflowBlock.ReceiveAsync (source, TimeSpan.FromMilliseconds (-1));
395 			AssertEx.Throws<ArgumentOutOfRangeException> (
396 				() => DataflowBlock.ReceiveAsync (source, TimeSpan.FromMilliseconds (-2)));
397 			// shouldn't throw
398 			DataflowBlock.ReceiveAsync (source, TimeSpan.FromMilliseconds (int.MaxValue));
399 			AssertEx.Throws<ArgumentOutOfRangeException> (
400 				() => DataflowBlock.ReceiveAsync (source,
401 					TimeSpan.FromMilliseconds (int.MaxValue + 1L)));
402 
403 			AssertEx.Throws<ArgumentNullException> (
404 				() => DataflowBlock.ReceiveAsync ((ISourceBlock<int>)null,
405 					TimeSpan.FromMinutes (1), new CancellationToken(false)));
406 			// shouldn't throw
407 			DataflowBlock.ReceiveAsync (source, TimeSpan.FromMilliseconds (-1),
408 				new CancellationToken (false));
409 			AssertEx.Throws<ArgumentOutOfRangeException> (
410 				() => DataflowBlock.ReceiveAsync (source, TimeSpan.FromMilliseconds (-2),
411 					new CancellationToken (false)));
412 			// shouldn't throw
413 			DataflowBlock.ReceiveAsync (source, TimeSpan.FromMilliseconds (int.MaxValue),
414 				new CancellationToken (false));
415 			AssertEx.Throws<ArgumentOutOfRangeException> (
416 				() => DataflowBlock.ReceiveAsync (source,
417 					TimeSpan.FromMilliseconds (int.MaxValue + 1L),
418 					new CancellationToken (false)));
419 		}
420 
421 		[Test]
TryReceiveTest()422 		public void TryReceiveTest()
423 		{
424 			int i;
425 			AssertEx.Throws<ArgumentNullException> (
426 				() => DataflowBlock.TryReceive (null, out i));
427 		}
428 
429 		[Test]
DataflowBlockOptionsTest()430 		public void DataflowBlockOptionsTest()
431 		{
432 			var options = new DataflowBlockOptions ();
433 
434 			AssertEx.Throws<ArgumentOutOfRangeException>(() => options.BoundedCapacity = -2);
435 
436 			AssertEx.Throws<ArgumentOutOfRangeException>(() => options.MaxMessagesPerTask = -2);
437 
438 			AssertEx.Throws<ArgumentNullException>(() => options.NameFormat = null);
439 			// shouldn't throw
440 			options.NameFormat = "{2}";
441 			new BufferBlock<int>(options).ToString();
442 
443 			AssertEx.Throws<ArgumentNullException>(() => options.TaskScheduler = null);
444 		}
445 
446 		[Test]
ExecutionDataflowBlockOptionsTest()447 		public void ExecutionDataflowBlockOptionsTest()
448 		{
449 			var options = new ExecutionDataflowBlockOptions ();
450 
451 			AssertEx.Throws<ArgumentOutOfRangeException>(() => options.MaxDegreeOfParallelism = -2);
452 		}
453 
454 		[Test]
GroupingDataflowBlockOptionsTest()455 		public void GroupingDataflowBlockOptionsTest()
456 		{
457 			var options = new GroupingDataflowBlockOptions ();
458 
459 			AssertEx.Throws<ArgumentOutOfRangeException>(() => options.MaxNumberOfGroups = -2);
460 		}
461 
462 		[Test]
DataflowLinkOptionsTest()463 		public void DataflowLinkOptionsTest()
464 		{
465 			var options = new DataflowLinkOptions ();
466 
467 			AssertEx.Throws<ArgumentOutOfRangeException>(() => options.MaxMessages = -2);
468 		}
469 	}
470 }