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