public void SendBuffer_must_throw_exception_if_nonbuffered_sequence_number_is_NACKed() { var b0 = new AckedSendBuffer <Sequenced>(10); var msg1 = Msg(1); var msg2 = Msg(2); var b1 = b0.Buffer(msg1).Buffer(msg2); XAssert.Throws <ResendUnfulfillableException>(() => b1.Acknowledge(new Ack(new SeqNo(2), new [] { new SeqNo(0) }))); }
public void SendBuffer_must_remove_messages_from_buffer_when_cumulative_ack_received() { var b0 = new AckedSendBuffer <Sequenced>(10); var msg0 = Msg(0); var msg1 = Msg(1); var msg2 = Msg(2); var msg3 = Msg(3); var msg4 = Msg(4); var b1 = b0.Buffer(msg0); Assert.True(b1.NonAcked.SequenceEqual(new[] { msg0 })); var b2 = b1.Buffer(msg1); Assert.True(b2.NonAcked.SequenceEqual(new[] { msg0, msg1 })); var b3 = b2.Buffer(msg2); Assert.True(b3.NonAcked.SequenceEqual(new[] { msg0, msg1, msg2 })); var b4 = b3.Acknowledge(new Ack(new SeqNo(1))); Assert.True(b4.NonAcked.SequenceEqual(new[] { msg2 })); var b5 = b4.Buffer(msg3); Assert.True(b5.NonAcked.SequenceEqual(new [] { msg2, msg3 })); var b6 = b5.Buffer(msg4); Assert.True(b6.NonAcked.SequenceEqual(new[] { msg2, msg3, msg4 })); var b7 = b6.Acknowledge(new Ack(new SeqNo(1))); Assert.True(b7.NonAcked.SequenceEqual(new[] { msg2, msg3, msg4 })); var b8 = b7.Acknowledge(new Ack(new SeqNo(2))); Assert.True(b8.NonAcked.SequenceEqual(new[] { msg3, msg4 })); var b9 = b8.Acknowledge(new Ack(new SeqNo(4))); Assert.True(b9.NonAcked.Count == 0); }
public void SendBuffer_must_aggregate_unacked_messages_in_order() { var b0 = new AckedSendBuffer <Sequenced>(10); var msg0 = Msg(0); var msg1 = Msg(1); var msg2 = Msg(2); var b1 = b0.Buffer(msg0); Assert.True(b1.NonAcked.SequenceEqual(new[] { msg0 })); var b2 = b1.Buffer(msg1); Assert.True(b2.NonAcked.SequenceEqual(new[] { msg0, msg1 })); var b3 = b2.Buffer(msg2); Assert.True(b3.NonAcked.SequenceEqual(new[] { msg0, msg1, msg2 })); }
public void SendBuffer_must_keep_NACKed_messages_in_buffer_if_selective_nacks_are_received() { var b0 = new AckedSendBuffer <Sequenced>(10); var msg0 = Msg(0); var msg1 = Msg(1); var msg2 = Msg(2); var msg3 = Msg(3); var msg4 = Msg(4); var b1 = b0.Buffer(msg0); Assert.True(b1.NonAcked.SequenceEqual(new[] { msg0 })); var b2 = b1.Buffer(msg1); Assert.True(b2.NonAcked.SequenceEqual(new[] { msg0, msg1 })); var b3 = b2.Buffer(msg2); Assert.True(b3.NonAcked.SequenceEqual(new[] { msg0, msg1, msg2 })); var b4 = b3.Acknowledge(new Ack(new SeqNo(1), new [] { new SeqNo(0) })); Assert.True(b4.NonAcked.SequenceEqual(new [] { msg2 })); Assert.True(b4.Nacked.SequenceEqual(new[] { msg0 })); var b5 = b4.Buffer(msg3).Buffer(msg4); Assert.True(b5.NonAcked.SequenceEqual(new[] { msg2, msg3, msg4 })); Assert.True(b5.Nacked.SequenceEqual(new[] { msg0 })); var b6 = b5.Acknowledge(new Ack(new SeqNo(4), new [] { new SeqNo(2), new SeqNo(3) })); Assert.True(b6.NonAcked.Count == 0); Assert.True(b6.Nacked.SequenceEqual(new[] { msg2, msg3 })); var b7 = b6.Acknowledge(new Ack(new SeqNo(4))); Assert.True(b7.NonAcked.Count == 0); Assert.True(b7.Nacked.Count == 0); }
public void SendBuffer_and_ReceiveBuffer_must_correctly_cooperate_with_each_other() { var msgCount = 1000; var deliveryProbability = 0.5D; var referenceList = Enumerable.Range(0, msgCount).Select(x => Msg(x)).ToList(); var toSend = referenceList; var received = new List <Sequenced>(); var sndBuf = new AckedSendBuffer <Sequenced>(10); var rcvBuf = new AckedReceiveBuffer <Sequenced>(); var log = new List <string>(); var lastAck = new Ack(new SeqNo(-1)); Action <string> dbLog = log.Add; Action <int, double> senderSteps = (steps, p) => { var resends = new List <Sequenced>(sndBuf.Nacked.Concat(sndBuf.NonAcked).Take(steps)); var sends = new List <Sequenced>(); if (steps - resends.Count > 0) { var tmp = toSend.Take(steps - resends.Count).ToList(); toSend = toSend.Drop(steps - resends.Count).ToList(); sends = tmp; } foreach (var msg in resends.Concat(sends)) { if (sends.Contains(msg)) { sndBuf = sndBuf.Buffer(msg); } if (Happened(p)) { var del = rcvBuf.Receive(msg).ExtractDeliverable(); rcvBuf = del.Buffer; dbLog(string.Format("{0} -- {1} --> {2}", sndBuf, msg, rcvBuf)); lastAck = del.Ack; received.AddRange(del.Deliverables); dbLog(string.Format("R: {0}", string.Join(",", received.Select(x => x.ToString())))); } else { dbLog(string.Format("{0} -- {1} --X {2}", sndBuf, msg, rcvBuf)); } } }; Action <double> receiverStep = (p) => { if (Happened(p)) { sndBuf = sndBuf.Acknowledge(lastAck); dbLog(string.Format("{0} <-- {1} -- {2}", sndBuf, lastAck, rcvBuf)); } else { dbLog(string.Format("{0} X-- {1} -- {2}", sndBuf, lastAck, rcvBuf)); } }; //Dropping phase global::System.Diagnostics.Debug.WriteLine("Starting unreliable delivery for {0} messages, with delivery probably P = {1}", msgCount, deliveryProbability); var nextSteps = msgCount * 2; while (nextSteps > 0) { var s = Geom(0.3, limit: 5); senderSteps(s, deliveryProbability); receiverStep(deliveryProbability); nextSteps--; } global::System.Diagnostics.Debug.WriteLine("Successfully delivered {0} messages from {1}", received.Count, msgCount); global::System.Diagnostics.Debug.WriteLine("Entering reliable phase"); //Finalizing phase for (var i = 1; i <= msgCount; i++) { senderSteps(1, 1.0); receiverStep(1.0); } if (!received.SequenceEqual(referenceList)) { global::System.Diagnostics.Debug.WriteLine(string.Join(Environment.NewLine, log)); global::System.Diagnostics.Debug.WriteLine("Received: "); global::System.Diagnostics.Debug.WriteLine(string.Join(Environment.NewLine, received.Select(x => x.ToString()))); Assert.True(false, "Not all messages were received"); } global::System.Diagnostics.Debug.WriteLine("All messages have been successfully delivered"); }
public void SendBuffer_must_refuse_buffering_new_messages_if_capacity_reached() { var buffer = new AckedSendBuffer <Sequenced>(4).Buffer(Msg(0)).Buffer(Msg(1)).Buffer(Msg(2)).Buffer(Msg(3)); XAssert.Throws <ResendBufferCapacityReachedException>(() => buffer.Buffer(Msg(4))); }
public void SendBuffer_and_ReceiveBuffer_must_correctly_cooperate_with_each_other() { var msgCount = 1000; var deliveryProbability = 0.5D; var referenceList = Enumerable.Range(0, msgCount).Select(x => Msg(x)).ToList(); var toSend = referenceList; var received = new List<Sequenced>(); var sndBuf = new AckedSendBuffer<Sequenced>(10); var rcvBuf = new AckedReceiveBuffer<Sequenced>(); var log = new List<string>(); var lastAck = new Ack(new SeqNo(-1)); Action<string> dbLog = log.Add; Action<int, double> senderSteps = (steps, p) => { var resends = new List<Sequenced>(sndBuf.Nacked.Concat(sndBuf.NonAcked).Take(steps)); var sends = new List<Sequenced>(); if (steps - resends.Count > 0) { var tmp = toSend.Take(steps - resends.Count).ToList(); toSend = toSend.Drop(steps - resends.Count).ToList(); sends = tmp; } foreach (var msg in resends.Concat(sends)) { if (sends.Contains(msg)) sndBuf = sndBuf.Buffer(msg); if (Happened(p)) { var del = rcvBuf.Receive(msg).ExtractDeliverable; rcvBuf = del.Buffer; dbLog(string.Format("{0} -- {1} --> {2}", sndBuf, msg, rcvBuf)); lastAck = del.Ack; received.AddRange(del.Deliverables); dbLog(string.Format("R: {0}", string.Join(",", received.Select(x => x.ToString())))); } else { dbLog(string.Format("{0} -- {1} --X {2}", sndBuf, msg, rcvBuf)); } } }; Action<double> receiverStep = (p) => { if (Happened(p)) { sndBuf = sndBuf.Acknowledge(lastAck); dbLog(string.Format("{0} <-- {1} -- {2}", sndBuf, lastAck, rcvBuf)); } else { dbLog(string.Format("{0} X-- {1} -- {2}", sndBuf, lastAck, rcvBuf)); } }; //Dropping phase global::System.Diagnostics.Debug.WriteLine("Starting unreliable delivery for {0} messages, with delivery probably P = {1}", msgCount, deliveryProbability); var nextSteps = msgCount*2; while (nextSteps > 0) { var s = Geom(0.3, limit: 5); senderSteps(s, deliveryProbability); receiverStep(deliveryProbability); nextSteps--; } global::System.Diagnostics.Debug.WriteLine("Successfully delivered {0} messages from {1}", received.Count, msgCount); global::System.Diagnostics.Debug.WriteLine("Entering reliable phase"); //Finalizing phase for (var i = 1; i <= msgCount; i++) { senderSteps(1, 1.0); receiverStep(1.0); } if (!received.SequenceEqual(referenceList)) { global::System.Diagnostics.Debug.WriteLine(string.Join(Environment.NewLine, log)); global::System.Diagnostics.Debug.WriteLine("Received: "); global::System.Diagnostics.Debug.WriteLine(string.Join(Environment.NewLine, received.Select(x => x.ToString()))); Assert.True(false,"Not all messages were received"); } global::System.Diagnostics.Debug.WriteLine("All messages have been successfully delivered"); }
public void SendBuffer_must_throw_exception_if_nonbuffered_sequence_number_is_NACKed() { var b0 = new AckedSendBuffer<Sequenced>(10); var msg1 = Msg(1); var msg2 = Msg(2); var b1 = b0.Buffer(msg1).Buffer(msg2); XAssert.Throws<ResendUnfulfillableException>(() => b1.Acknowledge(new Ack(new SeqNo(2), new []{ new SeqNo(0) }))); }
public void SendBuffer_must_keep_NACKed_messages_in_buffer_if_selective_nacks_are_received() { var b0 = new AckedSendBuffer<Sequenced>(10); var msg0 = Msg(0); var msg1 = Msg(1); var msg2 = Msg(2); var msg3 = Msg(3); var msg4 = Msg(4); var b1 = b0.Buffer(msg0); Assert.True(b1.NonAcked.SequenceEqual(new[] { msg0 })); var b2 = b1.Buffer(msg1); Assert.True(b2.NonAcked.SequenceEqual(new[] { msg0, msg1 })); var b3 = b2.Buffer(msg2); Assert.True(b3.NonAcked.SequenceEqual(new[] { msg0, msg1, msg2 })); var b4 = b3.Acknowledge(new Ack(new SeqNo(1), new [] {new SeqNo(0)})); Assert.True(b4.NonAcked.SequenceEqual(new []{ msg2 })); Assert.True(b4.Nacked.SequenceEqual(new[] { msg0 })); var b5 = b4.Buffer(msg3).Buffer(msg4); Assert.True(b5.NonAcked.SequenceEqual(new[] { msg2, msg3, msg4 })); Assert.True(b5.Nacked.SequenceEqual(new[] { msg0 })); var b6 = b5.Acknowledge(new Ack(new SeqNo(4), new []{new SeqNo(2), new SeqNo(3)})); Assert.True(b6.NonAcked.Count == 0); Assert.True(b6.Nacked.SequenceEqual(new[] { msg2, msg3 })); var b7 = b6.Acknowledge(new Ack(new SeqNo(5))); Assert.True(b7.NonAcked.Count == 0); Assert.True(b7.Nacked.Count == 0); }
public void SendBuffer_must_remove_messages_from_buffer_when_cumulative_ack_received() { var b0 = new AckedSendBuffer<Sequenced>(10); var msg0 = Msg(0); var msg1 = Msg(1); var msg2 = Msg(2); var msg3 = Msg(3); var msg4 = Msg(4); var b1 = b0.Buffer(msg0); Assert.True(b1.NonAcked.SequenceEqual(new[] { msg0 })); var b2 = b1.Buffer(msg1); Assert.True(b2.NonAcked.SequenceEqual(new[] { msg0, msg1 })); var b3 = b2.Buffer(msg2); Assert.True(b3.NonAcked.SequenceEqual(new[] { msg0, msg1, msg2 })); var b4 = b3.Acknowledge(new Ack(new SeqNo(1))); Assert.True(b4.NonAcked.SequenceEqual(new[]{ msg2 })); var b5 = b4.Buffer(msg3); Assert.True(b5.NonAcked.SequenceEqual(new []{ msg2,msg3 })); var b6 = b5.Buffer(msg4); Assert.True(b6.NonAcked.SequenceEqual(new[] { msg2, msg3, msg4 })); var b7 = b6.Acknowledge(new Ack(new SeqNo(1))); Assert.True(b7.NonAcked.SequenceEqual(new[] { msg2, msg3, msg4 })); var b8 = b7.Acknowledge(new Ack(new SeqNo(2))); Assert.True(b8.NonAcked.SequenceEqual(new[] { msg3, msg4 })); var b9 = b8.Acknowledge(new Ack(new SeqNo(5))); Assert.True(b9.NonAcked.Count == 0); }
public void SendBuffer_must_refuse_buffering_new_messages_if_capacity_reached() { var buffer = new AckedSendBuffer<Sequenced>(4).Buffer(Msg(0)).Buffer(Msg(1)).Buffer(Msg(2)).Buffer(Msg(3)); XAssert.Throws<ResendBufferCapacityReachedException>(() => buffer.Buffer(Msg(4))); }
public void SendBuffer_must_aggregate_unacked_messages_in_order() { var b0 = new AckedSendBuffer<Sequenced>(10); var msg0 = Msg(0); var msg1 = Msg(1); var msg2 = Msg(2); var b1 = b0.Buffer(msg0); Assert.True(b1.NonAcked.SequenceEqual(new[]{msg0})); var b2 = b1.Buffer(msg1); Assert.True(b2.NonAcked.SequenceEqual(new[] { msg0, msg1 })); var b3 = b2.Buffer(msg2); Assert.True(b3.NonAcked.SequenceEqual(new[] { msg0, msg1, msg2 })); }