예제 #1
0
        public void TestOrder()
        {
            NullTransport t = new NullTransport();
            MockConnexion cnx = new MockConnexion();
            cnx.Scheduler = new ImmediatePacketScheduler(cnx);
            cnx.Transports.Add(t);

            uint lastBytesSent = 0;
            for (int i = 0; i < 6; i++)
            {
                cnx.Scheduler.Schedule(new ObjectMessage(0, i), MessageDeliveryRequirements.LeastStrict, null);
                Assert.IsTrue(lastBytesSent < t.BytesSent);
                lastBytesSent = t.BytesSent;
            }
            cnx.Flush();
            Assert.IsTrue(t.BytesSent == lastBytesSent, "Flush() should have made no difference to bytes sent");

            // check order
            int msgNo = 0;
            foreach (TransportPacket tp in cnx.SentPackets)
            {
                while (tp.Length > 0)
                {
                    cnx.Marshaller.Unmarshal(tp, t, delegate(object sender, MessageEventArgs mea) {
                        Assert.AreEqual(msgNo, ((ObjectMessage)mea.Message).Object,
                            "message was sent out of order!");
                    });
                    msgNo++;
                }
            }
        }
예제 #2
0
        public void TestAggregationSendsNothingUntilFlush()
        {
            NullTransport t = new NullTransport();
            MockConnexion cnx = new MockConnexion();
            cnx.Scheduler = new RoundRobinPacketScheduler(cnx);
            cnx.Transports.Add(t);

            for (int i = 0; i < 6; i++)
            {
                cnx.Scheduler.Schedule(new ObjectMessage(0, i), MessageDeliveryRequirements.LeastStrict, null);
                Assert.AreEqual(0, t.BytesSent);
                Assert.AreEqual(0, cnx.SentPackets.Count);
            }
            cnx.Flush();
            Assert.IsTrue(t.BytesSent > 0);
            Assert.IsTrue(cnx.SentPackets.Count > 0);
        }
예제 #3
0
        public void TestImmediateComesFirst()
        {
            NullTransport t = new NullTransport();
            MockConnexion cnx = new MockConnexion();
            cnx.Scheduler = new RoundRobinPacketScheduler(cnx);
            cnx.Transports.Add(t);

            /// Send a bunch of messages that should be aggregated.
            /// Then send a message that should go immediately (i.e., sent
            /// before any of the aggregated messages).
            for (int i = 1; i < 6; i++)
            {
                cnx.Scheduler.Schedule(new ObjectMessage((byte)(i % 2), i), MessageDeliveryRequirements.LeastStrict, null);
                Assert.AreEqual(0, t.BytesSent);
                Assert.AreEqual(0, cnx.SentPackets.Count);
            }
            cnx.Scheduler.Schedule(new StringMessage(0, "foo"),
                new MessageDeliveryRequirements(Reliability.Unreliable,
                    MessageAggregation.Immediate, Ordering.Unordered), null);
            Assert.IsTrue(t.BytesSent > 0);
            Assert.IsTrue(cnx.SentPackets.Count > 0);

            int msgNo = 0;
            foreach (TransportPacket tp in cnx.SentPackets)
            {
                if (msgNo == 0)
                {
                    // Firt message should be the immediate message
                    cnx.Marshaller.Unmarshal(tp, t, delegate(object sender, MessageEventArgs mea)
                    {
                        Assert.IsInstanceOfType(typeof(StringMessage), mea.Message);
                        Assert.AreEqual("foo", ((StringMessage)mea.Message).Text);
                    });
                    msgNo++;
                }
                while(tp.Length > 0)
                {
                    cnx.Marshaller.Unmarshal(tp, t,
                        delegate(object sender, MessageEventArgs mea) {
                            Assert.AreEqual(msgNo, ((ObjectMessage)mea.Message).Object);
                            Assert.AreEqual(msgNo % 2, ((ObjectMessage)mea.Message).ChannelId);
                        });
                    msgNo++;
                }
            }
        }
예제 #4
0
        public void TestSendsOnSameChannelInOrder()
        {
            NullTransport t = new NullTransport();
            MockConnexion cnx = new MockConnexion();
            cnx.Scheduler = new RoundRobinPacketScheduler(cnx);
            cnx.Transports.Add(t);

            for (int i = 0; i < 6; i++)
            {
                cnx.Scheduler.Schedule(new ObjectMessage(0, i), MessageDeliveryRequirements.LeastStrict, null);
                Assert.AreEqual(0, t.BytesSent);
                Assert.AreEqual(0, cnx.SentPackets.Count);
            }
            cnx.Flush();
            Assert.IsTrue(t.BytesSent > 0);
            Assert.IsTrue(cnx.SentPackets.Count > 0);

            int msgNo = 0;
            foreach (TransportPacket tp in cnx.SentPackets)
            {
                while (tp.Length > 0)
                {
                    cnx.Marshaller.Unmarshal(tp, t, delegate(object sender, MessageEventArgs mea)
                    {
                        Assert.AreEqual(msgNo, ((ObjectMessage)mea.Message).Object);
                    });
                    msgNo++;
                }
            }
        }
예제 #5
0
        public void TestSendFragmentedPacket()
        {
            NullTransport t = new NullTransport();
            t.MaximumPacketSize = 100;
            t.Reliability = Reliability.Reliable;
            t.Ordering = Ordering.Ordered;
            MockConnexion cnx = new MockConnexion();
            cnx.Marshaller = new LargeObjectMarshaller(new DotNetSerializingMarshaller());
            cnx.Scheduler = new RoundRobinPacketScheduler(cnx);
            cnx.Transports.Add(t);

            cnx.ErrorEvents += delegate(ErrorSummary es) { Assert.Fail(es.ToString()); };

            byte[] sentData = new byte[500];
            for (int i = 0; i < 6; i++)
            {
                uint bytesSent = t.BytesSent;
                cnx.Scheduler.Schedule(new BinaryMessage(0, sentData), MessageDeliveryRequirements.MostStrict, null);
                Assert.IsTrue(cnx.SentPackets.Count > 0);
                Assert.IsTrue(t.BytesSent - bytesSent > 500); // should be 500 + message headers
            }
            int lastSentPacketsCount = cnx.SentPackets.Count;
            cnx.Flush();
            Assert.IsTrue(cnx.SentPackets.Count == lastSentPacketsCount, "there should not be any data remaining");

            int msgNo = 0;
            foreach (TransportPacket tp in cnx.SentPackets)
            {
                while (tp.Length > 0)
                {
                    cnx.Marshaller.Unmarshal(tp, t, delegate(object sender, MessageEventArgs mea)
                    {
                        Assert.IsInstanceOfType(typeof(BinaryMessage), mea.Message);
                        Assert.AreEqual(sentData, ((BinaryMessage)mea.Message).Bytes);
                        msgNo++;
                    });
                }
            }
            Assert.AreEqual(6, msgNo);
        }
예제 #6
0
        public void TestLeakyBucketTransport()
        {
            NullTransport nt = new NullTransport();
            // drain at 128 bytes every 100 milliseconds, and buffer up to
            // 384 bytes (or 3 packets of 128 bytes)
            // (100ms may seem long, but it seems to help avoid possible
            // race conditions in the test such as where the AvailableCapacity
            // is is suddenly recalcd and available)
            LeakyBucketTransport lbt = new LeakyBucketTransport(nt, 128,
                TimeSpan.FromMilliseconds(100), 384);
            bool backlogged = false;
            lbt.ErrorEvent += delegate(ErrorSummary es)
            {
                if (es.ErrorCode == SummaryErrorCode.TransportBacklogged)
                {
                    backlogged = true;
                }
            };

            for(int i = 0; i < 5; i++)
            {
                Assert.IsFalse(backlogged);
                uint startBytesSent = nt.BytesSent;
                Assert.AreEqual(128, lbt.AvailableCapacity);
                Assert.AreEqual(384, lbt.RemainingBucketCapacity);
                Assert.IsFalse(backlogged);

                lbt.SendPacket(new TransportPacket(new byte[128]));  // should send
                Assert.AreEqual(0, lbt.AvailableCapacity);
                Assert.AreEqual(384, lbt.RemainingBucketCapacity);
                Assert.IsFalse(backlogged);

                lbt.SendPacket(new TransportPacket(new byte[128]));  // should be buffered
                Assert.AreEqual(0, lbt.AvailableCapacity);
                Assert.AreEqual(256, lbt.RemainingBucketCapacity);
                Assert.IsFalse(backlogged);

                lbt.SendPacket(new TransportPacket(new byte[128]));  // should be buffered
                Assert.AreEqual(0, lbt.AvailableCapacity);
                Assert.AreEqual(128, lbt.RemainingBucketCapacity);
                Assert.IsFalse(backlogged);

                lbt.SendPacket(new TransportPacket(new byte[128]));  // should be buffered
                Assert.AreEqual(0, lbt.AvailableCapacity);
                Assert.AreEqual(0, lbt.RemainingBucketCapacity);
                Assert.IsFalse(backlogged);

                lbt.SendPacket(new TransportPacket(new byte[128]));  // should exceed bucket capacity
                Assert.IsTrue(backlogged);
                backlogged = false;

                Assert.AreEqual(128, nt.BytesSent - startBytesSent);

                // Drain the bucket
                do
                {
                    Thread.Sleep(20);
                    lbt.Update();
                    Assert.IsFalse(backlogged);
                }
                while (lbt.RemainingBucketCapacity < lbt.MaximumCapacity
                    || lbt.AvailableCapacity != 128);
            }
        }
예제 #7
0
 public void SetUp()
 {
     wrapped = new NullTransport(Reliability.Unreliable, Ordering.Unordered, 0, 1024);
     wrappedPacketsSent = 0;
     wrapped.PacketSent += delegate { wrappedPacketsSent++; };
     transport = new NetworkEmulatorTransport(wrapped);
     effects = new Bag<NetworkEmulatorTransport.PacketEffect>();
     transport.PacketDisposition += (mode, effect, packet) => effects.Add(effect);
 }
예제 #8
0
        public void TestTokenBucketTransport()
        {
            NullTransport nt = new NullTransport();
            TokenBucketTransport tbt = new TokenBucketTransport(nt, 512, 1024);
            bool backlogged = false;
            tbt.ErrorEvent += delegate(ErrorSummary es)
            {
                if (es.ErrorCode == SummaryErrorCode.TransportBacklogged)
                {
                    backlogged = true;
                }
            };
            Assert.IsTrue(tbt.AvailableCapacity == 1024, "starting capacity is the maximum capacity");
            for (int i = 0; i < 5; i++)
            {
                uint startBytesSent = nt.BytesSent;
                Assert.IsFalse(backlogged);
                Assert.IsTrue(tbt.AvailableCapacity >= tbt.MaximumCapacity);
                tbt.SendPacket(new TransportPacket(new byte[128]));
                Assert.IsFalse(backlogged);
                tbt.SendPacket(new TransportPacket(new byte[128]));
                Assert.IsFalse(backlogged);
                tbt.SendPacket(new TransportPacket(new byte[128]));
                Assert.IsFalse(backlogged);
                tbt.SendPacket(new TransportPacket(new byte[128]));
                Assert.IsFalse(backlogged);
                tbt.SendPacket(new TransportPacket(new byte[128]));
                Assert.IsFalse(backlogged);
                tbt.SendPacket(new TransportPacket(new byte[128]));
                Assert.IsFalse(backlogged);
                tbt.SendPacket(new TransportPacket(new byte[128]));
                Assert.IsFalse(backlogged);
                tbt.SendPacket(new TransportPacket(new byte[128]));
                Assert.IsFalse(backlogged);
                Assert.AreEqual(1024, nt.BytesSent - startBytesSent);

                // this packet will not be sent though
                tbt.SendPacket(new TransportPacket(new byte[128]));
                Assert.IsTrue(backlogged);
                backlogged = false;

                Assert.AreEqual(1024, nt.BytesSent - startBytesSent);

                // Build up some capacity
                while(tbt.AvailableCapacity < 128)
                {
                    Thread.Sleep(200);
                    tbt.Update();
                }
                //Console.WriteLine("Test: slept {0}ms", timer.ElapsedMilliseconds);
                // plus the outstanding packet
                while (tbt.AvailableCapacity > 128)
                {
                    Assert.IsFalse(backlogged);
                    tbt.SendPacket(new TransportPacket(new byte[128]));
                    Assert.IsFalse(backlogged);
                }

                // we should now have little capacity again, so sending another packet will backlog
                Assert.IsTrue(tbt.AvailableCapacity < 128);

                // this packet will not be sent next though
                Assert.IsFalse(backlogged);
                tbt.SendPacket(new TransportPacket(new byte[128]));
                Assert.IsTrue(backlogged);

                backlogged = false;
                // Sleep until there is plenty of capacity
                do
                {
                    Thread.Sleep(200);
                    tbt.Update();
                    Assert.IsFalse(backlogged);
                }
                while (tbt.AvailableCapacity < tbt.MaximumCapacity);
            }
        }