internal static bool TestConsumeMessage <T>(ISourceBlock <T> source) { bool consumed; source.ConsumeMessage(new DataflowMessageHeader(-99), new ActionBlock <T>(i => { }), out consumed); if (consumed) { Console.WriteLine("ConsumeMessage failed, didn't return messageConsumed==false for a unresrved msg"); return(false); } // test consume the correct message with different target var mres = new ManualResetEventSlim(false); var offeredMessage = default(DataflowMessageHeader); var target1 = new TransparentBlock <T>((msg) => { offeredMessage = msg; mres.Set(); }, false); source.LinkTo(target1); mres.Wait(); if (!source.ReserveMessage(offeredMessage, target1)) { Console.WriteLine("ReserveMessage failed, returned false"); return(false); } //exclude writeOnce and broadCast because they don't respect reservation to the target if (!(source is WriteOnceBlock <T> || source is BroadcastBlock <T>)) { //define another target var target2 = new TransparentBlock <T>(null); source.ConsumeMessage(offeredMessage, target2, out consumed); if (consumed) { Console.WriteLine("ConsumeMessage failed, a different target succeeded to consume the message that it doesn't own"); return(false); } } //same target different msg source.ConsumeMessage(new DataflowMessageHeader(-99), target1, out consumed); if (consumed) { Console.WriteLine("ConsumeMessage failed, the target succeeded to consume a differnt msg"); return(false); } //same target, same message source.ConsumeMessage(offeredMessage, target1, out consumed); if (!consumed) { Console.WriteLine("ConsumeMessage failed, the target failed to consume the reserved msg"); return(false); } return(true); }
internal static bool TestLinkTo <T>(ISourceBlock <T> source, int msgsCount) { // test LinkTo with unlink after once = true; var mres = new ManualResetEventSlim(false); int setCount = 1; int currentCount = 0; var target = new TransparentBlock <T>((msg) => { if (Interlocked.Increment(ref currentCount) == setCount) { mres.Set(); } }); var disposable = source.LinkTo(target, new DataflowLinkOptions() { MaxMessages = 1 }); if (disposable == null) { Console.WriteLine("LinkTo failed! returned null"); return(false); } if (target.Count != 1) { Console.WriteLine("LinkTo failed, The target didn't receive one msg, received {0}", target.Count); return(false); } // test LinkTo with unlink after once = false; mres.Reset(); // If the source is WriteOnceBlock or BroadcastBlock, only one msg will be propagated if (source is WriteOnceBlock <T> || source is BroadcastBlock <T> ) { setCount = 1; msgsCount = 2; } else { setCount = msgsCount - 1; } currentCount = 0; disposable = source.LinkTo(target); if (disposable == null) { Console.WriteLine("LinkTo failed! returned null"); return(false); } if (target.Count != msgsCount) { Console.WriteLine("LinkTo failed, The target didn't receive all messages, it received {0}", target.Count); } return(true); }
internal static bool TestReserveMessageAndReleaseReservation <T>(IReceivableSourceBlock <T> source) { // test consume the correct message with different target var mres = new ManualResetEventSlim(false); var offeredMessage = default(DataflowMessageHeader); var target1 = new TransparentBlock <T>((msg) => { offeredMessage = msg; mres.Set(); }, false); source.LinkTo(target1); mres.Wait(); if (!source.ReserveMessage(offeredMessage, target1)) { Console.WriteLine("ReserveMessage failed, returned false"); return(false); } // try to reserve another msg if (source.ReserveMessage(new DataflowMessageHeader(-99), target1)) { Console.WriteLine("ReserveMessage failed, succeeded to reserve a message while there is another reservation"); return(false); } // try TryReceive while reservation //exclude writeOnce and broadCast because they don't respect reservation to the target if (!(source is WriteOnceBlock <T> || source is BroadcastBlock <T>)) { T result; if (source.TryReceive(out result)) { Console.WriteLine("ReserveMessage failed, TryReceive succeeded while there is another reservation"); return(false); } } //try different target if (!(source is WriteOnceBlock <T>)) // exclude WriteOnce because RelaseReservation doesn't respect the target and will succeed { var target2 = new TransparentBlock <T>(null); bool passed = true; Assert.Throws <InvalidOperationException>(() => source.ReleaseReservation(offeredMessage, target2)); if (!passed) { Console.WriteLine("ReleaseMessage FAILED, another target succeeded to release the reservation"); return(false); } } // Now try releasing a different message. Even WriteOnce should throw. { bool passed = true; Assert.Throws <InvalidOperationException>(() => source.ReleaseReservation(new DataflowMessageHeader(-42), target1)); if (!passed) { Console.WriteLine("ReleaseMessage FAILED, the target succeeded to release the reservation of a different message"); return(false); } } // try TryReceive after release source.ReleaseReservation(offeredMessage, target1); T result1; if (!source.TryReceive(out result1)) { Console.WriteLine("ReleaseMessage FAILED, TryReceive failed after the release"); return(false); } return(true); }