24 #include "ns3/codel-queue-disc.h"
25 #include "ns3/packet.h"
26 #include "ns3/uinteger.h"
27 #include "ns3/string.h"
28 #include "ns3/double.h"
30 #include "ns3/simulator.h"
35 #define REC_INV_SQRT_BITS_ns3 (8 * sizeof(uint16_t))
38 #define REC_INV_SQRT_SHIFT_ns3 (32 - REC_INV_SQRT_BITS_ns3)
43 uint32_t invsqrt2 = ((uint64_t)invsqrt * invsqrt) >> 32;
44 uint64_t val = (3LL << 32) - ((uint64_t)count * invsqrt2);
47 val = (val * invsqrt) >> (32 - 2 + 1);
53 return (uint32_t)(((uint64_t)val * ep_ro) >> 32);
74 virtual void AddHeader (
void);
75 virtual bool Mark(
void);
95 m_ecnCapablePacket (ecnCapable)
133 virtual void DoRun (
void);
140 :
TestCase (
"Basic enqueue and dequeue operations, and attribute setting")
151 uint32_t modeSize = 0;
156 "Verify that we can actually set the attribute MinBytes");
158 "Verify that we can actually set the attribute Interval");
160 "Verify that we can actually set the attribute Target");
171 true,
"Verify that we can actually set the attribute MaxSize");
183 queue->
Enqueue (Create<CodelQueueDiscTestItem> (p1, dest,
false));
185 queue->
Enqueue (Create<CodelQueueDiscTestItem> (p2, dest,
false));
187 queue->
Enqueue (Create<CodelQueueDiscTestItem> (p3, dest,
false));
189 queue->
Enqueue (Create<CodelQueueDiscTestItem> (p4, dest,
false));
191 queue->
Enqueue (Create<CodelQueueDiscTestItem> (p5, dest,
false));
193 queue->
Enqueue (Create<CodelQueueDiscTestItem> (p6, dest,
false));
197 0,
"There should be no packets being dropped due to full queue");
235 "There should be no packet drops according to CoDel algorithm");
253 virtual void DoRun (
void);
267 :
TestCase (
"Basic overflow behavior")
277 uint32_t modeSize = 0;
296 true,
"Verify that we can actually set the attribute MaxSize");
298 "Verify that we can actually set the attribute MinBytes");
303 queue->
Enqueue (Create<CodelQueueDiscTestItem> (p1, dest,
false));
304 queue->
Enqueue (Create<CodelQueueDiscTestItem> (p2, dest,
false));
305 queue->
Enqueue (Create<CodelQueueDiscTestItem> (p3, dest,
false));
309 3,
"There should be three packets being dropped due to full queue");
316 for (uint32_t i = 0; i < nPkt; i++)
318 queue->
Enqueue (Create<CodelQueueDiscTestItem> (Create<Packet> (size), dest,
false));
332 virtual void DoRun (
void);
336 :
TestCase (
"NewtonStep arithmetic unit test")
348 for (uint16_t recInvSqrt = 0xff; recInvSqrt > 0; recInvSqrt /= 2)
350 for (uint32_t count = 1; count < 0xff; count *= 2)
352 result = queue->
NewtonStep (recInvSqrt, count);
355 "ns-3 NewtonStep() fails to match Linux equivalent");
370 virtual void DoRun (
void);
381 :
TestCase (
"ControlLaw arithmetic unit test")
402 uint32_t codelTimeVal;
405 for (uint16_t recInvSqrt = 0xff; recInvSqrt > 0; recInvSqrt /= 2)
408 uint32_t ns3Result = queue->
ControlLaw (codelTimeVal, interval, recInvSqrt);
410 NS_TEST_EXPECT_MSG_EQ (ns3Result, linuxResult,
"Linux result for ControlLaw should equal ns-3 result");
430 virtual void DoRun (
void);
456 :
TestCase (
"Basic drop operations")
475 uint32_t modeSize = 0;
487 true,
"Verify that we can actually set the attribute MaxSize");
500 Time waitUntilSecondDequeue = waitUntilFirstDequeue + 2 * queue->
GetInterval ();
512 Simulator::Destroy ();
519 for (uint32_t i = 0; i < nPkt; i++)
521 queue->
Enqueue (Create<CodelQueueDiscTestItem> (Create<Packet> (size), dest,
false));
532 uint32_t currentDropCount = 0;
534 if (initialDropCount > 0 && currentTime.
GetMicroSeconds () >= initialDropNext)
539 if (initialQSize != 0)
542 if (initialDropCount == 0 && currentTime > queue->
GetTarget ())
544 if (currentTime < queue->GetInterval ())
548 "Sojourn time has just gone above target from below."
549 "Hence, there should be no packet drops");
557 "We enter the dropping state, perform initial packet drop, and dequeue the next."
558 "So there should be 2 more packets dequeued.");
562 else if (initialDropCount > 0)
568 "Sojourn is still above target."
569 "However, it's not time for next drop."
570 "So there should be only 1 more packet dequeued");
572 NS_TEST_EXPECT_MSG_EQ (currentDropCount, 1,
"There should still be only 1 packet drop from the last dequeue");
578 "It's time for next drop."
579 "The number of packets dequeued equals to the number of times m_dropNext is updated plus initial dequeue");
601 virtual void DoRun (
void);
631 :
TestCase (
"Basic mark operations")
657 uint32_t modeSize = 0;
671 true,
"Verify that we can actually set the attribute MaxSize");
673 true,
"Verify that we can actually set the attribute UseEcn");
687 Time waitUntilSecondDequeue = waitUntilFirstDequeue + 2 * queue->
GetInterval ();
691 Simulator::Destroy ();
694 queue = CreateObject<CoDelQueueDisc> ();
696 true,
"Verify that we can actually set the attribute MaxSize");
698 true,
"Verify that we can actually set the attribute UseEcn");
722 Simulator::Destroy ();
725 queue = CreateObject<CoDelQueueDisc> ();
727 true,
"Verify that we can actually set the attribute MaxSize");
729 true,
"Verify that we can actually set the attribute UseEcn");
731 true,
"Verify that we can actually set the attribute CeThreshold");
757 Simulator::Destroy ();
760 queue = CreateObject<CoDelQueueDisc> ();
762 true,
"Verify that we can actually set the attribute MaxSize");
764 true,
"Verify that we can actually set the attribute UseEcn");
766 true,
"Verify that we can actually set the attribute CeThreshold");
788 Simulator::Destroy ();
795 for (uint32_t i = 0; i < nPkt; i++)
797 queue->
Enqueue (Create<CodelQueueDiscTestItem> (Create<Packet> (size), dest, ecnCapable));
809 uint32_t currentDropCount = 0;
810 uint32_t currentTargetMarkCount = 0;
811 uint32_t currentCeThreshMarkCount = 0;
813 if (initialTargetMarkCount > 0 && currentTime.
GetMicroSeconds () >= initialDropNext && testCase == 3)
818 if (initialQSize != 0)
824 if (currentDropCount == 1)
829 else if (testCase == 2)
831 if (initialTargetMarkCount == 0 && currentTime > queue->
GetTarget ())
833 if (currentTime < queue->GetInterval ())
841 "Sojourn time has just gone above target from below."
842 "Hence, there should be no target exceeded marked packets");
844 "Hence, there should not be any CE threshold exceeded marked packet");
853 "We enter the dropping state and perform initial packet marking"
854 "So there should be only 1 more packet dequeued.");
856 NS_TEST_EXPECT_MSG_EQ (currentTargetMarkCount, 1,
"There should be 1 target exceeded marked packet");
857 NS_TEST_ASSERT_MSG_EQ (currentCeThreshMarkCount, 0,
"There should not be any CE threshold exceeded marked packet");
860 else if (initialTargetMarkCount > 0)
868 "Sojourn is still above target."
869 "However, it's not time for next target exceeded mark."
870 "So there should be only 1 more packet dequeued");
872 NS_TEST_EXPECT_MSG_EQ (currentTargetMarkCount, 1,
"There should still be only 1 target exceeded marked packet from the last dequeue");
873 NS_TEST_ASSERT_MSG_EQ (currentCeThreshMarkCount, 0,
"There should not be any CE threshold exceeded marked packet");
881 "It's time for packet to be marked"
882 "So there should be only 1 more packet dequeued");
886 "to number of packets in the queue before first mark as the behavior untill packet N should be the same.");
887 NS_TEST_ASSERT_MSG_EQ (currentCeThreshMarkCount, 0,
"There should not be any CE threshold exceeded marked packet");
891 else if (testCase == 3)
893 if (initialTargetMarkCount == 0 && currentTime > queue->
GetTarget ())
895 if (currentTime < queue->GetInterval ())
903 "Sojourn time has just gone above target from below."
904 "Hence, there should be no target exceeded marked packets");
906 "Hence, there should be 1 CE threshold exceeded marked packet");
914 "We enter the dropping state and perform initial packet marking"
915 "So there should be only 1 more packet dequeued.");
917 NS_TEST_EXPECT_MSG_EQ (currentTargetMarkCount, 1,
"There should be 1 target exceeded marked packet");
918 NS_TEST_EXPECT_MSG_EQ (currentCeThreshMarkCount, 1,
"There should be 1 CE threshold exceeded marked packets");
921 else if (initialTargetMarkCount > 0)
929 "Sojourn is still above target."
930 "However, it's not time for next target exceeded mark."
931 "So there should be only 1 more packet dequeued");
933 NS_TEST_EXPECT_MSG_EQ (currentTargetMarkCount, 1,
"There should still be only 1 target exceeded marked packet from the last dequeue");
934 NS_TEST_EXPECT_MSG_EQ (currentCeThreshMarkCount, 2,
"There should be 2 CE threshold exceeded marked packets");
942 "It's time for packet to be dropped as packets are not ecnCapable"
943 "The number of packets dequeued equals to the number of times m_dropNext is updated plus initial dequeue");
945 NS_TEST_EXPECT_MSG_EQ (currentTargetMarkCount, 1,
"There should still be only 1 target exceeded marked packet");
946 NS_TEST_EXPECT_MSG_EQ (currentCeThreshMarkCount, 2,
"There should still be 2 CE threshold exceeded marked packet as packets are not ecnCapable");
950 else if (testCase == 4)
952 if (currentTime < queue->GetTarget ())
954 if (initialCeThreshMarkCount == 0 && currentTime <
MilliSeconds (2))
961 "Hence, there should not be any CE threshold exceeded marked packet");
970 "There should be 1 CE threshold exceeded marked packet");
973 else if (initialCeThreshMarkCount > 0 && currentTime < queue->GetInterval ())
975 if (initialCeThreshMarkCount < 2)
981 NS_TEST_EXPECT_MSG_EQ (currentCeThreshMarkCount, 2,
"There should be 2 CE threshold exceeded marked packets");
989 NS_TEST_EXPECT_MSG_EQ (currentCeThreshMarkCount, 3,
"There should be 3 CE threshold exceeded marked packet");