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:
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  {
536  queue->TraceConnectWithoutContext ("DropNext", MakeCallback (&CoDelQueueDiscBasicDrop::DropNextTracer, this));
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  {
815  queue->TraceConnectWithoutContext ("DropNext", MakeCallback (&CoDelQueueDiscBasicMark::DropNextTracer, this));
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  }
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 &)
Copy constructor Disable default implementation to avoid misuse.
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:148
Class for representing queue sizes.
Definition: queue-size.h:95
Hold variables of type string.
Definition: string.h:41
encapsulates test code
Definition: test.h:1154
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:1344
@ UNIT
This test suite implements a Unit Test.
Definition: test.h:1353
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:104
int64_t GetMicroSeconds(void) const
Get an approximation of the time stored in this instance in the indicated unit.
Definition: nstime.h:388
AttributeValue implementation for Time.
Definition: nstime.h:1353
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)
#define NS_UNUSED(x)
Mark a local variable as unused.
Definition: unused.h:36
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:166
#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
CoDelQueueDiscTestSuite g_coDelQueueTestSuite
the test suite
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1289
Time MilliSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1297
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:1642
uint32_t pktSize
packet size used for the simulation (in bytes)
Definition: wifi-bianchi.cc:86