23 #include "ns3/codel-queue.h" 
   24 #include "ns3/uinteger.h" 
   25 #include "ns3/string.h" 
   26 #include "ns3/double.h" 
   28 #include "ns3/simulator.h" 
   29 #include "ns3/network-module.h" 
   30 #include "ns3/core-module.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);
 
   63   virtual void DoRun (
void);
 
   84   : 
TestCase (
"Basic enqueue and dequeue operations, and attribute setting for " + mode)
 
   94   uint32_t pktSize = 1000;
 
   95   uint32_t modeSize = 0;
 
   98                          "Verify that we can actually set the attribute Mode");
 
  100                          "Verify that we can actually set the attribute MaxPackets");
 
  102                          "Verify that we can actually set the attribute MaxBytes");
 
  104                          "Verify that we can actually set the attribute MinBytes");
 
  106                          "Verify that we can actually set the attribute Interval");
 
  108                          "Verify that we can actually set the attribute Target");
 
  110   if (queue->
GetMode () == CoDelQueue::QUEUE_MODE_BYTES)
 
  114   else if (queue->
GetMode () == CoDelQueue::QUEUE_MODE_PACKETS)
 
  120   p1 = Create<Packet> (pktSize);
 
  121   p2 = Create<Packet> (pktSize);
 
  122   p3 = Create<Packet> (pktSize);
 
  123   p4 = Create<Packet> (pktSize);
 
  124   p5 = Create<Packet> (pktSize);
 
  125   p6 = Create<Packet> (pktSize);
 
  127   QueueTestSize (queue, 0 * modeSize, 
"There should be no packets in queue");
 
  129   QueueTestSize (queue, 1 * modeSize, 
"There should be one packet in queue");
 
  131   QueueTestSize (queue, 2 * modeSize, 
"There should be two packets in queue");
 
  133   QueueTestSize (queue, 3 * modeSize, 
"There should be three packets in queue");
 
  135   QueueTestSize (queue, 4 * modeSize, 
"There should be four packets in queue");
 
  137   QueueTestSize (queue, 5 * modeSize, 
"There should be five packets in queue");
 
  139   QueueTestSize (queue, 6 * modeSize, 
"There should be six packets in queue");
 
  147   QueueTestSize (queue, 5 * modeSize, 
"There should be five packets in queue");
 
  152   QueueTestSize (queue, 4 * modeSize, 
"There should be four packets in queue");
 
  157   QueueTestSize (queue, 3 * modeSize, 
"There should be three packets in queue");
 
  162   QueueTestSize (queue, 2 * modeSize, 
"There should be two packets in queue");
 
  167   QueueTestSize (queue, 1 * modeSize, 
"There should be one packet in queue");
 
  172   QueueTestSize (queue, 0 * modeSize, 
"There should be zero packet in queue");
 
  186   virtual void DoRun (
void);
 
  190     if (queue->
GetMode () == CoDelQueue::QUEUE_MODE_BYTES)
 
  194     else if (queue->
GetMode () == CoDelQueue::QUEUE_MODE_PACKETS)
 
  208   : 
TestCase (
"Basic overflow behavior for " + mode)
 
  217   uint32_t pktSize = 1000;
 
  218   uint32_t modeSize = 0;
 
  221                          "Verify that we can actually set the attribute Mode");
 
  223   if (queue->
GetMode () == CoDelQueue::QUEUE_MODE_BYTES)
 
  227   else if (queue->
GetMode () == CoDelQueue::QUEUE_MODE_PACKETS)
 
  233   p1 = Create<Packet> (pktSize);
 
  234   p2 = Create<Packet> (pktSize);
 
  235   p3 = Create<Packet> (pktSize);
 
  238                          "Verify that we can actually set the attribute MaxPackets");
 
  240                          "Verify that we can actually set the attribute MaxBytes");
 
  242                          "Verify that we can actually set the attribute MinBytes");
 
  249   QueueTestSize (queue, 500 * modeSize, 
"There should be 500 packets in queue");
 
  256   for (uint32_t i = 0; i < nPkt; i++)
 
  258       queue->
Enqueue (Create<Packet> (size));
 
  268   virtual void DoRun (
void);
 
  272   : 
TestCase (
"NewtonStep arithmetic unit test")
 
  284   uint16_t recInvSqrt = 65535;
 
  290                          "ns-3 NewtonStep() fails to match Linux equivalent");
 
  299                          "ns-3 NewtonStep() fails to match Linux equivalent");
 
  308   virtual void DoRun (
void);
 
  313   : 
TestCase (
"ControlLaw arithmetic unit test")
 
  335   uint32_t dropNextTestVals [4] = {292299, 341128, 9804717, 55885007};
 
  337   for (
int i = 0; i < 4; ++i)
 
  339       uint32_t ns3Result = queue->
ControlLaw (dropNextTestVals[i]);
 
  340       uint32_t upperBound = ns3Result + 0.02 * ns3Result;
 
  341       uint32_t lowerBound = ns3Result - 0.02 * ns3Result;
 
  344                              "Linux result should stay within 2% of ns-3 result");
 
  353   virtual void DoRun (
void);
 
  357     if (queue->
GetMode () == CoDelQueue::QUEUE_MODE_BYTES)
 
  361     else if (queue->
GetMode () == CoDelQueue::QUEUE_MODE_PACKETS)
 
  378   : 
TestCase (
"Basic drop operations for " + mode)
 
  394   uint32_t pktSize = 1000;
 
  395   uint32_t modeSize = 0;
 
  398                          "Verify that we can actually set the attribute Mode");
 
  400   if (queue->
GetMode () == CoDelQueue::QUEUE_MODE_BYTES)
 
  404   else if (queue->
GetMode () == CoDelQueue::QUEUE_MODE_PACKETS)
 
  418   Time waitUntilSecondDequeue = waitUntilFirstDequeue + 2 * queue->
GetInterval ();
 
  430   Simulator::Destroy ();
 
  436   for (uint32_t i = 0; i < nPkt; i++)
 
  438       queue->
Enqueue (Create<Packet> (size));
 
  449   uint32_t currentDropCount = 0;
 
  451   if (initialDropCount > 0 && currentTime.
GetMicroSeconds () >= initialDropNext)
 
  456   if (initialQSize != 0)
 
  459       if (initialDropCount == 0 && currentTime > queue->
GetTarget ())
 
  461           if (currentTime < queue->GetInterval ())
 
  465                                      "Sojourn time has just gone above target from below." 
  466                                      "Hence, there should be no packet drops");
 
  467               QueueTestSize (queue, initialQSize - modeSize, 
"There should be 1 packet dequeued.");
 
  473               QueueTestSize (queue, initialQSize - 2 * modeSize, 
"Sojourn time has been above target for at least interval." 
  474                                      "We enter the dropping state, perform initial packet drop, and dequeue the next." 
  475                                      "So there should be 2 more packets dequeued.");
 
  479       else if (initialDropCount > 0)
 
  484               QueueTestSize (queue, initialQSize - modeSize, 
"We are in dropping state." 
  485                                      "Sojourn is still above target." 
  486                                      "However, it's not time for next drop." 
  487                                      "So there should be only 1 more packet dequeued");
 
  489               NS_TEST_EXPECT_MSG_EQ (currentDropCount, 1, 
"There should still be only 1 packet drop from the last dequeue");
 
  495                                      "It's time for next drop." 
  496                                      "The number of packets dequeued equals to the number of times m_dropNext is updated plus initial dequeue");
 
uint32_t GetDropOverLimit(void)
Get the number of packets dropped when packets arrive at a full queue and cannot be enqueued...
 
Simulation virtual time values and global simulation resolution. 
 
Smart pointer class similar to boost::intrusive_ptr. 
 
bool Enqueue(Ptr< Packet > p)
Place a packet into the rear of the Queue. 
 
Hold variables of type string. 
 
Use number of bytes for maximum queue size. 
 
CoDelQueueTestSuite g_coDelQueueTestSuite
 
uint64_t GetUid(void) const 
Returns the packet's Uid. 
 
void QueueTestSize(Ptr< CoDelQueue > queue, uint32_t size, std::string error)
 
#define NS_TEST_EXPECT_MSG_EQ(actual, limit, msg)
Test that an actual and expected (limit) value are equal and report if not. 
 
bool SetAttributeFailSafe(std::string name, const AttributeValue &value)
Set a single attribute without raising errors. 
 
uint32_t GetDropCount(void)
Get the number of packets dropped according to CoDel algorithm. 
 
virtual void DoRun(void)
Implementation to actually run this TestCase. 
 
uint32_t ControlLaw(uint32_t t)
Determine the time for next drop CoDel control law is t + m_interval/sqrt(m_count). 
 
This test suite implements a Unit Test. 
 
CoDelQueueNewtonStepTest()
 
virtual void DoRun(void)
Implementation to actually run this TestCase. 
 
uint16_t m_recInvSqrt
Reciprocal inverse square root. 
 
Time m_interval
100 ms sliding minimum time window width 
 
Time GetTarget(void)
Get the target queue delay. 
 
virtual void DoRun(void)
Implementation to actually run this TestCase. 
 
CoDelQueue::QueueMode GetMode(void)
Get the encapsulation mode of this device. 
 
int64_t GetMicroSeconds(void) const 
Get an approximation of the time stored in this instance in the indicated unit. 
 
void AddTestCase(TestCase *testCase, enum TestDuration duration)
Add an individual child TestCase to this test suite. 
 
uint32_t GetQueueSize(void)
Get the current value of the queue in bytes or packets. 
 
static uint32_t _reciprocal_scale(uint32_t val, uint32_t ep_ro)
 
Hold an unsigned integer type. 
 
#define NS_TEST_ASSERT_MSG_EQ(actual, limit, msg)
Test that an actual and expected (limit) value are equal and report and abort if not. 
 
Ptr< Packet > Dequeue(void)
Remove a packet from the front of the Queue. 
 
Callback< R > MakeCallback(R(T::*memPtr)(void), OBJ objPtr)
 
uint32_t GetNPackets(void) const 
 
#define REC_INV_SQRT_SHIFT_ns3
 
CoDelQueueBasicDrop(std::string mode)
 
bool TraceConnectWithoutContext(std::string name, const CallbackBase &cb)
Connect a TraceSource to a Callback without a context. 
 
void QueueTestSize(Ptr< CoDelQueue > queue, uint32_t size, std::string error)
 
virtual void DoRun(void)
Implementation to actually run this TestCase. 
 
Every class exported by the ns3 library is enclosed in the ns3 namespace. 
 
CoDelQueueBasicEnqueueDequeue(std::string mode)
 
void Dequeue(Ptr< CoDelQueue > queue, uint32_t modeSize)
 
void DropNextTracer(uint32_t oldVal, uint32_t newVal)
 
uint32_t GetNBytes(void) const 
 
uint32_t GetDropNext(void)
Get the time for next packet drop while in the dropping state. 
 
void QueueTestSize(Ptr< CoDelQueue > queue, uint32_t size, std::string error)
 
void NewtonStep(void)
Calculate the reciprocal square root of m_count by using Newton's method http://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Iterative_methods_for_reciprocal_square_roots m_recInvSqrt (new) = (m_recInvSqrt (old) / 2) * (3 - m_count * m_recInvSqrt^2) 
 
CoDelQueueBasicOverflow(std::string mode)
 
virtual void DoRun(void)
Implementation to actually run this TestCase. 
 
uint32_t Time2CoDel(Time t)
returned unsigned 32-bit integer representation of the input Time object units are microseconds ...
 
void Enqueue(Ptr< CoDelQueue > queue, uint32_t size, uint32_t nPkt)
 
void Enqueue(Ptr< CoDelQueue > queue, uint32_t size, uint32_t nPkt)
 
Time GetInterval(void)
Get the interval. 
 
Time Now(void)
create an ns3::Time instance which contains the current simulation time. 
 
static uint16_t _codel_Newton_step(uint32_t count, uint16_t rec_inv_sqrt)
 
Use number of packets for maximum queue size. 
 
CoDelQueueControlLawTest()
 
TracedValue< uint32_t > m_count
Number of packets dropped since entering drop state. 
 
uint32_t _codel_control_law(Ptr< CoDelQueue > queue, uint32_t t)