public void TestUnbalanced2() { const int Iters = 10, NumBatches = 2; int batchSize = Iters / NumBatches; var block = new BatchedJoinBlock <string, int>(batchSize); for (int i = 0; i < Iters; i++) { block.Target2.Post(i); Assert.Equal(expected: (i + 1) / batchSize, actual: block.OutputCount); } IList <Tuple <IList <string>, IList <int> > > items; Assert.True(block.TryReceiveAll(out items)); Assert.Equal(expected: NumBatches, actual: items.Count); for (int i = 0; i < items.Count; i++) { var item = items[i]; Assert.NotNull(item.Item1); Assert.NotNull(item.Item2); Assert.Equal(expected: batchSize, actual: item.Item2.Count); for (int j = 0; j < batchSize; j++) { Assert.Equal(expected: (i * batchSize) + j, actual: item.Item2[j]); } } Assert.False(block.TryReceiveAll(out items)); }
public async Task TestMaxNumberOfGroups() { const int MaxGroups = 2; var b2 = new BatchedJoinBlock <int, int>(1, new GroupingDataflowBlockOptions { MaxNumberOfGroups = MaxGroups }); b2.Target1.PostRange(0, MaxGroups); Assert.False(b2.Target1.Post(42)); Assert.False(b2.Target2.Post(42)); IList <Tuple <IList <int>, IList <int> > > items2; Assert.True(b2.TryReceiveAll(out items2)); Assert.Equal(expected: MaxGroups, actual: items2.Count); await b2.Completion; var b3 = new BatchedJoinBlock <int, int, int>(1, new GroupingDataflowBlockOptions { MaxNumberOfGroups = MaxGroups }); b3.Target1.PostRange(0, MaxGroups); Assert.False(b3.Target1.Post(42)); Assert.False(b3.Target2.Post(42)); Assert.False(b3.Target3.Post(42)); IList <Tuple <IList <int>, IList <int>, IList <int> > > items3; Assert.True(b3.TryReceiveAll(out items3)); Assert.Equal(expected: MaxGroups, actual: items3.Count); await b3.Completion; }
public async Task TestPrecanceled3() { var b = new BatchedJoinBlock <int, int, int>(42, new GroupingDataflowBlockOptions { CancellationToken = new CancellationToken(canceled: true), MaxNumberOfGroups = 1 }); Tuple <IList <int>, IList <int>, IList <int> > ignoredValue; IList <Tuple <IList <int>, IList <int>, IList <int> > > ignoredValues; Assert.NotNull(b.LinkTo(new ActionBlock <Tuple <IList <int>, IList <int>, IList <int> > >(delegate { }))); Assert.False(b.Target1.Post(42)); Assert.False(b.Target2.Post(42)); foreach (var target in new[] { b.Target1, b.Target2 }) { var t = target.SendAsync(42); Assert.True(t.IsCompleted); Assert.False(t.Result); } Assert.False(b.TryReceiveAll(out ignoredValues)); Assert.False(b.TryReceive(out ignoredValue)); Assert.Equal(expected: 0, actual: b.OutputCount); Assert.NotNull(b.Completion); b.Target1.Complete(); b.Target2.Complete(); await Assert.ThrowsAnyAsync <OperationCanceledException>(() => b.Completion); }
public void RunBatchedJoinBlockConformanceTests() { // Test Post/Receive single block var block = new BatchedJoinBlock<int, int>(2); int iter = 10; for (int i = 0; i < iter; i++) { block.Target1.Post(i); block.Target2.Post(i); if (i % block.BatchSize == 0) { var msg = block.Receive(); Assert.False(msg.Item1.Count != msg.Item2.Count, "BatchedJoinBlock Post/Receive failed, returned arrays of differnet length"); for (int j = 0; j < msg.Item1.Count; j++) { if (msg.Item1[j] != msg.Item2[j]) { Assert.False(true, "BatchedJoinBlock Post/Receive failed, returned arrys items are different"); } } } } // Test PostAll then Receive single block block = new BatchedJoinBlock<int, int>(2); for (int i = 0; i < iter; i++) { block.Target1.Post(i); block.Target2.Post(i); } Assert.False(block.OutputCount != iter, string.Format("BatchedJoinBlock Post failed, expected, incorrect OutputCount. Expected {0} actual {1}", iter, block.OutputCount)); for (int i = 0; i < block.OutputCount; i++) { var msg = block.Receive(); if (msg.Item1.Count != msg.Item2.Count) { Assert.False(true, "BatchedJoinBlock PostAll then Receive failed, returned arrays of differnet length"); } for (int j = 0; j < msg.Item1.Count; j++) { if (msg.Item1[j] != msg.Item2[j]) { Assert.False(true, "BatchedJoinBlock PostAll then Receive failed, returned arrys items are different"); } } } //Test one target Post < patchSize msg with TryReceive block = new BatchedJoinBlock<int, int>(2); block.Target1.Post(0); Tuple<IList<int>, IList<int>> result; if (block.TryReceive(out result)) { Assert.False(true, "BatchedJoinBlock.TryReceive failed, returned true and the number of messages is less than the batch size"); } if (block.OutputCount > 0) { Assert.False(true, "BatchedJoinBlock.OutputCount failed, returned count > 0 and only one target posted a message"); } // Test handling of stragglers at end of block's life block = new BatchedJoinBlock<int, int>(2); for (int i = 0; i < 10; i++) { block.Target1.Post(i); block.Target2.Post(i); } block.Target1.Post(10); block.Target1.Complete(); block.Target2.Complete(); if (block.OutputCount != 11) { Assert.False(true, "BatchedJoinBlock last batch not generated correctly"); } for (int i = 0; i < 10; i++) block.Receive(); var lastResult = block.Receive(); if (lastResult.Item1.Count != 1 || lastResult.Item2.Count != 0) { Assert.False(true, "BatchedJoinBlock last batch contains incorrect data"); } // Test BatchedJoinBlock`2 using a precanceled token { var localPassed = true; try { var cts = new CancellationTokenSource(); cts.Cancel(); var dbo = new GroupingDataflowBlockOptions { CancellationToken = cts.Token, MaxNumberOfGroups = 1 }; var bjb = new BatchedJoinBlock<int, int>(42, dbo); Tuple<IList<int>, IList<int>> ignoredValue; IList<Tuple<IList<int>, IList<int>>> ignoredValues; localPassed &= bjb.LinkTo(new ActionBlock<Tuple<IList<int>, IList<int>>>(delegate { })) != null; localPassed &= bjb.Target1.Post(42) == false; localPassed &= bjb.Target2.Post(42) == false; localPassed &= bjb.Target1.SendAsync(42).Result == false; localPassed &= bjb.Target2.SendAsync(42).Result == false; localPassed &= bjb.TryReceiveAll(out ignoredValues) == false; localPassed &= bjb.TryReceive(out ignoredValue) == false; localPassed &= bjb.OutputCount == 0; localPassed &= bjb.Completion != null; bjb.Target1.Complete(); bjb.Target2.Complete(); } catch (Exception) { localPassed = false; } Assert.True(localPassed, "Precanceled tokens don't work correctly on BJB`2"); } // Test BatchedJoinBlock`3 using a precanceled token { var localPassed = true; try { var cts = new CancellationTokenSource(); cts.Cancel(); var dbo = new GroupingDataflowBlockOptions { CancellationToken = cts.Token, MaxNumberOfGroups = 1 }; var bjb = new BatchedJoinBlock<int, int, int>(42, dbo); Tuple<IList<int>, IList<int>, IList<int>> ignoredValue; IList<Tuple<IList<int>, IList<int>, IList<int>>> ignoredValues; localPassed &= bjb.LinkTo(new ActionBlock<Tuple<IList<int>, IList<int>, IList<int>>>(delegate { })) != null; localPassed &= bjb.Target1.Post(42) == false; localPassed &= bjb.Target2.Post(42) == false; localPassed &= bjb.Target3.Post(42) == false; localPassed &= bjb.Target1.SendAsync(42).Result == false; localPassed &= bjb.Target2.SendAsync(42).Result == false; localPassed &= bjb.Target3.SendAsync(42).Result == false; localPassed &= bjb.TryReceiveAll(out ignoredValues) == false; localPassed &= bjb.TryReceive(out ignoredValue) == false; localPassed &= bjb.OutputCount == 0; localPassed &= bjb.Completion != null; bjb.Target1.Complete(); bjb.Target2.Complete(); bjb.Target3.Complete(); } catch (Exception) { localPassed = false; } Assert.True(localPassed, "Precanceled tokens don't work correctly on BJB`3"); } // Test BatchedJoinBlock`2 completion through all targets { var localPassed = true; var batchedJoin = new BatchedJoinBlock<int, int>(99); var terminator = new ActionBlock<Tuple<IList<int>, IList<int>>>(x => { }); batchedJoin.LinkTo(terminator); batchedJoin.Target1.Post(1); batchedJoin.Target1.Complete(); batchedJoin.Target2.Complete(); localPassed = batchedJoin.Completion.Wait(2000); Assert.True(localPassed, string.Format("BatchedJoinBlock`2 completed through targets - {0}", localPassed ? "Passed" : "FAILED")); } // Test BatchedJoinBlock`3 completion through all targets { var localPassed = true; var batchedJoin = new BatchedJoinBlock<int, int, int>(99); var terminator = new ActionBlock<Tuple<IList<int>, IList<int>, IList<int>>>(x => { }); batchedJoin.LinkTo(terminator); batchedJoin.Target1.Post(1); batchedJoin.Target1.Complete(); batchedJoin.Target2.Complete(); batchedJoin.Target3.Complete(); localPassed = batchedJoin.Completion.Wait(2000); Assert.True(localPassed, string.Format("BatchedJoinBlock`3 completed through targets - {0}", localPassed ? "Passed" : "FAILED")); } // Test BatchedJoinBlock`2 completion through block { var localPassed = true; var batchedJoin = new BatchedJoinBlock<int, int>(99); var terminator = new ActionBlock<Tuple<IList<int>, IList<int>>>(x => { }); batchedJoin.LinkTo(terminator); batchedJoin.Target1.Post(1); batchedJoin.Complete(); localPassed = batchedJoin.Completion.Wait(2000); Assert.True(localPassed, string.Format("BatchedJoinBlock`2 completed through block - {0}", localPassed ? "Passed" : "FAILED")); } // Test BatchedJoinBlock`3 completion through block { var localPassed = true; var batchedJoin = new BatchedJoinBlock<int, int, int>(99); var terminator = new ActionBlock<Tuple<IList<int>, IList<int>, IList<int>>>(x => { }); batchedJoin.LinkTo(terminator); batchedJoin.Target1.Post(1); batchedJoin.Complete(); localPassed = batchedJoin.Completion.Wait(2000); Assert.True(localPassed, string.Format("BatchedJoinBlock`3 completed through block - {0}", localPassed ? "Passed" : "FAILED")); } }
public void RunBatchedJoinBlockConformanceTests() { // Test Post/Receive single block var block = new BatchedJoinBlock <int, int>(2); int iter = 10; for (int i = 0; i < iter; i++) { block.Target1.Post(i); block.Target2.Post(i); if (i % block.BatchSize == 0) { var msg = block.Receive(); Assert.False(msg.Item1.Count != msg.Item2.Count, "BatchedJoinBlock Post/Receive failed, returned arrays of differnet length"); for (int j = 0; j < msg.Item1.Count; j++) { if (msg.Item1[j] != msg.Item2[j]) { Assert.False(true, "BatchedJoinBlock Post/Receive failed, returned arrys items are different"); } } } } // Test PostAll then Receive single block block = new BatchedJoinBlock <int, int>(2); for (int i = 0; i < iter; i++) { block.Target1.Post(i); block.Target2.Post(i); } Assert.False(block.OutputCount != iter, string.Format("BatchedJoinBlock Post failed, expected, incorrect OutputCount. Expected {0} actual {1}", iter, block.OutputCount)); for (int i = 0; i < block.OutputCount; i++) { var msg = block.Receive(); if (msg.Item1.Count != msg.Item2.Count) { Assert.False(true, "BatchedJoinBlock PostAll then Receive failed, returned arrays of differnet length"); } for (int j = 0; j < msg.Item1.Count; j++) { if (msg.Item1[j] != msg.Item2[j]) { Assert.False(true, "BatchedJoinBlock PostAll then Receive failed, returned arrys items are different"); } } } //Test one target Post < patchSize msg with TryReceive block = new BatchedJoinBlock <int, int>(2); block.Target1.Post(0); Tuple <IList <int>, IList <int> > result; if (block.TryReceive(out result)) { Assert.False(true, "BatchedJoinBlock.TryReceive failed, returned true and the number of messages is less than the batch size"); } if (block.OutputCount > 0) { Assert.False(true, "BatchedJoinBlock.OutputCount failed, returned count > 0 and only one target posted a message"); } // Test handling of stragglers at end of block's life block = new BatchedJoinBlock <int, int>(2); for (int i = 0; i < 10; i++) { block.Target1.Post(i); block.Target2.Post(i); } block.Target1.Post(10); block.Target1.Complete(); block.Target2.Complete(); if (block.OutputCount != 11) { Assert.False(true, "BatchedJoinBlock last batch not generated correctly"); } for (int i = 0; i < 10; i++) { block.Receive(); } var lastResult = block.Receive(); if (lastResult.Item1.Count != 1 || lastResult.Item2.Count != 0) { Assert.False(true, "BatchedJoinBlock last batch contains incorrect data"); } // Test BatchedJoinBlock`2 using a precanceled token { var localPassed = true; try { var cts = new CancellationTokenSource(); cts.Cancel(); var dbo = new GroupingDataflowBlockOptions { CancellationToken = cts.Token, MaxNumberOfGroups = 1 }; var bjb = new BatchedJoinBlock <int, int>(42, dbo); Tuple <IList <int>, IList <int> > ignoredValue; IList <Tuple <IList <int>, IList <int> > > ignoredValues; localPassed &= bjb.LinkTo(new ActionBlock <Tuple <IList <int>, IList <int> > >(delegate { })) != null; localPassed &= bjb.Target1.Post(42) == false; localPassed &= bjb.Target2.Post(42) == false; localPassed &= bjb.Target1.SendAsync(42).Result == false; localPassed &= bjb.Target2.SendAsync(42).Result == false; localPassed &= bjb.TryReceiveAll(out ignoredValues) == false; localPassed &= bjb.TryReceive(out ignoredValue) == false; localPassed &= bjb.OutputCount == 0; localPassed &= bjb.Completion != null; bjb.Target1.Complete(); bjb.Target2.Complete(); } catch (Exception) { localPassed = false; } Assert.True(localPassed, "Precanceled tokens don't work correctly on BJB`2"); } // Test BatchedJoinBlock`3 using a precanceled token { var localPassed = true; try { var cts = new CancellationTokenSource(); cts.Cancel(); var dbo = new GroupingDataflowBlockOptions { CancellationToken = cts.Token, MaxNumberOfGroups = 1 }; var bjb = new BatchedJoinBlock <int, int, int>(42, dbo); Tuple <IList <int>, IList <int>, IList <int> > ignoredValue; IList <Tuple <IList <int>, IList <int>, IList <int> > > ignoredValues; localPassed &= bjb.LinkTo(new ActionBlock <Tuple <IList <int>, IList <int>, IList <int> > >(delegate { })) != null; localPassed &= bjb.Target1.Post(42) == false; localPassed &= bjb.Target2.Post(42) == false; localPassed &= bjb.Target3.Post(42) == false; localPassed &= bjb.Target1.SendAsync(42).Result == false; localPassed &= bjb.Target2.SendAsync(42).Result == false; localPassed &= bjb.Target3.SendAsync(42).Result == false; localPassed &= bjb.TryReceiveAll(out ignoredValues) == false; localPassed &= bjb.TryReceive(out ignoredValue) == false; localPassed &= bjb.OutputCount == 0; localPassed &= bjb.Completion != null; bjb.Target1.Complete(); bjb.Target2.Complete(); bjb.Target3.Complete(); } catch (Exception) { localPassed = false; } Assert.True(localPassed, "Precanceled tokens don't work correctly on BJB`3"); } // Test BatchedJoinBlock`2 completion through all targets { var localPassed = true; var batchedJoin = new BatchedJoinBlock <int, int>(99); var terminator = new ActionBlock <Tuple <IList <int>, IList <int> > >(x => { }); batchedJoin.LinkTo(terminator); batchedJoin.Target1.Post(1); batchedJoin.Target1.Complete(); batchedJoin.Target2.Complete(); localPassed = batchedJoin.Completion.Wait(2000); Assert.True(localPassed, string.Format("BatchedJoinBlock`2 completed through targets - {0}", localPassed ? "Passed" : "FAILED")); } // Test BatchedJoinBlock`3 completion through all targets { var localPassed = true; var batchedJoin = new BatchedJoinBlock <int, int, int>(99); var terminator = new ActionBlock <Tuple <IList <int>, IList <int>, IList <int> > >(x => { }); batchedJoin.LinkTo(terminator); batchedJoin.Target1.Post(1); batchedJoin.Target1.Complete(); batchedJoin.Target2.Complete(); batchedJoin.Target3.Complete(); localPassed = batchedJoin.Completion.Wait(2000); Assert.True(localPassed, string.Format("BatchedJoinBlock`3 completed through targets - {0}", localPassed ? "Passed" : "FAILED")); } // Test BatchedJoinBlock`2 completion through block { var localPassed = true; var batchedJoin = new BatchedJoinBlock <int, int>(99); var terminator = new ActionBlock <Tuple <IList <int>, IList <int> > >(x => { }); batchedJoin.LinkTo(terminator); batchedJoin.Target1.Post(1); batchedJoin.Complete(); localPassed = batchedJoin.Completion.Wait(2000); Assert.True(localPassed, string.Format("BatchedJoinBlock`2 completed through block - {0}", localPassed ? "Passed" : "FAILED")); } // Test BatchedJoinBlock`3 completion through block { var localPassed = true; var batchedJoin = new BatchedJoinBlock <int, int, int>(99); var terminator = new ActionBlock <Tuple <IList <int>, IList <int>, IList <int> > >(x => { }); batchedJoin.LinkTo(terminator); batchedJoin.Target1.Post(1); batchedJoin.Complete(); localPassed = batchedJoin.Completion.Wait(2000); Assert.True(localPassed, string.Format("BatchedJoinBlock`3 completed through block - {0}", localPassed ? "Passed" : "FAILED")); } }
public async Task TestMaxNumberOfGroups() { const int MaxGroups = 2; var b2 = new BatchedJoinBlock<int, int>(1, new GroupingDataflowBlockOptions { MaxNumberOfGroups = MaxGroups }); b2.Target1.PostRange(0, MaxGroups); Assert.False(b2.Target1.Post(42)); Assert.False(b2.Target2.Post(42)); IList<Tuple<IList<int>, IList<int>>> items2; Assert.True(b2.TryReceiveAll(out items2)); Assert.Equal(expected: MaxGroups, actual: items2.Count); await b2.Completion; var b3 = new BatchedJoinBlock<int, int, int>(1, new GroupingDataflowBlockOptions { MaxNumberOfGroups = MaxGroups }); b3.Target1.PostRange(0, MaxGroups); Assert.False(b3.Target1.Post(42)); Assert.False(b3.Target2.Post(42)); Assert.False(b3.Target3.Post(42)); IList<Tuple<IList<int>, IList<int>, IList<int>>> items3; Assert.True(b3.TryReceiveAll(out items3)); Assert.Equal(expected: MaxGroups, actual: items3.Count); await b3.Completion; }
public async Task TestPrecanceled3() { var b = new BatchedJoinBlock<int, int, int>(42, new GroupingDataflowBlockOptions { CancellationToken = new CancellationToken(canceled: true), MaxNumberOfGroups = 1 }); Tuple<IList<int>, IList<int>, IList<int>> ignoredValue; IList<Tuple<IList<int>, IList<int>, IList<int>>> ignoredValues; Assert.NotNull(b.LinkTo(new ActionBlock<Tuple<IList<int>, IList<int>, IList<int>>>(delegate { }))); Assert.False(b.Target1.Post(42)); Assert.False(b.Target2.Post(42)); foreach (var target in new[] { b.Target1, b.Target2 }) { var t = target.SendAsync(42); Assert.True(t.IsCompleted); Assert.False(t.Result); } Assert.False(b.TryReceiveAll(out ignoredValues)); Assert.False(b.TryReceive(out ignoredValue)); Assert.Equal(expected: 0, actual: b.OutputCount); Assert.NotNull(b.Completion); b.Target1.Complete(); b.Target2.Complete(); await Assert.ThrowsAnyAsync<OperationCanceledException>(() => b.Completion); }
public void TestUnbalanced2() { const int Iters = 10, NumBatches = 2; int batchSize = Iters / NumBatches; var block = new BatchedJoinBlock<string, int>(batchSize); for (int i = 0; i < Iters; i++) { block.Target2.Post(i); Assert.Equal(expected: (i + 1) / batchSize, actual: block.OutputCount); } IList<Tuple<IList<string>, IList<int>>> items; Assert.True(block.TryReceiveAll(out items)); Assert.Equal(expected: NumBatches, actual: items.Count); for (int i = 0; i < items.Count; i++) { var item = items[i]; Assert.NotNull(item.Item1); Assert.NotNull(item.Item2); Assert.Equal(expected: batchSize, actual: item.Item2.Count); for (int j = 0; j < batchSize; j++) { Assert.Equal(expected: (i * batchSize) + j, actual: item.Item2[j]); } } Assert.False(block.TryReceiveAll(out items)); }