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);
127 virtual void DoRun (
void);
137 if (queue->
GetMode () == CoDelQueueDisc::QUEUE_DISC_MODE_BYTES)
141 else if (queue->
GetMode () == CoDelQueueDisc::QUEUE_DISC_MODE_PACKETS)
154 :
TestCase (
"Basic enqueue and dequeue operations, and attribute setting for " + mode)
164 uint32_t pktSize = 1000;
165 uint32_t modeSize = 0;
170 "Verify that we can actually set the attribute Mode");
172 "Verify that we can actually set the attribute MaxPackets");
174 "Verify that we can actually set the attribute MaxBytes");
176 "Verify that we can actually set the attribute MinBytes");
178 "Verify that we can actually set the attribute Interval");
180 "Verify that we can actually set the attribute Target");
182 if (queue->
GetMode () == CoDelQueueDisc::QUEUE_DISC_MODE_BYTES)
186 else if (queue->
GetMode () == CoDelQueueDisc::QUEUE_DISC_MODE_PACKETS)
193 p1 = Create<Packet> (pktSize);
194 p2 = Create<Packet> (pktSize);
195 p3 = Create<Packet> (pktSize);
196 p4 = Create<Packet> (pktSize);
197 p5 = Create<Packet> (pktSize);
198 p6 = Create<Packet> (pktSize);
200 QueueTestSize (queue, 0 * modeSize,
"There should be no packets in queue");
201 queue->
Enqueue (Create<CodelQueueDiscTestItem> (p1, dest, 0));
202 QueueTestSize (queue, 1 * modeSize,
"There should be one packet in queue");
203 queue->
Enqueue (Create<CodelQueueDiscTestItem> (p2, dest, 0));
204 QueueTestSize (queue, 2 * modeSize,
"There should be two packets in queue");
205 queue->
Enqueue (Create<CodelQueueDiscTestItem> (p3, dest, 0));
206 QueueTestSize (queue, 3 * modeSize,
"There should be three packets in queue");
207 queue->
Enqueue (Create<CodelQueueDiscTestItem> (p4, dest, 0));
208 QueueTestSize (queue, 4 * modeSize,
"There should be four packets in queue");
209 queue->
Enqueue (Create<CodelQueueDiscTestItem> (p5, dest, 0));
210 QueueTestSize (queue, 5 * modeSize,
"There should be five packets in queue");
211 queue->
Enqueue (Create<CodelQueueDiscTestItem> (p6, dest, 0));
212 QueueTestSize (queue, 6 * modeSize,
"There should be six packets in queue");
215 0,
"There should be no packets being dropped due to full queue");
221 QueueTestSize (queue, 5 * modeSize,
"There should be five packets in queue");
226 QueueTestSize (queue, 4 * modeSize,
"There should be four packets in queue");
227 NS_TEST_EXPECT_MSG_EQ (item->GetPacket ()->GetUid (), p2->GetUid (),
"Was this the second packet ?");
231 QueueTestSize (queue, 3 * modeSize,
"There should be three packets in queue");
236 QueueTestSize (queue, 2 * modeSize,
"There should be two packets in queue");
237 NS_TEST_EXPECT_MSG_EQ (item->GetPacket ()->GetUid (), p4->GetUid (),
"Was this the fourth packet ?");
241 QueueTestSize (queue, 1 * modeSize,
"There should be one packet in queue");
246 QueueTestSize (queue, 0 * modeSize,
"There should be zero packet in queue");
253 "There should be no packet drops according to CoDel algorithm");
271 virtual void DoRun (
void);
281 if (queue->
GetMode () == CoDelQueueDisc::QUEUE_DISC_MODE_BYTES)
285 else if (queue->
GetMode () == CoDelQueueDisc::QUEUE_DISC_MODE_PACKETS)
305 :
TestCase (
"Basic overflow behavior for " + mode)
314 uint32_t pktSize = 1000;
315 uint32_t modeSize = 0;
318 "Verify that we can actually set the attribute Mode");
322 if (queue->
GetMode () == CoDelQueueDisc::QUEUE_DISC_MODE_BYTES)
326 else if (queue->
GetMode () == CoDelQueueDisc::QUEUE_DISC_MODE_PACKETS)
332 p1 = Create<Packet> (pktSize);
333 p2 = Create<Packet> (pktSize);
334 p3 = Create<Packet> (pktSize);
337 "Verify that we can actually set the attribute MaxPackets");
339 "Verify that we can actually set the attribute MaxBytes");
341 "Verify that we can actually set the attribute MinBytes");
346 queue->
Enqueue (Create<CodelQueueDiscTestItem> (p1, dest, 0));
347 queue->
Enqueue (Create<CodelQueueDiscTestItem> (p2, dest, 0));
348 queue->
Enqueue (Create<CodelQueueDiscTestItem> (p3, dest, 0));
350 QueueTestSize (queue, 500 * modeSize,
"There should be 500 packets in queue");
352 3,
"There should be three packets being dropped due to full queue");
359 for (uint32_t i = 0; i < nPkt; i++)
361 queue->
Enqueue (Create<CodelQueueDiscTestItem> (Create<Packet> (size), dest, 0));
375 virtual void DoRun (
void);
379 :
TestCase (
"NewtonStep arithmetic unit test")
391 uint16_t recInvSqrt = 65535;
397 "ns-3 NewtonStep() fails to match Linux equivalent");
406 "ns-3 NewtonStep() fails to match Linux equivalent");
419 virtual void DoRun (
void);
430 :
TestCase (
"ControlLaw arithmetic unit test")
452 uint32_t dropNextTestVals [4] = {292299, 341128, 9804717, 55885007};
454 for (
int i = 0; i < 4; ++i)
456 uint32_t ns3Result = queue->
ControlLaw (dropNextTestVals[i]);
457 uint32_t upperBound = ns3Result + 0.02 * ns3Result;
458 uint32_t lowerBound = ns3Result - 0.02 * ns3Result;
461 "Linux result should stay within 2% of ns-3 result");
480 virtual void DoRun (
void);
490 if (queue->
GetMode () == CoDelQueueDisc::QUEUE_DISC_MODE_BYTES)
494 else if (queue->
GetMode () == CoDelQueueDisc::QUEUE_DISC_MODE_PACKETS)
526 :
TestCase (
"Basic drop operations for " + mode)
542 uint32_t pktSize = 1000;
543 uint32_t modeSize = 0;
546 "Verify that we can actually set the attribute Mode");
548 if (queue->
GetMode () == CoDelQueueDisc::QUEUE_DISC_MODE_BYTES)
552 else if (queue->
GetMode () == CoDelQueueDisc::QUEUE_DISC_MODE_PACKETS)
568 Time waitUntilSecondDequeue = waitUntilFirstDequeue + 2 * queue->
GetInterval ();
580 Simulator::Destroy ();
587 for (uint32_t i = 0; i < nPkt; i++)
589 queue->
Enqueue (Create<CodelQueueDiscTestItem> (Create<Packet> (size), dest, 0));
600 uint32_t currentDropCount = 0;
602 if (initialDropCount > 0 && currentTime.
GetMicroSeconds () >= initialDropNext)
607 if (initialQSize != 0)
610 if (initialDropCount == 0 && currentTime > queue->
GetTarget ())
612 if (currentTime < queue->GetInterval ())
616 "Sojourn time has just gone above target from below."
617 "Hence, there should be no packet drops");
618 QueueTestSize (queue, initialQSize - modeSize,
"There should be 1 packet dequeued.");
624 QueueTestSize (queue, initialQSize - 2 * modeSize,
"Sojourn time has been above target for at least interval."
625 "We enter the dropping state, perform initial packet drop, and dequeue the next."
626 "So there should be 2 more packets dequeued.");
630 else if (initialDropCount > 0)
635 QueueTestSize (queue, initialQSize - modeSize,
"We are in dropping state."
636 "Sojourn is still above target."
637 "However, it's not time for next drop."
638 "So there should be only 1 more packet dequeued");
640 NS_TEST_EXPECT_MSG_EQ (currentDropCount, 1,
"There should still be only 1 packet drop from the last dequeue");
646 "It's time for next drop."
647 "The number of packets dequeued equals to the number of times m_dropNext is updated plus initial dequeue");
CoDelQueueDiscBasicOverflow(std::string mode)
Constructor.
virtual void DoRun(void)
Implementation to actually run this TestCase.
Simulation virtual time values and global simulation resolution.
virtual void DoRun(void)
Implementation to actually run this TestCase.
Codel Queue Disc Test Item.
bool Enqueue(Ptr< QueueDiscItem > item)
Pass a packet to store to the queue discipline.
CoDelQueueDiscControlLawTest()
CoDelQueueDiscTestSuite()
Hold variables of type string.
uint32_t GetDropNext(void)
Get the time for next packet drop while in the dropping state.
CoDelQueueDiscBasicEnqueueDequeue(std::string mode)
Constructor.
virtual void DoRun(void)
Implementation to actually run this TestCase.
uint32_t GetNBytes(void) const
Get the amount of bytes stored by the queue disc.
TracedValue< uint32_t > m_count
Number of packets dropped since entering drop state.
#define REC_INV_SQRT_SHIFT_ns3
uint64_t GetUid(void) const
Returns the packet's Uid.
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.
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()
This test suite implements a Unit Test.
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
int64_t GetMicroSeconds(void) const
Get an approximation of the time stored in this instance in the indicated unit.
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.
virtual bool Mark(void)
Marks the packet as a substitute for dropping it, such as for Explicit Congestion Notification...
#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.
QueueDiscMode GetMode(void)
Get the operating mode of this queue disc.
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.
uint32_t GetQueueSize(void)
Get the current value of the queue in bytes or packets.
uint32_t GetNDroppedPackets(std::string reason) const
Get the number of packets dropped for the given reason.
Time m_interval
100 ms sliding minimum time window width
virtual void DoRun(void)
Implementation to actually run this TestCase.
Ptr< QueueDiscItem > Dequeue(void)
Request the queue discipline to extract a packet.
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 QueueTestSize(Ptr< CoDelQueueDisc > queue, uint32_t size, std::string error)
Queue test size function.
void Enqueue(Ptr< CoDelQueueDisc > queue, uint32_t size, uint32_t nPkt)
Enqueue function.
CoDelQueueDiscBasicDrop(std::string mode)
Constructor.
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.
void QueueTestSize(Ptr< CoDelQueueDisc > queue, uint32_t size, std::string error)
Queue test size function.
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)
void QueueTestSize(Ptr< CoDelQueueDisc > queue, uint32_t size, std::string error)
Queue test size function.
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.
uint32_t GetNPackets(void) const
Get the number of packets stored by the queue disc.