コード例 #1
0
        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) })));
        }
コード例 #2
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);
        }
コード例 #3
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 }));
        }
コード例 #4
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(4)));

            Assert.True(b7.NonAcked.Count == 0);
            Assert.True(b7.Nacked.Count == 0);
        }
コード例 #5
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");
        }
コード例 #6
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)));
        }
コード例 #7
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");
        }
コード例 #8
0
        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) })));
        }
コード例 #9
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);
        }
コード例 #10
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);
        }
コード例 #11
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)));
        }
コード例 #12
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 }));
        }