24 #include "ns3/codel-queue-disc.h"
25 #include "ns3/uinteger.h"
26 #include "ns3/string.h"
27 #include "ns3/double.h"
29 #include "ns3/simulator.h"
34 #define REC_INV_SQRT_BITS_ns3 (8 * sizeof(uint16_t))
37 #define REC_INV_SQRT_SHIFT_ns3 (32 - REC_INV_SQRT_BITS_ns3)
42 uint32_t invsqrt2 = ((uint64_t)invsqrt * invsqrt) >> 32;
43 uint64_t val = (3LL << 32) - ((uint64_t)count * invsqrt2);
46 val = (val * invsqrt) >> (32 - 2 + 1);
52 return (uint32_t)(((uint64_t)val * ep_ro) >> 32);
61 virtual void AddHeader (
void);
88 virtual void DoRun (
void);
92 if (queue->
GetMode () == Queue::QUEUE_MODE_BYTES)
96 else if (queue->
GetMode () == Queue::QUEUE_MODE_PACKETS)
109 :
TestCase (
"Basic enqueue and dequeue operations, and attribute setting for " + mode)
119 uint32_t pktSize = 1000;
120 uint32_t modeSize = 0;
125 "Verify that we can actually set the attribute Mode");
127 "Verify that we can actually set the attribute MaxPackets");
129 "Verify that we can actually set the attribute MaxBytes");
131 "Verify that we can actually set the attribute MinBytes");
133 "Verify that we can actually set the attribute Interval");
135 "Verify that we can actually set the attribute Target");
137 if (queue->
GetMode () == Queue::QUEUE_MODE_BYTES)
141 else if (queue->
GetMode () == Queue::QUEUE_MODE_PACKETS)
148 p1 = Create<Packet> (pktSize);
149 p2 = Create<Packet> (pktSize);
150 p3 = Create<Packet> (pktSize);
151 p4 = Create<Packet> (pktSize);
152 p5 = Create<Packet> (pktSize);
153 p6 = Create<Packet> (pktSize);
155 QueueTestSize (queue, 0 * modeSize,
"There should be no packets in queue");
156 queue->
Enqueue (Create<CodelQueueDiscTestItem> (p1, dest, 0));
157 QueueTestSize (queue, 1 * modeSize,
"There should be one packet in queue");
158 queue->
Enqueue (Create<CodelQueueDiscTestItem> (p2, dest, 0));
159 QueueTestSize (queue, 2 * modeSize,
"There should be two packets in queue");
160 queue->
Enqueue (Create<CodelQueueDiscTestItem> (p3, dest, 0));
161 QueueTestSize (queue, 3 * modeSize,
"There should be three packets in queue");
162 queue->
Enqueue (Create<CodelQueueDiscTestItem> (p4, dest, 0));
163 QueueTestSize (queue, 4 * modeSize,
"There should be four packets in queue");
164 queue->
Enqueue (Create<CodelQueueDiscTestItem> (p5, dest, 0));
165 QueueTestSize (queue, 5 * modeSize,
"There should be five packets in queue");
166 queue->
Enqueue (Create<CodelQueueDiscTestItem> (p6, dest, 0));
167 QueueTestSize (queue, 6 * modeSize,
"There should be six packets in queue");
175 QueueTestSize (queue, 5 * modeSize,
"There should be five packets in queue");
180 QueueTestSize (queue, 4 * modeSize,
"There should be four packets in queue");
181 NS_TEST_EXPECT_MSG_EQ (item->GetPacket ()->GetUid (), p2->GetUid (),
"Was this the second packet ?");
185 QueueTestSize (queue, 3 * modeSize,
"There should be three packets in queue");
190 QueueTestSize (queue, 2 * modeSize,
"There should be two packets in queue");
191 NS_TEST_EXPECT_MSG_EQ (item->GetPacket ()->GetUid (), p4->GetUid (),
"Was this the fourth packet ?");
195 QueueTestSize (queue, 1 * modeSize,
"There should be one packet in queue");
200 QueueTestSize (queue, 0 * modeSize,
"There should be zero packet in queue");
214 virtual void DoRun (
void);
218 if (queue->
GetMode () == Queue::QUEUE_MODE_BYTES)
222 else if (queue->
GetMode () == Queue::QUEUE_MODE_PACKETS)
236 :
TestCase (
"Basic overflow behavior for " + mode)
245 uint32_t pktSize = 1000;
246 uint32_t modeSize = 0;
249 "Verify that we can actually set the attribute Mode");
253 if (queue->
GetMode () == Queue::QUEUE_MODE_BYTES)
257 else if (queue->
GetMode () == Queue::QUEUE_MODE_PACKETS)
263 p1 = Create<Packet> (pktSize);
264 p2 = Create<Packet> (pktSize);
265 p3 = Create<Packet> (pktSize);
268 "Verify that we can actually set the attribute MaxPackets");
270 "Verify that we can actually set the attribute MaxBytes");
272 "Verify that we can actually set the attribute MinBytes");
277 queue->
Enqueue (Create<CodelQueueDiscTestItem> (p1, dest, 0));
278 queue->
Enqueue (Create<CodelQueueDiscTestItem> (p2, dest, 0));
279 queue->
Enqueue (Create<CodelQueueDiscTestItem> (p3, dest, 0));
281 QueueTestSize (queue, 500 * modeSize,
"There should be 500 packets in queue");
289 for (uint32_t i = 0; i < nPkt; i++)
291 queue->
Enqueue (Create<CodelQueueDiscTestItem> (Create<Packet> (size), dest, 0));
301 virtual void DoRun (
void);
305 :
TestCase (
"NewtonStep arithmetic unit test")
317 uint16_t recInvSqrt = 65535;
323 "ns-3 NewtonStep() fails to match Linux equivalent");
332 "ns-3 NewtonStep() fails to match Linux equivalent");
341 virtual void DoRun (
void);
346 :
TestCase (
"ControlLaw arithmetic unit test")
368 uint32_t dropNextTestVals [4] = {292299, 341128, 9804717, 55885007};
370 for (
int i = 0; i < 4; ++i)
372 uint32_t ns3Result = queue->
ControlLaw (dropNextTestVals[i]);
373 uint32_t upperBound = ns3Result + 0.02 * ns3Result;
374 uint32_t lowerBound = ns3Result - 0.02 * ns3Result;
377 "Linux result should stay within 2% of ns-3 result");
386 virtual void DoRun (
void);
390 if (queue->
GetMode () == Queue::QUEUE_MODE_BYTES)
394 else if (queue->
GetMode () == Queue::QUEUE_MODE_PACKETS)
411 :
TestCase (
"Basic drop operations for " + mode)
427 uint32_t pktSize = 1000;
428 uint32_t modeSize = 0;
431 "Verify that we can actually set the attribute Mode");
433 if (queue->
GetMode () == Queue::QUEUE_MODE_BYTES)
437 else if (queue->
GetMode () == Queue::QUEUE_MODE_PACKETS)
453 Time waitUntilSecondDequeue = waitUntilFirstDequeue + 2 * queue->
GetInterval ();
465 Simulator::Destroy ();
472 for (uint32_t i = 0; i < nPkt; i++)
474 queue->
Enqueue (Create<CodelQueueDiscTestItem> (Create<Packet> (size), dest, 0));
485 uint32_t currentDropCount = 0;
487 if (initialDropCount > 0 && currentTime.
GetMicroSeconds () >= initialDropNext)
492 if (initialQSize != 0)
495 if (initialDropCount == 0 && currentTime > queue->
GetTarget ())
497 if (currentTime < queue->GetInterval ())
501 "Sojourn time has just gone above target from below."
502 "Hence, there should be no packet drops");
503 QueueTestSize (queue, initialQSize - modeSize,
"There should be 1 packet dequeued.");
509 QueueTestSize (queue, initialQSize - 2 * modeSize,
"Sojourn time has been above target for at least interval."
510 "We enter the dropping state, perform initial packet drop, and dequeue the next."
511 "So there should be 2 more packets dequeued.");
515 else if (initialDropCount > 0)
520 QueueTestSize (queue, initialQSize - modeSize,
"We are in dropping state."
521 "Sojourn is still above target."
522 "However, it's not time for next drop."
523 "So there should be only 1 more packet dequeued");
525 NS_TEST_EXPECT_MSG_EQ (currentDropCount, 1,
"There should still be only 1 packet drop from the last dequeue");
531 "It's time for next drop."
532 "The number of packets dequeued equals to the number of times m_dropNext is updated plus initial dequeue");
CoDelQueueDiscBasicOverflow(std::string mode)
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.
bool Enqueue(Ptr< QueueDiscItem > item)
Pass a packet to store to the queue discipline.
uint32_t GetDropOverLimit(void)
Get the number of packets dropped when packets arrive at a full queue and cannot be enqueued...
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)
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.
Time GetInterval(void)
Get the interval.
#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)
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)
void Enqueue(Ptr< CoDelQueueDisc > queue, uint32_t size, uint32_t nPkt)
a polymophic address class
Queue::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.
static uint16_t _codel_Newton_step(uint32_t count, uint16_t rec_inv_sqrt)
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.
CoDelQueueDiscTestSuite g_coDelQueueTestSuite
Callback< R > MakeCallback(R(T::*memPtr)(void), OBJ objPtr)
virtual void AddHeader(void)
Add the header to the packet.
uint32_t GetQueueSize(void)
Get the current value of the queue in bytes or packets.
uint32_t GetDropCount(void)
Get the number of packets dropped according to CoDel algorithm.
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.
uint16_t m_recInvSqrt
Reciprocal inverse square root.
uint32_t _codel_control_law(Ptr< CoDelQueueDisc > queue, uint32_t t)
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)
void Enqueue(Ptr< CoDelQueueDisc > queue, uint32_t size, uint32_t nPkt)
CoDelQueueDiscBasicDrop(std::string mode)
uint32_t Time2CoDel(Time t)
returned unsigned 32-bit integer representation of the input Time object units are microseconds ...
void QueueTestSize(Ptr< CoDelQueueDisc > queue, uint32_t size, std::string error)
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.
void QueueTestSize(Ptr< CoDelQueueDisc > queue, uint32_t size, std::string error)
virtual void DoRun(void)
Implementation to actually run this TestCase.
void Initialize(void)
Invoke DoInitialize on all Objects aggregated to this one.
uint32_t GetNPackets(void) const
Get the number of packets stored by the queue disc.