A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
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 * SPDX-License-Identifier: GPL-2.0-only
5 *
6 * Author: Truc Anh N Nguyen <trucanh524@gmail.com>
7 * Modified by: Pasquale Imputato <p.imputato@gmail.com>
8 *
9 */
10
11#include "ns3/codel-queue-disc.h"
12#include "ns3/double.h"
13#include "ns3/log.h"
14#include "ns3/packet.h"
15#include "ns3/simulator.h"
16#include "ns3/string.h"
17#include "ns3/test.h"
18#include "ns3/uinteger.h"
19
20using namespace ns3;
21
22// The following code borrowed from Linux codel.h, for unit testing
23#define REC_INV_SQRT_BITS_ns3 (8 * sizeof(uint16_t))
24/* or sizeof_in_bits(rec_inv_sqrt) */
25/* needed shift to get a Q0.32 number from rec_inv_sqrt */
26#define REC_INV_SQRT_SHIFT_ns3 (32 - REC_INV_SQRT_BITS_ns3)
27
28static uint16_t
29_codel_Newton_step(uint16_t rec_inv_sqrt, uint32_t count)
30{
31 uint32_t invsqrt = ((uint32_t)rec_inv_sqrt) << REC_INV_SQRT_SHIFT_ns3;
32 uint32_t invsqrt2 = ((uint64_t)invsqrt * invsqrt) >> 32;
33 uint64_t val = (3LL << 32) - ((uint64_t)count * invsqrt2);
34
35 val >>= 2; /* avoid overflow in following multiply */
36 val = (val * invsqrt) >> (32 - 2 + 1);
37 return static_cast<uint16_t>(val >> REC_INV_SQRT_SHIFT_ns3);
38}
39
40static uint32_t
42{
43 return (uint32_t)(((uint64_t)val * ep_ro) >> 32);
44}
45
46// End Linux borrow
47
48/**
49 * \ingroup traffic-control-test
50 *
51 * \brief Codel Queue Disc Test Item
52 */
54{
55 public:
56 /**
57 * Constructor
58 *
59 * \param p packet
60 * \param addr address
61 * \param ecnCapable ECN capable
62 */
63 CodelQueueDiscTestItem(Ptr<Packet> p, const Address& addr, bool ecnCapable);
64 ~CodelQueueDiscTestItem() override;
65
66 // Delete default constructor, copy constructor and assignment operator to avoid misuse
70
71 void AddHeader() override;
72 bool Mark() override;
73
74 private:
75 bool m_ecnCapablePacket; ///< ECN capable packet?
76};
77
79 : QueueDiscItem(p, addr, 0),
80 m_ecnCapablePacket(ecnCapable)
81{
82}
83
87
88void
92
93bool
98
99/**
100 * \ingroup traffic-control-test
101 *
102 * \brief Test 1: simple enqueue/dequeue with no drops
103 */
105{
106 public:
107 /**
108 * Constructor
109 *
110 * \param mode the mode
111 */
113 void DoRun() override;
114
115 private:
117};
118
120 : TestCase("Basic enqueue and dequeue operations, and attribute setting")
121{
122 m_mode = mode;
123}
124
125void
127{
129
130 uint32_t pktSize = 1000;
131 uint32_t modeSize = 0;
132
133 Address dest;
134
135 NS_TEST_ASSERT_MSG_EQ(queue->SetAttributeFailSafe("MinBytes", UintegerValue(pktSize)),
136 true,
137 "Verify that we can actually set the attribute MinBytes");
138 NS_TEST_ASSERT_MSG_EQ(queue->SetAttributeFailSafe("Interval", StringValue("50ms")),
139 true,
140 "Verify that we can actually set the attribute Interval");
141 NS_TEST_ASSERT_MSG_EQ(queue->SetAttributeFailSafe("Target", StringValue("4ms")),
142 true,
143 "Verify that we can actually set the attribute Target");
144
145 if (m_mode == QueueSizeUnit::BYTES)
146 {
147 modeSize = pktSize;
148 }
149 else if (m_mode == QueueSizeUnit::PACKETS)
150 {
151 modeSize = 1;
152 }
154 queue->SetAttributeFailSafe("MaxSize", QueueSizeValue(QueueSize(m_mode, modeSize * 1500))),
155 true,
156 "Verify that we can actually set the attribute MaxSize");
157 queue->Initialize();
158
159 Ptr<Packet> p1;
160 Ptr<Packet> p2;
161 Ptr<Packet> p3;
162 Ptr<Packet> p4;
163 Ptr<Packet> p5;
164 Ptr<Packet> p6;
171
172 NS_TEST_ASSERT_MSG_EQ(queue->GetCurrentSize().GetValue(),
173 0 * modeSize,
174 "There should be no packets in queue");
175 queue->Enqueue(Create<CodelQueueDiscTestItem>(p1, dest, false));
176 NS_TEST_ASSERT_MSG_EQ(queue->GetCurrentSize().GetValue(),
177 1 * modeSize,
178 "There should be one packet in queue");
179 queue->Enqueue(Create<CodelQueueDiscTestItem>(p2, dest, false));
180 NS_TEST_ASSERT_MSG_EQ(queue->GetCurrentSize().GetValue(),
181 2 * modeSize,
182 "There should be two packets in queue");
183 queue->Enqueue(Create<CodelQueueDiscTestItem>(p3, dest, false));
184 NS_TEST_ASSERT_MSG_EQ(queue->GetCurrentSize().GetValue(),
185 3 * modeSize,
186 "There should be three packets in queue");
187 queue->Enqueue(Create<CodelQueueDiscTestItem>(p4, dest, false));
188 NS_TEST_ASSERT_MSG_EQ(queue->GetCurrentSize().GetValue(),
189 4 * modeSize,
190 "There should be four packets in queue");
191 queue->Enqueue(Create<CodelQueueDiscTestItem>(p5, dest, false));
192 NS_TEST_ASSERT_MSG_EQ(queue->GetCurrentSize().GetValue(),
193 5 * modeSize,
194 "There should be five packets in queue");
195 queue->Enqueue(Create<CodelQueueDiscTestItem>(p6, dest, false));
196 NS_TEST_ASSERT_MSG_EQ(queue->GetCurrentSize().GetValue(),
197 6 * modeSize,
198 "There should be six packets in queue");
199
200 NS_TEST_ASSERT_MSG_EQ(queue->GetStats().GetNDroppedPackets(CoDelQueueDisc::OVERLIMIT_DROP),
201 0,
202 "There should be no packets being dropped due to full queue");
203
205
206 item = queue->Dequeue();
207 NS_TEST_ASSERT_MSG_NE(item, nullptr, "I want to remove the first packet");
208 NS_TEST_ASSERT_MSG_EQ(queue->GetCurrentSize().GetValue(),
209 5 * modeSize,
210 "There should be five packets in queue");
211 NS_TEST_ASSERT_MSG_EQ(item->GetPacket()->GetUid(), p1->GetUid(), "was this the first packet ?");
212
213 item = queue->Dequeue();
214 NS_TEST_ASSERT_MSG_NE(item, nullptr, "I want to remove the second packet");
215 NS_TEST_ASSERT_MSG_EQ(queue->GetCurrentSize().GetValue(),
216 4 * modeSize,
217 "There should be four packets in queue");
218 NS_TEST_ASSERT_MSG_EQ(item->GetPacket()->GetUid(),
219 p2->GetUid(),
220 "Was this the second packet ?");
221
222 item = queue->Dequeue();
223 NS_TEST_ASSERT_MSG_NE(item, nullptr, "I want to remove the third packet");
224 NS_TEST_ASSERT_MSG_EQ(queue->GetCurrentSize().GetValue(),
225 3 * modeSize,
226 "There should be three packets in queue");
227 NS_TEST_ASSERT_MSG_EQ(item->GetPacket()->GetUid(), p3->GetUid(), "Was this the third packet ?");
228
229 item = queue->Dequeue();
230 NS_TEST_ASSERT_MSG_NE(item, nullptr, "I want to remove the forth packet");
231 NS_TEST_ASSERT_MSG_EQ(queue->GetCurrentSize().GetValue(),
232 2 * modeSize,
233 "There should be two packets in queue");
234 NS_TEST_ASSERT_MSG_EQ(item->GetPacket()->GetUid(),
235 p4->GetUid(),
236 "Was this the fourth packet ?");
237
238 item = queue->Dequeue();
239 NS_TEST_ASSERT_MSG_NE(item, nullptr, "I want to remove the fifth packet");
240 NS_TEST_ASSERT_MSG_EQ(queue->GetCurrentSize().GetValue(),
241 1 * modeSize,
242 "There should be one packet in queue");
243 NS_TEST_ASSERT_MSG_EQ(item->GetPacket()->GetUid(), p5->GetUid(), "Was this the fifth packet ?");
244
245 item = queue->Dequeue();
246 NS_TEST_ASSERT_MSG_NE(item, nullptr, "I want to remove the last packet");
247 NS_TEST_ASSERT_MSG_EQ(queue->GetCurrentSize().GetValue(),
248 0 * modeSize,
249 "There should be zero packet in queue");
250 NS_TEST_ASSERT_MSG_EQ(item->GetPacket()->GetUid(), p6->GetUid(), "Was this the sixth packet ?");
251
252 item = queue->Dequeue();
253 NS_TEST_ASSERT_MSG_EQ(item, nullptr, "There are really no packets in queue");
254
256 queue->GetStats().GetNDroppedPackets(CoDelQueueDisc::TARGET_EXCEEDED_DROP),
257 0,
258 "There should be no packet drops according to CoDel algorithm");
259}
260
261/**
262 * \ingroup traffic-control-test
263 *
264 * \brief Test 2: enqueue with drops due to queue overflow
265 */
267{
268 public:
269 /**
270 * Constructor
271 *
272 * \param mode the mode
273 */
275 void DoRun() override;
276
277 private:
278 /**
279 * Enqueue function
280 * \param queue the queue disc
281 * \param size the size
282 * \param nPkt the number of packets
283 */
284 void Enqueue(Ptr<CoDelQueueDisc> queue, uint32_t size, uint32_t nPkt);
286};
287
289 : TestCase("Basic overflow behavior")
290{
291 m_mode = mode;
292}
293
294void
296{
298 uint32_t pktSize = 1000;
299 uint32_t modeSize = 0;
300
301 Address dest;
302
303 if (m_mode == QueueSizeUnit::BYTES)
304 {
305 modeSize = pktSize;
306 }
307 else if (m_mode == QueueSizeUnit::PACKETS)
308 {
309 modeSize = 1;
310 }
311
312 Ptr<Packet> p1;
313 Ptr<Packet> p2;
314 Ptr<Packet> p3;
318
320 queue->SetAttributeFailSafe("MaxSize", QueueSizeValue(QueueSize(m_mode, modeSize * 500))),
321 true,
322 "Verify that we can actually set the attribute MaxSize");
323 NS_TEST_ASSERT_MSG_EQ(queue->SetAttributeFailSafe("MinBytes", UintegerValue(pktSize)),
324 true,
325 "Verify that we can actually set the attribute MinBytes");
326
327 queue->Initialize();
328
329 Enqueue(queue, pktSize, 500);
330 queue->Enqueue(Create<CodelQueueDiscTestItem>(p1, dest, false));
331 queue->Enqueue(Create<CodelQueueDiscTestItem>(p2, dest, false));
332 queue->Enqueue(Create<CodelQueueDiscTestItem>(p3, dest, false));
333
334 NS_TEST_ASSERT_MSG_EQ(queue->GetCurrentSize().GetValue(),
335 500 * modeSize,
336 "There should be 500 packets in queue");
337 NS_TEST_ASSERT_MSG_EQ(queue->GetStats().GetNDroppedPackets(CoDelQueueDisc::OVERLIMIT_DROP),
338 3,
339 "There should be three packets being dropped due to full queue");
340}
341
342void
344{
345 Address dest;
346 for (uint32_t i = 0; i < nPkt; i++)
347 {
348 queue->Enqueue(Create<CodelQueueDiscTestItem>(Create<Packet>(size), dest, false));
349 }
350}
351
352/**
353 * \ingroup traffic-control-test
354 *
355 * \brief Test 3: NewtonStep unit test - test against explicit port of Linux implementation
356 */
358{
359 public:
361 void DoRun() override;
362};
363
365 : TestCase("NewtonStep arithmetic unit test")
366{
367}
368
369void
371{
373
374 // Spot check a few points in the expected operational range of
375 // CoDelQueueDisc's m_count and m_recInvSqrt variables
376 uint16_t result;
377 for (uint16_t recInvSqrt = 0xff; recInvSqrt > 0; recInvSqrt /= 2)
378 {
379 for (uint32_t count = 1; count < 0xff; count *= 2)
380 {
381 result = queue->NewtonStep(recInvSqrt, count);
382 // Test that ns-3 value is exactly the same as the Linux value
383 NS_TEST_ASSERT_MSG_EQ(_codel_Newton_step(recInvSqrt, count),
384 result,
385 "ns-3 NewtonStep() fails to match Linux equivalent");
386 }
387 }
388}
389
390/**
391 * \ingroup traffic-control-test
392 *
393 * \brief Test 4: ControlLaw unit test - test against explicit port of Linux implementation
394 */
396{
397 public:
399 void DoRun() override;
400 /**
401 * Codel control law function
402 * \param t
403 * \param interval
404 * \param recInvSqrt
405 * \returns the codel control law
406 */
407 uint32_t _codel_control_law(uint32_t t, uint32_t interval, uint32_t recInvSqrt);
408};
409
411 : TestCase("ControlLaw arithmetic unit test")
412{
413}
414
415// The following code borrowed from Linux codel.h,
416// except the addition of queue parameter
419{
420 return t + _reciprocal_scale(interval, recInvSqrt << REC_INV_SQRT_SHIFT_ns3);
421}
422
423// End Linux borrow
424
425void
427{
429
430 // Check a few points within the operational range of ControlLaw
431 uint32_t interval = queue->Time2CoDel(MilliSeconds(100));
432
433 uint32_t codelTimeVal;
434 for (Time timeVal = Seconds(0); timeVal <= Seconds(20); timeVal += MilliSeconds(100))
435 {
436 for (uint16_t recInvSqrt = 0xff; recInvSqrt > 0; recInvSqrt /= 2)
437 {
438 codelTimeVal = queue->Time2CoDel(timeVal);
439 uint32_t ns3Result = queue->ControlLaw(codelTimeVal, interval, recInvSqrt);
440 uint32_t linuxResult = _codel_control_law(codelTimeVal, interval, recInvSqrt);
441 NS_TEST_ASSERT_MSG_EQ(ns3Result,
442 linuxResult,
443 "Linux result for ControlLaw should equal ns-3 result");
444 }
445 }
446}
447
448/**
449 * \ingroup traffic-control-test
450 *
451 * \brief Test 5: enqueue/dequeue with drops according to CoDel algorithm
452 */
454{
455 public:
456 /**
457 * Constructor
458 *
459 * \param mode the mode
460 */
462 void DoRun() override;
463
464 private:
465 /**
466 * Enqueue function
467 * \param queue the queue disc
468 * \param size the size
469 * \param nPkt the number of packets
470 */
471 void Enqueue(Ptr<CoDelQueueDisc> queue, uint32_t size, uint32_t nPkt);
472 /** Dequeue function
473 * \param queue the queue disc
474 * \param modeSize the mode size
475 */
476 void Dequeue(Ptr<CoDelQueueDisc> queue, uint32_t modeSize);
477 /**
478 * Drop next tracer function
479 * \param oldVal the old value
480 * \param newVal the new value
481 */
482 void DropNextTracer(uint32_t oldVal, uint32_t newVal);
484 uint32_t m_dropNextCount; ///< count the number of times m_dropNext is recalculated
485};
486
488 : TestCase("Basic drop operations")
489{
490 m_mode = mode;
491 m_dropNextCount = 0;
492}
493
494void
499
500void
502{
504 uint32_t pktSize = 1000;
505 uint32_t modeSize = 0;
506
507 if (m_mode == QueueSizeUnit::BYTES)
508 {
509 modeSize = pktSize;
510 }
511 else if (m_mode == QueueSizeUnit::PACKETS)
512 {
513 modeSize = 1;
514 }
515
517 queue->SetAttributeFailSafe("MaxSize", QueueSizeValue(QueueSize(m_mode, modeSize * 500))),
518 true,
519 "Verify that we can actually set the attribute MaxSize");
520
521 queue->Initialize();
522
523 Enqueue(queue, pktSize, 20);
524 NS_TEST_ASSERT_MSG_EQ(queue->GetCurrentSize().GetValue(),
525 20 * modeSize,
526 "There should be 20 packets in queue.");
527
528 // Although the first dequeue occurs with a sojourn time above target
529 // the dequeue should be successful in this interval
530 Time waitUntilFirstDequeue = 2 * queue->GetTarget();
531 Simulator::Schedule(waitUntilFirstDequeue,
533 this,
534 queue,
535 modeSize);
536
537 // This dequeue should cause a drop
538 Time waitUntilSecondDequeue = waitUntilFirstDequeue + 2 * queue->GetInterval();
539 Simulator::Schedule(waitUntilSecondDequeue,
541 this,
542 queue,
543 modeSize);
544
545 // Although we are in dropping state, it's not time for next drop
546 // the dequeue should not cause a drop
547 Simulator::Schedule(waitUntilSecondDequeue,
549 this,
550 queue,
551 modeSize);
552
553 // In dropping time and it's time for next drop
554 // the dequeue should cause additional packet drops
555 Simulator::Schedule(waitUntilSecondDequeue * 2,
557 this,
558 queue,
559 modeSize);
560
563}
564
565void
567{
568 Address dest;
569 for (uint32_t i = 0; i < nPkt; i++)
570 {
571 queue->Enqueue(Create<CodelQueueDiscTestItem>(Create<Packet>(size), dest, false));
572 }
573}
574
575void
577{
578 uint32_t initialDropCount =
579 queue->GetStats().GetNDroppedPackets(CoDelQueueDisc::TARGET_EXCEEDED_DROP);
580 uint32_t initialQSize = queue->GetCurrentSize().GetValue();
581 uint32_t initialDropNext = queue->GetDropNext();
582 Time currentTime = Simulator::Now();
583 uint32_t currentDropCount = 0;
584
585 if (initialDropCount > 0 && currentTime.GetMicroSeconds() >= initialDropNext)
586 {
587 queue->TraceConnectWithoutContext(
588 "DropNext",
590 }
591
592 if (initialQSize != 0)
593 {
594 Ptr<QueueDiscItem> item = queue->Dequeue();
595 if (initialDropCount == 0 && currentTime > queue->GetTarget())
596 {
597 if (currentTime < queue->GetInterval())
598 {
599 currentDropCount =
600 queue->GetStats().GetNDroppedPackets(CoDelQueueDisc::TARGET_EXCEEDED_DROP);
601 NS_TEST_EXPECT_MSG_EQ(currentDropCount,
602 0,
603 "We are not in dropping state."
604 "Sojourn time has just gone above target from below."
605 "Hence, there should be no packet drops");
606 NS_TEST_EXPECT_MSG_EQ(queue->GetCurrentSize().GetValue(),
607 initialQSize - modeSize,
608 "There should be 1 packet dequeued.");
609 }
610 else if (currentTime >= queue->GetInterval())
611 {
612 currentDropCount =
613 queue->GetStats().GetNDroppedPackets(CoDelQueueDisc::TARGET_EXCEEDED_DROP);
614 NS_TEST_EXPECT_MSG_EQ(queue->GetCurrentSize().GetValue(),
615 initialQSize - 2 * modeSize,
616 "Sojourn time has been above target for at least interval."
617 "We enter the dropping state, perform initial packet drop, "
618 "and dequeue the next."
619 "So there should be 2 more packets dequeued.");
620 NS_TEST_EXPECT_MSG_EQ(currentDropCount, 1, "There should be 1 packet drop");
621 }
622 }
623 else if (initialDropCount > 0)
624 { // In dropping state
625 if (currentTime.GetMicroSeconds() < initialDropNext)
626 {
627 currentDropCount =
628 queue->GetStats().GetNDroppedPackets(CoDelQueueDisc::TARGET_EXCEEDED_DROP);
629 NS_TEST_EXPECT_MSG_EQ(queue->GetCurrentSize().GetValue(),
630 initialQSize - modeSize,
631 "We are in dropping state."
632 "Sojourn is still above target."
633 "However, it's not time for next drop."
634 "So there should be only 1 more packet dequeued");
635
637 currentDropCount,
638 1,
639 "There should still be only 1 packet drop from the last dequeue");
640 }
641 else if (currentTime.GetMicroSeconds() >= initialDropNext)
642 {
643 currentDropCount =
644 queue->GetStats().GetNDroppedPackets(CoDelQueueDisc::TARGET_EXCEEDED_DROP);
645 NS_TEST_EXPECT_MSG_EQ(queue->GetCurrentSize().GetValue(),
646 initialQSize - (m_dropNextCount + 1) * modeSize,
647 "We are in dropping state."
648 "It's time for next drop."
649 "The number of packets dequeued equals to the number of "
650 "times m_dropNext is updated plus initial dequeue");
651 NS_TEST_EXPECT_MSG_EQ(currentDropCount,
652 1 + m_dropNextCount,
653 "The number of drops equals to the number of times "
654 "m_dropNext is updated plus 1 from last dequeue");
655 }
656 }
657 }
658}
659
660/**
661 * \ingroup traffic-control-test
662 *
663 * \brief Test 6: enqueue/dequeue with marks according to CoDel algorithm
664 */
666{
667 public:
668 /**
669 * Constructor
670 *
671 * \param mode the mode
672 */
674 void DoRun() override;
675
676 private:
677 /**
678 * Enqueue function
679 * \param queue the queue disc
680 * \param size the size
681 * \param nPkt the number of packets
682 * \param ecnCapable ECN capable traffic
683 */
684 void Enqueue(Ptr<CoDelQueueDisc> queue, uint32_t size, uint32_t nPkt, bool ecnCapable);
685 /** Dequeue function
686 * \param queue the queue disc
687 * \param modeSize the mode size
688 * \param testCase the test case number
689 */
690 void Dequeue(Ptr<CoDelQueueDisc> queue, uint32_t modeSize, uint32_t testCase);
691 /**
692 * Drop next tracer function
693 * \param oldVal the old value
694 * \param newVal the new value
695 */
696 void DropNextTracer(uint32_t oldVal, uint32_t newVal);
698 uint32_t m_dropNextCount; ///< count the number of times m_dropNext is recalculated
699 uint32_t nPacketsBeforeFirstDrop; ///< Number of packets in the queue before first drop
700 uint32_t nPacketsBeforeFirstMark; ///< Number of packets in the queue before first mark
701};
702
704 : TestCase("Basic mark operations")
705{
706 m_mode = mode;
707 m_dropNextCount = 0;
708}
709
710void
715
716void
718{
719 // Test is divided into 4 sub test cases:
720 // 1) Packets are not ECN capable.
721 // 2) Packets are ECN capable but marking due to exceeding CE threshold disabled
722 // 3) Some packets are ECN capable, with CE threshold set to 2ms.
723 // 4) Packets are ECN capable and CE threshold set to 2ms
724
725 // Test case 1
727 uint32_t pktSize = 1000;
728 uint32_t modeSize = 0;
731
732 if (m_mode == QueueSizeUnit::BYTES)
733 {
734 modeSize = pktSize;
735 }
736 else if (m_mode == QueueSizeUnit::PACKETS)
737 {
738 modeSize = 1;
739 }
740
742 queue->SetAttributeFailSafe("MaxSize", QueueSizeValue(QueueSize(m_mode, modeSize * 500))),
743 true,
744 "Verify that we can actually set the attribute MaxSize");
745 NS_TEST_ASSERT_MSG_EQ(queue->SetAttributeFailSafe("UseEcn", BooleanValue(true)),
746 true,
747 "Verify that we can actually set the attribute UseEcn");
748
749 queue->Initialize();
750
751 // Not-ECT traffic to induce packet drop
752 Enqueue(queue, pktSize, 20, false);
753 NS_TEST_ASSERT_MSG_EQ(queue->GetCurrentSize().GetValue(),
754 20 * modeSize,
755 "There should be 20 packets in queue.");
756
757 // Although the first dequeue occurs with a sojourn time above target
758 // there should not be any dropped packets in this interval
759 Time waitUntilFirstDequeue = 2 * queue->GetTarget();
760 Simulator::Schedule(waitUntilFirstDequeue,
762 this,
763 queue,
764 modeSize,
765 1);
766
767 // This dequeue should cause a packet to be dropped
768 Time waitUntilSecondDequeue = waitUntilFirstDequeue + 2 * queue->GetInterval();
769 Simulator::Schedule(waitUntilSecondDequeue,
771 this,
772 queue,
773 modeSize,
774 1);
775
778
779 // Test case 2, queue with ECN capable traffic for marking of packets instead of dropping
782 queue->SetAttributeFailSafe("MaxSize", QueueSizeValue(QueueSize(m_mode, modeSize * 500))),
783 true,
784 "Verify that we can actually set the attribute MaxSize");
785 NS_TEST_ASSERT_MSG_EQ(queue->SetAttributeFailSafe("UseEcn", BooleanValue(true)),
786 true,
787 "Verify that we can actually set the attribute UseEcn");
788
789 queue->Initialize();
790
791 // ECN capable traffic to induce packets to be marked
792 Enqueue(queue, pktSize, 20, true);
793 NS_TEST_ASSERT_MSG_EQ(queue->GetCurrentSize().GetValue(),
794 20 * modeSize,
795 "There should be 20 packets in queue.");
796
797 // Although the first dequeue occurs with a sojourn time above target
798 // there should not be any target exceeded marked packets in this interval
799 Simulator::Schedule(waitUntilFirstDequeue,
801 this,
802 queue,
803 modeSize,
804 2);
805
806 // This dequeue should cause a packet to be marked
807 Simulator::Schedule(waitUntilSecondDequeue,
809 this,
810 queue,
811 modeSize,
812 2);
813
814 // Although we are in dropping state, it's not time for next packet to be target exceeded marked
815 // the dequeue should not cause a packet to be target exceeded marked
816 Simulator::Schedule(waitUntilSecondDequeue,
818 this,
819 queue,
820 modeSize,
821 2);
822
823 // In dropping time and it's time for next packet to be target exceeded marked
824 // the dequeue should cause additional packet to be target exceeded marked
825 Simulator::Schedule(waitUntilSecondDequeue * 2,
827 this,
828 queue,
829 modeSize,
830 2);
831
834
835 // Test case 3, some packets are ECN capable, with CE threshold set to 2ms
838 queue->SetAttributeFailSafe("MaxSize", QueueSizeValue(QueueSize(m_mode, modeSize * 500))),
839 true,
840 "Verify that we can actually set the attribute MaxSize");
841 NS_TEST_ASSERT_MSG_EQ(queue->SetAttributeFailSafe("UseEcn", BooleanValue(true)),
842 true,
843 "Verify that we can actually set the attribute UseEcn");
844 NS_TEST_ASSERT_MSG_EQ(queue->SetAttributeFailSafe("CeThreshold", TimeValue(MilliSeconds(2))),
845 true,
846 "Verify that we can actually set the attribute CeThreshold");
847
848 queue->Initialize();
849
850 // First 3 packets in the queue are ecnCapable
851 Enqueue(queue, pktSize, 3, true);
852 // Rest of the packet are not ecnCapable
853 Enqueue(queue, pktSize, 17, false);
854 NS_TEST_ASSERT_MSG_EQ(queue->GetCurrentSize().GetValue(),
855 20 * modeSize,
856 "There should be 20 packets in queue.");
857
858 // Although the first dequeue occurs with a sojourn time above target
859 // there should not be any target exceeded marked packets in this interval
860 Simulator::Schedule(waitUntilFirstDequeue,
862 this,
863 queue,
864 modeSize,
865 3);
866
867 // This dequeue should cause a packet to be marked
868 Simulator::Schedule(waitUntilSecondDequeue,
870 this,
871 queue,
872 modeSize,
873 3);
874
875 // Although we are in dropping state, it's not time for next packet to be target exceeded marked
876 // the dequeue should not cause a packet to be target exceeded marked
877 Simulator::Schedule(waitUntilSecondDequeue,
879 this,
880 queue,
881 modeSize,
882 3);
883
884 // In dropping time and it's time for next packet to be dropped as packets are not ECN capable
885 // the dequeue should cause packet to be dropped
886 Simulator::Schedule(waitUntilSecondDequeue * 2,
888 this,
889 queue,
890 modeSize,
891 3);
892
895
896 // Test case 4, queue with ECN capable traffic and CeThreshold set for marking of packets
897 // instead of dropping
900 queue->SetAttributeFailSafe("MaxSize", QueueSizeValue(QueueSize(m_mode, modeSize * 500))),
901 true,
902 "Verify that we can actually set the attribute MaxSize");
903 NS_TEST_ASSERT_MSG_EQ(queue->SetAttributeFailSafe("UseEcn", BooleanValue(true)),
904 true,
905 "Verify that we can actually set the attribute UseEcn");
906 NS_TEST_ASSERT_MSG_EQ(queue->SetAttributeFailSafe("CeThreshold", TimeValue(MilliSeconds(2))),
907 true,
908 "Verify that we can actually set the attribute CeThreshold");
909
910 queue->Initialize();
911
912 // ECN capable traffic to induce packets to be marked
913 Enqueue(queue, pktSize, 20, true);
914 NS_TEST_ASSERT_MSG_EQ(queue->GetCurrentSize().GetValue(),
915 20 * modeSize,
916 "There should be 20 packets in queue.");
917
918 // The first dequeue occurs with a sojourn time below CE threshold
919 // there should not any be CE threshold exceeded marked packets
922 this,
923 queue,
924 modeSize,
925 4);
926
927 // Sojourn time above CE threshold so this dequeue should cause a packet to be CE thershold
928 // exceeded marked
931 this,
932 queue,
933 modeSize,
934 4);
935
936 // the dequeue should cause a packet to be CE threshold exceeded marked
937 Simulator::Schedule(waitUntilFirstDequeue,
939 this,
940 queue,
941 modeSize,
942 4);
943
944 // In dropping time and it's time for next packet to be dropped but because of using ECN, packet
945 // should be marked
946 Simulator::Schedule(waitUntilSecondDequeue,
948 this,
949 queue,
950 modeSize,
951 4);
952
955}
956
957void
959 uint32_t size,
960 uint32_t nPkt,
961 bool ecnCapable)
962{
963 Address dest;
964 for (uint32_t i = 0; i < nPkt; i++)
965 {
966 queue->Enqueue(Create<CodelQueueDiscTestItem>(Create<Packet>(size), dest, ecnCapable));
967 }
968}
969
970void
972{
973 uint32_t initialTargetMarkCount =
974 queue->GetStats().GetNMarkedPackets(CoDelQueueDisc::TARGET_EXCEEDED_MARK);
975 uint32_t initialCeThreshMarkCount =
976 queue->GetStats().GetNMarkedPackets(CoDelQueueDisc::CE_THRESHOLD_EXCEEDED_MARK);
977 uint32_t initialQSize = queue->GetCurrentSize().GetValue();
978 uint32_t initialDropNext = queue->GetDropNext();
979 Time currentTime = Simulator::Now();
980 uint32_t currentDropCount = 0;
981 uint32_t currentTargetMarkCount = 0;
982 uint32_t currentCeThreshMarkCount = 0;
983
984 if (initialTargetMarkCount > 0 && currentTime.GetMicroSeconds() >= initialDropNext &&
985 testCase == 3)
986 {
987 queue->TraceConnectWithoutContext(
988 "DropNext",
990 }
991
992 if (initialQSize != 0)
993 {
994 Ptr<QueueDiscItem> item = queue->Dequeue();
995 if (testCase == 1)
996 {
997 currentDropCount =
998 queue->GetStats().GetNDroppedPackets(CoDelQueueDisc::TARGET_EXCEEDED_DROP);
999 if (currentDropCount == 1)
1000 {
1001 nPacketsBeforeFirstDrop = initialQSize;
1002 }
1003 }
1004 else if (testCase == 2)
1005 {
1006 if (initialTargetMarkCount == 0 && currentTime > queue->GetTarget())
1007 {
1008 if (currentTime < queue->GetInterval())
1009 {
1010 currentDropCount =
1011 queue->GetStats().GetNDroppedPackets(CoDelQueueDisc::TARGET_EXCEEDED_DROP);
1012 currentTargetMarkCount =
1013 queue->GetStats().GetNMarkedPackets(CoDelQueueDisc::TARGET_EXCEEDED_MARK);
1014 currentCeThreshMarkCount = queue->GetStats().GetNMarkedPackets(
1016 NS_TEST_ASSERT_MSG_EQ(queue->GetCurrentSize().GetValue(),
1017 initialQSize - modeSize,
1018 "There should be 1 packet dequeued.");
1019 NS_TEST_ASSERT_MSG_EQ(currentDropCount,
1020 0,
1021 "There should not be any packet drops");
1023 currentTargetMarkCount,
1024 0,
1025 "We are not in dropping state."
1026 "Sojourn time has just gone above target from below."
1027 "Hence, there should be no target exceeded marked packets");
1029 currentCeThreshMarkCount,
1030 0,
1031 "Marking due to CE threshold is disabled"
1032 "Hence, there should not be any CE threshold exceeded marked packet");
1033 }
1034 else if (currentTime >= queue->GetInterval())
1035 {
1036 currentDropCount =
1037 queue->GetStats().GetNDroppedPackets(CoDelQueueDisc::TARGET_EXCEEDED_DROP);
1038 currentTargetMarkCount =
1039 queue->GetStats().GetNMarkedPackets(CoDelQueueDisc::TARGET_EXCEEDED_MARK);
1040 nPacketsBeforeFirstMark = initialQSize;
1041 currentCeThreshMarkCount = queue->GetStats().GetNMarkedPackets(
1044 queue->GetCurrentSize().GetValue(),
1045 initialQSize - modeSize,
1046 "Sojourn time has been above target for at least interval."
1047 "We enter the dropping state and perform initial packet marking"
1048 "So there should be only 1 more packet dequeued.");
1049 NS_TEST_ASSERT_MSG_EQ(currentDropCount,
1050 0,
1051 "There should not be any packet drops");
1052 NS_TEST_ASSERT_MSG_EQ(currentTargetMarkCount,
1053 1,
1054 "There should be 1 target exceeded marked packet");
1056 currentCeThreshMarkCount,
1057 0,
1058 "There should not be any CE threshold exceeded marked packet");
1059 }
1060 }
1061 else if (initialTargetMarkCount > 0)
1062 { // In dropping state
1063 if (currentTime.GetMicroSeconds() < initialDropNext)
1064 {
1065 currentDropCount =
1066 queue->GetStats().GetNDroppedPackets(CoDelQueueDisc::TARGET_EXCEEDED_DROP);
1067 currentTargetMarkCount =
1068 queue->GetStats().GetNMarkedPackets(CoDelQueueDisc::TARGET_EXCEEDED_MARK);
1069 currentCeThreshMarkCount = queue->GetStats().GetNMarkedPackets(
1071 NS_TEST_ASSERT_MSG_EQ(queue->GetCurrentSize().GetValue(),
1072 initialQSize - modeSize,
1073 "We are in dropping state."
1074 "Sojourn is still above target."
1075 "However, it's not time for next target exceeded mark."
1076 "So there should be only 1 more packet dequeued");
1077 NS_TEST_ASSERT_MSG_EQ(currentDropCount,
1078 0,
1079 "There should not be any packet drops");
1080 NS_TEST_ASSERT_MSG_EQ(currentTargetMarkCount,
1081 1,
1082 "There should still be only 1 target exceeded marked "
1083 "packet from the last dequeue");
1085 currentCeThreshMarkCount,
1086 0,
1087 "There should not be any CE threshold exceeded marked packet");
1088 }
1089 else if (currentTime.GetMicroSeconds() >= initialDropNext)
1090 {
1091 currentDropCount =
1092 queue->GetStats().GetNDroppedPackets(CoDelQueueDisc::TARGET_EXCEEDED_DROP);
1093 currentTargetMarkCount =
1094 queue->GetStats().GetNMarkedPackets(CoDelQueueDisc::TARGET_EXCEEDED_MARK);
1095 currentCeThreshMarkCount = queue->GetStats().GetNMarkedPackets(
1097 NS_TEST_ASSERT_MSG_EQ(queue->GetCurrentSize().GetValue(),
1098 initialQSize - modeSize,
1099 "We are in dropping state."
1100 "It's time for packet to be marked"
1101 "So there should be only 1 more packet dequeued");
1102 NS_TEST_ASSERT_MSG_EQ(currentDropCount,
1103 0,
1104 "There should not be any packet drops");
1105 NS_TEST_ASSERT_MSG_EQ(currentTargetMarkCount,
1106 2,
1107 "There should 2 target exceeded marked packet");
1111 "Number of packets in the queue before drop should be equal"
1112 "to number of packets in the queue before first mark as the behavior "
1113 "until packet N should be the same.");
1115 currentCeThreshMarkCount,
1116 0,
1117 "There should not be any CE threshold exceeded marked packet");
1118 }
1119 }
1120 }
1121 else if (testCase == 3)
1122 {
1123 if (initialTargetMarkCount == 0 && currentTime > queue->GetTarget())
1124 {
1125 if (currentTime < queue->GetInterval())
1126 {
1127 currentDropCount =
1128 queue->GetStats().GetNDroppedPackets(CoDelQueueDisc::TARGET_EXCEEDED_DROP);
1129 currentTargetMarkCount =
1130 queue->GetStats().GetNMarkedPackets(CoDelQueueDisc::TARGET_EXCEEDED_MARK);
1131 currentCeThreshMarkCount = queue->GetStats().GetNMarkedPackets(
1133 NS_TEST_ASSERT_MSG_EQ(queue->GetCurrentSize().GetValue(),
1134 initialQSize - modeSize,
1135 "There should be 1 packet dequeued.");
1136 NS_TEST_ASSERT_MSG_EQ(currentDropCount,
1137 0,
1138 "There should not be any packet drops");
1140 currentTargetMarkCount,
1141 0,
1142 "We are not in dropping state."
1143 "Sojourn time has just gone above target from below."
1144 "Hence, there should be no target exceeded marked packets");
1146 currentCeThreshMarkCount,
1147 1,
1148 "Sojourn time has gone above CE threshold."
1149 "Hence, there should be 1 CE threshold exceeded marked packet");
1150 }
1151 else if (currentTime >= queue->GetInterval())
1152 {
1153 currentDropCount =
1154 queue->GetStats().GetNDroppedPackets(CoDelQueueDisc::TARGET_EXCEEDED_DROP);
1155 currentTargetMarkCount =
1156 queue->GetStats().GetNMarkedPackets(CoDelQueueDisc::TARGET_EXCEEDED_MARK);
1157 currentCeThreshMarkCount = queue->GetStats().GetNMarkedPackets(
1160 queue->GetCurrentSize().GetValue(),
1161 initialQSize - modeSize,
1162 "Sojourn time has been above target for at least interval."
1163 "We enter the dropping state and perform initial packet marking"
1164 "So there should be only 1 more packet dequeued.");
1165 NS_TEST_ASSERT_MSG_EQ(currentDropCount,
1166 0,
1167 "There should not be any packet drops");
1168 NS_TEST_ASSERT_MSG_EQ(currentTargetMarkCount,
1169 1,
1170 "There should be 1 target exceeded marked packet");
1171 NS_TEST_ASSERT_MSG_EQ(currentCeThreshMarkCount,
1172 1,
1173 "There should be 1 CE threshold exceeded marked packets");
1174 }
1175 }
1176 else if (initialTargetMarkCount > 0)
1177 { // In dropping state
1178 if (currentTime.GetMicroSeconds() < initialDropNext)
1179 {
1180 currentDropCount =
1181 queue->GetStats().GetNDroppedPackets(CoDelQueueDisc::TARGET_EXCEEDED_DROP);
1182 currentTargetMarkCount =
1183 queue->GetStats().GetNMarkedPackets(CoDelQueueDisc::TARGET_EXCEEDED_MARK);
1184 currentCeThreshMarkCount = queue->GetStats().GetNMarkedPackets(
1186 NS_TEST_ASSERT_MSG_EQ(queue->GetCurrentSize().GetValue(),
1187 initialQSize - modeSize,
1188 "We are in dropping state."
1189 "Sojourn is still above target."
1190 "However, it's not time for next target exceeded mark."
1191 "So there should be only 1 more packet dequeued");
1192 NS_TEST_ASSERT_MSG_EQ(currentDropCount,
1193 0,
1194 "There should not be any packet drops");
1195 NS_TEST_ASSERT_MSG_EQ(currentTargetMarkCount,
1196 1,
1197 "There should still be only 1 target exceeded marked "
1198 "packet from the last dequeue");
1199 NS_TEST_ASSERT_MSG_EQ(currentCeThreshMarkCount,
1200 2,
1201 "There should be 2 CE threshold exceeded marked packets");
1202 }
1203 else if (currentTime.GetMicroSeconds() >= initialDropNext)
1204 {
1205 currentDropCount =
1206 queue->GetStats().GetNDroppedPackets(CoDelQueueDisc::TARGET_EXCEEDED_DROP);
1207 currentTargetMarkCount =
1208 queue->GetStats().GetNMarkedPackets(CoDelQueueDisc::TARGET_EXCEEDED_MARK);
1209 currentCeThreshMarkCount = queue->GetStats().GetNMarkedPackets(
1212 queue->GetCurrentSize().GetValue(),
1213 initialQSize - (m_dropNextCount + 1) * modeSize,
1214 "We are in dropping state."
1215 "It's time for packet to be dropped as packets are not ecnCapable"
1216 "The number of packets dequeued equals to the number of times m_dropNext "
1217 "is updated plus initial dequeue");
1219 currentDropCount,
1221 "The number of drops equals to the number of times m_dropNext is updated");
1223 currentTargetMarkCount,
1224 1,
1225 "There should still be only 1 target exceeded marked packet");
1226 NS_TEST_ASSERT_MSG_EQ(currentCeThreshMarkCount,
1227 2,
1228 "There should still be 2 CE threshold exceeded marked "
1229 "packet as packets are not ecnCapable");
1230 }
1231 }
1232 }
1233 else if (testCase == 4)
1234 {
1235 if (currentTime < queue->GetTarget())
1236 {
1237 if (initialCeThreshMarkCount == 0 && currentTime < MilliSeconds(2))
1238 {
1239 currentDropCount =
1240 queue->GetStats().GetNDroppedPackets(CoDelQueueDisc::TARGET_EXCEEDED_DROP);
1241 currentCeThreshMarkCount = queue->GetStats().GetNMarkedPackets(
1243 NS_TEST_ASSERT_MSG_EQ(queue->GetCurrentSize().GetValue(),
1244 initialQSize - modeSize,
1245 "There should be 1 packet dequeued.");
1246 NS_TEST_ASSERT_MSG_EQ(currentDropCount,
1247 0,
1248 "There should not be any packet drops");
1250 currentCeThreshMarkCount,
1251 0,
1252 "Sojourn time has not gone above CE threshold."
1253 "Hence, there should not be any CE threshold exceeded marked packet");
1254 }
1255 else
1256 {
1257 currentDropCount =
1258 queue->GetStats().GetNDroppedPackets(CoDelQueueDisc::TARGET_EXCEEDED_DROP);
1259 currentCeThreshMarkCount = queue->GetStats().GetNMarkedPackets(
1261 NS_TEST_ASSERT_MSG_EQ(queue->GetCurrentSize().GetValue(),
1262 initialQSize - modeSize,
1263 "There should be only 1 more packet dequeued.");
1264 NS_TEST_ASSERT_MSG_EQ(currentDropCount,
1265 0,
1266 "There should not be any packet drops");
1267 NS_TEST_ASSERT_MSG_EQ(currentCeThreshMarkCount,
1268 1,
1269 "Sojourn time has gone above CE threshold."
1270 "There should be 1 CE threshold exceeded marked packet");
1271 }
1272 }
1273 else if (initialCeThreshMarkCount > 0 && currentTime < queue->GetInterval())
1274 {
1275 if (initialCeThreshMarkCount < 2)
1276 {
1277 currentDropCount =
1278 queue->GetStats().GetNDroppedPackets(CoDelQueueDisc::TARGET_EXCEEDED_DROP);
1279 currentCeThreshMarkCount = queue->GetStats().GetNMarkedPackets(
1281 NS_TEST_ASSERT_MSG_EQ(queue->GetCurrentSize().GetValue(),
1282 initialQSize - modeSize,
1283 "There should be only 1 more packet dequeued.");
1284 NS_TEST_ASSERT_MSG_EQ(currentDropCount,
1285 0,
1286 "There should not be any packet drops");
1287 NS_TEST_ASSERT_MSG_EQ(currentCeThreshMarkCount,
1288 2,
1289 "There should be 2 CE threshold exceeded marked packets");
1290 }
1291 else
1292 { // In dropping state
1293 currentDropCount =
1294 queue->GetStats().GetNDroppedPackets(CoDelQueueDisc::TARGET_EXCEEDED_DROP);
1295 currentCeThreshMarkCount = queue->GetStats().GetNMarkedPackets(
1297 NS_TEST_ASSERT_MSG_EQ(queue->GetCurrentSize().GetValue(),
1298 initialQSize - modeSize,
1299 "There should be only 1 more packet dequeued.");
1300 NS_TEST_ASSERT_MSG_EQ(currentDropCount,
1301 0,
1302 "There should not be any packet drops");
1303 NS_TEST_ASSERT_MSG_EQ(currentCeThreshMarkCount,
1304 3,
1305 "There should be 3 CE threshold exceeded marked packet");
1306 }
1307 }
1308 }
1309 }
1310}
1311
1312/**
1313 * \ingroup traffic-control-test
1314 *
1315 * \brief CoDel Queue Disc Test Suite
1316 */
1318{
1319 public:
1321 : TestSuite("codel-queue-disc", Type::UNIT)
1322 {
1323 // Test 1: simple enqueue/dequeue with no drops
1324 AddTestCase(new CoDelQueueDiscBasicEnqueueDequeue(QueueSizeUnit::PACKETS),
1325 TestCase::Duration::QUICK);
1326 AddTestCase(new CoDelQueueDiscBasicEnqueueDequeue(QueueSizeUnit::BYTES),
1327 TestCase::Duration::QUICK);
1328 // Test 2: enqueue with drops due to queue overflow
1329 AddTestCase(new CoDelQueueDiscBasicOverflow(QueueSizeUnit::PACKETS),
1330 TestCase::Duration::QUICK);
1331 AddTestCase(new CoDelQueueDiscBasicOverflow(QueueSizeUnit::BYTES),
1332 TestCase::Duration::QUICK);
1333 // Test 3: test NewtonStep() against explicit port of Linux implementation
1334 AddTestCase(new CoDelQueueDiscNewtonStepTest(), TestCase::Duration::QUICK);
1335 // Test 4: test ControlLaw() against explicit port of Linux implementation
1336 AddTestCase(new CoDelQueueDiscControlLawTest(), TestCase::Duration::QUICK);
1337 // Test 5: enqueue/dequeue with drops according to CoDel algorithm
1338 AddTestCase(new CoDelQueueDiscBasicDrop(QueueSizeUnit::PACKETS), TestCase::Duration::QUICK);
1339 AddTestCase(new CoDelQueueDiscBasicDrop(QueueSizeUnit::BYTES), TestCase::Duration::QUICK);
1340 // Test 6: enqueue/dequeue with marks according to CoDel algorithm
1341 AddTestCase(new CoDelQueueDiscBasicMark(QueueSizeUnit::PACKETS), TestCase::Duration::QUICK);
1342 AddTestCase(new CoDelQueueDiscBasicMark(QueueSizeUnit::BYTES), TestCase::Duration::QUICK);
1343 }
1344} g_coDelQueueTestSuite; ///< the test suite
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.
bool m_ecnCapablePacket
ECN capable packet?
CodelQueueDiscTestItem & operator=(const CodelQueueDiscTestItem &)=delete
CodelQueueDiscTestItem(const CodelQueueDiscTestItem &)=delete
CodelQueueDiscTestItem()=delete
a polymophic address class
Definition address.h:90
static constexpr const char * OVERLIMIT_DROP
Overlimit dropped packet.
static constexpr const char * TARGET_EXCEEDED_DROP
Sojourn time above target.
static constexpr const char * CE_THRESHOLD_EXCEEDED_MARK
Sojourn time above CE threshold.
static constexpr const char * TARGET_EXCEEDED_MARK
Sojourn time above target.
Smart pointer class similar to boost::intrusive_ptr.
QueueDiscItem is the abstract base class for items that are stored in a queue disc.
Definition queue-item.h:122
Class for representing queue sizes.
Definition queue-size.h:85
static EventId Schedule(const Time &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
Definition simulator.h:560
static void Destroy()
Execute the events scheduled with ScheduleDestroy().
Definition simulator.cc:131
static Time Now()
Return the current simulation virtual time.
Definition simulator.cc:197
static void Run()
Run the simulation.
Definition simulator.cc:167
Hold variables of type string.
Definition string.h:45
encapsulates test code
Definition test.h:1050
void AddTestCase(TestCase *testCase, Duration duration=Duration::QUICK)
Add an individual child TestCase to this test suite.
Definition test.cc:292
A suite of tests to run.
Definition test.h:1267
Type
Type of test.
Definition test.h:1274
static constexpr auto UNIT
Definition test.h:1291
Simulation virtual time values and global simulation resolution.
Definition nstime.h:94
int64_t GetMicroSeconds() const
Get an approximation of the time stored in this instance in the indicated unit.
Definition nstime.h:402
Hold an unsigned integer type.
Definition uinteger.h:34
#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)
Ptr< T > CreateObject(Args &&... args)
Create an object by type, with varying number of constructor parameters.
Definition object.h:619
Ptr< T > Create(Ts &&... args)
Create class instances by constructors with varying numbers of arguments and return them by Ptr.
Definition ptr.h:436
QueueSizeUnit
Enumeration of the operating modes of queues.
Definition queue-size.h:33
#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:134
#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:241
#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:554
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition nstime.h:1308
Time MilliSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition nstime.h:1320
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:684
uint32_t pktSize
packet size used for the simulation (in bytes)