A Discrete-Event Network Simulator
QKDNetSim v2.0 (NS-3 v3.41) @ (+)
API
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
codel-queue-disc-test-suite.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2014 ResiliNets, ITTC, University of Kansas
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License version 2 as
6  * published by the Free Software Foundation;
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License
14  * along with this program; if not, write to the Free Software
15  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16  *
17  * Author: Truc Anh N Nguyen <trucanh524@gmail.com>
18  * Modified by: Pasquale Imputato <p.imputato@gmail.com>
19  *
20  */
21 
22 #include "ns3/codel-queue-disc.h"
23 #include "ns3/double.h"
24 #include "ns3/log.h"
25 #include "ns3/packet.h"
26 #include "ns3/simulator.h"
27 #include "ns3/string.h"
28 #include "ns3/test.h"
29 #include "ns3/uinteger.h"
30 
31 using namespace ns3;
32 
33 // The following code borrowed from Linux codel.h, for unit testing
34 #define REC_INV_SQRT_BITS_ns3 (8 * sizeof(uint16_t))
35 /* or sizeof_in_bits(rec_inv_sqrt) */
36 /* needed shift to get a Q0.32 number from rec_inv_sqrt */
37 #define REC_INV_SQRT_SHIFT_ns3 (32 - REC_INV_SQRT_BITS_ns3)
38 
39 static uint16_t
40 _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
52 _reciprocal_scale(uint32_t val, uint32_t ep_ro)
53 {
54  return (uint32_t)(((uint64_t)val * ep_ro) >> 32);
55 }
56 
57 // End Linux borrow
58 
65 {
66  public:
74  CodelQueueDiscTestItem(Ptr<Packet> p, const Address& addr, bool ecnCapable);
75  ~CodelQueueDiscTestItem() override;
76 
77  // Delete default constructor, copy constructor and assignment operator to avoid misuse
81 
82  void AddHeader() override;
83  bool Mark() override;
84 
85  private:
87 };
88 
90  : QueueDiscItem(p, addr, 0),
91  m_ecnCapablePacket(ecnCapable)
92 {
93 }
94 
96 {
97 }
98 
99 void
101 {
102 }
103 
104 bool
106 {
107  return m_ecnCapablePacket;
108 }
109 
116 {
117  public:
124  void DoRun() override;
125 
126  private:
128 };
129 
131  : TestCase("Basic enqueue and dequeue operations, and attribute setting")
132 {
133  m_mode = mode;
134 }
135 
136 void
138 {
139  Ptr<CoDelQueueDisc> queue = CreateObject<CoDelQueueDisc>();
140 
141  uint32_t pktSize = 1000;
142  uint32_t modeSize = 0;
143 
144  Address dest;
145 
146  NS_TEST_ASSERT_MSG_EQ(queue->SetAttributeFailSafe("MinBytes", UintegerValue(pktSize)),
147  true,
148  "Verify that we can actually set the attribute MinBytes");
149  NS_TEST_ASSERT_MSG_EQ(queue->SetAttributeFailSafe("Interval", StringValue("50ms")),
150  true,
151  "Verify that we can actually set the attribute Interval");
152  NS_TEST_ASSERT_MSG_EQ(queue->SetAttributeFailSafe("Target", StringValue("4ms")),
153  true,
154  "Verify that we can actually set the attribute Target");
155 
157  {
158  modeSize = pktSize;
159  }
160  else if (m_mode == QueueSizeUnit::PACKETS)
161  {
162  modeSize = 1;
163  }
165  queue->SetAttributeFailSafe("MaxSize", QueueSizeValue(QueueSize(m_mode, modeSize * 1500))),
166  true,
167  "Verify that we can actually set the attribute MaxSize");
168  queue->Initialize();
169 
170  Ptr<Packet> p1;
171  Ptr<Packet> p2;
172  Ptr<Packet> p3;
173  Ptr<Packet> p4;
174  Ptr<Packet> p5;
175  Ptr<Packet> p6;
176  p1 = Create<Packet>(pktSize);
177  p2 = Create<Packet>(pktSize);
178  p3 = Create<Packet>(pktSize);
179  p4 = Create<Packet>(pktSize);
180  p5 = Create<Packet>(pktSize);
181  p6 = Create<Packet>(pktSize);
182 
183  NS_TEST_ASSERT_MSG_EQ(queue->GetCurrentSize().GetValue(),
184  0 * modeSize,
185  "There should be no packets in queue");
186  queue->Enqueue(Create<CodelQueueDiscTestItem>(p1, dest, false));
187  NS_TEST_ASSERT_MSG_EQ(queue->GetCurrentSize().GetValue(),
188  1 * modeSize,
189  "There should be one packet in queue");
190  queue->Enqueue(Create<CodelQueueDiscTestItem>(p2, dest, false));
191  NS_TEST_ASSERT_MSG_EQ(queue->GetCurrentSize().GetValue(),
192  2 * modeSize,
193  "There should be two packets in queue");
194  queue->Enqueue(Create<CodelQueueDiscTestItem>(p3, dest, false));
195  NS_TEST_ASSERT_MSG_EQ(queue->GetCurrentSize().GetValue(),
196  3 * modeSize,
197  "There should be three packets in queue");
198  queue->Enqueue(Create<CodelQueueDiscTestItem>(p4, dest, false));
199  NS_TEST_ASSERT_MSG_EQ(queue->GetCurrentSize().GetValue(),
200  4 * modeSize,
201  "There should be four packets in queue");
202  queue->Enqueue(Create<CodelQueueDiscTestItem>(p5, dest, false));
203  NS_TEST_ASSERT_MSG_EQ(queue->GetCurrentSize().GetValue(),
204  5 * modeSize,
205  "There should be five packets in queue");
206  queue->Enqueue(Create<CodelQueueDiscTestItem>(p6, dest, false));
207  NS_TEST_ASSERT_MSG_EQ(queue->GetCurrentSize().GetValue(),
208  6 * modeSize,
209  "There should be six packets in queue");
210 
211  NS_TEST_ASSERT_MSG_EQ(queue->GetStats().GetNDroppedPackets(CoDelQueueDisc::OVERLIMIT_DROP),
212  0,
213  "There should be no packets being dropped due to full queue");
214 
215  Ptr<QueueDiscItem> item;
216 
217  item = queue->Dequeue();
218  NS_TEST_ASSERT_MSG_NE(item, nullptr, "I want to remove the first packet");
219  NS_TEST_ASSERT_MSG_EQ(queue->GetCurrentSize().GetValue(),
220  5 * modeSize,
221  "There should be five packets in queue");
222  NS_TEST_ASSERT_MSG_EQ(item->GetPacket()->GetUid(), p1->GetUid(), "was this the first packet ?");
223 
224  item = queue->Dequeue();
225  NS_TEST_ASSERT_MSG_NE(item, nullptr, "I want to remove the second packet");
226  NS_TEST_ASSERT_MSG_EQ(queue->GetCurrentSize().GetValue(),
227  4 * modeSize,
228  "There should be four packets in queue");
229  NS_TEST_ASSERT_MSG_EQ(item->GetPacket()->GetUid(),
230  p2->GetUid(),
231  "Was this the second packet ?");
232 
233  item = queue->Dequeue();
234  NS_TEST_ASSERT_MSG_NE(item, nullptr, "I want to remove the third packet");
235  NS_TEST_ASSERT_MSG_EQ(queue->GetCurrentSize().GetValue(),
236  3 * modeSize,
237  "There should be three packets in queue");
238  NS_TEST_ASSERT_MSG_EQ(item->GetPacket()->GetUid(), p3->GetUid(), "Was this the third packet ?");
239 
240  item = queue->Dequeue();
241  NS_TEST_ASSERT_MSG_NE(item, nullptr, "I want to remove the forth packet");
242  NS_TEST_ASSERT_MSG_EQ(queue->GetCurrentSize().GetValue(),
243  2 * modeSize,
244  "There should be two packets in queue");
245  NS_TEST_ASSERT_MSG_EQ(item->GetPacket()->GetUid(),
246  p4->GetUid(),
247  "Was this the fourth packet ?");
248 
249  item = queue->Dequeue();
250  NS_TEST_ASSERT_MSG_NE(item, nullptr, "I want to remove the fifth packet");
251  NS_TEST_ASSERT_MSG_EQ(queue->GetCurrentSize().GetValue(),
252  1 * modeSize,
253  "There should be one packet in queue");
254  NS_TEST_ASSERT_MSG_EQ(item->GetPacket()->GetUid(), p5->GetUid(), "Was this the fifth packet ?");
255 
256  item = queue->Dequeue();
257  NS_TEST_ASSERT_MSG_NE(item, nullptr, "I want to remove the last packet");
258  NS_TEST_ASSERT_MSG_EQ(queue->GetCurrentSize().GetValue(),
259  0 * modeSize,
260  "There should be zero packet in queue");
261  NS_TEST_ASSERT_MSG_EQ(item->GetPacket()->GetUid(), p6->GetUid(), "Was this the sixth packet ?");
262 
263  item = queue->Dequeue();
264  NS_TEST_ASSERT_MSG_EQ(item, nullptr, "There are really no packets in queue");
265 
267  queue->GetStats().GetNDroppedPackets(CoDelQueueDisc::TARGET_EXCEEDED_DROP),
268  0,
269  "There should be no packet drops according to CoDel algorithm");
270 }
271 
278 {
279  public:
286  void DoRun() override;
287 
288  private:
295  void Enqueue(Ptr<CoDelQueueDisc> queue, uint32_t size, uint32_t nPkt);
297 };
298 
300  : TestCase("Basic overflow behavior")
301 {
302  m_mode = mode;
303 }
304 
305 void
307 {
308  Ptr<CoDelQueueDisc> queue = CreateObject<CoDelQueueDisc>();
309  uint32_t pktSize = 1000;
310  uint32_t modeSize = 0;
311 
312  Address dest;
313 
315  {
316  modeSize = pktSize;
317  }
318  else if (m_mode == QueueSizeUnit::PACKETS)
319  {
320  modeSize = 1;
321  }
322 
323  Ptr<Packet> p1;
324  Ptr<Packet> p2;
325  Ptr<Packet> p3;
326  p1 = Create<Packet>(pktSize);
327  p2 = Create<Packet>(pktSize);
328  p3 = Create<Packet>(pktSize);
329 
331  queue->SetAttributeFailSafe("MaxSize", QueueSizeValue(QueueSize(m_mode, modeSize * 500))),
332  true,
333  "Verify that we can actually set the attribute MaxSize");
334  NS_TEST_ASSERT_MSG_EQ(queue->SetAttributeFailSafe("MinBytes", UintegerValue(pktSize)),
335  true,
336  "Verify that we can actually set the attribute MinBytes");
337 
338  queue->Initialize();
339 
340  Enqueue(queue, pktSize, 500);
341  queue->Enqueue(Create<CodelQueueDiscTestItem>(p1, dest, false));
342  queue->Enqueue(Create<CodelQueueDiscTestItem>(p2, dest, false));
343  queue->Enqueue(Create<CodelQueueDiscTestItem>(p3, dest, false));
344 
345  NS_TEST_ASSERT_MSG_EQ(queue->GetCurrentSize().GetValue(),
346  500 * modeSize,
347  "There should be 500 packets in queue");
348  NS_TEST_ASSERT_MSG_EQ(queue->GetStats().GetNDroppedPackets(CoDelQueueDisc::OVERLIMIT_DROP),
349  3,
350  "There should be three packets being dropped due to full queue");
351 }
352 
353 void
354 CoDelQueueDiscBasicOverflow::Enqueue(Ptr<CoDelQueueDisc> queue, uint32_t size, uint32_t nPkt)
355 {
356  Address dest;
357  for (uint32_t i = 0; i < nPkt; i++)
358  {
359  queue->Enqueue(Create<CodelQueueDiscTestItem>(Create<Packet>(size), dest, false));
360  }
361 }
362 
369 {
370  public:
372  void DoRun() override;
373 };
374 
376  : TestCase("NewtonStep arithmetic unit test")
377 {
378 }
379 
380 void
382 {
383  Ptr<CoDelQueueDisc> queue = CreateObject<CoDelQueueDisc>();
384 
385  // Spot check a few points in the expected operational range of
386  // CoDelQueueDisc's m_count and m_recInvSqrt variables
387  uint16_t result;
388  for (uint16_t recInvSqrt = 0xff; recInvSqrt > 0; recInvSqrt /= 2)
389  {
390  for (uint32_t count = 1; count < 0xff; count *= 2)
391  {
392  result = queue->NewtonStep(recInvSqrt, count);
393  // Test that ns-3 value is exactly the same as the Linux value
394  NS_TEST_ASSERT_MSG_EQ(_codel_Newton_step(recInvSqrt, count),
395  result,
396  "ns-3 NewtonStep() fails to match Linux equivalent");
397  }
398  }
399 }
400 
407 {
408  public:
410  void DoRun() override;
418  uint32_t _codel_control_law(uint32_t t, uint32_t interval, uint32_t recInvSqrt);
419 };
420 
422  : TestCase("ControlLaw arithmetic unit test")
423 {
424 }
425 
426 // The following code borrowed from Linux codel.h,
427 // except the addition of queue parameter
428 uint32_t
429 CoDelQueueDiscControlLawTest::_codel_control_law(uint32_t t, uint32_t interval, uint32_t recInvSqrt)
430 {
431  return t + _reciprocal_scale(interval, recInvSqrt << REC_INV_SQRT_SHIFT_ns3);
432 }
433 
434 // End Linux borrow
435 
436 void
438 {
439  Ptr<CoDelQueueDisc> queue = CreateObject<CoDelQueueDisc>();
440 
441  // Check a few points within the operational range of ControlLaw
442  uint32_t interval = queue->Time2CoDel(MilliSeconds(100));
443 
444  uint32_t codelTimeVal;
445  for (Time timeVal = Seconds(0); timeVal <= Seconds(20); timeVal += MilliSeconds(100))
446  {
447  for (uint16_t recInvSqrt = 0xff; recInvSqrt > 0; recInvSqrt /= 2)
448  {
449  codelTimeVal = queue->Time2CoDel(timeVal);
450  uint32_t ns3Result = queue->ControlLaw(codelTimeVal, interval, recInvSqrt);
451  uint32_t linuxResult = _codel_control_law(codelTimeVal, interval, recInvSqrt);
452  NS_TEST_ASSERT_MSG_EQ(ns3Result,
453  linuxResult,
454  "Linux result for ControlLaw should equal ns-3 result");
455  }
456  }
457 }
458 
465 {
466  public:
473  void DoRun() override;
474 
475  private:
482  void Enqueue(Ptr<CoDelQueueDisc> queue, uint32_t size, uint32_t nPkt);
487  void Dequeue(Ptr<CoDelQueueDisc> queue, uint32_t modeSize);
493  void DropNextTracer(uint32_t oldVal, uint32_t newVal);
495  uint32_t m_dropNextCount;
496 };
497 
499  : TestCase("Basic drop operations")
500 {
501  m_mode = mode;
502  m_dropNextCount = 0;
503 }
504 
505 void
506 CoDelQueueDiscBasicDrop::DropNextTracer(uint32_t /* oldVal */, uint32_t /* newVal */)
507 {
508  m_dropNextCount++;
509 }
510 
511 void
513 {
514  Ptr<CoDelQueueDisc> queue = CreateObject<CoDelQueueDisc>();
515  uint32_t pktSize = 1000;
516  uint32_t modeSize = 0;
517 
519  {
520  modeSize = pktSize;
521  }
522  else if (m_mode == QueueSizeUnit::PACKETS)
523  {
524  modeSize = 1;
525  }
526 
528  queue->SetAttributeFailSafe("MaxSize", QueueSizeValue(QueueSize(m_mode, modeSize * 500))),
529  true,
530  "Verify that we can actually set the attribute MaxSize");
531 
532  queue->Initialize();
533 
534  Enqueue(queue, pktSize, 20);
535  NS_TEST_ASSERT_MSG_EQ(queue->GetCurrentSize().GetValue(),
536  20 * modeSize,
537  "There should be 20 packets in queue.");
538 
539  // Although the first dequeue occurs with a sojourn time above target
540  // the dequeue should be successful in this interval
541  Time waitUntilFirstDequeue = 2 * queue->GetTarget();
542  Simulator::Schedule(waitUntilFirstDequeue,
544  this,
545  queue,
546  modeSize);
547 
548  // This dequeue should cause a drop
549  Time waitUntilSecondDequeue = waitUntilFirstDequeue + 2 * queue->GetInterval();
550  Simulator::Schedule(waitUntilSecondDequeue,
552  this,
553  queue,
554  modeSize);
555 
556  // Although we are in dropping state, it's not time for next drop
557  // the dequeue should not cause a drop
558  Simulator::Schedule(waitUntilSecondDequeue,
560  this,
561  queue,
562  modeSize);
563 
564  // In dropping time and it's time for next drop
565  // the dequeue should cause additional packet drops
566  Simulator::Schedule(waitUntilSecondDequeue * 2,
568  this,
569  queue,
570  modeSize);
571 
572  Simulator::Run();
573  Simulator::Destroy();
574 }
575 
576 void
577 CoDelQueueDiscBasicDrop::Enqueue(Ptr<CoDelQueueDisc> queue, uint32_t size, uint32_t nPkt)
578 {
579  Address dest;
580  for (uint32_t i = 0; i < nPkt; i++)
581  {
582  queue->Enqueue(Create<CodelQueueDiscTestItem>(Create<Packet>(size), dest, false));
583  }
584 }
585 
586 void
588 {
589  uint32_t initialDropCount =
590  queue->GetStats().GetNDroppedPackets(CoDelQueueDisc::TARGET_EXCEEDED_DROP);
591  uint32_t initialQSize = queue->GetCurrentSize().GetValue();
592  uint32_t initialDropNext = queue->GetDropNext();
593  Time currentTime = Simulator::Now();
594  uint32_t currentDropCount = 0;
595 
596  if (initialDropCount > 0 && currentTime.GetMicroSeconds() >= initialDropNext)
597  {
598  queue->TraceConnectWithoutContext(
599  "DropNext",
601  }
602 
603  if (initialQSize != 0)
604  {
605  Ptr<QueueDiscItem> item = queue->Dequeue();
606  if (initialDropCount == 0 && currentTime > queue->GetTarget())
607  {
608  if (currentTime < queue->GetInterval())
609  {
610  currentDropCount =
611  queue->GetStats().GetNDroppedPackets(CoDelQueueDisc::TARGET_EXCEEDED_DROP);
612  NS_TEST_EXPECT_MSG_EQ(currentDropCount,
613  0,
614  "We are not in dropping state."
615  "Sojourn time has just gone above target from below."
616  "Hence, there should be no packet drops");
617  NS_TEST_EXPECT_MSG_EQ(queue->GetCurrentSize().GetValue(),
618  initialQSize - modeSize,
619  "There should be 1 packet dequeued.");
620  }
621  else if (currentTime >= queue->GetInterval())
622  {
623  currentDropCount =
624  queue->GetStats().GetNDroppedPackets(CoDelQueueDisc::TARGET_EXCEEDED_DROP);
625  NS_TEST_EXPECT_MSG_EQ(queue->GetCurrentSize().GetValue(),
626  initialQSize - 2 * modeSize,
627  "Sojourn time has been above target for at least interval."
628  "We enter the dropping state, perform initial packet drop, "
629  "and dequeue the next."
630  "So there should be 2 more packets dequeued.");
631  NS_TEST_EXPECT_MSG_EQ(currentDropCount, 1, "There should be 1 packet drop");
632  }
633  }
634  else if (initialDropCount > 0)
635  { // In dropping state
636  if (currentTime.GetMicroSeconds() < initialDropNext)
637  {
638  currentDropCount =
639  queue->GetStats().GetNDroppedPackets(CoDelQueueDisc::TARGET_EXCEEDED_DROP);
640  NS_TEST_EXPECT_MSG_EQ(queue->GetCurrentSize().GetValue(),
641  initialQSize - modeSize,
642  "We are in dropping state."
643  "Sojourn is still above target."
644  "However, it's not time for next drop."
645  "So there should be only 1 more packet dequeued");
646 
648  currentDropCount,
649  1,
650  "There should still be only 1 packet drop from the last dequeue");
651  }
652  else if (currentTime.GetMicroSeconds() >= initialDropNext)
653  {
654  currentDropCount =
655  queue->GetStats().GetNDroppedPackets(CoDelQueueDisc::TARGET_EXCEEDED_DROP);
656  NS_TEST_EXPECT_MSG_EQ(queue->GetCurrentSize().GetValue(),
657  initialQSize - (m_dropNextCount + 1) * modeSize,
658  "We are in dropping state."
659  "It's time for next drop."
660  "The number of packets dequeued equals to the number of "
661  "times m_dropNext is updated plus initial dequeue");
662  NS_TEST_EXPECT_MSG_EQ(currentDropCount,
663  1 + m_dropNextCount,
664  "The number of drops equals to the number of times "
665  "m_dropNext is updated plus 1 from last dequeue");
666  }
667  }
668  }
669 }
670 
677 {
678  public:
685  void DoRun() override;
686 
687  private:
695  void Enqueue(Ptr<CoDelQueueDisc> queue, uint32_t size, uint32_t nPkt, bool ecnCapable);
701  void Dequeue(Ptr<CoDelQueueDisc> queue, uint32_t modeSize, uint32_t testCase);
707  void DropNextTracer(uint32_t oldVal, uint32_t newVal);
709  uint32_t m_dropNextCount;
712 };
713 
715  : TestCase("Basic mark operations")
716 {
717  m_mode = mode;
718  m_dropNextCount = 0;
719 }
720 
721 void
722 CoDelQueueDiscBasicMark::DropNextTracer(uint32_t /* oldVal */, uint32_t /* newVal */)
723 {
724  m_dropNextCount++;
725 }
726 
727 void
729 {
730  // Test is divided into 4 sub test cases:
731  // 1) Packets are not ECN capable.
732  // 2) Packets are ECN capable but marking due to exceeding CE threshold disabled
733  // 3) Some packets are ECN capable, with CE threshold set to 2ms.
734  // 4) Packets are ECN capable and CE threshold set to 2ms
735 
736  // Test case 1
737  Ptr<CoDelQueueDisc> queue = CreateObject<CoDelQueueDisc>();
738  uint32_t pktSize = 1000;
739  uint32_t modeSize = 0;
742 
744  {
745  modeSize = pktSize;
746  }
747  else if (m_mode == QueueSizeUnit::PACKETS)
748  {
749  modeSize = 1;
750  }
751 
753  queue->SetAttributeFailSafe("MaxSize", QueueSizeValue(QueueSize(m_mode, modeSize * 500))),
754  true,
755  "Verify that we can actually set the attribute MaxSize");
756  NS_TEST_ASSERT_MSG_EQ(queue->SetAttributeFailSafe("UseEcn", BooleanValue(true)),
757  true,
758  "Verify that we can actually set the attribute UseEcn");
759 
760  queue->Initialize();
761 
762  // Not-ECT traffic to induce packet drop
763  Enqueue(queue, pktSize, 20, false);
764  NS_TEST_ASSERT_MSG_EQ(queue->GetCurrentSize().GetValue(),
765  20 * modeSize,
766  "There should be 20 packets in queue.");
767 
768  // Although the first dequeue occurs with a sojourn time above target
769  // there should not be any dropped packets in this interval
770  Time waitUntilFirstDequeue = 2 * queue->GetTarget();
771  Simulator::Schedule(waitUntilFirstDequeue,
773  this,
774  queue,
775  modeSize,
776  1);
777 
778  // This dequeue should cause a packet to be dropped
779  Time waitUntilSecondDequeue = waitUntilFirstDequeue + 2 * queue->GetInterval();
780  Simulator::Schedule(waitUntilSecondDequeue,
782  this,
783  queue,
784  modeSize,
785  1);
786 
787  Simulator::Run();
788  Simulator::Destroy();
789 
790  // Test case 2, queue with ECN capable traffic for marking of packets instead of dropping
791  queue = CreateObject<CoDelQueueDisc>();
793  queue->SetAttributeFailSafe("MaxSize", QueueSizeValue(QueueSize(m_mode, modeSize * 500))),
794  true,
795  "Verify that we can actually set the attribute MaxSize");
796  NS_TEST_ASSERT_MSG_EQ(queue->SetAttributeFailSafe("UseEcn", BooleanValue(true)),
797  true,
798  "Verify that we can actually set the attribute UseEcn");
799 
800  queue->Initialize();
801 
802  // ECN capable traffic to induce packets to be marked
803  Enqueue(queue, pktSize, 20, true);
804  NS_TEST_ASSERT_MSG_EQ(queue->GetCurrentSize().GetValue(),
805  20 * modeSize,
806  "There should be 20 packets in queue.");
807 
808  // Although the first dequeue occurs with a sojourn time above target
809  // there should not be any target exceeded marked packets in this interval
810  Simulator::Schedule(waitUntilFirstDequeue,
812  this,
813  queue,
814  modeSize,
815  2);
816 
817  // This dequeue should cause a packet to be marked
818  Simulator::Schedule(waitUntilSecondDequeue,
820  this,
821  queue,
822  modeSize,
823  2);
824 
825  // Although we are in dropping state, it's not time for next packet to be target exceeded marked
826  // the dequeue should not cause a packet to be target exceeded marked
827  Simulator::Schedule(waitUntilSecondDequeue,
829  this,
830  queue,
831  modeSize,
832  2);
833 
834  // In dropping time and it's time for next packet to be target exceeded marked
835  // the dequeue should cause additional packet to be target exceeded marked
836  Simulator::Schedule(waitUntilSecondDequeue * 2,
838  this,
839  queue,
840  modeSize,
841  2);
842 
843  Simulator::Run();
844  Simulator::Destroy();
845 
846  // Test case 3, some packets are ECN capable, with CE threshold set to 2ms
847  queue = CreateObject<CoDelQueueDisc>();
849  queue->SetAttributeFailSafe("MaxSize", QueueSizeValue(QueueSize(m_mode, modeSize * 500))),
850  true,
851  "Verify that we can actually set the attribute MaxSize");
852  NS_TEST_ASSERT_MSG_EQ(queue->SetAttributeFailSafe("UseEcn", BooleanValue(true)),
853  true,
854  "Verify that we can actually set the attribute UseEcn");
855  NS_TEST_ASSERT_MSG_EQ(queue->SetAttributeFailSafe("CeThreshold", TimeValue(MilliSeconds(2))),
856  true,
857  "Verify that we can actually set the attribute CeThreshold");
858 
859  queue->Initialize();
860 
861  // First 3 packets in the queue are ecnCapable
862  Enqueue(queue, pktSize, 3, true);
863  // Rest of the packet are not ecnCapable
864  Enqueue(queue, pktSize, 17, false);
865  NS_TEST_ASSERT_MSG_EQ(queue->GetCurrentSize().GetValue(),
866  20 * modeSize,
867  "There should be 20 packets in queue.");
868 
869  // Although the first dequeue occurs with a sojourn time above target
870  // there should not be any target exceeded marked packets in this interval
871  Simulator::Schedule(waitUntilFirstDequeue,
873  this,
874  queue,
875  modeSize,
876  3);
877 
878  // This dequeue should cause a packet to be marked
879  Simulator::Schedule(waitUntilSecondDequeue,
881  this,
882  queue,
883  modeSize,
884  3);
885 
886  // Although we are in dropping state, it's not time for next packet to be target exceeded marked
887  // the dequeue should not cause a packet to be target exceeded marked
888  Simulator::Schedule(waitUntilSecondDequeue,
890  this,
891  queue,
892  modeSize,
893  3);
894 
895  // In dropping time and it's time for next packet to be dropped as packets are not ECN capable
896  // the dequeue should cause packet to be dropped
897  Simulator::Schedule(waitUntilSecondDequeue * 2,
899  this,
900  queue,
901  modeSize,
902  3);
903 
904  Simulator::Run();
905  Simulator::Destroy();
906 
907  // Test case 4, queue with ECN capable traffic and CeThreshold set for marking of packets
908  // instead of dropping
909  queue = CreateObject<CoDelQueueDisc>();
911  queue->SetAttributeFailSafe("MaxSize", QueueSizeValue(QueueSize(m_mode, modeSize * 500))),
912  true,
913  "Verify that we can actually set the attribute MaxSize");
914  NS_TEST_ASSERT_MSG_EQ(queue->SetAttributeFailSafe("UseEcn", BooleanValue(true)),
915  true,
916  "Verify that we can actually set the attribute UseEcn");
917  NS_TEST_ASSERT_MSG_EQ(queue->SetAttributeFailSafe("CeThreshold", TimeValue(MilliSeconds(2))),
918  true,
919  "Verify that we can actually set the attribute CeThreshold");
920 
921  queue->Initialize();
922 
923  // ECN capable traffic to induce packets to be marked
924  Enqueue(queue, pktSize, 20, true);
925  NS_TEST_ASSERT_MSG_EQ(queue->GetCurrentSize().GetValue(),
926  20 * modeSize,
927  "There should be 20 packets in queue.");
928 
929  // The first dequeue occurs with a sojourn time below CE threshold
930  // there should not any be CE threshold exceeded marked packets
931  Simulator::Schedule(MilliSeconds(1),
933  this,
934  queue,
935  modeSize,
936  4);
937 
938  // Sojourn time above CE threshold so this dequeue should cause a packet to be CE thershold
939  // exceeded marked
940  Simulator::Schedule(MilliSeconds(3),
942  this,
943  queue,
944  modeSize,
945  4);
946 
947  // the dequeue should cause a packet to be CE threshold exceeded marked
948  Simulator::Schedule(waitUntilFirstDequeue,
950  this,
951  queue,
952  modeSize,
953  4);
954 
955  // In dropping time and it's time for next packet to be dropped but because of using ECN, packet
956  // should be marked
957  Simulator::Schedule(waitUntilSecondDequeue,
959  this,
960  queue,
961  modeSize,
962  4);
963 
964  Simulator::Run();
965  Simulator::Destroy();
966 }
967 
968 void
970  uint32_t size,
971  uint32_t nPkt,
972  bool ecnCapable)
973 {
974  Address dest;
975  for (uint32_t i = 0; i < nPkt; i++)
976  {
977  queue->Enqueue(Create<CodelQueueDiscTestItem>(Create<Packet>(size), dest, ecnCapable));
978  }
979 }
980 
981 void
982 CoDelQueueDiscBasicMark::Dequeue(Ptr<CoDelQueueDisc> queue, uint32_t modeSize, uint32_t testCase)
983 {
984  uint32_t initialTargetMarkCount =
985  queue->GetStats().GetNMarkedPackets(CoDelQueueDisc::TARGET_EXCEEDED_MARK);
986  uint32_t initialCeThreshMarkCount =
987  queue->GetStats().GetNMarkedPackets(CoDelQueueDisc::CE_THRESHOLD_EXCEEDED_MARK);
988  uint32_t initialQSize = queue->GetCurrentSize().GetValue();
989  uint32_t initialDropNext = queue->GetDropNext();
990  Time currentTime = Simulator::Now();
991  uint32_t currentDropCount = 0;
992  uint32_t currentTargetMarkCount = 0;
993  uint32_t currentCeThreshMarkCount = 0;
994 
995  if (initialTargetMarkCount > 0 && currentTime.GetMicroSeconds() >= initialDropNext &&
996  testCase == 3)
997  {
998  queue->TraceConnectWithoutContext(
999  "DropNext",
1001  }
1002 
1003  if (initialQSize != 0)
1004  {
1005  Ptr<QueueDiscItem> item = queue->Dequeue();
1006  if (testCase == 1)
1007  {
1008  currentDropCount =
1009  queue->GetStats().GetNDroppedPackets(CoDelQueueDisc::TARGET_EXCEEDED_DROP);
1010  if (currentDropCount == 1)
1011  {
1012  nPacketsBeforeFirstDrop = initialQSize;
1013  }
1014  }
1015  else if (testCase == 2)
1016  {
1017  if (initialTargetMarkCount == 0 && currentTime > queue->GetTarget())
1018  {
1019  if (currentTime < queue->GetInterval())
1020  {
1021  currentDropCount =
1022  queue->GetStats().GetNDroppedPackets(CoDelQueueDisc::TARGET_EXCEEDED_DROP);
1023  currentTargetMarkCount =
1024  queue->GetStats().GetNMarkedPackets(CoDelQueueDisc::TARGET_EXCEEDED_MARK);
1025  currentCeThreshMarkCount = queue->GetStats().GetNMarkedPackets(
1026  CoDelQueueDisc::CE_THRESHOLD_EXCEEDED_MARK);
1027  NS_TEST_ASSERT_MSG_EQ(queue->GetCurrentSize().GetValue(),
1028  initialQSize - modeSize,
1029  "There should be 1 packet dequeued.");
1030  NS_TEST_ASSERT_MSG_EQ(currentDropCount,
1031  0,
1032  "There should not be any packet drops");
1034  currentTargetMarkCount,
1035  0,
1036  "We are not in dropping state."
1037  "Sojourn time has just gone above target from below."
1038  "Hence, there should be no target exceeded marked packets");
1040  currentCeThreshMarkCount,
1041  0,
1042  "Marking due to CE threshold is disabled"
1043  "Hence, there should not be any CE threshold exceeded marked packet");
1044  }
1045  else if (currentTime >= queue->GetInterval())
1046  {
1047  currentDropCount =
1048  queue->GetStats().GetNDroppedPackets(CoDelQueueDisc::TARGET_EXCEEDED_DROP);
1049  currentTargetMarkCount =
1050  queue->GetStats().GetNMarkedPackets(CoDelQueueDisc::TARGET_EXCEEDED_MARK);
1051  nPacketsBeforeFirstMark = initialQSize;
1052  currentCeThreshMarkCount = queue->GetStats().GetNMarkedPackets(
1053  CoDelQueueDisc::CE_THRESHOLD_EXCEEDED_MARK);
1055  queue->GetCurrentSize().GetValue(),
1056  initialQSize - modeSize,
1057  "Sojourn time has been above target for at least interval."
1058  "We enter the dropping state and perform initial packet marking"
1059  "So there should be only 1 more packet dequeued.");
1060  NS_TEST_ASSERT_MSG_EQ(currentDropCount,
1061  0,
1062  "There should not be any packet drops");
1063  NS_TEST_ASSERT_MSG_EQ(currentTargetMarkCount,
1064  1,
1065  "There should be 1 target exceeded marked packet");
1067  currentCeThreshMarkCount,
1068  0,
1069  "There should not be any CE threshold exceeded marked packet");
1070  }
1071  }
1072  else if (initialTargetMarkCount > 0)
1073  { // In dropping state
1074  if (currentTime.GetMicroSeconds() < initialDropNext)
1075  {
1076  currentDropCount =
1077  queue->GetStats().GetNDroppedPackets(CoDelQueueDisc::TARGET_EXCEEDED_DROP);
1078  currentTargetMarkCount =
1079  queue->GetStats().GetNMarkedPackets(CoDelQueueDisc::TARGET_EXCEEDED_MARK);
1080  currentCeThreshMarkCount = queue->GetStats().GetNMarkedPackets(
1081  CoDelQueueDisc::CE_THRESHOLD_EXCEEDED_MARK);
1082  NS_TEST_ASSERT_MSG_EQ(queue->GetCurrentSize().GetValue(),
1083  initialQSize - modeSize,
1084  "We are in dropping state."
1085  "Sojourn is still above target."
1086  "However, it's not time for next target exceeded mark."
1087  "So there should be only 1 more packet dequeued");
1088  NS_TEST_ASSERT_MSG_EQ(currentDropCount,
1089  0,
1090  "There should not be any packet drops");
1091  NS_TEST_ASSERT_MSG_EQ(currentTargetMarkCount,
1092  1,
1093  "There should still be only 1 target exceeded marked "
1094  "packet from the last dequeue");
1096  currentCeThreshMarkCount,
1097  0,
1098  "There should not be any CE threshold exceeded marked packet");
1099  }
1100  else if (currentTime.GetMicroSeconds() >= initialDropNext)
1101  {
1102  currentDropCount =
1103  queue->GetStats().GetNDroppedPackets(CoDelQueueDisc::TARGET_EXCEEDED_DROP);
1104  currentTargetMarkCount =
1105  queue->GetStats().GetNMarkedPackets(CoDelQueueDisc::TARGET_EXCEEDED_MARK);
1106  currentCeThreshMarkCount = queue->GetStats().GetNMarkedPackets(
1107  CoDelQueueDisc::CE_THRESHOLD_EXCEEDED_MARK);
1108  NS_TEST_ASSERT_MSG_EQ(queue->GetCurrentSize().GetValue(),
1109  initialQSize - modeSize,
1110  "We are in dropping state."
1111  "It's time for packet to be marked"
1112  "So there should be only 1 more packet dequeued");
1113  NS_TEST_ASSERT_MSG_EQ(currentDropCount,
1114  0,
1115  "There should not be any packet drops");
1116  NS_TEST_ASSERT_MSG_EQ(currentTargetMarkCount,
1117  2,
1118  "There should 2 target exceeded marked packet");
1122  "Number of packets in the queue before drop should be equal"
1123  "to number of packets in the queue before first mark as the behavior "
1124  "until packet N should be the same.");
1126  currentCeThreshMarkCount,
1127  0,
1128  "There should not be any CE threshold exceeded marked packet");
1129  }
1130  }
1131  }
1132  else if (testCase == 3)
1133  {
1134  if (initialTargetMarkCount == 0 && currentTime > queue->GetTarget())
1135  {
1136  if (currentTime < queue->GetInterval())
1137  {
1138  currentDropCount =
1139  queue->GetStats().GetNDroppedPackets(CoDelQueueDisc::TARGET_EXCEEDED_DROP);
1140  currentTargetMarkCount =
1141  queue->GetStats().GetNMarkedPackets(CoDelQueueDisc::TARGET_EXCEEDED_MARK);
1142  currentCeThreshMarkCount = queue->GetStats().GetNMarkedPackets(
1143  CoDelQueueDisc::CE_THRESHOLD_EXCEEDED_MARK);
1144  NS_TEST_ASSERT_MSG_EQ(queue->GetCurrentSize().GetValue(),
1145  initialQSize - modeSize,
1146  "There should be 1 packet dequeued.");
1147  NS_TEST_ASSERT_MSG_EQ(currentDropCount,
1148  0,
1149  "There should not be any packet drops");
1151  currentTargetMarkCount,
1152  0,
1153  "We are not in dropping state."
1154  "Sojourn time has just gone above target from below."
1155  "Hence, there should be no target exceeded marked packets");
1157  currentCeThreshMarkCount,
1158  1,
1159  "Sojourn time has gone above CE threshold."
1160  "Hence, there should be 1 CE threshold exceeded marked packet");
1161  }
1162  else if (currentTime >= queue->GetInterval())
1163  {
1164  currentDropCount =
1165  queue->GetStats().GetNDroppedPackets(CoDelQueueDisc::TARGET_EXCEEDED_DROP);
1166  currentTargetMarkCount =
1167  queue->GetStats().GetNMarkedPackets(CoDelQueueDisc::TARGET_EXCEEDED_MARK);
1168  currentCeThreshMarkCount = queue->GetStats().GetNMarkedPackets(
1169  CoDelQueueDisc::CE_THRESHOLD_EXCEEDED_MARK);
1171  queue->GetCurrentSize().GetValue(),
1172  initialQSize - modeSize,
1173  "Sojourn time has been above target for at least interval."
1174  "We enter the dropping state and perform initial packet marking"
1175  "So there should be only 1 more packet dequeued.");
1176  NS_TEST_ASSERT_MSG_EQ(currentDropCount,
1177  0,
1178  "There should not be any packet drops");
1179  NS_TEST_ASSERT_MSG_EQ(currentTargetMarkCount,
1180  1,
1181  "There should be 1 target exceeded marked packet");
1182  NS_TEST_ASSERT_MSG_EQ(currentCeThreshMarkCount,
1183  1,
1184  "There should be 1 CE threshold exceeded marked packets");
1185  }
1186  }
1187  else if (initialTargetMarkCount > 0)
1188  { // In dropping state
1189  if (currentTime.GetMicroSeconds() < initialDropNext)
1190  {
1191  currentDropCount =
1192  queue->GetStats().GetNDroppedPackets(CoDelQueueDisc::TARGET_EXCEEDED_DROP);
1193  currentTargetMarkCount =
1194  queue->GetStats().GetNMarkedPackets(CoDelQueueDisc::TARGET_EXCEEDED_MARK);
1195  currentCeThreshMarkCount = queue->GetStats().GetNMarkedPackets(
1196  CoDelQueueDisc::CE_THRESHOLD_EXCEEDED_MARK);
1197  NS_TEST_ASSERT_MSG_EQ(queue->GetCurrentSize().GetValue(),
1198  initialQSize - modeSize,
1199  "We are in dropping state."
1200  "Sojourn is still above target."
1201  "However, it's not time for next target exceeded mark."
1202  "So there should be only 1 more packet dequeued");
1203  NS_TEST_ASSERT_MSG_EQ(currentDropCount,
1204  0,
1205  "There should not be any packet drops");
1206  NS_TEST_ASSERT_MSG_EQ(currentTargetMarkCount,
1207  1,
1208  "There should still be only 1 target exceeded marked "
1209  "packet from the last dequeue");
1210  NS_TEST_ASSERT_MSG_EQ(currentCeThreshMarkCount,
1211  2,
1212  "There should be 2 CE threshold exceeded marked packets");
1213  }
1214  else if (currentTime.GetMicroSeconds() >= initialDropNext)
1215  {
1216  currentDropCount =
1217  queue->GetStats().GetNDroppedPackets(CoDelQueueDisc::TARGET_EXCEEDED_DROP);
1218  currentTargetMarkCount =
1219  queue->GetStats().GetNMarkedPackets(CoDelQueueDisc::TARGET_EXCEEDED_MARK);
1220  currentCeThreshMarkCount = queue->GetStats().GetNMarkedPackets(
1221  CoDelQueueDisc::CE_THRESHOLD_EXCEEDED_MARK);
1223  queue->GetCurrentSize().GetValue(),
1224  initialQSize - (m_dropNextCount + 1) * modeSize,
1225  "We are in dropping state."
1226  "It's time for packet to be dropped as packets are not ecnCapable"
1227  "The number of packets dequeued equals to the number of times m_dropNext "
1228  "is updated plus initial dequeue");
1230  currentDropCount,
1232  "The number of drops equals to the number of times m_dropNext is updated");
1234  currentTargetMarkCount,
1235  1,
1236  "There should still be only 1 target exceeded marked packet");
1237  NS_TEST_ASSERT_MSG_EQ(currentCeThreshMarkCount,
1238  2,
1239  "There should still be 2 CE threshold exceeded marked "
1240  "packet as packets are not ecnCapable");
1241  }
1242  }
1243  }
1244  else if (testCase == 4)
1245  {
1246  if (currentTime < queue->GetTarget())
1247  {
1248  if (initialCeThreshMarkCount == 0 && currentTime < MilliSeconds(2))
1249  {
1250  currentDropCount =
1251  queue->GetStats().GetNDroppedPackets(CoDelQueueDisc::TARGET_EXCEEDED_DROP);
1252  currentCeThreshMarkCount = queue->GetStats().GetNMarkedPackets(
1253  CoDelQueueDisc::CE_THRESHOLD_EXCEEDED_MARK);
1254  NS_TEST_ASSERT_MSG_EQ(queue->GetCurrentSize().GetValue(),
1255  initialQSize - modeSize,
1256  "There should be 1 packet dequeued.");
1257  NS_TEST_ASSERT_MSG_EQ(currentDropCount,
1258  0,
1259  "There should not be any packet drops");
1261  currentCeThreshMarkCount,
1262  0,
1263  "Sojourn time has not gone above CE threshold."
1264  "Hence, there should not be any CE threshold exceeded marked packet");
1265  }
1266  else
1267  {
1268  currentDropCount =
1269  queue->GetStats().GetNDroppedPackets(CoDelQueueDisc::TARGET_EXCEEDED_DROP);
1270  currentCeThreshMarkCount = queue->GetStats().GetNMarkedPackets(
1271  CoDelQueueDisc::CE_THRESHOLD_EXCEEDED_MARK);
1272  NS_TEST_ASSERT_MSG_EQ(queue->GetCurrentSize().GetValue(),
1273  initialQSize - modeSize,
1274  "There should be only 1 more packet dequeued.");
1275  NS_TEST_ASSERT_MSG_EQ(currentDropCount,
1276  0,
1277  "There should not be any packet drops");
1278  NS_TEST_ASSERT_MSG_EQ(currentCeThreshMarkCount,
1279  1,
1280  "Sojourn time has gone above CE threshold."
1281  "There should be 1 CE threshold exceeded marked packet");
1282  }
1283  }
1284  else if (initialCeThreshMarkCount > 0 && currentTime < queue->GetInterval())
1285  {
1286  if (initialCeThreshMarkCount < 2)
1287  {
1288  currentDropCount =
1289  queue->GetStats().GetNDroppedPackets(CoDelQueueDisc::TARGET_EXCEEDED_DROP);
1290  currentCeThreshMarkCount = queue->GetStats().GetNMarkedPackets(
1291  CoDelQueueDisc::CE_THRESHOLD_EXCEEDED_MARK);
1292  NS_TEST_ASSERT_MSG_EQ(queue->GetCurrentSize().GetValue(),
1293  initialQSize - modeSize,
1294  "There should be only 1 more packet dequeued.");
1295  NS_TEST_ASSERT_MSG_EQ(currentDropCount,
1296  0,
1297  "There should not be any packet drops");
1298  NS_TEST_ASSERT_MSG_EQ(currentCeThreshMarkCount,
1299  2,
1300  "There should be 2 CE threshold exceeded marked packets");
1301  }
1302  else
1303  { // In dropping state
1304  currentDropCount =
1305  queue->GetStats().GetNDroppedPackets(CoDelQueueDisc::TARGET_EXCEEDED_DROP);
1306  currentCeThreshMarkCount = queue->GetStats().GetNMarkedPackets(
1307  CoDelQueueDisc::CE_THRESHOLD_EXCEEDED_MARK);
1308  NS_TEST_ASSERT_MSG_EQ(queue->GetCurrentSize().GetValue(),
1309  initialQSize - modeSize,
1310  "There should be only 1 more packet dequeued.");
1311  NS_TEST_ASSERT_MSG_EQ(currentDropCount,
1312  0,
1313  "There should not be any packet drops");
1314  NS_TEST_ASSERT_MSG_EQ(currentCeThreshMarkCount,
1315  3,
1316  "There should be 3 CE threshold exceeded marked packet");
1317  }
1318  }
1319  }
1320  }
1321 }
1322 
1328 static class CoDelQueueDiscTestSuite : public TestSuite
1329 {
1330  public:
1332  : TestSuite("codel-queue-disc", UNIT)
1333  {
1334  // Test 1: simple enqueue/dequeue with no drops
1337  // Test 2: enqueue with drops due to queue overflow
1340  // Test 3: test NewtonStep() against explicit port of Linux implementation
1341  AddTestCase(new CoDelQueueDiscNewtonStepTest(), TestCase::QUICK);
1342  // Test 4: test ControlLaw() against explicit port of Linux implementation
1343  AddTestCase(new CoDelQueueDiscControlLawTest(), TestCase::QUICK);
1344  // Test 5: enqueue/dequeue with drops according to CoDel algorithm
1347  // Test 6: enqueue/dequeue with marks according to CoDel algorithm
1350  }
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.
void DoRun() override
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.
void DoRun() override
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.
void DoRun() override
Implementation to actually run this TestCase.
CoDelQueueDiscBasicMark(QueueSizeUnit mode)
Constructor.
Test 2: enqueue with drops due to queue overflow.
CoDelQueueDiscBasicOverflow(QueueSizeUnit mode)
Constructor.
void DoRun() override
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.
void DoRun() override
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.
void DoRun() override
Implementation to actually run this TestCase.
CoDel Queue Disc Test Suite.
Codel Queue Disc Test Item.
void AddHeader() override
Add the header to the packet.
bool Mark() override
Marks the packet as a substitute for dropping it, such as for Explicit Congestion Notification.
CodelQueueDiscTestItem & operator=(const CodelQueueDiscTestItem &)=delete
bool m_ecnCapablePacket
ECN capable packet?
CodelQueueDiscTestItem(const CodelQueueDiscTestItem &)=delete
CodelQueueDiscTestItem()=delete
a polymophic address class
Definition: address.h:101
uint64_t GetUid() const
Returns the packet's Uid.
Definition: packet.cc:412
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:96
Hold variables of type string.
Definition: string.h:56
encapsulates test code
Definition: test.h:1060
void AddTestCase(TestCase *testCase, TestDuration duration=QUICK)
Add an individual child TestCase to this test suite.
Definition: test.cc:301
A suite of tests to run.
Definition: test.h:1256
@ UNIT
This test suite implements a Unit Test.
Definition: test.h:1265
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:105
int64_t GetMicroSeconds() const
Get an approximation of the time stored in this instance in the indicated unit.
Definition: nstime.h:413
Hold an unsigned integer type.
Definition: uinteger.h:45
#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:44
@ BYTES
Use number of bytes for queue size.
Definition: queue-size.h:46
@ PACKETS
Use number of packets for queue size.
Definition: queue-size.h:45
Time Now()
create an ns3::Time instance which contains the current simulation time.
Definition: simulator.cc:305
#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:144
#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:251
#define NS_TEST_ASSERT_MSG_NE(actual, limit, msg)
Test that an actual and expected (limit) value are not equal and report and abort if not.
Definition: test.h:564
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1326
Time MilliSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1338
CoDelQueueDiscTestSuite g_coDelQueueTestSuite
the test suite
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Callback< R, Args... > MakeCallback(R(T::*memPtr)(Args...), OBJ objPtr)
Build Callbacks for class method members which take varying numbers of arguments and potentially retu...
Definition: callback.h:704
uint32_t pktSize
packet size used for the simulation (in bytes)