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 (uint16_t rec_inv_sqrt, uint32_t count)
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 static_cast<uint16_t>(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, bool ecnCapable);
73  virtual ~CodelQueueDiscTestItem ();
74  virtual void AddHeader (void);
75  virtual bool Mark(void);
76 
77 private:
89  CodelQueueDiscTestItem &operator = (const CodelQueueDiscTestItem &);
91 };
92 
94  : QueueDiscItem (p, addr, ecnCapable),
95  m_ecnCapablePacket (ecnCapable)
96 {
97 }
98 
100 {
101 }
102 
103 void
105 {
106 }
107 
108 bool
110 {
111  if (m_ecnCapablePacket)
112  {
113  return true;
114  }
115  return false;
116 }
117 
125 {
126 public:
133  virtual void DoRun (void);
134 
135 private:
137 };
138 
140  : TestCase ("Basic enqueue and dequeue operations, and attribute setting")
141 {
142  m_mode = mode;
143 }
144 
145 void
147 {
148  Ptr<CoDelQueueDisc> queue = CreateObject<CoDelQueueDisc> ();
149 
150  uint32_t pktSize = 1000;
151  uint32_t modeSize = 0;
152 
153  Address dest;
154 
155  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("MinBytes", UintegerValue (pktSize)), true,
156  "Verify that we can actually set the attribute MinBytes");
157  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("Interval", StringValue ("50ms")), true,
158  "Verify that we can actually set the attribute Interval");
159  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("Target", StringValue ("4ms")), true,
160  "Verify that we can actually set the attribute Target");
161 
163  {
164  modeSize = pktSize;
165  }
166  else if (m_mode == QueueSizeUnit::PACKETS)
167  {
168  modeSize = 1;
169  }
170  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("MaxSize", QueueSizeValue (QueueSize (m_mode, modeSize * 1500))),
171  true, "Verify that we can actually set the attribute MaxSize");
172  queue->Initialize ();
173 
174  Ptr<Packet> p1, p2, p3, p4, p5, p6;
175  p1 = Create<Packet> (pktSize);
176  p2 = Create<Packet> (pktSize);
177  p3 = Create<Packet> (pktSize);
178  p4 = Create<Packet> (pktSize);
179  p5 = Create<Packet> (pktSize);
180  p6 = Create<Packet> (pktSize);
181 
182  NS_TEST_EXPECT_MSG_EQ (queue->GetCurrentSize().GetValue (), 0 * modeSize, "There should be no packets in queue");
183  queue->Enqueue (Create<CodelQueueDiscTestItem> (p1, dest, false));
184  NS_TEST_EXPECT_MSG_EQ (queue->GetCurrentSize().GetValue (), 1 * modeSize, "There should be one packet in queue");
185  queue->Enqueue (Create<CodelQueueDiscTestItem> (p2, dest, false));
186  NS_TEST_EXPECT_MSG_EQ (queue->GetCurrentSize().GetValue (), 2 * modeSize, "There should be two packets in queue");
187  queue->Enqueue (Create<CodelQueueDiscTestItem> (p3, dest, false));
188  NS_TEST_EXPECT_MSG_EQ (queue->GetCurrentSize().GetValue (), 3 * modeSize, "There should be three packets in queue");
189  queue->Enqueue (Create<CodelQueueDiscTestItem> (p4, dest, false));
190  NS_TEST_EXPECT_MSG_EQ (queue->GetCurrentSize().GetValue (), 4 * modeSize, "There should be four packets in queue");
191  queue->Enqueue (Create<CodelQueueDiscTestItem> (p5, dest, false));
192  NS_TEST_EXPECT_MSG_EQ (queue->GetCurrentSize().GetValue (), 5 * modeSize, "There should be five packets in queue");
193  queue->Enqueue (Create<CodelQueueDiscTestItem> (p6, dest, false));
194  NS_TEST_EXPECT_MSG_EQ (queue->GetCurrentSize().GetValue (), 6 * modeSize, "There should be six packets in queue");
195 
196  NS_TEST_EXPECT_MSG_EQ (queue->GetStats ().GetNDroppedPackets (CoDelQueueDisc::OVERLIMIT_DROP),
197  0, "There should be no packets being dropped due to full queue");
198 
199  Ptr<QueueDiscItem> item;
200 
201  item = queue->Dequeue ();
202  NS_TEST_EXPECT_MSG_EQ ((item != 0), true, "I want to remove the first packet");
203  NS_TEST_EXPECT_MSG_EQ (queue->GetCurrentSize().GetValue (), 5 * modeSize, "There should be five packets in queue");
204  NS_TEST_EXPECT_MSG_EQ (item->GetPacket ()->GetUid (), p1->GetUid (), "was this the first packet ?");
205 
206  item = queue->Dequeue ();
207  NS_TEST_EXPECT_MSG_EQ ((item != 0), true, "I want to remove the second packet");
208  NS_TEST_EXPECT_MSG_EQ (queue->GetCurrentSize().GetValue (), 4 * modeSize, "There should be four packets in queue");
209  NS_TEST_EXPECT_MSG_EQ (item->GetPacket ()->GetUid (), p2->GetUid (), "Was this the second packet ?");
210 
211  item = queue->Dequeue ();
212  NS_TEST_EXPECT_MSG_EQ ((item != 0), true, "I want to remove the third packet");
213  NS_TEST_EXPECT_MSG_EQ (queue->GetCurrentSize().GetValue (), 3 * modeSize, "There should be three packets in queue");
214  NS_TEST_EXPECT_MSG_EQ (item->GetPacket ()->GetUid (), p3->GetUid (), "Was this the third packet ?");
215 
216  item = queue->Dequeue ();
217  NS_TEST_EXPECT_MSG_EQ ((item != 0), true, "I want to remove the forth packet");
218  NS_TEST_EXPECT_MSG_EQ (queue->GetCurrentSize().GetValue (), 2 * modeSize, "There should be two packets in queue");
219  NS_TEST_EXPECT_MSG_EQ (item->GetPacket ()->GetUid (), p4->GetUid (), "Was this the fourth packet ?");
220 
221  item = queue->Dequeue ();
222  NS_TEST_EXPECT_MSG_EQ ((item != 0), true, "I want to remove the fifth packet");
223  NS_TEST_EXPECT_MSG_EQ (queue->GetCurrentSize().GetValue (), 1 * modeSize, "There should be one packet in queue");
224  NS_TEST_EXPECT_MSG_EQ (item->GetPacket ()->GetUid (), p5->GetUid (), "Was this the fifth packet ?");
225 
226  item = queue->Dequeue ();
227  NS_TEST_EXPECT_MSG_EQ ((item != 0), true, "I want to remove the last packet");
228  NS_TEST_EXPECT_MSG_EQ (queue->GetCurrentSize().GetValue (), 0 * modeSize, "There should be zero packet in queue");
229  NS_TEST_EXPECT_MSG_EQ (item->GetPacket ()->GetUid (), p6->GetUid (), "Was this the sixth packet ?");
230 
231  item = queue->Dequeue ();
232  NS_TEST_EXPECT_MSG_EQ ((item == 0), true, "There are really no packets in queue");
233 
234  NS_TEST_EXPECT_MSG_EQ (queue->GetStats ().GetNDroppedPackets (CoDelQueueDisc::TARGET_EXCEEDED_DROP), 0,
235  "There should be no packet drops according to CoDel algorithm");
236 }
237 
245 {
246 public:
253  virtual void DoRun (void);
254 
255 private:
262  void Enqueue (Ptr<CoDelQueueDisc> queue, uint32_t size, uint32_t nPkt);
264 };
265 
267  : TestCase ("Basic overflow behavior")
268 {
269  m_mode = mode;
270 }
271 
272 void
274 {
275  Ptr<CoDelQueueDisc> queue = CreateObject<CoDelQueueDisc> ();
276  uint32_t pktSize = 1000;
277  uint32_t modeSize = 0;
278 
279  Address dest;
280 
282  {
283  modeSize = pktSize;
284  }
285  else if (m_mode == QueueSizeUnit::PACKETS)
286  {
287  modeSize = 1;
288  }
289 
290  Ptr<Packet> p1, p2, p3;
291  p1 = Create<Packet> (pktSize);
292  p2 = Create<Packet> (pktSize);
293  p3 = Create<Packet> (pktSize);
294 
295  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("MaxSize", QueueSizeValue (QueueSize (m_mode, modeSize * 500))),
296  true, "Verify that we can actually set the attribute MaxSize");
297  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("MinBytes", UintegerValue (pktSize)), true,
298  "Verify that we can actually set the attribute MinBytes");
299 
300  queue->Initialize ();
301 
302  Enqueue (queue, pktSize, 500);
303  queue->Enqueue (Create<CodelQueueDiscTestItem> (p1, dest, false));
304  queue->Enqueue (Create<CodelQueueDiscTestItem> (p2, dest, false));
305  queue->Enqueue (Create<CodelQueueDiscTestItem> (p3, dest, false));
306 
307  NS_TEST_EXPECT_MSG_EQ (queue->GetCurrentSize().GetValue (), 500 * modeSize, "There should be 500 packets in queue");
308  NS_TEST_EXPECT_MSG_EQ (queue->GetStats ().GetNDroppedPackets (CoDelQueueDisc::OVERLIMIT_DROP),
309  3, "There should be three packets being dropped due to full queue");
310 }
311 
312 void
313 CoDelQueueDiscBasicOverflow::Enqueue (Ptr<CoDelQueueDisc> queue, uint32_t size, uint32_t nPkt)
314 {
315  Address dest;
316  for (uint32_t i = 0; i < nPkt; i++)
317  {
318  queue->Enqueue (Create<CodelQueueDiscTestItem> (Create<Packet> (size), dest, false));
319  }
320 }
321 
329 {
330 public:
332  virtual void DoRun (void);
333 };
334 
336  : TestCase ("NewtonStep arithmetic unit test")
337 {
338 }
339 
340 void
342 {
343  Ptr<CoDelQueueDisc> queue = CreateObject<CoDelQueueDisc> ();
344 
345  // Spot check a few points in the expected operational range of
346  // CoDelQueueDisc's m_count and m_recInvSqrt variables
347  uint16_t result;
348  for (uint16_t recInvSqrt = 0xff; recInvSqrt > 0; recInvSqrt /= 2)
349  {
350  for (uint32_t count = 1; count < 0xff; count *= 2)
351  {
352  result = queue->NewtonStep (recInvSqrt, count);
353  // Test that ns-3 value is exactly the same as the Linux value
354  NS_TEST_ASSERT_MSG_EQ (_codel_Newton_step (recInvSqrt, count), result,
355  "ns-3 NewtonStep() fails to match Linux equivalent");
356  }
357  }
358 }
359 
367 {
368 public:
370  virtual void DoRun (void);
377  uint32_t _codel_control_law (uint32_t t, uint32_t interval, uint32_t recInvSqrt);
378 };
379 
381  : TestCase ("ControlLaw arithmetic unit test")
382 {
383 }
384 
385 // The following code borrowed from Linux codel.h,
386 // except the addition of queue parameter
387 uint32_t
388 CoDelQueueDiscControlLawTest::_codel_control_law (uint32_t t, uint32_t interval, uint32_t recInvSqrt)
389 {
390  return t + _reciprocal_scale (interval, recInvSqrt << REC_INV_SQRT_SHIFT_ns3);
391 }
392 // End Linux borrrow
393 
394 void
396 {
397  Ptr<CoDelQueueDisc> queue = CreateObject<CoDelQueueDisc> ();
398 
399  // Check a few points within the operational range of ControlLaw
400  uint32_t interval = queue->Time2CoDel (MilliSeconds (100));
401 
402  uint32_t codelTimeVal;
403  for (Time timeVal = Seconds (0); timeVal <= Seconds (20); timeVal += MilliSeconds (100))
404  {
405  for (uint16_t recInvSqrt = 0xff; recInvSqrt > 0; recInvSqrt /= 2)
406  {
407  codelTimeVal = queue->Time2CoDel (timeVal);
408  uint32_t ns3Result = queue->ControlLaw (codelTimeVal, interval, recInvSqrt);
409  uint32_t linuxResult = _codel_control_law (codelTimeVal, interval, recInvSqrt);
410  NS_TEST_EXPECT_MSG_EQ (ns3Result, linuxResult, "Linux result for ControlLaw should equal ns-3 result");
411  }
412  }
413 }
414 
422 {
423 public:
430  virtual void DoRun (void);
431 
432 private:
439  void Enqueue (Ptr<CoDelQueueDisc> queue, uint32_t size, uint32_t nPkt);
444  void Dequeue (Ptr<CoDelQueueDisc> queue, uint32_t modeSize);
450  void DropNextTracer (uint32_t oldVal, uint32_t newVal);
452  uint32_t m_dropNextCount;
453 };
454 
456  : TestCase ("Basic drop operations")
457 {
458  m_mode = mode;
459  m_dropNextCount = 0;
460 }
461 
462 void
463 CoDelQueueDiscBasicDrop::DropNextTracer (uint32_t oldVal, uint32_t newVal)
464 {
465  NS_UNUSED(oldVal);
466  NS_UNUSED(newVal);
467  m_dropNextCount++;
468 }
469 
470 void
472 {
473  Ptr<CoDelQueueDisc> queue = CreateObject<CoDelQueueDisc> ();
474  uint32_t pktSize = 1000;
475  uint32_t modeSize = 0;
476 
478  {
479  modeSize = pktSize;
480  }
481  else if (m_mode == QueueSizeUnit::PACKETS)
482  {
483  modeSize = 1;
484  }
485 
486  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("MaxSize", QueueSizeValue (QueueSize (m_mode, modeSize * 500))),
487  true, "Verify that we can actually set the attribute MaxSize");
488 
489  queue->Initialize ();
490 
491  Enqueue (queue, pktSize, 20);
492  NS_TEST_EXPECT_MSG_EQ (queue->GetCurrentSize ().GetValue (), 20 * modeSize, "There should be 20 packets in queue.");
493 
494  // Although the first dequeue occurs with a sojourn time above target
495  // the dequeue should be successful in this interval
496  Time waitUntilFirstDequeue = 2 * queue->GetTarget ();
497  Simulator::Schedule (waitUntilFirstDequeue, &CoDelQueueDiscBasicDrop::Dequeue, this, queue, modeSize);
498 
499  // This dequeue should cause a drop
500  Time waitUntilSecondDequeue = waitUntilFirstDequeue + 2 * queue->GetInterval ();
501  Simulator::Schedule (waitUntilSecondDequeue, &CoDelQueueDiscBasicDrop::Dequeue, this, queue, modeSize);
502 
503  // Although we are in dropping state, it's not time for next drop
504  // the dequeue should not cause a drop
505  Simulator::Schedule (waitUntilSecondDequeue, &CoDelQueueDiscBasicDrop::Dequeue, this, queue, modeSize);
506 
507  // In dropping time and it's time for next drop
508  // the dequeue should cause additional packet drops
509  Simulator::Schedule (waitUntilSecondDequeue * 2, &CoDelQueueDiscBasicDrop::Dequeue, this, queue, modeSize);
510 
511  Simulator::Run ();
512  Simulator::Destroy ();
513 }
514 
515 void
516 CoDelQueueDiscBasicDrop::Enqueue (Ptr<CoDelQueueDisc> queue, uint32_t size, uint32_t nPkt)
517 {
518  Address dest;
519  for (uint32_t i = 0; i < nPkt; i++)
520  {
521  queue->Enqueue (Create<CodelQueueDiscTestItem> (Create<Packet> (size), dest, false));
522  }
523 }
524 
525 void
527 {
528  uint32_t initialDropCount = queue->GetStats ().GetNDroppedPackets (CoDelQueueDisc::TARGET_EXCEEDED_DROP);
529  uint32_t initialQSize = queue->GetCurrentSize ().GetValue ();
530  uint32_t initialDropNext = queue->GetDropNext ();
531  Time currentTime = Simulator::Now ();
532  uint32_t currentDropCount = 0;
533 
534  if (initialDropCount > 0 && currentTime.GetMicroSeconds () >= initialDropNext)
535  {
537  }
538 
539  if (initialQSize != 0)
540  {
541  Ptr<QueueDiscItem> item = queue->Dequeue ();
542  if (initialDropCount == 0 && currentTime > queue->GetTarget ())
543  {
544  if (currentTime < queue->GetInterval ())
545  {
546  currentDropCount = queue->GetStats ().GetNDroppedPackets (CoDelQueueDisc::TARGET_EXCEEDED_DROP);
547  NS_TEST_EXPECT_MSG_EQ (currentDropCount, 0, "We are not in dropping state."
548  "Sojourn time has just gone above target from below."
549  "Hence, there should be no packet drops");
550  NS_TEST_EXPECT_MSG_EQ (queue->GetCurrentSize ().GetValue (), initialQSize - modeSize, "There should be 1 packet dequeued.");
551 
552  }
553  else if (currentTime >= queue->GetInterval ())
554  {
555  currentDropCount = queue->GetStats ().GetNDroppedPackets (CoDelQueueDisc::TARGET_EXCEEDED_DROP);
556  NS_TEST_EXPECT_MSG_EQ (queue->GetCurrentSize ().GetValue (), initialQSize - 2 * modeSize, "Sojourn time has been above target for at least interval."
557  "We enter the dropping state, perform initial packet drop, and dequeue the next."
558  "So there should be 2 more packets dequeued.");
559  NS_TEST_EXPECT_MSG_EQ (currentDropCount, 1, "There should be 1 packet drop");
560  }
561  }
562  else if (initialDropCount > 0)
563  { // In dropping state
564  if (currentTime.GetMicroSeconds () < initialDropNext)
565  {
566  currentDropCount = queue->GetStats ().GetNDroppedPackets (CoDelQueueDisc::TARGET_EXCEEDED_DROP);
567  NS_TEST_EXPECT_MSG_EQ (queue->GetCurrentSize ().GetValue (), initialQSize - modeSize, "We are in dropping state."
568  "Sojourn is still above target."
569  "However, it's not time for next drop."
570  "So there should be only 1 more packet dequeued");
571 
572  NS_TEST_EXPECT_MSG_EQ (currentDropCount, 1, "There should still be only 1 packet drop from the last dequeue");
573  }
574  else if (currentTime.GetMicroSeconds () >= initialDropNext)
575  {
576  currentDropCount = queue->GetStats ().GetNDroppedPackets (CoDelQueueDisc::TARGET_EXCEEDED_DROP);
577  NS_TEST_EXPECT_MSG_EQ (queue->GetCurrentSize ().GetValue (), initialQSize - (m_dropNextCount + 1) * modeSize, "We are in dropping state."
578  "It's time for next drop."
579  "The number of packets dequeued equals to the number of times m_dropNext is updated plus initial dequeue");
580  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");
581  }
582  }
583  }
584 }
585 
593 {
594 public:
601  virtual void DoRun (void);
602 
603 private:
611  void Enqueue (Ptr<CoDelQueueDisc> queue, uint32_t size, uint32_t nPkt, bool ecnCapable);
617  void Dequeue (Ptr<CoDelQueueDisc> queue, uint32_t modeSize, uint32_t testCase);
623  void DropNextTracer (uint32_t oldVal, uint32_t newVal);
625  uint32_t m_dropNextCount;
628 };
629 
631  : TestCase ("Basic mark operations")
632 {
633  m_mode = mode;
634  m_dropNextCount = 0;
635 }
636 
637 void
638 CoDelQueueDiscBasicMark::DropNextTracer (uint32_t oldVal, uint32_t newVal)
639 {
640  NS_UNUSED(oldVal);
641  NS_UNUSED(newVal);
642  m_dropNextCount++;
643 }
644 
645 void
647 {
648  // Test is divided into 4 sub test cases:
649  // 1) Packets are not ECN capable.
650  // 2) Packets are ECN capable but marking due to exceeding CE threshold disabled
651  // 3) Some packets are ECN capable, with CE threshold set to 2ms.
652  // 4) Packets are ECN capable and CE threshold set to 2ms
653 
654  // Test case 1
655  Ptr<CoDelQueueDisc> queue = CreateObject<CoDelQueueDisc> ();
656  uint32_t pktSize = 1000;
657  uint32_t modeSize = 0;
660 
662  {
663  modeSize = pktSize;
664  }
665  else if (m_mode == QueueSizeUnit::PACKETS)
666  {
667  modeSize = 1;
668  }
669 
670  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("MaxSize", QueueSizeValue (QueueSize (m_mode, modeSize * 500))),
671  true, "Verify that we can actually set the attribute MaxSize");
672  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("UseEcn", BooleanValue (true)),
673  true, "Verify that we can actually set the attribute UseEcn");
674 
675  queue->Initialize ();
676 
677  // Not-ECT traffic to induce packet drop
678  Enqueue (queue, pktSize, 20, false);
679  NS_TEST_EXPECT_MSG_EQ (queue->GetCurrentSize ().GetValue (), 20 * modeSize, "There should be 20 packets in queue.");
680 
681  // Although the first dequeue occurs with a sojourn time above target
682  // there should not be any dropped packets in this interval
683  Time waitUntilFirstDequeue = 2 * queue->GetTarget ();
684  Simulator::Schedule (waitUntilFirstDequeue, &CoDelQueueDiscBasicMark::Dequeue, this, queue, modeSize, 1);
685 
686  // This dequeue should cause a packet to be dropped
687  Time waitUntilSecondDequeue = waitUntilFirstDequeue + 2 * queue->GetInterval ();
688  Simulator::Schedule (waitUntilSecondDequeue, &CoDelQueueDiscBasicMark::Dequeue, this, queue, modeSize, 1);
689 
690  Simulator::Run ();
691  Simulator::Destroy ();
692 
693  // Test case 2, queue with ECN capable traffic for marking of packets instead of dropping
694  queue = CreateObject<CoDelQueueDisc> ();
695  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("MaxSize", QueueSizeValue (QueueSize (m_mode, modeSize * 500))),
696  true, "Verify that we can actually set the attribute MaxSize");
697  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("UseEcn", BooleanValue (true)),
698  true, "Verify that we can actually set the attribute UseEcn");
699 
700  queue->Initialize ();
701 
702  // ECN capable traffic to induce packets to be marked
703  Enqueue (queue, pktSize, 20, true);
704  NS_TEST_EXPECT_MSG_EQ (queue->GetCurrentSize ().GetValue (), 20 * modeSize, "There should be 20 packets in queue.");
705 
706  // Although the first dequeue occurs with a sojourn time above target
707  // there should not be any target exceeded marked packets in this interval
708  Simulator::Schedule (waitUntilFirstDequeue, &CoDelQueueDiscBasicMark::Dequeue, this, queue, modeSize, 2);
709 
710  // This dequeue should cause a packet to be marked
711  Simulator::Schedule (waitUntilSecondDequeue, &CoDelQueueDiscBasicMark::Dequeue, this, queue, modeSize, 2);
712 
713  // Although we are in dropping state, it's not time for next packet to be target exceeded marked
714  // the dequeue should not cause a packet to be target exceeded marked
715  Simulator::Schedule (waitUntilSecondDequeue, &CoDelQueueDiscBasicMark::Dequeue, this, queue, modeSize, 2);
716 
717  // In dropping time and it's time for next packet to be target exceeded marked
718  // the dequeue should cause additional packet to be target exceeded marked
719  Simulator::Schedule (waitUntilSecondDequeue * 2, &CoDelQueueDiscBasicMark::Dequeue, this, queue, modeSize, 2);
720 
721  Simulator::Run ();
722  Simulator::Destroy ();
723 
724  // Test case 3, some packets are ECN capable, with CE threshold set to 2ms
725  queue = CreateObject<CoDelQueueDisc> ();
726  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("MaxSize", QueueSizeValue (QueueSize (m_mode, modeSize * 500))),
727  true, "Verify that we can actually set the attribute MaxSize");
728  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("UseEcn", BooleanValue (true)),
729  true, "Verify that we can actually set the attribute UseEcn");
730  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("CeThreshold", TimeValue (MilliSeconds (2))),
731  true, "Verify that we can actually set the attribute CeThreshold");
732 
733  queue->Initialize ();
734 
735  // First 3 packets in the queue are ecnCapable
736  Enqueue (queue, pktSize, 3, true);
737  // Rest of the packet are not ecnCapable
738  Enqueue (queue, pktSize, 17, false);
739  NS_TEST_EXPECT_MSG_EQ (queue->GetCurrentSize ().GetValue (), 20 * modeSize, "There should be 20 packets in queue.");
740 
741  // Although the first dequeue occurs with a sojourn time above target
742  // there should not be any target exceeded marked packets in this interval
743  Simulator::Schedule (waitUntilFirstDequeue, &CoDelQueueDiscBasicMark::Dequeue, this, queue, modeSize, 3);
744 
745  // This dequeue should cause a packet to be marked
746  Simulator::Schedule (waitUntilSecondDequeue, &CoDelQueueDiscBasicMark::Dequeue, this, queue, modeSize, 3);
747 
748  // Although we are in dropping state, it's not time for next packet to be target exceeded marked
749  // the dequeue should not cause a packet to be target exceeded marked
750  Simulator::Schedule (waitUntilSecondDequeue, &CoDelQueueDiscBasicMark::Dequeue, this, queue, modeSize, 3);
751 
752  // In dropping time and it's time for next packet to be dropped as packets are not ECN capable
753  // the dequeue should cause packet to be dropped
754  Simulator::Schedule (waitUntilSecondDequeue * 2, &CoDelQueueDiscBasicMark::Dequeue, this, queue, modeSize, 3);
755 
756  Simulator::Run ();
757  Simulator::Destroy ();
758 
759  // Test case 4, queue with ECN capable traffic and CeThreshold set for marking of packets instead of dropping
760  queue = CreateObject<CoDelQueueDisc> ();
761  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("MaxSize", QueueSizeValue (QueueSize (m_mode, modeSize * 500))),
762  true, "Verify that we can actually set the attribute MaxSize");
763  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("UseEcn", BooleanValue (true)),
764  true, "Verify that we can actually set the attribute UseEcn");
765  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("CeThreshold", TimeValue (MilliSeconds (2))),
766  true, "Verify that we can actually set the attribute CeThreshold");
767 
768  queue->Initialize ();
769 
770  // ECN capable traffic to induce packets to be marked
771  Enqueue (queue, pktSize, 20, true);
772  NS_TEST_EXPECT_MSG_EQ (queue->GetCurrentSize ().GetValue (), 20 * modeSize, "There should be 20 packets in queue.");
773 
774  // The first dequeue occurs with a sojourn time below CE threshold
775  // there should not any be CE threshold exceeded marked packets
776  Simulator::Schedule (MilliSeconds (1), &CoDelQueueDiscBasicMark::Dequeue, this, queue, modeSize, 4);
777 
778  // Sojourn time above CE threshold so this dequeue should cause a packet to be CE thershold exceeded marked
779  Simulator::Schedule (MilliSeconds (3), &CoDelQueueDiscBasicMark::Dequeue, this, queue, modeSize, 4);
780 
781  // the dequeue should cause a packet to be CE threshold exceeded marked
782  Simulator::Schedule (waitUntilFirstDequeue, &CoDelQueueDiscBasicMark::Dequeue, this, queue, modeSize, 4);
783 
784  // In dropping time and it's time for next packet to be dropped but because of using ECN, packet should be marked
785  Simulator::Schedule (waitUntilSecondDequeue, &CoDelQueueDiscBasicMark::Dequeue, this, queue, modeSize, 4);
786 
787  Simulator::Run ();
788  Simulator::Destroy ();
789 }
790 
791 void
792 CoDelQueueDiscBasicMark::Enqueue (Ptr<CoDelQueueDisc> queue, uint32_t size, uint32_t nPkt, bool ecnCapable)
793 {
794  Address dest;
795  for (uint32_t i = 0; i < nPkt; i++)
796  {
797  queue->Enqueue (Create<CodelQueueDiscTestItem> (Create<Packet> (size), dest, ecnCapable));
798  }
799 }
800 
801 void
802 CoDelQueueDiscBasicMark::Dequeue (Ptr<CoDelQueueDisc> queue, uint32_t modeSize, uint32_t testCase)
803 {
804  uint32_t initialTargetMarkCount = queue->GetStats ().GetNMarkedPackets (CoDelQueueDisc::TARGET_EXCEEDED_MARK);
805  uint32_t initialCeThreshMarkCount = queue->GetStats ().GetNMarkedPackets (CoDelQueueDisc::CE_THRESHOLD_EXCEEDED_MARK);
806  uint32_t initialQSize = queue->GetCurrentSize ().GetValue ();
807  uint32_t initialDropNext = queue->GetDropNext ();
808  Time currentTime = Simulator::Now ();
809  uint32_t currentDropCount = 0;
810  uint32_t currentTargetMarkCount = 0;
811  uint32_t currentCeThreshMarkCount = 0;
812 
813  if (initialTargetMarkCount > 0 && currentTime.GetMicroSeconds () >= initialDropNext && testCase == 3)
814  {
816  }
817 
818  if (initialQSize != 0)
819  {
820  Ptr<QueueDiscItem> item = queue->Dequeue ();
821  if (testCase == 1)
822  {
823  currentDropCount = queue->GetStats ().GetNDroppedPackets (CoDelQueueDisc::TARGET_EXCEEDED_DROP);
824  if (currentDropCount == 1)
825  {
826  nPacketsBeforeFirstDrop = initialQSize;
827  }
828  }
829  else if (testCase == 2)
830  {
831  if (initialTargetMarkCount == 0 && currentTime > queue->GetTarget ())
832  {
833  if (currentTime < queue->GetInterval ())
834  {
835  currentDropCount = queue->GetStats ().GetNDroppedPackets (CoDelQueueDisc::TARGET_EXCEEDED_DROP);
836  currentTargetMarkCount = queue->GetStats ().GetNMarkedPackets (CoDelQueueDisc::TARGET_EXCEEDED_MARK);
837  currentCeThreshMarkCount = queue->GetStats ().GetNMarkedPackets (CoDelQueueDisc::CE_THRESHOLD_EXCEEDED_MARK);
838  NS_TEST_EXPECT_MSG_EQ (queue->GetCurrentSize ().GetValue (), initialQSize - modeSize, "There should be 1 packet dequeued.");
839  NS_TEST_EXPECT_MSG_EQ (currentDropCount, 0, "There should not be any packet drops");
840  NS_TEST_ASSERT_MSG_EQ (currentTargetMarkCount, 0, "We are not in dropping state."
841  "Sojourn time has just gone above target from below."
842  "Hence, there should be no target exceeded marked packets");
843  NS_TEST_ASSERT_MSG_EQ (currentCeThreshMarkCount, 0, "Marking due to CE threshold is disabled"
844  "Hence, there should not be any CE threshold exceeded marked packet");
845  }
846  else if (currentTime >= queue->GetInterval ())
847  {
848  currentDropCount = queue->GetStats ().GetNDroppedPackets (CoDelQueueDisc::TARGET_EXCEEDED_DROP);
849  currentTargetMarkCount = queue->GetStats ().GetNMarkedPackets (CoDelQueueDisc::TARGET_EXCEEDED_MARK);
850  nPacketsBeforeFirstMark = initialQSize;
851  currentCeThreshMarkCount = queue->GetStats ().GetNMarkedPackets (CoDelQueueDisc::CE_THRESHOLD_EXCEEDED_MARK);
852  NS_TEST_EXPECT_MSG_EQ (queue->GetCurrentSize ().GetValue (), initialQSize - modeSize, "Sojourn time has been above target for at least interval."
853  "We enter the dropping state and perform initial packet marking"
854  "So there should be only 1 more packet dequeued.");
855  NS_TEST_EXPECT_MSG_EQ (currentDropCount, 0, "There should not be any packet drops");
856  NS_TEST_EXPECT_MSG_EQ (currentTargetMarkCount, 1, "There should be 1 target exceeded marked packet");
857  NS_TEST_ASSERT_MSG_EQ (currentCeThreshMarkCount, 0, "There should not be any CE threshold exceeded marked packet");
858  }
859  }
860  else if (initialTargetMarkCount > 0)
861  { // In dropping state
862  if (currentTime.GetMicroSeconds () < initialDropNext)
863  {
864  currentDropCount = queue->GetStats ().GetNDroppedPackets (CoDelQueueDisc::TARGET_EXCEEDED_DROP);
865  currentTargetMarkCount = queue->GetStats ().GetNMarkedPackets (CoDelQueueDisc::TARGET_EXCEEDED_MARK);
866  currentCeThreshMarkCount = queue->GetStats ().GetNMarkedPackets (CoDelQueueDisc::CE_THRESHOLD_EXCEEDED_MARK);
867  NS_TEST_EXPECT_MSG_EQ (queue->GetCurrentSize ().GetValue (), initialQSize - modeSize, "We are in dropping state."
868  "Sojourn is still above target."
869  "However, it's not time for next target exceeded mark."
870  "So there should be only 1 more packet dequeued");
871  NS_TEST_EXPECT_MSG_EQ (currentDropCount, 0, "There should not be any packet drops");
872  NS_TEST_EXPECT_MSG_EQ (currentTargetMarkCount, 1, "There should still be only 1 target exceeded marked packet from the last dequeue");
873  NS_TEST_ASSERT_MSG_EQ (currentCeThreshMarkCount, 0, "There should not be any CE threshold exceeded marked packet");
874  }
875  else if (currentTime.GetMicroSeconds () >= initialDropNext)
876  {
877  currentDropCount = queue->GetStats ().GetNDroppedPackets (CoDelQueueDisc::TARGET_EXCEEDED_DROP);
878  currentTargetMarkCount = queue->GetStats ().GetNMarkedPackets (CoDelQueueDisc::TARGET_EXCEEDED_MARK);
879  currentCeThreshMarkCount = queue->GetStats ().GetNMarkedPackets (CoDelQueueDisc::CE_THRESHOLD_EXCEEDED_MARK);
880  NS_TEST_EXPECT_MSG_EQ (queue->GetCurrentSize ().GetValue (), initialQSize - modeSize, "We are in dropping state."
881  "It's time for packet to be marked"
882  "So there should be only 1 more packet dequeued");
883  NS_TEST_EXPECT_MSG_EQ (currentDropCount, 0, "There should not be any packet drops");
884  NS_TEST_EXPECT_MSG_EQ (currentTargetMarkCount, 2, "There should 2 target exceeded marked packet");
885  NS_TEST_EXPECT_MSG_EQ (nPacketsBeforeFirstDrop, nPacketsBeforeFirstMark, "Number of packets in the queue before drop should be equal"
886  "to number of packets in the queue before first mark as the behavior untill packet N should be the same.");
887  NS_TEST_ASSERT_MSG_EQ (currentCeThreshMarkCount, 0, "There should not be any CE threshold exceeded marked packet");
888  }
889  }
890  }
891  else if (testCase == 3)
892  {
893  if (initialTargetMarkCount == 0 && currentTime > queue->GetTarget ())
894  {
895  if (currentTime < queue->GetInterval ())
896  {
897  currentDropCount = queue->GetStats ().GetNDroppedPackets (CoDelQueueDisc::TARGET_EXCEEDED_DROP);
898  currentTargetMarkCount = queue->GetStats ().GetNMarkedPackets (CoDelQueueDisc::TARGET_EXCEEDED_MARK);
899  currentCeThreshMarkCount = queue->GetStats ().GetNMarkedPackets (CoDelQueueDisc::CE_THRESHOLD_EXCEEDED_MARK);
900  NS_TEST_EXPECT_MSG_EQ (queue->GetCurrentSize ().GetValue (), initialQSize - modeSize, "There should be 1 packet dequeued.");
901  NS_TEST_EXPECT_MSG_EQ (currentDropCount, 0, "There should not be any packet drops");
902  NS_TEST_ASSERT_MSG_EQ (currentTargetMarkCount, 0, "We are not in dropping state."
903  "Sojourn time has just gone above target from below."
904  "Hence, there should be no target exceeded marked packets");
905  NS_TEST_ASSERT_MSG_EQ (currentCeThreshMarkCount, 1, "Sojourn time has gone above CE threshold."
906  "Hence, there should be 1 CE threshold exceeded marked packet");
907  }
908  else if (currentTime >= queue->GetInterval ())
909  {
910  currentDropCount = queue->GetStats ().GetNDroppedPackets (CoDelQueueDisc::TARGET_EXCEEDED_DROP);
911  currentTargetMarkCount = queue->GetStats ().GetNMarkedPackets (CoDelQueueDisc::TARGET_EXCEEDED_MARK);
912  currentCeThreshMarkCount = queue->GetStats ().GetNMarkedPackets (CoDelQueueDisc::CE_THRESHOLD_EXCEEDED_MARK);
913  NS_TEST_EXPECT_MSG_EQ (queue->GetCurrentSize ().GetValue (), initialQSize - modeSize, "Sojourn time has been above target for at least interval."
914  "We enter the dropping state and perform initial packet marking"
915  "So there should be only 1 more packet dequeued.");
916  NS_TEST_EXPECT_MSG_EQ (currentDropCount, 0, "There should not be any packet drops");
917  NS_TEST_EXPECT_MSG_EQ (currentTargetMarkCount, 1, "There should be 1 target exceeded marked packet");
918  NS_TEST_EXPECT_MSG_EQ (currentCeThreshMarkCount, 1, "There should be 1 CE threshold exceeded marked packets");
919  }
920  }
921  else if (initialTargetMarkCount > 0)
922  { // In dropping state
923  if (currentTime.GetMicroSeconds () < initialDropNext)
924  {
925  currentDropCount = queue->GetStats ().GetNDroppedPackets (CoDelQueueDisc::TARGET_EXCEEDED_DROP);
926  currentTargetMarkCount = queue->GetStats ().GetNMarkedPackets (CoDelQueueDisc::TARGET_EXCEEDED_MARK);
927  currentCeThreshMarkCount = queue->GetStats ().GetNMarkedPackets (CoDelQueueDisc::CE_THRESHOLD_EXCEEDED_MARK);
928  NS_TEST_EXPECT_MSG_EQ (queue->GetCurrentSize ().GetValue (), initialQSize - modeSize, "We are in dropping state."
929  "Sojourn is still above target."
930  "However, it's not time for next target exceeded mark."
931  "So there should be only 1 more packet dequeued");
932  NS_TEST_EXPECT_MSG_EQ (currentDropCount, 0, "There should not be any packet drops");
933  NS_TEST_EXPECT_MSG_EQ (currentTargetMarkCount, 1, "There should still be only 1 target exceeded marked packet from the last dequeue");
934  NS_TEST_EXPECT_MSG_EQ (currentCeThreshMarkCount, 2, "There should be 2 CE threshold exceeded marked packets");
935  }
936  else if (currentTime.GetMicroSeconds () >= initialDropNext)
937  {
938  currentDropCount = queue->GetStats ().GetNDroppedPackets (CoDelQueueDisc::TARGET_EXCEEDED_DROP);
939  currentTargetMarkCount = queue->GetStats ().GetNMarkedPackets (CoDelQueueDisc::TARGET_EXCEEDED_MARK);
940  currentCeThreshMarkCount = queue->GetStats ().GetNMarkedPackets (CoDelQueueDisc::CE_THRESHOLD_EXCEEDED_MARK);
941  NS_TEST_EXPECT_MSG_EQ (queue->GetCurrentSize ().GetValue (), initialQSize - (m_dropNextCount + 1) * modeSize, "We are in dropping state."
942  "It's time for packet to be dropped as packets are not ecnCapable"
943  "The number of packets dequeued equals to the number of times m_dropNext is updated plus initial dequeue");
944  NS_TEST_EXPECT_MSG_EQ (currentDropCount, m_dropNextCount, "The number of drops equals to the number of times m_dropNext is updated");
945  NS_TEST_EXPECT_MSG_EQ (currentTargetMarkCount, 1, "There should still be only 1 target exceeded marked packet");
946  NS_TEST_EXPECT_MSG_EQ (currentCeThreshMarkCount, 2, "There should still be 2 CE threshold exceeded marked packet as packets are not ecnCapable");
947  }
948  }
949  }
950  else if (testCase == 4)
951  {
952  if (currentTime < queue->GetTarget ())
953  {
954  if (initialCeThreshMarkCount == 0 && currentTime < MilliSeconds (2))
955  {
956  currentDropCount = queue->GetStats ().GetNDroppedPackets (CoDelQueueDisc::TARGET_EXCEEDED_DROP);
957  currentCeThreshMarkCount = queue->GetStats ().GetNMarkedPackets (CoDelQueueDisc::CE_THRESHOLD_EXCEEDED_MARK);
958  NS_TEST_EXPECT_MSG_EQ (queue->GetCurrentSize ().GetValue (), initialQSize - modeSize, "There should be 1 packet dequeued.");
959  NS_TEST_EXPECT_MSG_EQ (currentDropCount, 0, "There should not be any packet drops");
960  NS_TEST_ASSERT_MSG_EQ (currentCeThreshMarkCount, 0, "Sojourn time has not gone above CE threshold."
961  "Hence, there should not be any CE threshold exceeded marked packet");
962  }
963  else
964  {
965  currentDropCount = queue->GetStats ().GetNDroppedPackets (CoDelQueueDisc::TARGET_EXCEEDED_DROP);
966  currentCeThreshMarkCount = queue->GetStats ().GetNMarkedPackets (CoDelQueueDisc::CE_THRESHOLD_EXCEEDED_MARK);
967  NS_TEST_EXPECT_MSG_EQ (queue->GetCurrentSize ().GetValue (), initialQSize - modeSize, "There should be only 1 more packet dequeued.");
968  NS_TEST_EXPECT_MSG_EQ (currentDropCount, 0, "There should not be any packet drops");
969  NS_TEST_EXPECT_MSG_EQ (currentCeThreshMarkCount, 1, "Sojourn time has gone above CE threshold."
970  "There should be 1 CE threshold exceeded marked packet");
971  }
972  }
973  else if (initialCeThreshMarkCount > 0 && currentTime < queue->GetInterval ())
974  {
975  if (initialCeThreshMarkCount < 2)
976  {
977  currentDropCount = queue->GetStats ().GetNDroppedPackets (CoDelQueueDisc::TARGET_EXCEEDED_DROP);
978  currentCeThreshMarkCount = queue->GetStats ().GetNMarkedPackets (CoDelQueueDisc::CE_THRESHOLD_EXCEEDED_MARK);
979  NS_TEST_EXPECT_MSG_EQ (queue->GetCurrentSize ().GetValue (), initialQSize - modeSize, "There should be only 1 more packet dequeued.");
980  NS_TEST_EXPECT_MSG_EQ (currentDropCount, 0, "There should not be any packet drops");
981  NS_TEST_EXPECT_MSG_EQ (currentCeThreshMarkCount, 2, "There should be 2 CE threshold exceeded marked packets");
982  }
983  else
984  { // In dropping state
985  currentDropCount = queue->GetStats ().GetNDroppedPackets (CoDelQueueDisc::TARGET_EXCEEDED_DROP);
986  currentCeThreshMarkCount = queue->GetStats ().GetNMarkedPackets (CoDelQueueDisc::CE_THRESHOLD_EXCEEDED_MARK);
987  NS_TEST_EXPECT_MSG_EQ (queue->GetCurrentSize ().GetValue (), initialQSize - modeSize, "There should be only 1 more packet dequeued.");
988  NS_TEST_EXPECT_MSG_EQ (currentDropCount, 0, "There should not be any packet drops");
989  NS_TEST_EXPECT_MSG_EQ (currentCeThreshMarkCount, 3, "There should be 3 CE threshold exceeded marked packet");
990  }
991  }
992  }
993  }
994 }
995 
1002 static class CoDelQueueDiscTestSuite : public TestSuite
1003 {
1004 public:
1006  : TestSuite ("codel-queue-disc", UNIT)
1007  {
1008  // Test 1: simple enqueue/dequeue with no drops
1011  // Test 2: enqueue with drops due to queue overflow
1014  // Test 3: test NewtonStep() against explicit port of Linux implementation
1015  AddTestCase (new CoDelQueueDiscNewtonStepTest (), TestCase::QUICK);
1016  // Test 4: test ControlLaw() against explicit port of Linux implementation
1017  AddTestCase (new CoDelQueueDiscControlLawTest (), TestCase::QUICK);
1018  // Test 5: enqueue/dequeue with drops according to CoDel algorithm
1020  AddTestCase (new CoDelQueueDiscBasicDrop (QueueSizeUnit::BYTES), TestCase::QUICK);
1021  // Test 6: enqueue/dequeue with marks according to CoDel algorithm
1023  AddTestCase (new CoDelQueueDiscBasicMark (QueueSizeUnit::BYTES), TestCase::QUICK);
1024  }
virtual void DoRun(void)
Implementation to actually run this TestCase.
uint64_t GetUid(void) const
Returns the packet&#39;s Uid.
Definition: packet.cc:390
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:103
virtual void DoRun(void)
Implementation to actually run this TestCase.
static uint32_t ControlLaw(uint32_t t, uint32_t interval, uint32_t recInvSqrt)
Determine the time for next drop CoDel control law is t + m_interval/sqrt(m_count).
Codel Queue Disc Test Item.
AttributeValue implementation for Boolean.
Definition: boolean.h:36
Class for representing queue sizes.
Definition: queue-size.h:94
Test 6: enqueue/dequeue with marks according to CoDel algorithm.
bool Enqueue(Ptr< QueueDiscItem > item)
Pass a packet to store to the queue discipline.
Definition: queue-disc.cc:861
uint32_t nPacketsBeforeFirstDrop
Number of packets in the queue before first drop.
Hold variables of type string.
Definition: string.h:41
uint32_t GetValue() const
Get the underlying value.
Definition: queue-size.cc:175
uint32_t GetDropNext(void)
Get the time for next packet drop while in the dropping state.
QueueSizeUnit
Enumeration of the operating modes of queues.
Definition: queue-size.h:42
virtual void DoRun(void)
Implementation to actually run this TestCase.
QueueSize GetCurrentSize(void)
Get the current size of the queue disc in bytes, if operating in bytes mode, or packets, otherwise.
Definition: queue-disc.cc:523
virtual void DoRun(void)
Implementation to actually run this TestCase.
A suite of tests to run.
Definition: test.h:1343
#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.
Time MilliSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1297
#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:283
bool m_ecnCapablePacket
ECN capable packet?
#define NS_UNUSED(x)
Mark a local variable as unused.
Definition: unused.h:36
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
uint32_t nPacketsBeforeFirstMark
Number of packets in the queue before first mark.
QueueDiscItem is the abstract base class for items that are stored in a queue disc.
Definition: queue-item.h:148
static uint16_t NewtonStep(uint16_t recInvSqrt, uint32_t count)
Calculate the reciprocal square root of m_count by using Newton&#39;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)
encapsulates test code
Definition: test.h:1153
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
AttributeValue implementation for Time.
Definition: nstime.h:1353
void AddTestCase(TestCase *testCase, TestDuration duration=QUICK)
Add an individual child TestCase to this test suite.
Definition: test.cc:299
void Enqueue(Ptr< CoDelQueueDisc > queue, uint32_t size, uint32_t nPkt, bool ecnCapable)
Enqueue function.
Hold an unsigned integer type.
Definition: uinteger.h:44
uint32_t GetNDroppedPackets(std::string reason) const
Get the number of packets dropped for the given reason.
Definition: queue-disc.cc:110
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.
Definition: queue-size.h:44
#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:166
virtual void AddHeader(void)
Add the header to the packet.
static uint16_t _codel_Newton_step(uint16_t rec_inv_sqrt, uint32_t count)
const Stats & GetStats(void)
Retrieve all the collected statistics.
Definition: queue-disc.cc:421
CoDelQueueDiscBasicOverflow(QueueSizeUnit mode)
Constructor.
CoDelQueueDiscBasicDrop(QueueSizeUnit mode)
Constructor.
void DropNextTracer(uint32_t oldVal, uint32_t newVal)
Drop next tracer function.
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...
Definition: queue-disc.cc:896
int64_t GetMicroSeconds(void) const
Get an approximation of the time stored in this instance in the indicated unit.
Definition: nstime.h:388
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.
uint32_t GetNMarkedPackets(std::string reason) const
Get the number of packets marked for the given reason.
Definition: queue-disc.cc:152
Time GetTarget(void)
Get the target queue delay.
uint32_t m_dropNextCount
count the number of times m_dropNext is recalculated
void Enqueue(Ptr< CoDelQueueDisc > queue, uint32_t size, uint32_t nPkt)
Enqueue function.
CoDelQueueDiscTestSuite g_coDelQueueTestSuite
the test suite
void Dequeue(Ptr< CoDelQueueDisc > queue, uint32_t modeSize, uint32_t testCase)
Dequeue function.
uint32_t Time2CoDel(Time t)
Return the unsigned 32-bit integer representation of the input Time object.
CoDel Queue Disc Test Suite.
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1289
Time Now(void)
create an ns3::Time instance which contains the current simulation time.
Definition: simulator.cc:287
static uint32_t _reciprocal_scale(uint32_t val, uint32_t ep_ro)
This test suite implements a Unit Test.
Definition: test.h:1353
uint32_t pktSize
packet size used for the simulation (in bytes)
Definition: wifi-bianchi.cc:86
Use number of bytes for queue size.
Definition: queue-size.h:45
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.
Callback< R, Ts... > MakeCallback(R(T::*memPtr)(Ts...), OBJ objPtr)
Build Callbacks for class method members which take varying numbers of arguments and potentially retu...
Definition: callback.h:1642
void Initialize(void)
Invoke DoInitialize on all Objects aggregated to this one.
Definition: object.cc:183
uint32_t _codel_control_law(uint32_t t, uint32_t interval, uint32_t recInvSqrt)
Codel control law function.
CoDelQueueDiscBasicMark(QueueSizeUnit mode)
Constructor.
Test 2: enqueue with drops due to queue overflow.
CoDelQueueDiscBasicEnqueueDequeue(QueueSizeUnit mode)
Constructor.