A Discrete-Event Network Simulator
API
codel-queue-disc-test-suite.cc
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2014 ResiliNets, ITTC, University of Kansas
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License version 2 as
7  * published by the Free Software Foundation;
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17  *
18  * Author: Truc Anh N Nguyen <trucanh524@gmail.com>
19  * Modified by: Pasquale Imputato <p.imputato@gmail.com>
20  *
21  */
22 
23 #include "ns3/test.h"
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"
29 #include "ns3/log.h"
30 #include "ns3/simulator.h"
31 
32 using namespace ns3;
33 
34 // The following code borrowed from Linux codel.h, for unit testing
35 #define REC_INV_SQRT_BITS_ns3 (8 * sizeof(uint16_t))
36 /* or sizeof_in_bits(rec_inv_sqrt) */
37 /* needed shift to get a Q0.32 number from rec_inv_sqrt */
38 #define REC_INV_SQRT_SHIFT_ns3 (32 - REC_INV_SQRT_BITS_ns3)
39 
40 static uint16_t _codel_Newton_step (uint32_t count, uint16_t rec_inv_sqrt)
41 {
42  uint32_t invsqrt = ((uint32_t)rec_inv_sqrt) << REC_INV_SQRT_SHIFT_ns3;
43  uint32_t invsqrt2 = ((uint64_t)invsqrt * invsqrt) >> 32;
44  uint64_t val = (3LL << 32) - ((uint64_t)count * invsqrt2);
45 
46  val >>= 2; /* avoid overflow in following multiply */
47  val = (val * invsqrt) >> (32 - 2 + 1);
48  return (val >> REC_INV_SQRT_SHIFT_ns3);
49 }
50 
51 static uint32_t _reciprocal_scale (uint32_t val, uint32_t ep_ro)
52 {
53  return (uint32_t)(((uint64_t)val * ep_ro) >> 32);
54 }
55 // End Linux borrow
56 
64 public:
72  CodelQueueDiscTestItem (Ptr<Packet> p, const Address & addr, uint16_t protocol);
73  virtual ~CodelQueueDiscTestItem ();
74  virtual void AddHeader (void);
75  virtual bool Mark(void);
76 
77 private:
89  CodelQueueDiscTestItem &operator = (const CodelQueueDiscTestItem &);
90 };
91 
93  : QueueDiscItem (p, addr, protocol)
94 {
95 }
96 
98 {
99 }
100 
101 void
103 {
104 }
105 
106 bool
108 {
109  return false;
110 }
111 
119 {
120 public:
126  CoDelQueueDiscBasicEnqueueDequeue (std::string mode);
127  virtual void DoRun (void);
128 
135  void QueueTestSize (Ptr<CoDelQueueDisc> queue, uint32_t size, std::string error)
136  {
137  if (queue->GetMode () == CoDelQueueDisc::QUEUE_DISC_MODE_BYTES)
138  {
139  NS_TEST_EXPECT_MSG_EQ (queue->GetNBytes (), size, error);
140  }
141  else if (queue->GetMode () == CoDelQueueDisc::QUEUE_DISC_MODE_PACKETS)
142  {
143  NS_TEST_EXPECT_MSG_EQ (queue->GetNPackets (), size, error);
144  }
145 
146  NS_TEST_EXPECT_MSG_EQ (queue->GetQueueSize (), size, error);
147  }
148 
149 private:
151 };
152 
154  : TestCase ("Basic enqueue and dequeue operations, and attribute setting for " + mode)
155 {
156  m_mode = StringValue (mode);
157 }
158 
159 void
161 {
162  Ptr<CoDelQueueDisc> queue = CreateObject<CoDelQueueDisc> ();
163 
164  uint32_t pktSize = 1000;
165  uint32_t modeSize = 0;
166 
167  Address dest;
168 
169  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("Mode", m_mode), true,
170  "Verify that we can actually set the attribute Mode");
171  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("MaxPackets", UintegerValue (1500)), true,
172  "Verify that we can actually set the attribute MaxPackets");
173  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("MaxBytes", UintegerValue (pktSize * 1500)), true,
174  "Verify that we can actually set the attribute MaxBytes");
175  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("MinBytes", UintegerValue (pktSize)), true,
176  "Verify that we can actually set the attribute MinBytes");
177  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("Interval", StringValue ("50ms")), true,
178  "Verify that we can actually set the attribute Interval");
179  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("Target", StringValue ("4ms")), true,
180  "Verify that we can actually set the attribute Target");
181 
182  if (queue->GetMode () == CoDelQueueDisc::QUEUE_DISC_MODE_BYTES)
183  {
184  modeSize = pktSize;
185  }
186  else if (queue->GetMode () == CoDelQueueDisc::QUEUE_DISC_MODE_PACKETS)
187  {
188  modeSize = 1;
189  }
190  queue->Initialize ();
191 
192  Ptr<Packet> p1, p2, p3, p4, p5, p6;
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);
199 
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");
213 
214  NS_TEST_EXPECT_MSG_EQ (queue->GetStats ().GetNDroppedPackets (CoDelQueueDisc::OVERLIMIT_DROP),
215  0, "There should be no packets being dropped due to full queue");
216 
217  Ptr<QueueDiscItem> item;
218 
219  item = queue->Dequeue ();
220  NS_TEST_EXPECT_MSG_EQ ((item != 0), true, "I want to remove the first packet");
221  QueueTestSize (queue, 5 * modeSize, "There should be five packets in queue");
222  NS_TEST_EXPECT_MSG_EQ (item->GetPacket ()->GetUid (), p1->GetUid (), "was this the first packet ?");
223 
224  item = queue->Dequeue ();
225  NS_TEST_EXPECT_MSG_EQ ((item != 0), true, "I want to remove the second packet");
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 ?");
228 
229  item = queue->Dequeue ();
230  NS_TEST_EXPECT_MSG_EQ ((item != 0), true, "I want to remove the third packet");
231  QueueTestSize (queue, 3 * modeSize, "There should be three packets in queue");
232  NS_TEST_EXPECT_MSG_EQ (item->GetPacket ()->GetUid (), p3->GetUid (), "Was this the third packet ?");
233 
234  item = queue->Dequeue ();
235  NS_TEST_EXPECT_MSG_EQ ((item != 0), true, "I want to remove the forth packet");
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 ?");
238 
239  item = queue->Dequeue ();
240  NS_TEST_EXPECT_MSG_EQ ((item != 0), true, "I want to remove the fifth packet");
241  QueueTestSize (queue, 1 * modeSize, "There should be one packet in queue");
242  NS_TEST_EXPECT_MSG_EQ (item->GetPacket ()->GetUid (), p5->GetUid (), "Was this the fifth packet ?");
243 
244  item = queue->Dequeue ();
245  NS_TEST_EXPECT_MSG_EQ ((item != 0), true, "I want to remove the last packet");
246  QueueTestSize (queue, 0 * modeSize, "There should be zero packet in queue");
247  NS_TEST_EXPECT_MSG_EQ (item->GetPacket ()->GetUid (), p6->GetUid (), "Was this the sixth packet ?");
248 
249  item = queue->Dequeue ();
250  NS_TEST_EXPECT_MSG_EQ ((item == 0), true, "There are really no packets in queue");
251 
252  NS_TEST_EXPECT_MSG_EQ (queue->GetStats ().GetNDroppedPackets (CoDelQueueDisc::TARGET_EXCEEDED_DROP), 0,
253  "There should be no packet drops according to CoDel algorithm");
254 }
255 
263 {
264 public:
270  CoDelQueueDiscBasicOverflow (std::string mode);
271  virtual void DoRun (void);
272 
279  void QueueTestSize (Ptr<CoDelQueueDisc> queue, uint32_t size, std::string error)
280  {
281  if (queue->GetMode () == CoDelQueueDisc::QUEUE_DISC_MODE_BYTES)
282  {
283  NS_TEST_EXPECT_MSG_EQ (queue->GetNBytes (), size, error);
284  }
285  else if (queue->GetMode () == CoDelQueueDisc::QUEUE_DISC_MODE_PACKETS)
286  {
287  NS_TEST_EXPECT_MSG_EQ (queue->GetNPackets (), size, error);
288  }
289 
290  NS_TEST_EXPECT_MSG_EQ (queue->GetQueueSize (), size, error);
291  }
292 
293 private:
300  void Enqueue (Ptr<CoDelQueueDisc> queue, uint32_t size, uint32_t nPkt);
302 };
303 
305  : TestCase ("Basic overflow behavior for " + mode)
306 {
307  m_mode = StringValue (mode);
308 }
309 
310 void
312 {
313  Ptr<CoDelQueueDisc> queue = CreateObject<CoDelQueueDisc> ();
314  uint32_t pktSize = 1000;
315  uint32_t modeSize = 0;
316 
317  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("Mode", m_mode), true,
318  "Verify that we can actually set the attribute Mode");
319 
320  Address dest;
321 
322  if (queue->GetMode () == CoDelQueueDisc::QUEUE_DISC_MODE_BYTES)
323  {
324  modeSize = pktSize;
325  }
326  else if (queue->GetMode () == CoDelQueueDisc::QUEUE_DISC_MODE_PACKETS)
327  {
328  modeSize = 1;
329  }
330 
331  Ptr<Packet> p1, p2, p3;
332  p1 = Create<Packet> (pktSize);
333  p2 = Create<Packet> (pktSize);
334  p3 = Create<Packet> (pktSize);
335 
336  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("MaxPackets", UintegerValue (500)), true,
337  "Verify that we can actually set the attribute MaxPackets");
338  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("MaxBytes", UintegerValue (pktSize * 500)), true,
339  "Verify that we can actually set the attribute MaxBytes");
340  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("MinBytes", UintegerValue (pktSize)), true,
341  "Verify that we can actually set the attribute MinBytes");
342 
343  queue->Initialize ();
344 
345  Enqueue (queue, pktSize, 500);
346  queue->Enqueue (Create<CodelQueueDiscTestItem> (p1, dest, 0));
347  queue->Enqueue (Create<CodelQueueDiscTestItem> (p2, dest, 0));
348  queue->Enqueue (Create<CodelQueueDiscTestItem> (p3, dest, 0));
349 
350  QueueTestSize (queue, 500 * modeSize, "There should be 500 packets in queue");
351  NS_TEST_EXPECT_MSG_EQ (queue->GetStats ().GetNDroppedPackets (CoDelQueueDisc::OVERLIMIT_DROP),
352  3, "There should be three packets being dropped due to full queue");
353 }
354 
355 void
356 CoDelQueueDiscBasicOverflow::Enqueue (Ptr<CoDelQueueDisc> queue, uint32_t size, uint32_t nPkt)
357 {
358  Address dest;
359  for (uint32_t i = 0; i < nPkt; i++)
360  {
361  queue->Enqueue (Create<CodelQueueDiscTestItem> (Create<Packet> (size), dest, 0));
362  }
363 }
364 
372 {
373 public:
375  virtual void DoRun (void);
376 };
377 
379  : TestCase ("NewtonStep arithmetic unit test")
380 {
381 }
382 
383 void
385 {
386  Ptr<CoDelQueueDisc> queue = CreateObject<CoDelQueueDisc> ();
387 
388  // Spot check a few points in the expected operational range of
389  // CoDelQueueDisc's m_count and m_recInvSqrt variables
390  uint32_t count = 2;
391  uint16_t recInvSqrt = 65535;
392  queue->m_count = count;
393  queue->m_recInvSqrt = recInvSqrt;
394  queue->NewtonStep ();
395  // Test that ns-3 value is exactly the same as the Linux value
396  NS_TEST_ASSERT_MSG_EQ (_codel_Newton_step (count, recInvSqrt), queue->m_recInvSqrt,
397  "ns-3 NewtonStep() fails to match Linux equivalent");
398 
399  count = 4;
400  recInvSqrt = 36864;
401  queue->m_count = count;
402  queue->m_recInvSqrt = recInvSqrt;
403  queue->NewtonStep ();
404  // Test that ns-3 value is exactly the same as the Linux value
405  NS_TEST_ASSERT_MSG_EQ (_codel_Newton_step (count, recInvSqrt), queue->m_recInvSqrt,
406  "ns-3 NewtonStep() fails to match Linux equivalent");
407 }
408 
416 {
417 public:
419  virtual void DoRun (void);
426  uint32_t _codel_control_law (Ptr<CoDelQueueDisc> queue, uint32_t t);
427 };
428 
430  : TestCase ("ControlLaw arithmetic unit test")
431 {
432 }
433 
434 // The following code borrowed from Linux codel.h,
435 // except the addition of queue parameter
436 uint32_t
438 {
439  return t + _reciprocal_scale (queue->Time2CoDel (queue->m_interval), queue->m_recInvSqrt << REC_INV_SQRT_SHIFT_ns3);
440 }
441 // End Linux borrrow
442 
443 void
445 {
446  Ptr<CoDelQueueDisc> queue = CreateObject<CoDelQueueDisc> ();
447 
448  /* Spot check a few points of m_dropNext
449  The integer approximations in Linux should be within
450  2% of the true floating point value obtained in ns-3
451  */
452  uint32_t dropNextTestVals [4] = {292299, 341128, 9804717, 55885007};
453 
454  for (int i = 0; i < 4; ++i)
455  {
456  uint32_t ns3Result = queue->ControlLaw (dropNextTestVals[i]);
457  uint32_t upperBound = ns3Result + 0.02 * ns3Result;
458  uint32_t lowerBound = ns3Result - 0.02 * ns3Result;
459  uint32_t linuxResult = _codel_control_law (queue, dropNextTestVals[i]);
460  NS_TEST_EXPECT_MSG_EQ ((lowerBound < linuxResult || linuxResult < upperBound), true,
461  "Linux result should stay within 2% of ns-3 result");
462  }
463 }
464 
472 {
473 public:
479  CoDelQueueDiscBasicDrop (std::string mode);
480  virtual void DoRun (void);
481 
488  void QueueTestSize (Ptr<CoDelQueueDisc> queue, uint32_t size, std::string error)
489  {
490  if (queue->GetMode () == CoDelQueueDisc::QUEUE_DISC_MODE_BYTES)
491  {
492  NS_TEST_EXPECT_MSG_EQ (queue->GetNBytes (), size, error);
493  }
494  else if (queue->GetMode () == CoDelQueueDisc::QUEUE_DISC_MODE_PACKETS)
495  {
496  NS_TEST_EXPECT_MSG_EQ (queue->GetNPackets (), size, error);
497  }
498 
499  NS_TEST_EXPECT_MSG_EQ (queue->GetQueueSize (), size, error);
500  }
501 
502 private:
509  void Enqueue (Ptr<CoDelQueueDisc> queue, uint32_t size, uint32_t nPkt);
514  void Dequeue (Ptr<CoDelQueueDisc> queue, uint32_t modeSize);
520  void DropNextTracer (uint32_t oldVal, uint32_t newVal);
522  uint32_t m_dropNextCount;
523 };
524 
526  : TestCase ("Basic drop operations for " + mode)
527 {
528  m_mode = StringValue (mode);
529  m_dropNextCount = 0;
530 }
531 
532 void
533 CoDelQueueDiscBasicDrop::DropNextTracer (uint32_t oldVal, uint32_t newVal)
534 {
535  m_dropNextCount++;
536 }
537 
538 void
540 {
541  Ptr<CoDelQueueDisc> queue = CreateObject<CoDelQueueDisc> ();
542  uint32_t pktSize = 1000;
543  uint32_t modeSize = 0;
544 
545  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("Mode", m_mode), true,
546  "Verify that we can actually set the attribute Mode");
547 
548  if (queue->GetMode () == CoDelQueueDisc::QUEUE_DISC_MODE_BYTES)
549  {
550  modeSize = pktSize;
551  }
552  else if (queue->GetMode () == CoDelQueueDisc::QUEUE_DISC_MODE_PACKETS)
553  {
554  modeSize = 1;
555  }
556 
557  queue->Initialize ();
558 
559  Enqueue (queue, pktSize, 20);
560  NS_TEST_EXPECT_MSG_EQ (queue->GetQueueSize (), 20 * modeSize, "There should be 20 packets in queue.");
561 
562  // Although the first dequeue occurs with a sojourn time above target
563  // the dequeue should be successful in this interval
564  Time waitUntilFirstDequeue = 2 * queue->GetTarget ();
565  Simulator::Schedule (waitUntilFirstDequeue, &CoDelQueueDiscBasicDrop::Dequeue, this, queue, modeSize);
566 
567  // This dequeue should cause a drop
568  Time waitUntilSecondDequeue = waitUntilFirstDequeue + 2 * queue->GetInterval ();
569  Simulator::Schedule (waitUntilSecondDequeue, &CoDelQueueDiscBasicDrop::Dequeue, this, queue, modeSize);
570 
571  // Although we are in dropping state, it's not time for next drop
572  // the dequeue should not cause a drop
573  Simulator::Schedule (waitUntilSecondDequeue, &CoDelQueueDiscBasicDrop::Dequeue, this, queue, modeSize);
574 
575  // In dropping time and it's time for next drop
576  // the dequeue should cause additional packet drops
577  Simulator::Schedule (waitUntilSecondDequeue * 2, &CoDelQueueDiscBasicDrop::Dequeue, this, queue, modeSize);
578 
579  Simulator::Run ();
580  Simulator::Destroy ();
581 }
582 
583 void
584 CoDelQueueDiscBasicDrop::Enqueue (Ptr<CoDelQueueDisc> queue, uint32_t size, uint32_t nPkt)
585 {
586  Address dest;
587  for (uint32_t i = 0; i < nPkt; i++)
588  {
589  queue->Enqueue (Create<CodelQueueDiscTestItem> (Create<Packet> (size), dest, 0));
590  }
591 }
592 
593 void
595 {
596  uint32_t initialDropCount = queue->GetStats ().GetNDroppedPackets (CoDelQueueDisc::TARGET_EXCEEDED_DROP);
597  uint32_t initialQSize = queue->GetQueueSize ();
598  uint32_t initialDropNext = queue->GetDropNext ();
599  Time currentTime = Simulator::Now ();
600  uint32_t currentDropCount = 0;
601 
602  if (initialDropCount > 0 && currentTime.GetMicroSeconds () >= initialDropNext)
603  {
605  }
606 
607  if (initialQSize != 0)
608  {
609  Ptr<QueueDiscItem> item = queue->Dequeue ();
610  if (initialDropCount == 0 && currentTime > queue->GetTarget ())
611  {
612  if (currentTime < queue->GetInterval ())
613  {
614  currentDropCount = queue->GetStats ().GetNDroppedPackets (CoDelQueueDisc::TARGET_EXCEEDED_DROP);
615  NS_TEST_EXPECT_MSG_EQ (currentDropCount, 0, "We are not in dropping state."
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.");
619 
620  }
621  else if (currentTime >= queue->GetInterval ())
622  {
623  currentDropCount = queue->GetStats ().GetNDroppedPackets (CoDelQueueDisc::TARGET_EXCEEDED_DROP);
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.");
627  NS_TEST_EXPECT_MSG_EQ (currentDropCount, 1, "There should be 1 packet drop");
628  }
629  }
630  else if (initialDropCount > 0)
631  { // In dropping state
632  if (currentTime.GetMicroSeconds () < initialDropNext)
633  {
634  currentDropCount = queue->GetStats ().GetNDroppedPackets (CoDelQueueDisc::TARGET_EXCEEDED_DROP);
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");
639 
640  NS_TEST_EXPECT_MSG_EQ (currentDropCount, 1, "There should still be only 1 packet drop from the last dequeue");
641  }
642  else if (currentTime.GetMicroSeconds () >= initialDropNext)
643  {
644  currentDropCount = queue->GetStats ().GetNDroppedPackets (CoDelQueueDisc::TARGET_EXCEEDED_DROP);
645  QueueTestSize (queue, initialQSize - (m_dropNextCount + 1) * modeSize, "We are in dropping state."
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");
648  NS_TEST_EXPECT_MSG_EQ (currentDropCount, 1 + m_dropNextCount, "The number of drops equals to the number of times m_dropNext is updated plus 1 from last dequeue");
649  }
650  }
651  }
652 }
653 
660 static class CoDelQueueDiscTestSuite : public TestSuite
661 {
662 public:
664  : TestSuite ("codel-queue-disc", UNIT)
665  {
666  // Test 1: simple enqueue/dequeue with no drops
667  AddTestCase (new CoDelQueueDiscBasicEnqueueDequeue ("QUEUE_DISC_MODE_PACKETS"), TestCase::QUICK);
668  AddTestCase (new CoDelQueueDiscBasicEnqueueDequeue ("QUEUE_DISC_MODE_BYTES"), TestCase::QUICK);
669  // Test 2: enqueue with drops due to queue overflow
670  AddTestCase (new CoDelQueueDiscBasicOverflow ("QUEUE_DISC_MODE_PACKETS"), TestCase::QUICK);
671  AddTestCase (new CoDelQueueDiscBasicOverflow ("QUEUE_DISC_MODE_BYTES"), TestCase::QUICK);
672  // Test 3: test NewtonStep() against explicit port of Linux implementation
673  AddTestCase (new CoDelQueueDiscNewtonStepTest (), TestCase::QUICK);
674  // Test 4: test ControlLaw() against explicit port of Linux implementation
675  AddTestCase (new CoDelQueueDiscControlLawTest (), TestCase::QUICK);
676  // Test 5: enqueue/dequeue with drops according to CoDel algorithm
677  AddTestCase (new CoDelQueueDiscBasicDrop ("QUEUE_DISC_MODE_PACKETS"), TestCase::QUICK);
678  AddTestCase (new CoDelQueueDiscBasicDrop ("QUEUE_DISC_MODE_BYTES"), TestCase::QUICK);
679  }
CoDelQueueDiscBasicOverflow(std::string mode)
Constructor.
virtual void DoRun(void)
Implementation to actually run this TestCase.
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:102
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.
Definition: queue-disc.cc:730
Hold variables of type string.
Definition: string.h:41
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.
Definition: queue-disc.cc:437
TracedValue< uint32_t > m_count
Number of packets dropped since entering drop state.
A suite of tests to run.
Definition: test.h:1342
#define REC_INV_SQRT_SHIFT_ns3
uint64_t GetUid(void) const
Returns the packet's Uid.
Definition: packet.cc:367
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.
Definition: test.h:285
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.
Definition: object-base.cc:205
QueueDiscItem is the abstract base class for items that are stored in a queue disc.
Definition: queue-item.h:148
encapsulates test code
Definition: test.h:1155
This test suite implements a Unit Test.
Definition: test.h:1352
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
Definition: address.h:90
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.
Definition: nstime.h:349
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.
Definition: test.cc:299
Hold an unsigned integer type.
Definition: uinteger.h:44
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.
Definition: test.h:168
QueueDiscMode GetMode(void)
Get the operating mode of this queue disc.
Callback< R > MakeCallback(R(T::*memPtr)(void), OBJ objPtr)
Definition: callback.h:1489
virtual void AddHeader(void)
Add the header to the packet.
const Stats & GetStats(void)
Retrieve all the collected statistics.
Definition: queue-disc.cc:411
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.
Definition: queue-disc.cc:113
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.
Definition: queue-disc.cc:765
bool TraceConnectWithoutContext(std::string name, const CallbackBase &cb)
Connect a TraceSource to a Callback without a context.
Definition: object-base.cc:293
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.
Time Now(void)
create an ns3::Time instance which contains the current simulation time.
Definition: simulator.cc:365
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.
Definition: object.cc:183
Test 2: enqueue with drops due to queue overflow.
uint32_t GetNPackets(void) const
Get the number of packets stored by the queue disc.
Definition: queue-disc.cc:430