A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
pie-queue-disc-test-suite.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2016 NITK Surathkal
3 *
4 * SPDX-License-Identifier: GPL-2.0-only
5 *
6 * Authors: Shravya Ks <shravya.ks0@gmail.com>
7 * Smriti Murali <m.smriti.95@gmail.com>
8 * Mohit P. Tahiliani <tahiliani@nitk.edu.in>
9 *
10 */
11
12#include "ns3/double.h"
13#include "ns3/log.h"
14#include "ns3/packet.h"
15#include "ns3/pie-queue-disc.h"
16#include "ns3/simulator.h"
17#include "ns3/string.h"
18#include "ns3/test.h"
19#include "ns3/uinteger.h"
20
21using namespace ns3;
22
23/**
24 * \ingroup traffic-control-test
25 *
26 * \brief Pie Queue Disc Test Item
27 */
29{
30 public:
31 /**
32 * Constructor
33 *
34 * \param p the packet
35 * \param addr the address
36 * \param ecnCapable ECN capable flag
37 */
38 PieQueueDiscTestItem(Ptr<Packet> p, const Address& addr, bool ecnCapable);
39
40 // Delete default constructor, copy constructor and assignment operator to avoid misuse
44
45 void AddHeader() override;
46 bool Mark() override;
47
48 // ** Variables for testing m_isCapDropAdjustment
50 0.0; //!< Maximum difference between two consecutive drop probability values
51 double m_prevDropProb = 0.0; //!< Previous drop probability
52 bool m_checkProb = false; //!< Enable/Disable drop probability checks
53
54 // ** Variable for testing ECN
55 double m_maxDropProb = 0.0; //!< Maximum value of drop probability
56 bool m_ecnCapable = false; //!< Enable/Disable ECN capability
57
58 // ** Variables for testing Derandomization
59 bool m_checkAccuProb = false; //!< Enable/Disable accumulated drop probability checks
60 bool m_constAccuProb = false; //!< Enable/Disable fixed accumulated drop probability
61 bool m_checkMaxAccuProb = false; //!< Enable/Disable Maximum accumulated drop probability checks
62 double m_accuProbError = 0.0; //!< Error in accumulated drop probability
63 double m_prevAccuProb = 0.0; //!< Previous accumulated drop probability
64 double m_setAccuProb = 0.0; //!< Value to be set for accumulated drop probability
65 uint32_t m_expectedDrops = 0; //!< Number of expected unforced drops
66
67 private:
68 bool m_ecnCapablePacket; //!< ECN capable packet?
69};
70
72 : QueueDiscItem(p, addr, 0),
73 m_ecnCapablePacket(ecnCapable)
74{
75}
76
77void
81
82bool
87
88/**
89 * \ingroup traffic-control-test
90 *
91 * \brief Pie Queue Disc Test Case
92 */
94{
95 public:
97 void DoRun() override;
98
99 private:
100 /**
101 * Enqueue function
102 * \param queue the queue disc
103 * \param size the size
104 * \param nPkt the number of packets
105 * \param testAttributes attributes for testing
106 */
107 void Enqueue(Ptr<PieQueueDisc> queue,
108 uint32_t size,
109 uint32_t nPkt,
110 Ptr<PieQueueDiscTestItem> testAttributes);
111 /**
112 * Enqueue with delay function
113 * \param queue the queue disc
114 * \param size the size
115 * \param nPkt the number of packets
116 * \param testAttributes attributes for testing
117 */
119 uint32_t size,
120 uint32_t nPkt,
121 Ptr<PieQueueDiscTestItem> testAttributes);
122 /**
123 * Dequeue function
124 * \param queue the queue disc
125 * \param nPkt the number of packets
126 */
127 void Dequeue(Ptr<PieQueueDisc> queue, uint32_t nPkt);
128 /**
129 * Dequeue with delay function
130 * \param queue the queue disc
131 * \param delay the delay
132 * \param nPkt the number of packets
133 */
134 void DequeueWithDelay(Ptr<PieQueueDisc> queue, double delay, uint32_t nPkt);
135 /**
136 * Run test function
137 * \param mode the test mode
138 */
139 void RunPieTest(QueueSizeUnit mode);
140 /**
141 * \brief Check Drop Probability
142 * \param queue the queue disc
143 * \param testAttributes attributes for testing
144 */
146 /**
147 * \brief Check Accumulated Drop Probability
148 * \param queue the queue disc
149 * \param testAttributes attributes for testing
150 */
152 /**
153 * \brief Check Maximum Accumulated Drop Probability
154 * \param queue the queue disc
155 * \param testAttributes attributes for testing
156 */
158};
159
161 : TestCase("Sanity check on the pie queue disc implementation")
162{
163}
164
165void
167{
168 uint32_t pktSize = 0;
169
170 // 1 for packets; pktSize for bytes
171 uint32_t modeSize = 1;
172
173 uint32_t qSize = 300;
175
176 // test 1: simple enqueue/dequeue with defaults, no drops
177 Address dest;
178 // PieQueueDiscItem pointer for attributes
179 Ptr<PieQueueDiscTestItem> testAttributes =
181
182 if (mode == QueueSizeUnit::BYTES)
183 {
184 // pktSize should be same as MeanPktSize to avoid performance gap between byte and packet
185 // mode
186 pktSize = 1000;
187 modeSize = pktSize;
188 qSize = qSize * modeSize;
189 }
190
192 queue->SetAttributeFailSafe("MaxSize", QueueSizeValue(QueueSize(mode, qSize))),
193 true,
194 "Verify that we can actually set the attribute MaxSize");
195
196 Ptr<Packet> p1;
197 Ptr<Packet> p2;
198 Ptr<Packet> p3;
199 Ptr<Packet> p4;
200 Ptr<Packet> p5;
201 Ptr<Packet> p6;
202 Ptr<Packet> p7;
203 Ptr<Packet> p8;
212
213 queue->Initialize();
214 NS_TEST_ASSERT_MSG_EQ(queue->GetCurrentSize().GetValue(),
215 0 * modeSize,
216 "There should be no packets in there");
217 queue->Enqueue(Create<PieQueueDiscTestItem>(p1, dest, false));
218 NS_TEST_ASSERT_MSG_EQ(queue->GetCurrentSize().GetValue(),
219 1 * modeSize,
220 "There should be one packet in there");
221 queue->Enqueue(Create<PieQueueDiscTestItem>(p2, dest, false));
222 NS_TEST_ASSERT_MSG_EQ(queue->GetCurrentSize().GetValue(),
223 2 * modeSize,
224 "There should be two packets in there");
225 queue->Enqueue(Create<PieQueueDiscTestItem>(p3, dest, false));
226 queue->Enqueue(Create<PieQueueDiscTestItem>(p4, dest, false));
227 queue->Enqueue(Create<PieQueueDiscTestItem>(p5, dest, false));
228 queue->Enqueue(Create<PieQueueDiscTestItem>(p6, dest, false));
229 queue->Enqueue(Create<PieQueueDiscTestItem>(p7, dest, false));
230 queue->Enqueue(Create<PieQueueDiscTestItem>(p8, dest, false));
231 NS_TEST_ASSERT_MSG_EQ(queue->GetCurrentSize().GetValue(),
232 8 * modeSize,
233 "There should be eight packets in there");
234
236
237 item = queue->Dequeue();
238 NS_TEST_ASSERT_MSG_NE(item, nullptr, "I want to remove the first packet");
239 NS_TEST_ASSERT_MSG_EQ(queue->GetCurrentSize().GetValue(),
240 7 * modeSize,
241 "There should be seven packets in there");
242 NS_TEST_ASSERT_MSG_EQ(item->GetPacket()->GetUid(), p1->GetUid(), "was this the first packet ?");
243
244 item = queue->Dequeue();
245 NS_TEST_ASSERT_MSG_NE(item, nullptr, "I want to remove the second packet");
246 NS_TEST_ASSERT_MSG_EQ(queue->GetCurrentSize().GetValue(),
247 6 * modeSize,
248 "There should be six packet in there");
249 NS_TEST_ASSERT_MSG_EQ(item->GetPacket()->GetUid(),
250 p2->GetUid(),
251 "Was this the second packet ?");
252
253 item = queue->Dequeue();
254 NS_TEST_ASSERT_MSG_NE(item, nullptr, "I want to remove the third packet");
255 NS_TEST_ASSERT_MSG_EQ(queue->GetCurrentSize().GetValue(),
256 5 * modeSize,
257 "There should be five packets in there");
258 NS_TEST_ASSERT_MSG_EQ(item->GetPacket()->GetUid(), p3->GetUid(), "Was this the third packet ?");
259
260 item = queue->Dequeue();
261 item = queue->Dequeue();
262 item = queue->Dequeue();
263 item = queue->Dequeue();
264 item = queue->Dequeue();
265
266 item = queue->Dequeue();
267 NS_TEST_ASSERT_MSG_EQ(item, nullptr, "There are really no packets in there");
268
269 // test 2: more data with defaults, unforced drops but no forced drops
271 // PieQueueDiscItem pointer for attributes
272 testAttributes = Create<PieQueueDiscTestItem>(Create<Packet>(pktSize), dest, false);
273 pktSize = 1000; // pktSize != 0 because DequeueThreshold always works in bytes
275 queue->SetAttributeFailSafe("MaxSize", QueueSizeValue(QueueSize(mode, qSize))),
276 true,
277 "Verify that we can actually set the attribute MaxSize");
278 NS_TEST_ASSERT_MSG_EQ(queue->SetAttributeFailSafe("Tupdate", TimeValue(Seconds(0.03))),
279 true,
280 "Verify that we can actually set the attribute Tupdate");
281 NS_TEST_ASSERT_MSG_EQ(queue->SetAttributeFailSafe("DequeueThreshold", UintegerValue(10000)),
282 true,
283 "Verify that we can actually set the attribute DequeueThreshold");
285 queue->SetAttributeFailSafe("QueueDelayReference", TimeValue(Seconds(0.02))),
286 true,
287 "Verify that we can actually set the attribute QueueDelayReference");
288 NS_TEST_ASSERT_MSG_EQ(queue->SetAttributeFailSafe("MaxBurstAllowance", TimeValue(Seconds(0.1))),
289 true,
290 "Verify that we can actually set the attribute MaxBurstAllowance");
291 queue->Initialize();
292 EnqueueWithDelay(queue, pktSize, 400, testAttributes);
293 DequeueWithDelay(queue, 0.012, 400);
296 QueueDisc::Stats st = queue->GetStats();
298 NS_TEST_ASSERT_MSG_NE(test2, 0, "There should be some unforced drops");
300 0,
301 "There should be zero forced drops");
302
303 // test 3: same as test 2, but with higher QueueDelayReference
305 // PieQueueDiscItem pointer for attributes
306 testAttributes = Create<PieQueueDiscTestItem>(Create<Packet>(pktSize), dest, false);
308 queue->SetAttributeFailSafe("MaxSize", QueueSizeValue(QueueSize(mode, qSize))),
309 true,
310 "Verify that we can actually set the attribute MaxSize");
311 NS_TEST_ASSERT_MSG_EQ(queue->SetAttributeFailSafe("Tupdate", TimeValue(Seconds(0.03))),
312 true,
313 "Verify that we can actually set the attribute Tupdate");
314 NS_TEST_ASSERT_MSG_EQ(queue->SetAttributeFailSafe("DequeueThreshold", UintegerValue(10000)),
315 true,
316 "Verify that we can actually set the attribute DequeueThreshold");
318 queue->SetAttributeFailSafe("QueueDelayReference", TimeValue(Seconds(0.08))),
319 true,
320 "Verify that we can actually set the attribute QueueDelayReference");
321 NS_TEST_ASSERT_MSG_EQ(queue->SetAttributeFailSafe("MaxBurstAllowance", TimeValue(Seconds(0.1))),
322 true,
323 "Verify that we can actually set the attribute MaxBurstAllowance");
324 queue->Initialize();
325 EnqueueWithDelay(queue, pktSize, 400, testAttributes);
326 DequeueWithDelay(queue, 0.012, 400);
329 st = queue->GetStats();
331 NS_TEST_ASSERT_MSG_LT(test3, test2, "Test 3 should have less unforced drops than test 2");
333 0,
334 "There should be zero forced drops");
335
336 // test 4: same as test 2, but with reduced dequeue rate
338 // PieQueueDiscItem pointer for attributes
339 testAttributes = Create<PieQueueDiscTestItem>(Create<Packet>(pktSize), dest, false);
341 queue->SetAttributeFailSafe("MaxSize", QueueSizeValue(QueueSize(mode, qSize))),
342 true,
343 "Verify that we can actually set the attribute MaxSize");
344 NS_TEST_ASSERT_MSG_EQ(queue->SetAttributeFailSafe("Tupdate", TimeValue(Seconds(0.03))),
345 true,
346 "Verify that we can actually set the attribute Tupdate");
347 NS_TEST_ASSERT_MSG_EQ(queue->SetAttributeFailSafe("DequeueThreshold", UintegerValue(10000)),
348 true,
349 "Verify that we can actually set the attribute DequeueThreshold");
351 queue->SetAttributeFailSafe("QueueDelayReference", TimeValue(Seconds(0.02))),
352 true,
353 "Verify that we can actually set the attribute QueueDelayReference");
354 NS_TEST_ASSERT_MSG_EQ(queue->SetAttributeFailSafe("MaxBurstAllowance", TimeValue(Seconds(0.1))),
355 true,
356 "Verify that we can actually set the attribute MaxBurstAllowance");
357 queue->Initialize();
358 EnqueueWithDelay(queue, pktSize, 400, testAttributes);
359 DequeueWithDelay(queue, 0.015, 400); // delay between two successive dequeue events is increased
362 st = queue->GetStats();
364 NS_TEST_ASSERT_MSG_GT(test4, test2, "Test 4 should have more unforced drops than test 2");
366 0,
367 "There should be zero forced drops");
368
369 // test 5: same dequeue rate as test 4, but with higher Tupdate
371 // PieQueueDiscItem pointer for attributes
372 testAttributes = Create<PieQueueDiscTestItem>(Create<Packet>(pktSize), dest, false);
374 queue->SetAttributeFailSafe("MaxSize", QueueSizeValue(QueueSize(mode, qSize))),
375 true,
376 "Verify that we can actually set the attribute MaxSize");
377 NS_TEST_ASSERT_MSG_EQ(queue->SetAttributeFailSafe("Tupdate", TimeValue(Seconds(0.09))),
378 true,
379 "Verify that we can actually set the attribute Tupdate");
380 NS_TEST_ASSERT_MSG_EQ(queue->SetAttributeFailSafe("DequeueThreshold", UintegerValue(10000)),
381 true,
382 "Verify that we can actually set the attribute DequeueThreshold");
384 queue->SetAttributeFailSafe("QueueDelayReference", TimeValue(Seconds(0.02))),
385 true,
386 "Verify that we can actually set the attribute QueueDelayReference");
387 NS_TEST_ASSERT_MSG_EQ(queue->SetAttributeFailSafe("MaxBurstAllowance", TimeValue(Seconds(0.1))),
388 true,
389 "Verify that we can actually set the attribute MaxBurstAllowance");
390 queue->Initialize();
391 EnqueueWithDelay(queue, pktSize, 400, testAttributes);
392 DequeueWithDelay(queue, 0.015, 400);
395 st = queue->GetStats();
397 NS_TEST_ASSERT_MSG_LT(test5, test4, "Test 5 should have less unforced drops than test 4");
399 0,
400 "There should be zero forced drops");
401
402 // test 6: same as test 2, but with UseDequeueRateEstimator enabled
404 // PieQueueDiscItem pointer for attributes
405 testAttributes = Create<PieQueueDiscTestItem>(Create<Packet>(pktSize), dest, false);
407 queue->SetAttributeFailSafe("MaxSize", QueueSizeValue(QueueSize(mode, qSize))),
408 true,
409 "Verify that we can actually set the attribute MaxSize");
411 queue->SetAttributeFailSafe("UseDequeueRateEstimator", BooleanValue(true)),
412 true,
413 "Verify that we can actually set the attribute UseTimestamp");
414 queue->Initialize();
415 EnqueueWithDelay(queue, pktSize, 400, testAttributes);
416 DequeueWithDelay(queue, 0.014, 400);
419 st = queue->GetStats();
421 NS_TEST_ASSERT_MSG_NE(test6, 0, "There should be some unforced drops");
423 0,
424 "There should be zero forced drops");
425
426 // test 7: test with CapDropAdjustment disabled
428 // PieQueueDiscItem pointer for attributes
429 testAttributes = Create<PieQueueDiscTestItem>(Create<Packet>(pktSize), dest, false);
431 queue->SetAttributeFailSafe("MaxSize", QueueSizeValue(QueueSize(mode, qSize))),
432 true,
433 "Verify that we can actually set the attribute MaxSize");
434 NS_TEST_ASSERT_MSG_EQ(queue->SetAttributeFailSafe("UseCapDropAdjustment", BooleanValue(false)),
435 true,
436 "Verify that we can actually set the attribute UseCapDropAdjustment");
437 queue->Initialize();
438 testAttributes->m_checkProb = true;
439 EnqueueWithDelay(queue, pktSize, 400, testAttributes);
440 DequeueWithDelay(queue, 0.014, 400);
443 st = queue->GetStats();
445 NS_TEST_ASSERT_MSG_NE(test7, 0, "There should be some unforced drops");
447 0,
448 "There should be zero forced drops");
449 NS_TEST_ASSERT_MSG_GT(testAttributes->m_maxDropProbDiff,
450 0.02,
451 "Maximum increase in drop probability should be greater than 0.02");
452
453 // test 8: test with CapDropAdjustment enabled
455 // PieQueueDiscItem pointer for attributes
456 testAttributes = Create<PieQueueDiscTestItem>(Create<Packet>(pktSize), dest, false);
458 queue->SetAttributeFailSafe("MaxSize", QueueSizeValue(QueueSize(mode, qSize))),
459 true,
460 "Verify that we can actually set the attribute MaxSize");
461 NS_TEST_ASSERT_MSG_EQ(queue->SetAttributeFailSafe("UseCapDropAdjustment", BooleanValue(true)),
462 true,
463 "Verify that we can actually set the attribute UseCapDropAdjustment");
464 queue->Initialize();
465 testAttributes->m_checkProb = true;
466 EnqueueWithDelay(queue, pktSize, 400, testAttributes);
467 DequeueWithDelay(queue, 0.014, 400);
470 st = queue->GetStats();
472 NS_TEST_ASSERT_MSG_NE(test8, 0, "There should be some unforced drops");
474 0,
475 "There should be zero forced drops");
477 testAttributes->m_maxDropProbDiff,
478 0.0200000000000001,
479 "Maximum increase in drop probability should be less than or equal to 0.02");
480
481 // test 9: PIE queue disc is ECN enabled, but packets are not ECN capable
483 // PieQueueDiscItem pointer for attributes
484 testAttributes = Create<PieQueueDiscTestItem>(Create<Packet>(pktSize), dest, false);
486 queue->SetAttributeFailSafe("MaxSize", QueueSizeValue(QueueSize(mode, qSize))),
487 true,
488 "Verify that we can actually set the attribute MaxSize");
489 NS_TEST_ASSERT_MSG_EQ(queue->SetAttributeFailSafe("UseEcn", BooleanValue(true)),
490 true,
491 "Verify that we can actually set the attribute UseEcn");
492 NS_TEST_ASSERT_MSG_EQ(queue->SetAttributeFailSafe("MarkEcnThreshold", DoubleValue(0.3)),
493 true,
494 "Verify that we can actually set the attribute MarkEcnThreshold");
495 queue->Initialize();
496 EnqueueWithDelay(queue, pktSize, 400, testAttributes);
497 DequeueWithDelay(queue, 0.014, 400);
500 st = queue->GetStats();
502 NS_TEST_ASSERT_MSG_EQ(test9, 0, "There should be zero unforced marks");
504 0,
505 "There should be some unforced drops");
507 0,
508 "There should be zero forced drops");
509
510 // test 10: Packets are ECN capable, but PIE queue disc is not ECN enabled
512 // PieQueueDiscItem pointer for attributes
513 testAttributes = Create<PieQueueDiscTestItem>(Create<Packet>(pktSize), dest, false);
515 queue->SetAttributeFailSafe("MaxSize", QueueSizeValue(QueueSize(mode, qSize))),
516 true,
517 "Verify that we can actually set the attribute MaxSize");
518 NS_TEST_ASSERT_MSG_EQ(queue->SetAttributeFailSafe("UseEcn", BooleanValue(false)),
519 true,
520 "Verify that we can actually set the attribute UseEcn");
521 NS_TEST_ASSERT_MSG_EQ(queue->SetAttributeFailSafe("MarkEcnThreshold", DoubleValue(0.3)),
522 true,
523 "Verify that we can actually set the attribute MarkEcnThreshold");
524 queue->Initialize();
525 testAttributes->m_ecnCapable = true;
526 EnqueueWithDelay(queue, pktSize, 400, testAttributes);
527 DequeueWithDelay(queue, 0.014, 400);
530 st = queue->GetStats();
532 NS_TEST_ASSERT_MSG_EQ(test10, 0, "There should be zero unforced marks");
534 0,
535 "There should be some unforced drops");
537 0,
538 "There should be zero forced drops");
539
540 // test 11: Packets and PIE queue disc both are ECN capable
542 // PieQueueDiscItem pointer for attributes
543 testAttributes = Create<PieQueueDiscTestItem>(Create<Packet>(pktSize), dest, false);
545 queue->SetAttributeFailSafe("MaxSize", QueueSizeValue(QueueSize(mode, qSize))),
546 true,
547 "Verify that we can actually set the attribute MaxSize");
548 NS_TEST_ASSERT_MSG_EQ(queue->SetAttributeFailSafe("UseEcn", BooleanValue(true)),
549 true,
550 "Verify that we can actually set the attribute UseEcn");
551 NS_TEST_ASSERT_MSG_EQ(queue->SetAttributeFailSafe("MarkEcnThreshold", DoubleValue(0.3)),
552 true,
553 "Verify that we can actually set the attribute MarkEcnThreshold");
554 queue->Initialize();
555 testAttributes->m_ecnCapable = true;
556 testAttributes->m_checkProb = true;
557 EnqueueWithDelay(queue, pktSize, 400, testAttributes);
558 DequeueWithDelay(queue, 0.014, 400);
561 st = queue->GetStats();
563 NS_TEST_ASSERT_MSG_NE(test11, 0, "There should be some unforced marks");
564 // There are unforced drops because the value of m_maxDropProb goes beyond 0.3 in this test.
565 // PIE drops the packets even when they are ECN capable if drop probability is more than 30%.
567 0,
568 "There should be some unforced drops");
569 // Confirm that m_maxDropProb goes above 0.3 in this test
570 NS_TEST_ASSERT_MSG_GT(testAttributes->m_maxDropProb,
571 0.3,
572 "Maximum Drop probability should be greater than 0.3");
574 0,
575 "There should be zero forced drops");
576
577 // test 12: test with derandomization enabled
579 // PieQueueDiscItem pointer for attributes
580 testAttributes = Create<PieQueueDiscTestItem>(Create<Packet>(pktSize), dest, false);
582 queue->SetAttributeFailSafe("MaxSize", QueueSizeValue(QueueSize(mode, qSize))),
583 true,
584 "Verify that we can actually set the attribute MaxSize");
585 NS_TEST_ASSERT_MSG_EQ(queue->SetAttributeFailSafe("UseDerandomization", BooleanValue(true)),
586 true,
587 "Verify that we can actually set the attribute UseDerandomization");
588 queue->Initialize();
589 testAttributes->m_checkAccuProb = true;
590 EnqueueWithDelay(queue, pktSize, 400, testAttributes);
591 DequeueWithDelay(queue, 0.014, 400);
594 st = queue->GetStats();
596 NS_TEST_ASSERT_MSG_NE(test12, 0, "There should be some unforced drops");
598 0,
599 "There should be zero forced drops");
600 NS_TEST_ASSERT_MSG_EQ(testAttributes->m_accuProbError,
601 0.0,
602 "There should not be any error in setting accuProb");
603
604 // test 13: same as test 11 but with accumulated drop probability set below the low threshold
606 // PieQueueDiscItem pointer for attributes
607 testAttributes = Create<PieQueueDiscTestItem>(Create<Packet>(pktSize), dest, false);
609 queue->SetAttributeFailSafe("MaxSize", QueueSizeValue(QueueSize(mode, qSize))),
610 true,
611 "Verify that we can actually set the attribute MaxSize");
612 NS_TEST_ASSERT_MSG_EQ(queue->SetAttributeFailSafe("UseDerandomization", BooleanValue(true)),
613 true,
614 "Verify that we can actually set the attribute UseDerandomization");
615 queue->Initialize();
616 testAttributes->m_constAccuProb = true;
617 // Final value of accumulated drop probability to drop packet will be maximum 0.84 while
618 // threshold to drop packet is 0.85
619 testAttributes->m_setAccuProb = -0.16;
620 EnqueueWithDelay(queue, pktSize, 400, testAttributes);
621 DequeueWithDelay(queue, 0.014, 400);
624 st = queue->GetStats();
626 NS_TEST_ASSERT_MSG_EQ(test13, 0, "There should be zero unforced drops");
628 0,
629 "There should be zero forced drops");
630
631 // test 14: same as test 12 but with accumulated drop probability set above the high threshold
633 // PieQueueDiscItem pointer for attributes
634 testAttributes = Create<PieQueueDiscTestItem>(Create<Packet>(pktSize), dest, false);
636 queue->SetAttributeFailSafe("MaxSize", QueueSizeValue(QueueSize(mode, qSize))),
637 true,
638 "Verify that we can actually set the attribute MaxSize");
639 NS_TEST_ASSERT_MSG_EQ(queue->SetAttributeFailSafe("MaxBurstAllowance", TimeValue(Seconds(0.0))),
640 true,
641 "Verify that we can actually set the attribute MaxBurstAllowance");
642 NS_TEST_ASSERT_MSG_EQ(queue->SetAttributeFailSafe("UseDerandomization", BooleanValue(true)),
643 true,
644 "Verify that we can actually set the attribute UseDerandomization");
645 queue->Initialize();
646 testAttributes->m_constAccuProb = true;
647 testAttributes->m_checkMaxAccuProb = true;
648 // Final value of accumulated drop probability to drop packet will be minimum 8.6 while
649 // threshold to drop packet is 8.5
650 testAttributes->m_setAccuProb = 8.6;
651 EnqueueWithDelay(queue, pktSize, 400, testAttributes);
652 DequeueWithDelay(queue, 0.014, 400);
655 st = queue->GetStats();
658 test14,
659 testAttributes->m_expectedDrops,
660 "The number of unforced drops should be equal to number of expected unforced drops");
662 0,
663 "There should be zero forced drops");
664
665 // test 15: tests Active/Inactive feature, ActiveThreshold set to a high value so PIE never
666 // starts and there should not be any drops
668 // PieQueueDiscItem pointer for attributes
669 testAttributes = Create<PieQueueDiscTestItem>(Create<Packet>(pktSize), dest, false);
670 queue->SetAttributeFailSafe("MaxSize", QueueSizeValue(QueueSize(mode, qSize)));
671 queue->SetAttributeFailSafe("ActiveThreshold", TimeValue(Seconds(1)));
672 queue->Initialize();
673
674 EnqueueWithDelay(queue, pktSize, 100, testAttributes);
675 DequeueWithDelay(queue, 0.02, 100);
678 st = queue->GetStats();
680 NS_TEST_ASSERT_MSG_EQ(test15, 0, "There should not be any drops.");
682 0,
683 "There should be zero marks");
684
685 // test 16: tests Active/Inactive feature, ActiveThreshold set to a low value so PIE starts
686 // early and some packets should be dropped.
688 // PieQueueDiscItem pointer for attributes
689 testAttributes = Create<PieQueueDiscTestItem>(Create<Packet>(pktSize), dest, false);
690 queue->SetAttributeFailSafe("MaxSize", QueueSizeValue(QueueSize(mode, qSize)));
691 queue->SetAttributeFailSafe("ActiveThreshold", TimeValue(Seconds(0.001)));
692 queue->Initialize();
693
694 EnqueueWithDelay(queue, pktSize, 100, testAttributes);
695 DequeueWithDelay(queue, 0.02, 100);
698 st = queue->GetStats();
700 NS_TEST_ASSERT_MSG_NE(test16, 0, "There should be some drops.");
702 0,
703 "There should be zero marks");
704}
705
706void
708 uint32_t size,
709 uint32_t nPkt,
710 Ptr<PieQueueDiscTestItem> testAttributes)
711{
712 Address dest;
713 for (uint32_t i = 0; i < nPkt; i++)
714 {
715 if (testAttributes->m_constAccuProb)
716 {
717 queue->m_accuProb = testAttributes->m_setAccuProb;
718 if (testAttributes->m_checkMaxAccuProb)
719 {
720 CheckMaxAccuProb(queue, testAttributes);
721 }
722 }
723 queue->Enqueue(
724 Create<PieQueueDiscTestItem>(Create<Packet>(size), dest, testAttributes->m_ecnCapable));
725 if (testAttributes->m_checkProb)
726 {
727 CheckDropProb(queue, testAttributes);
728 }
729 if (testAttributes->m_checkAccuProb)
730 {
731 CheckAccuProb(queue, testAttributes);
732 }
733 }
734}
735
736void
738 Ptr<PieQueueDiscTestItem> testAttributes)
739{
740 double dropProb = queue->m_dropProb;
741 if (testAttributes->m_maxDropProb < dropProb)
742 {
743 testAttributes->m_maxDropProb = dropProb;
744 }
745 if (testAttributes->m_prevDropProb > 0.1)
746 {
747 double currentDiff = dropProb - testAttributes->m_prevDropProb;
748 if (testAttributes->m_maxDropProbDiff < currentDiff)
749 {
750 testAttributes->m_maxDropProbDiff = currentDiff;
751 }
752 }
753 testAttributes->m_prevDropProb = dropProb;
754}
755
756void
758 Ptr<PieQueueDiscTestItem> testAttributes)
759{
760 double dropProb = queue->m_dropProb;
761 double accuProb = queue->m_accuProb;
762 if (accuProb != 0)
763 {
764 double expectedAccuProb = testAttributes->m_prevAccuProb + dropProb;
765 testAttributes->m_accuProbError = accuProb - expectedAccuProb;
766 }
767 testAttributes->m_prevAccuProb = accuProb;
768}
769
770void
772 Ptr<PieQueueDiscTestItem> testAttributes)
773{
774 queue->m_dropProb = 0.001;
775 QueueSize queueSize = queue->GetCurrentSize();
776 if ((queueSize.GetUnit() == QueueSizeUnit::PACKETS && queueSize.GetValue() > 2) ||
777 (queueSize.GetUnit() == QueueSizeUnit::BYTES && queueSize.GetValue() > 2000))
778 {
779 testAttributes->m_expectedDrops = testAttributes->m_expectedDrops + 1;
780 }
781}
782
783void
785 uint32_t size,
786 uint32_t nPkt,
787 Ptr<PieQueueDiscTestItem> testAttributes)
788{
789 Address dest;
790 double delay = 0.01; // enqueue packets with delay
791 for (uint32_t i = 0; i < nPkt; i++)
792 {
793 Simulator::Schedule(Time(Seconds((i + 1) * delay)),
795 this,
796 queue,
797 size,
798 1,
799 testAttributes);
800 }
801}
802
803void
805{
806 for (uint32_t i = 0; i < nPkt; i++)
807 {
808 Ptr<QueueDiscItem> item = queue->Dequeue();
809 }
810}
811
812void
814{
815 for (uint32_t i = 0; i < nPkt; i++)
816 {
817 Simulator::Schedule(Time(Seconds((i + 1) * delay)),
819 this,
820 queue,
821 1);
822 }
823}
824
825void
827{
828 RunPieTest(QueueSizeUnit::PACKETS);
829 RunPieTest(QueueSizeUnit::BYTES);
831}
832
833/**
834 * \ingroup traffic-control-test
835 *
836 * \brief Pie Queue Disc Test Suite
837 */
838static class PieQueueDiscTestSuite : public TestSuite
839{
840 public:
842 : TestSuite("pie-queue-disc", Type::UNIT)
843 {
844 AddTestCase(new PieQueueDiscTestCase(), TestCase::Duration::QUICK);
845 }
846} g_pieQueueTestSuite; ///< the test suite
Pie Queue Disc Test Case.
void Dequeue(Ptr< PieQueueDisc > queue, uint32_t nPkt)
Dequeue function.
void RunPieTest(QueueSizeUnit mode)
Run test function.
void CheckMaxAccuProb(Ptr< PieQueueDisc > queue, Ptr< PieQueueDiscTestItem > testAttributes)
Check Maximum Accumulated Drop Probability.
void EnqueueWithDelay(Ptr< PieQueueDisc > queue, uint32_t size, uint32_t nPkt, Ptr< PieQueueDiscTestItem > testAttributes)
Enqueue with delay function.
void CheckAccuProb(Ptr< PieQueueDisc > queue, Ptr< PieQueueDiscTestItem > testAttributes)
Check Accumulated Drop Probability.
void CheckDropProb(Ptr< PieQueueDisc > queue, Ptr< PieQueueDiscTestItem > testAttributes)
Check Drop Probability.
void DequeueWithDelay(Ptr< PieQueueDisc > queue, double delay, uint32_t nPkt)
Dequeue with delay function.
void Enqueue(Ptr< PieQueueDisc > queue, uint32_t size, uint32_t nPkt, Ptr< PieQueueDiscTestItem > testAttributes)
Enqueue function.
void DoRun() override
Implementation to actually run this TestCase.
Pie Queue Disc Test Item.
double m_prevDropProb
Previous drop probability.
bool m_checkAccuProb
Enable/Disable accumulated drop probability checks.
bool m_ecnCapable
Enable/Disable ECN capability.
double m_maxDropProbDiff
Maximum difference between two consecutive drop probability values.
bool m_constAccuProb
Enable/Disable fixed accumulated drop probability.
bool m_ecnCapablePacket
ECN capable packet?
PieQueueDiscTestItem & operator=(const PieQueueDiscTestItem &)=delete
PieQueueDiscTestItem(const PieQueueDiscTestItem &)=delete
bool m_checkProb
Enable/Disable drop probability checks.
bool m_checkMaxAccuProb
Enable/Disable Maximum accumulated drop probability checks.
double m_maxDropProb
Maximum value of drop probability.
double m_prevAccuProb
Previous accumulated drop probability.
PieQueueDiscTestItem()=delete
void AddHeader() override
Add the header to the packet.
uint32_t m_expectedDrops
Number of expected unforced drops.
double m_setAccuProb
Value to be set for accumulated drop probability.
bool Mark() override
Marks the packet as a substitute for dropping it, such as for Explicit Congestion Notification.
double m_accuProbError
Error in accumulated drop probability.
Pie Queue Disc Test Suite.
a polymophic address class
Definition address.h:90
This class can be used to hold variables of floating point type such as 'double' or 'float'.
Definition double.h:31
static constexpr const char * UNFORCED_DROP
Early probability drops: proactive.
static constexpr const char * FORCED_DROP
Drops due to queue limit: reactive.
static constexpr const char * UNFORCED_MARK
Early probability marks: proactive.
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 void Run()
Run the simulation.
Definition simulator.cc:167
static void Stop()
Tell the Simulator the calling event should be the last one executed.
Definition simulator.cc:175
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
Hold an unsigned integer type.
Definition uinteger.h:34
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_LT(actual, limit, msg)
Test that an actual value is less than a limit and report and abort if not.
Definition test.h:699
#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_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
#define NS_TEST_ASSERT_MSG_GT(actual, limit, msg)
Test that an actual value is greater than a limit and report and abort if not.
Definition test.h:864
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition nstime.h:1308
PieQueueDiscTestSuite g_pieQueueTestSuite
the test suite
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Structure that keeps the queue disc statistics.
Definition queue-disc.h:177
uint32_t GetNDroppedPackets(std::string reason) const
Get the number of packets dropped for the given reason.
uint32_t GetNMarkedPackets(std::string reason) const
Get the number of packets marked for the given reason.
std::ofstream queueSize
uint32_t pktSize
packet size used for the simulation (in bytes)