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);
73 virtual void AddHeader (
void);
74 virtual bool Mark(
void);
126 virtual void DoRun (
void);
133 :
TestCase (
"Basic enqueue and dequeue operations, and attribute setting")
143 uint32_t pktSize = 1000;
144 uint32_t modeSize = 0;
149 "Verify that we can actually set the attribute MinBytes");
151 "Verify that we can actually set the attribute Interval");
153 "Verify that we can actually set the attribute Target");
164 true,
"Verify that we can actually set the attribute MaxSize");
168 p1 = Create<Packet> (pktSize);
169 p2 = Create<Packet> (pktSize);
170 p3 = Create<Packet> (pktSize);
171 p4 = Create<Packet> (pktSize);
172 p5 = Create<Packet> (pktSize);
173 p6 = Create<Packet> (pktSize);
176 queue->
Enqueue (Create<CodelQueueDiscTestItem> (p1, dest));
178 queue->
Enqueue (Create<CodelQueueDiscTestItem> (p2, dest));
180 queue->
Enqueue (Create<CodelQueueDiscTestItem> (p3, dest));
182 queue->
Enqueue (Create<CodelQueueDiscTestItem> (p4, dest));
184 queue->
Enqueue (Create<CodelQueueDiscTestItem> (p5, dest));
186 queue->
Enqueue (Create<CodelQueueDiscTestItem> (p6, dest));
190 0,
"There should be no packets being dropped due to full queue");
202 NS_TEST_EXPECT_MSG_EQ (item->GetPacket ()->GetUid (), p2->GetUid (),
"Was this the second packet ?");
212 NS_TEST_EXPECT_MSG_EQ (item->GetPacket ()->GetUid (), p4->GetUid (),
"Was this the fourth packet ?");
228 "There should be no packet drops according to CoDel algorithm");
246 virtual void DoRun (
void);
260 :
TestCase (
"Basic overflow behavior")
269 uint32_t pktSize = 1000;
270 uint32_t modeSize = 0;
284 p1 = Create<Packet> (pktSize);
285 p2 = Create<Packet> (pktSize);
286 p3 = Create<Packet> (pktSize);
289 true,
"Verify that we can actually set the attribute MaxSize");
291 "Verify that we can actually set the attribute MinBytes");
296 queue->
Enqueue (Create<CodelQueueDiscTestItem> (p1, dest));
297 queue->
Enqueue (Create<CodelQueueDiscTestItem> (p2, dest));
298 queue->
Enqueue (Create<CodelQueueDiscTestItem> (p3, dest));
302 3,
"There should be three packets being dropped due to full queue");
309 for (uint32_t i = 0; i < nPkt; i++)
311 queue->
Enqueue (Create<CodelQueueDiscTestItem> (Create<Packet> (size), dest));
325 virtual void DoRun (
void);
329 :
TestCase (
"NewtonStep arithmetic unit test")
341 uint16_t recInvSqrt = 65535;
347 "ns-3 NewtonStep() fails to match Linux equivalent");
356 "ns-3 NewtonStep() fails to match Linux equivalent");
369 virtual void DoRun (
void);
380 :
TestCase (
"ControlLaw arithmetic unit test")
402 uint32_t dropNextTestVals [4] = {292299, 341128, 9804717, 55885007};
404 for (
int i = 0; i < 4; ++i)
406 uint32_t ns3Result = queue->
ControlLaw(dropNextTestVals[i]);
409 "Linux result should stay within 2% of ns-3 result");
428 virtual void DoRun (
void);
454 :
TestCase (
"Basic drop operations")
472 uint32_t pktSize = 1000;
473 uint32_t modeSize = 0;
485 true,
"Verify that we can actually set the attribute MaxSize");
498 Time waitUntilSecondDequeue = waitUntilFirstDequeue + 2 * queue->
GetInterval ();
510 Simulator::Destroy ();
517 for (uint32_t i = 0; i < nPkt; i++)
519 queue->
Enqueue (Create<CodelQueueDiscTestItem> (Create<Packet> (size), dest));
530 uint32_t currentDropCount = 0;
532 if (initialDropCount > 0 && currentTime.
GetMicroSeconds () >= initialDropNext)
537 if (initialQSize != 0)
540 if (initialDropCount == 0 && currentTime > queue->
GetTarget ())
542 if (currentTime < queue->GetInterval ())
546 "Sojourn time has just gone above target from below." 547 "Hence, there should be no packet drops");
555 "We enter the dropping state, perform initial packet drop, and dequeue the next." 556 "So there should be 2 more packets dequeued.");
560 else if (initialDropCount > 0)
566 "Sojourn is still above target." 567 "However, it's not time for next drop." 568 "So there should be only 1 more packet dequeued");
570 NS_TEST_EXPECT_MSG_EQ (currentDropCount, 1,
"There should still be only 1 packet drop from the last dequeue");
576 "It's time for next drop." 577 "The number of packets dequeued equals to the number of times m_dropNext is updated plus initial dequeue");
virtual void DoRun(void)
Implementation to actually run this TestCase.
uint64_t GetUid(void) const
Returns the packet's Uid.
Simulation virtual time values and global simulation resolution.
virtual void DoRun(void)
Implementation to actually run this TestCase.
Codel Queue Disc Test Item.
Class for representing queue sizes.
bool Enqueue(Ptr< QueueDiscItem > item)
Pass a packet to store to the queue discipline.
CoDelQueueDiscControlLawTest()
CoDelQueueDiscTestSuite()
Hold variables of type string.
uint32_t GetValue() const
Get the underlying value.
uint32_t GetDropNext(void)
Get the time for next packet drop while in the dropping state.
QueueSizeUnit
Enumeration of the operating modes of queues.
virtual void DoRun(void)
Implementation to actually run this TestCase.
TracedValue< uint32_t > m_count
Number of packets dropped since entering drop state.
QueueSize GetCurrentSize(void)
Get the current size of the queue disc in bytes, if operating in bytes mode, or packets, otherwise.
#define REC_INV_SQRT_SHIFT_ns3
Test 5: enqueue/dequeue with drops according to CoDel algorithm.
Time GetInterval(void)
Get the interval.
Test 3: NewtonStep unit test - test against explicit port of Linux implementation.
#define NS_TEST_EXPECT_MSG_EQ(actual, limit, msg)
Test that an actual and expected (limit) value are equal and report if not.
#define NS_UNUSED(x)
Mark a local variable as unused.
void Dequeue(Ptr< CoDelQueueDisc > queue, uint32_t modeSize)
Dequeue function.
bool SetAttributeFailSafe(std::string name, const AttributeValue &value)
Set a single attribute without raising errors.
QueueDiscItem is the abstract base class for items that are stored in a queue disc.
CoDelQueueDiscNewtonStepTest()
uint32_t ControlLaw(uint32_t t)
Determine the time for next drop CoDel control law is t + m_interval/sqrt(m_count).
void DropNextTracer(uint32_t oldVal, uint32_t newVal)
Drop next tracer function.
void Enqueue(Ptr< CoDelQueueDisc > queue, uint32_t size, uint32_t nPkt)
Enqueue function.
a polymophic address class
uint32_t m_dropNextCount
count the number of times m_dropNext is recalculated
static uint16_t _codel_Newton_step(uint32_t count, uint16_t rec_inv_sqrt)
void AddTestCase(TestCase *testCase, TestDuration duration=QUICK)
Add an individual child TestCase to this test suite.
Hold an unsigned integer type.
uint32_t GetNDroppedPackets(std::string reason) const
Get the number of packets dropped for the given reason.
virtual bool Mark(void)
Marks the packet as a substitute for dropping it, such as for Explicit Congestion Notification...
Use number of packets for queue size.
#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.
Callback< R > MakeCallback(R(T::*memPtr)(void), OBJ objPtr)
virtual void AddHeader(void)
Add the header to the packet.
const Stats & GetStats(void)
Retrieve all the collected statistics.
CoDelQueueDiscBasicOverflow(QueueSizeUnit mode)
Constructor.
CoDelQueueDiscBasicDrop(QueueSizeUnit mode)
Constructor.
Time m_interval
100 ms sliding minimum time window width
virtual void DoRun(void)
Implementation to actually run this TestCase.
Ptr< QueueDiscItem > Dequeue(void)
Extract from the queue disc the packet that has been dequeued by calling Peek, if any...
int64_t GetMicroSeconds(void) const
Get an approximation of the time stored in this instance in the indicated unit.
bool TraceConnectWithoutContext(std::string name, const CallbackBase &cb)
Connect a TraceSource to a Callback without a context.
Every class exported by the ns3 library is enclosed in the ns3 namespace.
uint16_t m_recInvSqrt
Reciprocal inverse square root.
uint32_t _codel_control_law(Ptr< CoDelQueueDisc > queue, uint32_t t)
Codel control law function.
Time GetTarget(void)
Get the target queue delay.
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)
void Enqueue(Ptr< CoDelQueueDisc > queue, uint32_t size, uint32_t nPkt)
Enqueue function.
CoDelQueueDiscTestSuite g_coDelQueueTestSuite
the test suite
uint32_t Time2CoDel(Time t)
Return the unsigned 32-bit integer representation of the input Time object.
CoDel Queue Disc Test Suite.
virtual ~CodelQueueDiscTestItem()
Time Now(void)
create an ns3::Time instance which contains the current simulation time.
static uint32_t _reciprocal_scale(uint32_t val, uint32_t ep_ro)
This test suite implements a Unit Test.
Use number of bytes for queue size.
Test 4: ControlLaw unit test - test against explicit port of Linux implementation.
virtual void DoRun(void)
Implementation to actually run this TestCase.
Test 1: simple enqueue/dequeue with no drops.
void Initialize(void)
Invoke DoInitialize on all Objects aggregated to this one.
Test 2: enqueue with drops due to queue overflow.
CoDelQueueDiscBasicEnqueueDequeue(QueueSizeUnit mode)
Constructor.