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)